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

核心工作负载 API GA

DaemonSet、Deployment、ReplicaSet 和 StatefulSet 均已达到 GA 稳定级别

编者按:我们很高兴地宣布,核心工作负载 API 在 Kubernetes 1.9 中已达到 GA 稳定级别!Kenneth Owens 的这篇博文回顾了核心工作负载从最初到 GA 的发展历程,揭示了 1.9 中的变化,并展望了未来的发展。

最初……

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

副本化是一个进步,但用户真正需要的是对其复制的 Pod 进行更高级别的编排。他们想要滚动更新、回滚和翻转。于是 OpenShift 团队创建了 DeploymentConfig。DeploymentConfig 也很有用,OpenShift 用户对此很高兴。为了让所有开源 Kubernetes 用户都能分享这份喜悦,并利用 基于集合的标签选择器ReplicaSetDeployment 被添加到 extensions/v1beta1 组版本,为所有 Kubernetes 用户提供滚动更新、回滚和翻转功能。

这在很大程度上解决了在 Kubernetes 上编排容器化 12 因素应用程序的问题,因此社区将注意力转向了另一个问题。将 Pod 复制 次并非集群中所有问题的正确解决方案。有时,您需要在每个节点或节点子集上运行 Pod(例如,像日志转发器和指标收集器这样的共享边车、Kubernetes 附加组件和分布式文件系统)。现有的技术是 Pod 与 NodeSelector 或静态 Pod 结合,但这很不方便。在习惯了 Deployment 提供的自动化便利性之后,用户要求为这类应用程序提供相同的功能,因此 DaemonSet 也被添加到 extension/v1beta1 中。

有一段时间,用户很满意,直到他们决定 Kubernetes 需要能够编排的不仅仅是 12 因素应用程序和集群基础设施。无论您的架构是 N 层、面向服务还是微服务,您的 12 因素应用程序都依赖有状态工作负载(例如,RDBMS、分布式键值存储和消息队列)来向最终用户和其他应用程序提供服务。这些有状态工作负载可能具有只有分布式系统才能实现的高可用性和持久性要求,用户已准备好使用 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 issue 或参与 SIG apps 告诉我们您的用例。

默认滚动更新

在 apps/v1beta2 之前,某些类型的更新策略默认设置为 RollingUpdate 以外的值(例如,app/v1beta1/StatefulSet 默认使用 OnDelete)。我们希望在将 RollingUpdate 设置为默认更新策略之前,确保它能正常工作,并且我们无法在已发布的版本中更改默认行为而不违反我们对向后兼容性的承诺。在 apps/v1beta2 中,我们默认启用了所有核心工作负载类型的 RollingUpdate。

createdBy 注解弃用

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

Scale 子资源

在 apps/v1beta2 中,所有适用类型都添加了 scale 子资源(DaemonSet 根据其节点选择器进行伸缩)。

Kubernetes 1.9 和 apps/v1

在 Kubernetes 1.9 中,按计划,我们将整个核心工作负载 API 表面提升到 apps/v1 组版本中的 GA 级别。我们做了一些额外的更改以使 API 保持一致,但 apps/v1 大体上与 apps/v1beta2 相同。实际情况是,大多数用户已经将核心工作负载 API 的 Beta 版本视为 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 控制器目前不填充它们,但我们将来可能会选择通过此机制将 Conditions 传递给客户端。

Scale 子资源迁移到 autoscale/v1

我们最初在 apps 组中添加了 scale 子资源。这对于与自动伸缩集成来说是错误的方向,而且,在某个时候,我们希望使用自定义指标来自动伸缩 StatefulSet。因此,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