本文超过一年。较旧的文章可能包含过时的内容。请检查页面中的信息自发布以来是否已变得不正确。

核心工作负载 API 正式发布

DaemonSet、Deployment、ReplicaSet 和 StatefulSet 正式发布 (GA)

编者按:我们很高兴地宣布,核心工作负载 API 在 Kubernetes 1.9 中正式发布!这篇 Kenneth Owens 的博文回顾了核心工作负载是如何从起源到正式发布的,揭示了 1.9 中的变化,并谈到了您可以期待的未来。

起初……

Pod,紧密耦合的容器共享资源需求、网络、存储和生命周期。Pod 很有用,但事实证明,用户希望无缝、可复制和自动地创建许多相同 Pod 的副本,因此我们创建了ReplicationController(副本控制器)。

复制是向前迈进了一步,但用户真正需要的是对其复制的 Pod 进行更高级别的编排。他们想要滚动更新、回滚和滚动升级。因此,OpenShift 团队创建了DeploymentConfig(部署配置)。DeploymentConfig 也很有用,OpenShift 用户很高兴。为了让所有 OSS Kubernetes 用户都能分享这种喜悦,并利用基于集合的标签选择器ReplicaSet(副本集)和Deployment(部署)被添加到 extensions/v1beta1 组版本中,为所有 Kubernetes 用户提供滚动更新、回滚和滚动升级。

这基本上解决了在 Kubernetes 上编排容器化 12 要素应用程序的问题,因此社区将注意力转向了另一个问题。将 Pod 复制 <n> 次并非适用于集群中所有情况的正确方法。有时,您需要在每个节点或节点的子集上运行 Pod(例如,共享边车(sidecar)程序,如日志传送器和指标收集器、Kubernetes 附加组件和分布式文件系统)。当时的最新技术是将 Pod 与 NodeSelectors 或静态 Pod 结合使用,但这很笨拙。在习惯了 Deployment 提供的自动化便利之后,用户要求对此类应用程序提供相同的功能,因此DaemonSet(守护进程集)也被添加到 extension/v1beta1 中。

有一段时间,用户很满意,直到他们决定 Kubernetes 需要能够编排的不仅仅是 12 要素应用程序和集群基础设施。无论您的架构是 N 层、面向服务还是面向微服务,您的 12 要素应用程序都依赖于有状态工作负载(例如,关系数据库、分布式键值存储和消息队列)来为最终用户和其他应用程序提供服务。这些有状态的工作负载可能具有只能通过分布式系统才能实现的可用性和持久性要求,并且用户已准备好使用 Kubernetes 来编排整个堆栈。

虽然 Deployment 非常适合无状态工作负载,但它们并不能为分布式系统的编排提供正确的保证。这些应用程序可能需要稳定的网络身份、有序的顺序部署、更新和删除,以及稳定、持久的存储。PetSet 被添加到 apps/v1beta1 组版本中,以解决此类应用程序。不幸的是,我们在命名方面考虑不周,并且,由于我们始终努力成为一个包容性社区,我们将类型重命名为StatefulSet(有状态集)。

终于,我们完成了。

...或者我们完成了吗?

Kubernetes 1.8 和 apps/v1beta2

Pod、ReplicationController、ReplicaSet、Deployment、DaemonSet 和 StatefulSet 统称为核心工作负载 API。我们终于可以编排所有东西了,但是 API 表面分散在三个组中,存在许多不一致之处,并且让用户想知道每个核心工作负载类型的稳定性。是时候停止添加新功能,而专注于一致性和稳定性了。

Pod 和 ReplicationController 处于 GA 稳定状态,即使您可以在 Pod 中运行工作负载,它也是属于核心的基本原语。由于 Deployment 是管理无状态应用程序的推荐方式,移动 ReplicationController 将毫无意义。在 Kubernetes 1.8 中,我们将所有其他核心工作负载 API 类型(Deployment、DaemonSet、ReplicaSet 和 StatefulSet)移动到 apps/v1beta2 组版本。这有利于在 API 表面提供更好的聚合,并允许我们打破向后兼容性以修复不一致之处。我们的计划是,当我们对其完整性感到满意时,将这个新的表面整体提升到 GA,并且保持原样。此版本中的修改(也在 apps/v1 中实现)如下所述。

弃用选择器默认值

在 apps 和 extensions 组的早期版本中,当未指定核心工作负载 API 类型的标签选择器时,默认情况下会将其设置为从该类型的模板标签生成的标签选择器。

这与策略性合并补丁和 kubectl apply 完全不兼容。此外,我们发现,通常情况下,从同一对象的另一个字段的值设置字段的默认值是一种反模式,对于用于编排工作负载的 API 对象尤其危险。

不可变选择器

选择器突变虽然允许某些用例(如可升级的 Deployment 金丝雀),但我们的工作负载控制器无法优雅地处理它,并且我们一直强烈建议用户不要这样做。为了提供一致、可用和稳定的 API,工作负载 API 中所有类型的选择器都设置为不可变。

我们相信有更好的方法来支持诸如可升级的金丝雀和精心策划的 Pod 重新标记等功能,但是,如果限制选择器突变对于我们的用户来说是必要的功能,我们可以在将来在不破坏向后兼容性的情况下放宽不可变性。

诸如可升级的金丝雀、精心策划的 Pod 重新标记和受限选择器可变性等功能的开发是由我们用户的需求信号驱动的。如果您当前正在修改核心工作负载 API 对象的选择器,请通过 GitHub 问题或参与 SIG 应用程序告诉我们您的用例。

默认滚动更新

在 apps/v1beta2 之前,某些类型的默认更新策略不是 RollingUpdate(例如,app/v1beta1/StatefulSet 默认使用 OnDelete)。我们希望在将其设置为默认更新策略之前确信 RollingUpdate 能够正常工作,并且我们无法在不破坏我们关于向后兼容性的承诺的情况下更改已发布版本中的默认行为。在 apps/v1beta2 中,我们默认情况下为所有核心工作负载类型启用了 RollingUpdate。

弃用 CreatedBy 注释

“kubernetes.io/created-by”是垃圾收集之前的遗留问题。用户应该使用其 ownerReferences 中对象的 ControllerRef 来确定对象所有权。我们在 1.8 中弃用了此功能,并在 1.9 中将其删除。

规模子资源

规模子资源已添加到 apps/v1beta2 中所有适用的类型(DaemonSet 根据其节点选择器进行扩展)。

Kubernetes 1.9 和 apps/v1

在 Kubernetes 1.9 中,按照计划,我们将 apps/v1 组版本中的整个核心工作负载 API 表面提升到 GA。我们进行了一些更改以使 API 保持一致,但 apps/v1 与 apps/v1beta2 基本相同。现实情况是,大多数用户已经将核心工作负载 API 的测试版视为 GA 一段时间了。任何仍在使用 ReplicationController 并且由于感知到的缺乏稳定性而回避 DaemonSet、Deployment 和 StatefulSet 的人都应该计划将其工作负载(如果适用)迁移到 apps/v1。晋升期间进行的细微更改如下所述。

垃圾收集默认设置为删除

在 apps/v1 之前,DaemonSet、Deployment、ReplicaSet 或 StatefulSet 中 Pod 的默认垃圾收集策略是孤立 Pod。也就是说,如果您删除了这些类型之一,则它们拥有的 Pod 将不会自动删除,除非显式指定级联删除。如果您使用 kubectl,您可能没有注意到这一点,因为这些类型在删除之前会缩放到零。在 apps/v1 中,所有核心工作负载 API 对象现在将在其所有者被删除时默认删除。对于大多数用户来说,此更改是透明的。
状态条件

在 apps/v1 之前,只有 Deployment 和 ReplicaSet 的 Status 对象中包含 Conditions。为了保持一致性,所有对象要么都应该有 Conditions,要么都不应该有。经过一番讨论,我们决定 Conditions 很有用,并将 Conditions 添加到了 StatefulSetStatus 和 DaemonSetStatus 中。StatefulSet 和 DaemonSet 控制器目前还没有填充它们,但我们将来可能会选择通过这种机制将状态信息传递给客户端。

Scale 子资源迁移到 autoscale/v1

我们最初将 scale 子资源添加到 apps 组中。这与自动缩放的集成方向错误,并且在某些时候,我们希望使用自定义指标来自动缩放 StatefulSets。因此,apps/v1 组版本使用 autoscaling/v1 scale 子资源。

迁移和弃用

您现在可能问的最多的问题是,“我迁移到 apps/v1 的路径是什么?我应该计划何时迁移?” Kubernetes 1.9 弃用了 apps/v1 之前的所有组版本,所有新代码都应该针对 apps/v1 进行开发,但是,如上所述,我们的许多用户将 extensions/v1beta1 视为 GA 版本。我们意识到这一点,并且我们的弃用策略中规定的最低支持时间线只是最低限度。

在将来的版本中,在完全删除任何组版本之前,我们将在 API 服务器中默认禁用它们。此时,您仍然可以使用该组版本,但必须显式启用它。我们还将提供实用程序来将 API 对象的存储版本升级到 apps/v1。请记住,所有核心工作负载类型的版本都是双向可转换的。如果您现在想手动更新核心工作负载 API 对象,可以使用kubectl convert在组版本之间转换清单。

下一步是什么?

核心工作负载 API 表面是稳定的,但它仍然是软件,而软件永远不会完成。我们经常向稳定的 API 添加功能以支持新的用例,我们也可能会对核心工作负载 API 这样做。GA 稳定性意味着我们添加的任何新功能都将与现有 API 表面严格向后兼容。从现在开始,我们所做的任何事情都不会破坏我们的向后兼容性保证。如果您希望参与 API 这部分的演变,请随时参与GitHub或参与SIG Apps