kubernetes v1.29 是 2023 年的第三个主要版本更新,也是今年的最后一个主要版本,包含 49 个主要更新。
翻译自 Kubernetes v1 中的新功能概述29,穆罕默德·本·侯赛因(Mohamed Ben Hassine)。 今年发布的第一个版本,v127 接近 60 个项目,第二版 v128 有 46 项。 尽管 Kubernetes 已经存在了将近 10 年,但 Kubernetes 仍然非常活跃!
此版本中有 19 项增强功能处于 alpha 阶段,19 项处于测试阶段,11 项处于稳定阶段。
如您所见,仍然有很多新功能正在逐步引入。
这个功能对于所有在 kubernetes 上开发的人来说都应该非常重要。 因为在大多数情况下,我们使用 CRD 在 Kubernetes 中实现功能扩展。
为了提供更好的用户体验和更可靠的输入验证,在通过 CRD 扩展功能时,需要支持验证。
CRD 目前原生支持两种类型的验证功能:
基于 CRD 结构定义的检查。
OpenAPIV3 验证规则。
例如:
apiversion: apiextensions.k8s.io/v1kind: customresourcedefinitionmetadata: annotations: controller-gen.kubebuilder.io/version: v0.13.0 name: kongplugins.configuration.konghq.comspec: group: configuration.konghq.com names: categories: -kong-ingress-controller kind: kongplugin listkind: kongpluginlist plural: kongplugins shortnames: -kp singular: kongplugin scope: namespaced versions: -name: v1 schema: openapiv3schema: description: kongplugin is the schema for the kongplugins api. properties: apiversion: description: 'apiversion defines the versioned schema of this representation of an object. servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. more info: ' type: string protocols: description: protocols configures plugin to run on requests received on specific protocols. items: description: kongprotocol is a valid kong protocol. this alias is necessary to deal with enum: -http - https - grpc - grpcs - tcp - tls - udp type: string type: array type: object ..x-kubernetes-validations: -message: using both config and configfrom fields is not allowed. rule: '!(has(self.config) &has(self.configfrom))' - message: using both configfrom and configpatches fields is not allowed. rule: '!(has(self.configfrom) &has(self.configpatches))' - message: the plugin field is immutable rule: self.plugin == oldself.plugin在上面的示例中,定义了一个名为 KongPluginin 的自定义资源,其中 OpenApiv3Schema 定义了 OpenAPI 架构的验证规则。
但是,这些内置规则相对有限。 如果要实现更丰富的验证规则功能,可以使用:
admission webhook
使用自定义验证程序。
然而准入 Webhook 和自定义验证器都与 CRD 本身解耦,这也增加了开发 CRD 的难度和后续维护成本。
为了解决这些问题,Kubernetes 社区为 CRD 引入了基于 CEL(通用表达式语言)的验证规则。 该规则可以直接写入 CRD 声明文件中,无需使用任何准入 Webhook 或自定义验证器,大大简化了 CRD 的开发和维护成本。
在 Kubernetes v1 中在版本 29 中,基于 CEL 的 CRD 验证能力达到 GA。 你只需要使用x-kubernetes-validations
定义验证规则。
它足够轻巧和安全,可以直接在 kube-apiserver 中运行。 让我们看一个例子:
apiversion: apiextensions.k8s.io/v1kind: customresourcedefinitionmetadata: annotations: controller-gen.kubebuilder.io/version: v0.13.0 name: kongplugins.configuration.konghq.comspec: group: configuration.konghq.com scope: namespaced versions: -name: v1 schema: openapiv3schema: description: kongplugin is the schema for the kongplugins api. properties: plugin: .x-kubernetes-validations: -message: using both config and configfrom fields is not allowed. rule: '!(has(self.config) &has(self.configfrom))' - message: the plugin field is immutable rule: self.plugin == oldself.plugin就像,在这句话中
self.plugin == oldself.plugin
self
跟oldself
表示更改之前和之后的资源对象。 一次plugin
一旦定义了字段的内容,就不允许对其进行修改。
此外,CEL具有非常丰富的功能,可以通过**游乐场体验。 正如我之前提到的,此功能已经可用两年多了。 它在 kubernetes v1 中在 25 年达到测试版并默认启用,现在终于达到 GA。
此外,Kubernetes Gateway API 项目正在删除其所有准入 Webhook,并使用基于 CEL 的规则对其进行验证。 这可能是目前社区中最大的单一用例。
在 Kubernetes 中,原生服务对象包含 nodeport 类型,用于向外部实体公开集群内的服务。 目前,创建新的节点端口并指定固定端口会带来一些风险。 指定的端口可能已被分配,导致冲突和服务创建失败。
此 Kubernetes 增强提案 (KEP) 建议为 nodeport 类型的服务引入动态和静态预留的可选范围,提供两种端口配置方法:
自动随机生成:Kubernetes 会根据预定义的规则自动生成端口。
手动设置:用户可以根据需要手动设置端口。
例如,可以使用 kube-apiserver--service-node-port-range
该标志控制 nodeport 可以使用的端口范围,默认范围为 30000-32767。 本 KEP 中建议的公式如下:
static band start=min(max($min,$node-range-size/$step),$max)哪里:
服务节点端口范围:30000-32767
范围大小:32767 30000 = 2767
带宽偏移: min(max(16,2767 32),128)=min(86,128)=86
静态带宽起始:30,000
静态带宽结束:30086
根据此计算,30000-30086 被视为静态段,而其余端口被视为动态段。
实施此方法可以降低使用固定端口创建节点端口类型服务时发生冲突的风险,从而提高整体集群稳定性。
┌──static │ dynamic │ gf]25c4[/gf]──gf]25ba[/gf] [gf]25c4[/gf]──gf]25ba[/gf]30000 30086 32767当用户希望自己指定节点端口端口时,如果所选端口位于上述静态范围内,则不太可能发生冲突。
首先,这个特性是 Kubernetes 的内部方面,对于大多数场景来说,一个简单的原则就足够了:“手动选择节点端口时,尽量选择前面提到的静态范围内的端口。 “如果用户指定的端口在动态范围内且尚未分配,则创建过程也将成功。
该计算方法源自 KEP-3070,用于为服务分配集群 IP,确保 Kubernetes 生态系统中的端口分配方法简化高效。
sidecar 充当辅助容器,并增强了主容器的功能。 虽然广泛用于服务网格场景,但许多用户也将它们部署在非服务网格上下文中,例如用于日志记录、监控和各种其他目的。
在使用 sidecar 的场景中,过去曾出现过问题。 一个值得注意的问题是缺乏对 sidecar 容器的生命周期管理。
例如,删除 Pod 时,如果 sidecar 容器缺乏适当的生命周期管理,可能会导致这些服务与主容器的生命周期之间的同步不匹配,从而对服务可靠性产生不利影响。
此 Kubernetes 增强提案 (KEP) 通过在 Pod 规范中将 sidecar 容器定义为 Init 容器的一部分来解决这些挑战。
此外,KEP 还规定 sidecar 容器应遵守“始终重启”策略。 通过将 sidecar 整合到具有一致重启策略的 init 容器中,该提案旨在增强 sidecar 容器的生命周期管理,从而促进服务网格和非服务网格场景的更好同步性和可靠性。
apiversion: v1kind: podmetadata: name: mohamedbenhassine-podspec: initcontainers: -name: log image: mohamedbenhassine/fluentbit restartpolicy: always ..在 Kubernetes v1 中29,此功能将默认启用,并且 sidecar 容器将按照启动时的相反顺序停止。
这可确保主容器首先停止,并有助于控制所有容器的组件生命周期。
这个 KEP 也很有趣,主要是为了简化最常见的需求之一。
许多应用程序 Pod 在关闭时需要断开连接,以避免影响用户流量。 因此,prestop 通常设置为在关闭之前执行一些相关处理或等待。
但是,当前的 Prestop 钩子只支持两种类型:exec 和 httpget。
此 KEP 旨在启用本机睡眠操作,例如:
apiversion: apps/v1kind: deploymentmetadata: name: nginxspec: template: spec: containers: -name: nginx image: nginx:1.25.3 lifecycle: prestop: sleep: seconds: 5 readinessprobe: httpget: path: / port: 80这可能非常简单。 在引入这个 kep 之前,需要将其设置为类似于 exec sh -c 的东西"sleep 5",这要求此命令包含在容器睡眠中。
但是,此功能目前处于 alpha 阶段,最终能否达到 GA 取决于社区的反馈。
在 Kubernetes 中,服务帐户令牌是确保安全性不可或缺的一部分。 它们用于对集群中的各个工作负载进行身份验证,并防止未经授权的访问。
kubernetes v1.29 这些令牌得到了进一步的保护:现在每个服务帐户只能与特定的 pod 实例相关联,并且在被泄露时不能被滥用。 这种方法有效地改善了服务帐户和 Pod 生命周期,大大降低了攻击者使用被盗令牌进行攻击的可能性。
在 v1 中29、kube-apiserver 具有以下相关功能门控来控制相关功能。 当然,除了 KEP-4193 之外,这个版本还推广了 KEP-2799,减少了基于 secret 的服务账号 token 的数量。 这有助于缩短令牌的有效性并最大程度地减少攻击面。
legacyserviceaccounttokencleanup=true|false (beta - default=true)serviceaccounttokenjti=true|false (alpha - default=false)serviceaccounttokennodebinding=true|false (alpha - default=false)serviceaccounttokennodebindin**alidation=true|false (alpha - default=false)serviceaccounttokenpodnodeinfo=true|false (alpha - default=false)这是一个有着悠久历史的KEP。 从最初的提案到GA花了5年时间,在此期间发生了很多有趣的事情。 这次涵盖的主要部分是以下指标:
container_cpu_usage_seconds_total
container_memory_working_set_bytes
container_start_time_seconds
node_cpu_usage_seconds_total
node_memory_working_set_bytes
pod_cpu_usage_seconds_total
pod_memory_working_set_bytes
resource_scrape_error
下面是一个示例的输出:
# help container_cpu_usage_seconds_total [stable] cumulative cpu time consumed by the container in core-seconds# type container_cpu_usage_seconds_total countercontainer_cpu_usage_seconds_total 0.195744 1691361886865# help container_memory_working_set_bytes [stable] current working set of the container in bytes# type container_memory_working_set_bytes gaugecontainer_memory_working_set_bytes 1.675264e+07 1691361886865# help container_start_time_seconds [stable] start time of the container since unix epoch in seconds# type container_start_time_seconds gauge此 KEP 的主要目的是允许每个组件公开自己的健康状态,以便可以根据集群健康状态的 SLI 计算集群的 SLO。
很久以前,Kubernetes 中有一个 componentstatus,可以用来查看集群中组件的状态。 但如下图所示,在 v1 中19 已被有效弃用。
mohamedbenhassine@k8s-test:~$kubectl get cswarning: v1 componentstatus is deprecated in v1.19+name status message errorscheduler healthy ok etcd-0 healthy ok controller-manager healthy ok我们希望使用此 KEP 将每个组件的运行状况状态用作 SLI,收集和聚合它,并计算集群的 SLO。 然后可以提供 SLA。 (对于对他们的关系感兴趣的朋友,可以搜索相关内容)。
下面是一个示例的输出:
test@mohamedbenhassine:/$ kubectl get --raw "/metrics/slis"# help kubernetes_healthcheck [stable] this metric records the result of a single healthcheck.# type kubernetes_healthcheck gaugekubernetes_healthcheck 1kubernetes_healthcheck 1kubernetes_healthcheck 1kubernetes_healthcheck 1kubernetes_healthcheck 1kubernetes_healthcheck 1kubernetes_healthcheck 1kubernetes_healthcheck 1在以前的版本中,ReadWriteOnce 访问模式允许共享节点上的多个 Pod 同时读取和写入同一卷。
使用 Kubernetes 1在 29 的发布中,readwriteoncepod 功能作为稳定版本中的新功能被引入。 这可确保整个集群独占的 Pod 对持久卷声明 (PVC) 具有独占读取或写入访问权限。
apiversion: v1kind: persistentvolumeclaimmetadata: name: my-pvcspec: accessmodes: -readwriteoncepod storageclassname: standard resources: requests: storage: 5gi这个新的 alpha 功能通过引入 matchlabelkeys 增强了 Podaffinity Podaffinity。 这一新增功能可确保在滚动更新期间进行更准确的计算,从而更好地控制基于指定标签键的 Pod 调度。
apiversion: apps/v1kind: deploymentmetadata: name: teckbootcamps-deploymentspec: template: spec: affinity: podaffinity: matchlabelkeys: -app-2024在 Kubernetes 版本 1 中29 中,增强了密钥管理服务 (KMS) v2 的稳定性。 此更新带来了改进的性能、密钥轮换功能、运行状况检查和增强的可观测性。 这些进步有助于在 Kubernetes 环境中对静态 API 数据进行安全加密。
apiversion: storage.k8s.io/v1kind: storageclassmetadata: name: encryptedprovisioner: kubernetes.io/aws-ebsvolumebindingmode: waitforfirstconsumerallowvolumeexpansion: true在 kubernetes 1 中29、默认配置涉及在没有与云服务提供商的内置集成的情况下运行。 用户可以灵活地启用外部云控制器管理器,或使用相关功能开关恢复到传统集成。
kubeadm init --cloud-provider=external在 v1 中事件化了此功能在 27 年升级到 beta,但在测试新版本时发现了一些问题,因此它现在默认禁用,并将在社区修复后再次启用。
在 v1 中推荐29 首先关闭此功能
KEP-2495:PV PVC readwriteoncepod 达到 GA 状态。
nodeexpandsecret 功能达到 ga 状态,kube-proxy 现在有了一个新的 nftables 后端。