这篇文章已超过一年。较旧的文章可能包含过时内容。请检查页面信息自发布以来是否已失效。

Core Workloads API 正式发布 (GA)

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

编辑注:我们很高兴地宣布 Core Workloads API 在 Kubernetes 1.9 中正式发布 (GA)!这篇来自 Kenneth Owens 的博文回顾了 Core Workloads 如何从起源发展到 GA,揭示了 1.9 中的变化,并展望了未来。

起初……

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

Replication 是向前迈进了一步,但用户真正需要的是对其副本 Pod 的更高层编排。他们需要滚动更新、回滚和翻转。因此 OpenShift 团队创建了 DeploymentConfig。DeploymentConfig 也很有用,OpenShift 用户对此很满意。为了让所有开源 Kubernetes 用户都能分享这份喜悦,并利用 基于集合的标签选择器,我们将 ReplicaSetDeployment 添加到了 extensions/v1beta1 组版本中,为所有 Kubernetes 用户提供了滚动更新、回滚和翻转功能。

这基本上解决了在 Kubernetes 上编排容器化 12 因素应用的问题,于是社区将注意力转向了另一个问题。将一个 Pod 复制 <n> 次并非集群中所有问题的合适解决方案。有时,你需要在每个节点上运行一个 Pod,或在一部分节点上运行(例如,像日志收集器和指标收集器这样的共享 side car、Kubernetes 附加组件以及分布式文件系统)。当时最先进的方法是将 Pod 与 NodeSelectors 或静态 Pods 结合使用,但这很不方便。习惯了 Deployment 提供的便捷自动化功能后,用户对这类应用也提出了同样的功能需求,因此 DaemonSet 也被添加到了 extension/v1beta1 中。

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

虽然 Deployments 非常适用于无状态工作负载,但它们无法为分布式系统的编排提供正确的保证。这些应用可能需要稳定的网络身份、有序的顺序部署、更新和删除,以及稳定、持久的存储。我们将 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 表面提供更好的聚合,并允许我们打破向后兼容性来修复不一致之处。我们的计划是在我们满意其完整性时,将这个新的 API 表面整体晋升到 GA。此版本中的修改(也在 apps/v1 中实现)如下所述。

选择器默认值已被废弃

在 apps 和 extensions 组的先前版本中,当未指定时,核心工作负载 API 类型的标签选择器会默认设置为由该类型的模板标签生成的标签选择器。

这与战略合并补丁 (strategic merge patch) 和 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 中将其移除。

扩缩容子资源

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

Kubernetes 1.9 和 apps/v1

在 Kubernetes 1.9 中,按照计划,我们将整个核心工作负载 API 表面在 apps/v1 组版本中晋升到 GA。我们做了一些额外的更改以使 API 保持一致,但 apps/v1 与 apps/v1beta2 基本相同。实际情况是,许多用户早已将核心工作负载 API 的 beta 版本视为 GA。任何仍然使用 ReplicationControllers 并因认为 DaemonSet、Deployment 和 StatefulSet 缺乏稳定性而回避它们的用户,都应计划将其工作负载(如适用)迁移到 apps/v1。晋升过程中进行的微小更改如下所述。

垃圾收集默认删除

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

在 apps/v1 之前,只有 Deployment 和 ReplicaSet 的 Status 对象中有 Conditions。为了保持一致性,所有对象都应有 Conditions,或者都没有。经过一番讨论,我们认为 Conditions 很有用,因此我们将 Conditions 添加到了 StatefulSetStatus 和 DaemonSetStatus 中。StatefulSet 和 DaemonSet 控制器目前不会填充这些 Conditions,但我们将来可能会选择通过这种机制向客户端传达状态。

扩缩容子资源迁移到 autoscale/v1

我们最初在 apps 组中添加了扩缩容子资源。这对于与自动扩缩容集成来说方向错误,而且在某个时候,我们希望使用自定义指标来自动扩缩容 StatefulSet。因此 apps/v1 组版本使用了 autoscale/v1 的扩缩容子资源。

迁移和废弃

你们现在可能最想问的问题是:“迁移到 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