本文发表于一年多前。旧文章可能包含过时内容。请检查页面中的信息自发布以来是否已变得不正确。
Kubernetes v1.28: Planternetes
宣布 Kubernetes v1.28 Planternetes 的发布,这是 2023 年的第二个版本!
此版本包含 45 项增强功能。在这些增强功能中,19 项进入 Alpha 阶段,14 项升级到 Beta 阶段,12 项升级到稳定(Stable)阶段。
发布主题和徽标
Kubernetes v1.28:Planternetes
Kubernetes v1.28 的主题是 Planternetes。

每个 Kubernetes 版本都是我们社区数千名成员辛勤工作的结晶。这个版本背后的人们来自各种各样的背景,有的是行业资深人士、父母,有的是学生和开源新手。我们将我们独特的经验结合起来,创造出一个具有全球影响力的集体成果。
就像一座花园,我们的版本总是在不断地成长,面临着挑战和机遇。这个主题旨在庆祝为使版本达到今天的状态所付出的精心呵护、意图和努力。和谐共处,我们共同成长得更好。
新功能(主要主题)
控制平面和节点版本之间支持的版本倾斜变更
Kubernetes v1.28 将核心节点和控制平面组件之间支持的版本倾斜度从 n-2 扩展到了 n-3,增加了一个小版本。这样,最旧的支持小版本的节点组件(kubelet 和 kube-proxy)可以与最新的支持小版本的控制平面组件(kube-apiserver、kube-scheduler、kube-controller-manager、cloud-controller-manager)协同工作。
一些集群运营者会避免节点维护,特别是对节点行为的更改,因为节点是工作负载运行的地方。对于 kubelet 的小版本升级,支持的流程包括排空该节点,因此会中断在该节点上执行的所有 Pod。对于运行时间非常长的工作负载的 Kubernetes 最终用户,以及希望 Pod 尽可能保持运行的情况,减少因节点维护而损失的时间是一个好处。
Kubernetes 的年度支持期已经使得年度升级成为可能。用户可以升级到最新的补丁版本以获取安全修复,并每年进行一次连续 3 个小版本的升级,以“赶上”最新的受支持小版本。
以前,为了保持在支持的版本倾斜范围内,计划进行年度升级的集群操作员需要升级他们的节点两次(可能仅相隔数小时)。现在,有了 Kubernetes v1.28,您可以选择每年只对节点进行一次小版本升级,同时仍然保持在上游支持范围内。
如果你想保持最新状态并更频繁地升级你的集群,那也完全没问题,并且仍然完全受支持。
正式发布:从非平滑节点关闭中恢复
如果节点意外关闭或进入不可恢复状态(可能是由于硬件故障或操作系统无响应),Kubernetes 允许你事后进行清理,并让有状态的工作负载在不同的节点上重新启动。对于 Kubernetes v1.28,这现在是一个稳定功能。
这使得有状态的工作负载在原始节点关闭或处于不可恢复状态(如硬件故障或操作系统损坏)后,能够成功地故障转移到另一个节点。
v1.20 之前的 Kubernetes 版本缺乏对 Linux 上节点关闭的处理,kubelet 与 systemd 集成并实现了平滑节点关闭(Beta 版,默认启用)。然而,即使是有意为之的关闭也可能处理不当,原因可能是:
- 该节点运行 Windows
- 节点运行 Linux,但使用不同的
init
系统(不是systemd
) - 关闭操作没有触发系统抑制锁机制
- 由于节点级配置错误(例如未为 `shutdownGracePeriod` 和 `shutdownGracePeriodCriticalPods` 设置适当的值)。
当一个节点关闭或发生故障,并且该关闭未被 kubelet 检测到时,属于 StatefulSet 的 Pod 将停留在已关闭节点上的终止状态。如果停止的节点重新启动,该节点上的 kubelet 可以清理(`DELETE`)那些 Kubernetes API 仍然认为绑定到该节点的 Pod。但是,如果节点一直处于停止状态——或者如果 kubelet 在重启后无法启动——那么 Kubernetes 可能无法创建替换的 Pod。当已关闭节点上的 kubelet 无法删除旧的 Pod 时,相关的 StatefulSet 无法创建新的 Pod(该 Pod 将具有相同的名称)。
存储方面也存在问题。如果 Pod 使用了卷,现有的 VolumeAttachments 将不会与原始的、现已关闭的节点解除关联,因此这些 Pod 使用的 PersistentVolumes 无法附加到另一个健康的节点上。结果,运行在受影响的 StatefulSet 上的应用程序可能无法正常运行。如果原始的、已关闭的节点恢复运行,那么它的 Pod 将被其 kubelet 删除,新的 Pod 可以在另一个运行中的节点上创建。如果原始节点没有恢复运行(在使用不可变基础设施设计时很常见),那些 Pod 将永远停留在已关闭节点上的 `Terminating` 状态。
要了解更多关于如何在非平滑节点关闭后触发清理的信息,请阅读非平滑节点关闭。
CustomResourceDefinition 验证规则的改进
通用表达式语言(CEL)可用于验证自定义资源。主要目标是允许大多数验证用例,而这些用例过去可能需要你作为 CustomResourceDefinition (CRD) 的作者来设计和实现一个 webhook。相反,作为一个 Beta 功能,你可以将**验证表达式**直接添加到 CRD 的模式中。
CRD 需要直接支持非平凡的验证。虽然准入 Webhook 确实支持 CRD 验证,但它们显著地复杂化了 CRD 的开发和可操作性。
在 1.28 中,添加了两个可选字段 `reason` 和 `fieldPath`,允许用户在验证失败时指定失败原因和字段路径。
欲了解更多信息,请阅读 CRD 文档中的验证规则。
ValidatingAdmissionPolicies 进阶至 Beta
用于准入控制的通用表达式语言是一种可定制的、进程内的对 Kubernetes API 服务器请求的验证方式,作为验证性准入 Webhook 的替代方案。
这建立在 1.25 版本中升级到 Beta 的 CRD 验证规则功能之上,但更侧重于验证性准入控制的策略执行能力。
这将降低实施可定制策略的基础设施门槛,并提供有助于社区建立和遵守 K8s 及其扩展的最佳实践的原语。
要使用ValidatingAdmissionPolicies,您需要在集群的控制平面中启用 `admissionregistration.k8s.io/v1beta1` API 组和 `ValidatingAdmissionPolicy` 特性门控。
准入 Webhook 的匹配条件
Kubernetes v1.27 允许你为准入 Webhook 指定**匹配条件**,这使你能够缩小 Kubernetes 在准入时进行远程 HTTP 调用的范围。ValidatingWebhookConfiguration 和 MutatingWebhookConfiguration 的 `matchCondition` 字段是一个 CEL 表达式,必须评估为 true,准入请求才会被发送到 Webhook。
在 Kubernetes v1.28 中,该字段已升级为 Beta,并且默认启用。
要了解更多信息,请参阅 Kubernetes 文档中的 `matchConditions`。
在 Linux 上启用交换空间的 Beta 支持
这以一种受控、可预测的方式为节点添加了交换空间支持,以便 Kubernetes 用户可以进行测试并提供数据,从而在交换空间之上继续构建集群能力。
交换空间有两种截然不同的用户类型,他们可能会重叠:
节点管理员,他们可能希望交换空间可用于节点级性能调优和稳定性/减少“吵闹邻居”问题。
应用程序开发者,他们编写的应用程序可以从使用交换内存中受益。
混合版本代理 (Alpha)
当集群中有多个不同版本的 API 服务器时(例如在升级/降级期间或当运行时配置发生变化并进行滚动更新时),并非每个 API 服务器都能处理所有资源的所有版本。
对于 Kubernetes v1.28,您可以在 API 服务器的聚合层中启用**混合版本代理**。混合版本代理会查找本地 API 服务器无法识别但控制平面内另一个 API 服务器能够支持的请求。找到合适的对等点后,聚合层会将请求代理到兼容的 API 服务器;这对客户端来说是透明的。
当对集群执行升级或降级时,在一段时间内,控制平面内的 API 服务器可能处于不同版本;当这种情况发生时,API 服务器的不同子集能够提供不同的内置资源集(不同的组、版本和资源都是可能的)。这种新的 alpha 机制可以让你向客户端隐藏这种版本差异。
控制平面组件的源代码重组
Kubernetes 贡献者已经开始重组 kube-apiserver 的代码,以构建一个新的暂存(staging)仓库。该仓库消费 k/apiserver,但包含了一个更大、经过精心挑选的 kube-apiserver 功能子集,以便可以重用。
这是一个渐进的重组;最终会有一个新的 git 仓库,其中包含从 Kubernetes 的 API 服务器中抽象出的通用功能。
支持向容器注入 CDI (alpha)
CDI 提供了一种将复杂设备注入容器的标准化方法(即,那些逻辑上需要注入多个 /dev 节点才能工作的设备)。这个新功能使得插件开发者可以利用在 1.27 版本 CRI 中新增的 CDIDevices 字段,将 CDI 设备直接传递给支持 CDI 的运行时(其中 containerd 和 crio-o 在最近的版本中已经支持)。
Sidecar 容器的 API 感知 (alpha)
Kubernetes 1.28 为初始化容器引入了一个 alpha 版本的 `restartPolicy` 字段,并用它来指示一个初始化容器是否也是一个**sidecar 容器**。kubelet 将按照定义的顺序启动 `restartPolicy: Always` 的初始化容器,以及其他初始化容器。kubelet 不会等待该 sidecar 容器完成后再启动 Pod 的主容器,而只会等待 sidecar 初始化容器已经启动。
如果启动探针成功且 postStart 处理器完成,kubelet 将认为 sidecar 容器的启动已经完成。这种情况由 ContainerStatus 类型的 Started 字段表示。如果你没有定义启动探针,kubelet 将在 postStart 处理器完成后立即认为容器启动完成。
对于 Init 容器,你可以省略 `restartPolicy` 字段,或者将其设置为 `Always`。省略该字段意味着你想要一个真正的 Init 容器,它在应用程序启动前运行至完成。
Sidecar 容器不会阻塞 Pod 的完成:如果所有常规容器都已完成,该 Pod 中的 sidecar 容器将被终止。
一旦 sidecar 容器已经启动(进程正在运行,`postStart` 已成功,并且任何配置的启动探针都通过),然后如果出现故障,即使 Pod 的整体 `restartPolicy` 是 `Never` 或 `OnFailure`,该 sidecar 容器也会被重启。此外,sidecar 容器将在**Pod 终止期间**被重启(无论是因为故障还是正常退出)。
要了解更多信息,请阅读Sidecar 容器的 API。
自动、追溯性地分配默认 StorageClass 的功能进入稳定阶段
如果你不提供值,Kubernetes 会自动为 PersistentVolumeClaim (PVC) 设置一个 `storageClassName`。控制平面还会为任何没有定义 `storageClassName` 的现有 PVC 设置一个 StorageClass。以前版本的 Kubernetes 也有这种行为;对于 Kubernetes v1.28,这是自动且始终激活的;该功能已升级至稳定(正式发布)。
要了解更多信息,请阅读 Kubernetes 文档中关于 StorageClass 的内容。
Job 的 Pod 替换策略 (alpha)
Kubernetes 1.28 为 Job API 添加了一个新字段,允许你指定是希望控制平面在旧 Pod 开始终止时就创建新 Pod(现有行为),还是仅在现有 Pod 完全终止后才创建(新的可选行为)。
许多常见的机器学习框架,如 Tensorflow 和 JAX,要求每个索引都有唯一的 Pod。在旧的行为下,如果一个属于 `Indexed` Job 的 Pod 进入终止状态(由于抢占、驱逐或其他外部因素),会创建一个替换的 Pod,但由于与尚未关闭的旧 Pod 冲突,新 Pod 会立即启动失败。
在旧的 Pod 完全终止之前就出现替换 Pod,也可能在资源稀缺或预算紧张的集群中引起问题。这些资源可能难以获取,因此 Pod 可能只有在现有 Pod 终止后才能找到节点。如果启用了集群自动伸缩器,提前创建替换 Pod 可能会产生不希望的扩容。
要了解更多信息,请阅读 Job 文档中的延迟创建替换 Pod。
按索引计数的 Job 重试退避限制 (alpha)
此功能扩展了 Job API,以支持索引式 Job,其中退避限制是按索引计数的,即使某些索引失败,Job 也可以继续执行。
目前,索引式作业的索引共享一个单一的退避限制。当作业达到这个共享的退避限制时,作业控制器会将整个作业标记为失败,并清理资源,包括那些尚未运行完成的索引。
因此,现有的实现没有涵盖工作负载是真正的易并行的情况:每个索引都完全独立于其他索引。
例如,如果使用索引式作业作为一套长时间运行的集成测试的基础,那么每次测试运行只能发现一个测试失败。
欲了解更多信息,请阅读 Kubernetes 文档中的处理 Pod 和容器故障。
更正:功能“无 cAdvisor 的 CRI 容器和 Pod 统计”已被移除,因为它未包含在此版本中。最初的发布公告曾声明 Kubernetes 1.28 包含了该新功能。
Kubernetes v1.28 中的功能升级和弃用
升级到稳定版
此版本共包含 12 项升级为稳定的增强功能:
- `kubectl events`
- 追溯性默认 StorageClass 分配
- 非平滑节点关闭
- 支持第三方设备监控插件
- 用于获取自身用户属性的 Auth API
- 代理正在终止的端点
- 扩展的 DNS 配置
- 清理 IPTables 链所有权
- 最小化 iptables-restore 输入大小
- 将 kubelet pod 资源端点升级至 GA
- 扩展 podresources API 以报告可分配资源
- 将 EndpointSlice Reconciler 移至 Staging
弃用和移除
移除
弃用
版本说明
Kubernetes v1.28 发布的完整详情可在我们的版本说明中找到。
可用性
Kubernetes v1.28 可在 GitHub 上下载。要开始使用 Kubernetes,您可以使用 minikube、kind 等工具运行本地 Kubernetes 集群。您也可以使用 kubeadm 轻松安装 v1.28。
发布团队
Kubernetes 的成功离不开其社区的支持、承诺和辛勤工作。每个发布团队都由敬业的社区志愿者组成,他们共同努力,构建出你所依赖的 Kubernetes 版本的各个部分。这需要我们社区各个角落的人们贡献他们的专业技能,从代码本身到文档和项目管理。
我们想感谢整个发布团队,感谢他们花费了大量时间辛勤工作,以确保我们为社区提供一个坚实的 Kubernetes v1.28 版本。
特别感谢我们的发布负责人 Grace Nguyen,感谢她带领我们顺利、成功地完成了这个发布周期。
生态系统更新
- KubeCon + CloudNativeCon China 2023 将于 2023 年 9 月 26 日至 28 日在中国上海举行!您可以在活动网站上找到有关会议和注册的更多信息。
- KubeCon + CloudNativeCon North America 2023 将于 2023 年 11 月 6 日至 9 日在美国伊利诺伊州芝加哥举行!您可以在活动网站上找到有关会议和注册的更多信息。
项目速度
CNCF K8s DevStats 项目汇总了许多与 Kubernetes 及其各个子项目开发速度相关的有趣数据点。这包括从个人贡献到贡献公司数量的各种信息,展示了发展这个生态系统所付出的努力的深度和广度。
在 v1.28 发布周期中,该周期持续了 14 周(5 月 15 日至 8 月 15 日),我们看到了来自 911 家公司和 1440 位个人的贡献。
即将举行的发布网络研讨会
欢迎在 2023 年 9 月 6 日(星期三)太平洋夏令时间上午 9 点加入 Kubernetes v1.28 发布团队成员的在线研讨会,了解此版本的主要功能,以及弃用和移除的内容,以帮助规划升级。更多信息和注册,请访问 CNCF 在线项目网站上的活动页面。
参与其中
参与 Kubernetes 的最简单方法是加入与你兴趣相符的众多特别兴趣小组(SIG)之一。
有什么想向 Kubernetes 社区广播的内容吗?在我们每周的社区会议上分享你的声音,并通过以下渠道进行分享:
在Kubernetes 贡献者网站上了解更多关于为 Kubernetes 做出贡献的信息。
在 Twitter 上关注我们 @Kubernetesio 以获取最新更新。
在 Discuss 上加入社区讨论。
在 Slack 上加入社区。
在 Server Fault 上提问(或回答问题)。
分享你的 Kubernetes 故事。
在博客上阅读更多关于 Kubernetes 的最新动态。
了解更多关于 Kubernetes 发布团队 的信息。