CRD 状态有什么用?

问题描述

我目前正在使用 operator-sdk 在 go 中编写 kubernetes 运算符。 此运算符创建了两个 StatefulSet 和两个 Service,并带有一些业务逻辑。

我想知道 CRD 状态是什么?在我的协调方法中,我使用认客户端(即 r.List(ctx,&setList,opts...))从集群中获取数据,我是否应该将数据存储在状态中以便稍后使用? 如果是这样,这种状态有多可靠?我的意思是它坚持了吗?如果控制平面死亡,它仍然可用吗? 灾难恢复怎么样,如果持久化数据消失了怎么办?这种情况不会使 CRD 状态的使用无效吗?

解决方法

CRD 的状态子资源可以被认为与非自定义资源具有相同的目标。虽然 spec 定义了该特定资源的期望状态,但基本上我声明了我想要的,status 反而解释了我在集群上声明的资源的当前情况,并且应该帮助理解期望状态和实际状态之间的区别。

StatefulSet spec 可以说我想要 3 个副本,它的 状态 表示现在只有 1 个副本准备就绪,并且下一个仍在开始,自定义资源状态可能会告诉我我在规范中声明的任何内容的当前情况。

例如,使用 Rook Operator,我可以声明我想要以某种方式制作的 CephCluster。由于 CephCluster 是一个相当复杂的东西(由几个 StatefulSet、Daemons 等组成),自定义资源定义的状态会告诉我整个 ceph 集群的当前情况,它的健康状况是否正常或者是否有什么需要我注意和以此类推。

根据我对 Kubernetes API 的理解,您不应该依赖状态子资源来决定您的操作员应该对 CRD 做什么,因为始终检查集群的当前情况(在运算符开始或定义、更新或删除资源时)


最后,让我引用 Kubernetes API 约定,因为它很好地解释了约定 (https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status)

按照惯例,Kubernetes API 区分 对象所需状态的规范(嵌套对象字段 称为“spec”)和对象当前的状态(a 名为“状态”的嵌套对象字段)。

规范是一个完整的 所需状态的描述,包括配置设置 用户提供,系统扩展的默认值,以及 在其他人创建后初始化或以其他方式更改的属性 生态系统组件(例如,调度程序、自动缩放程序),并且是 与 API 对象一起保存在稳定的存储中。如果规范 被删除,该对象将从系统中清除。

状态 总结系统中对象的当前状态,是 通常通过自动化过程与对象持久化,但也可能 动态生成。付出一些代价,也许是暂时的 行为退化,状态可以通过以下方式重建 观察是否丢失。

当一个对象的新版本被发布或放置时,“规范”是 更新并立即可用。随着时间的推移,系统将工作 使“状态”与“规范”一致。系统会驱动 朝着最新的“规范”,无论以前的版本如何 节。换句话说,如果一个值在一个 PUT 中从 2 变为 5 然后在另一个 PUT 中回退到 3,系统不需要 在将“状态”更改为 3 之前,将 'touch base' 设置为 5。换句话说, 系统的行为是基于层次的,而不是基于边缘的。这 在丢失中间状态的情况下实现稳健的行为 变化。