赞
踩
公众号关注 「奇妙的 Linux 世界」
设为「星标」,每天带你玩转 Linux !
Kubernetes v1.29 是 2023 年的第三个大版本更新,也是今年的最后一个大版本,包含了 49 项主要的更新。 而今年发布的第一个版本 v1.27 有近 60 项,第二个版本 v1.28 有 46 项。尽管 Kubernetes 已经发布快 10 年了,Kubernetes 的生命力仍然很旺盛!
这个版本中有 19 个增强功能正在进入 Alpha 阶段,19 个将升级到 Beta 阶段,而另外 11 个则将升级到稳定版。
可以看出来还是有很多新特性在逐步引入。
我维护的 「k8s生态周报」每篇都有一个叫上游进展的部分,会发一些值得关注的内容。不过正如我上篇提到的那样,最近发生了很多事情,断更了一段时间,这篇恰好都补上,感谢大家的支持。
这个特性对于所有在 Kubernetes 上进行开发的小伙伴来说应该都是非常重要的。因为大多数情况下,我们都是通过 CRD 来实现 Kubernetes 中的功能扩展。
在通过 CRD 实现功能扩展的时候,为了能提供更好的用户体验,和更可靠的输入校验,就需要支持校验了。
CRD 目前原生支持两类校验能力:
基于 CRD 结构定义的校验
OpenAPIv3 的校验规则
例如:
- ---
- apiVersion: apiextensions.k8s.io/v1
- kind: CustomResourceDefinition
- metadata:
- annotations:
- controller-gen.kubebuilder.io/version: v0.13.0
- name: kongplugins.configuration.konghq.com
- spec:
- 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: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
- 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 https://github.com/kubernetes-sigs/controller-tools/issues/342
- 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
以上示例中定义了一个名为 KongPlugin
的自定义资源,其中使用 openAPIV3Schema
定义了 OpenAPI schema 的校验规则。
但这些内置规则能达到的效果相对有限,如果想要实现更加丰富的校验规则/特性,则可以使用:
Admission Webhook: 关于 Adminssion webhook 可以参考我之前的文章 理清 Kubernetes 中的准入控制(Admission Controller) | MoeLove
使用自定义验证器:例如基于 Open Policy Agent(OPA) 的 Gatekeeper,关于 OPA 可以参考 Open Policy Agent (OPA) 入门实践 | MoeLove
不过 无论是 Admission webhook 还是自定义验证器,它们与 CRD 自身都是分离的,并且这也会导致开发 CRD 的难度和后续的维护成本增加。
为了能解决这些问题,Kubernetes 社区为 CRD 引入了一种基于 CEL(Common Expression Language)的校验规则,这个规则是可以直接 在 CRD 的声明文件中编写的,无需使用任何 Admission webhook 或者自定义验证器,大大简化了 CRD 的开发和维护成本。
在 Kubernetes v1.29 版本中基于 CEL 的 CRD 校验能力达到 GA,只需要使用 x-kubernetes-validations
定义校验规则即可, 它足够轻量且安全,可以直接在 kube-apiserver 中运行,我们来看一个例子:
- ---
- apiVersion: apiextensions.k8s.io/v1
- kind: CustomResourceDefinition
- metadata:
- annotations:
- controller-gen.kubebuilder.io/version: v0.13.0
- name: kongplugins.configuration.konghq.com
- spec:
- 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 还有非常丰富的特性,可以通过在线的 Playground 来体验它 https://playcel.undistro.io/
正如我前面提到的,这个特性引入的时间已经两年多了,在 Kubernetes v1.25 中达到 Beta 并默认开启,如今终于达到了 GA。
额外一说,Kubernetes Gateway API 项目正在将它的所有 Admission webhook 删掉,全部使用基于 CEL 的规则进行校验, 这大概是目前社区中最大的一个用例了。
众所周知 Kubernetes 原生的 Service 对象有一种 NodePort 的类型,用于将集群内的服务暴露到集群外。
在当前情况下,如果用户想要新建一个 NodePort,并为它固定的指定一个 Port,其实是存在一定的风险的。有可能指定的 Port 已经被分配出去了,这样就会冲突,导致 Service 创建失败。
这个 KEP 提出了为 NodePort 类型的 Services 动、静态地预留一段可选区间,并且支持两种方式进行 Port 配置:
自动化地随机生成(由 Kubernetes 按照规则自动生成)
手工设置(由用户根据需求自行设定)。
举个例子:
kube-apiserver 可以通过 --service-node-port-range
控制 NodePort 可以使用的端口范围,默认是 30000-32767
。在这个 KEP 中引入的计算公式是:min(max($min, node-range-size/$step), $max)
,也就是说:
Service Node Port 范围: 30000-32767
范围大小: 32767 - 30000 = 2767
Band Offset: min(max(16,2767/32),128) = min(86,128) = 86
Static band start: 30000
Static band ends: 30086
按照这种方式计算,也就是 30000-30086 作为 static 段,之后的作为 dynamic 段。
- ┌─────────────┬─────────────────────────────────────────────┐
- │ static │ dynamic │
- └─────────────┴─────────────────────────────────────────────┘
-
- ◄────────────► ◄────────────────────────────────────────────►
- 30000 30086 32767
如果用户想要自己指定一个 NodePort 的端口,若在 static 范围内,则相对来说不容易出现冲突。
不过,总体来说这个特性实际上是一个 Kubernetes 内部的特性,多数情况下只要记住一个原则:“手动指定 NodePort 时尽量选择在 static 范围(前段)内即可”。如果用户指定的 Port 在 dynamic 范围内,如果该 Port 尚未被分配,则也可以创建成功。
这种计算方式实际上是来自于 KEP-3070,用于给 Service 分配 ClusterIP 使用的。
Sidecars 是一种辅助容器,它们能够给主容器添加额外功能。尽管这种模式在 Service Mesh 场景用例更多,但很多用户也会在非 Service Mesh 场景下使用,比如像日志记录、监控等场景。
但是之前 Sidecars 在这些场景中使用存在一些问题,比如当 Pod 删除的时候,由于 Sidecar 容器的生命周期管理的缺失,会导致这些服务和主容器的生命周期不同步,进而影响服务的可靠性。
这个 KEP 在 Pod 规范中将 Sidecar 容器定义为 init containers 的一部分,并且指定其具有“始终重启”策略。
- apiVersion: v1
- kind: Pod
- metadata:
- name: moelove-pod
- spec:
- initContainers:
- - name: log
- image: moelove/fluentbit
- restartPolicy: Always
- ...
在 Kubernetes v1.29 版本中该特性将默认启用,同时 Sidecar containers 的停止顺序将按照与它们启动时候相反的顺序来进行,这样一方面可以确保是主容器先停止的,另一方面也便于控制所有组件的生命周期。
这个 KEP 也比较有意思,主要是为了简化一个最常见的需求。
很多应用 Pod 在关闭的时候,需要断开连接,以免影响用户流量。所以很多时候会在关闭前设置 PreStop 来进行一些相关的处理或者等待。
但是当前的 PreStop Hook 只支持 exec
和 httpGet
这两种,这个 KEP 是想要实现一种原生的 sleep
操作,例如:
- apiVersion: apps/v1
- kind: Deployment
- metadata:
- name: nginx
- spec:
- 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"
这样,这需要容器内还包含 sleep
这个命令才行。
不过这个特性目前处于 Alpha,能否最终 GA 还需要看看社区的反馈。
在 Kubernetes 中,service account token 是保障安全性不可或缺的一环。它们用于验证集群中各个工作负载,并且可以防止未经授权访问。
Kubernetes v1.29 中进一步加强了对这些令牌的安全保护:现在每个 service account 仅能与特定 Pod 实例相关联,在外泄后也无法被滥用。这种方式有效地将 service account 和 Pod 生命周期捆绑在一起,大大减少了攻击者利用盗取 token 进行攻击的可能。
在 v1.29 中 kube-apiserver 有如下相关的 feature gates 可以控制相关的特性,当然除了 KEP-4193 外,这个版本中也推进了 KEP-2799,减少了基于 secret 的 service account token。这有助于缩短 Token 的有效时间,尽可能的减少攻击面。
- LegacyServiceAccountTokenCleanUp=true|false (BETA - default=true)
- ServiceAccountTokenJTI=true|false (ALPHA - default=false)
- ServiceAccountTokenNodeBinding=true|false (ALPHA - default=false)
- ServiceAccountTokenNodeBindingValidation=true|false (ALPHA - default=false)
- ServiceAccountTokenPodNodeInfo=true|false (ALPHA - default=false)
这是一个有很长历史的 KEP 了,从开始提出到现在 GA 用了 5 年的时间,中间也发生了很多有趣的事情。这次主要涉及的部分是如下 metrics:
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 counter
- container_cpu_usage_seconds_total{container="coredns",namespace="kube-system",pod="coredns-55968cc89d-bhhbx"} 0.195744 1691361886865
- # HELP container_memory_working_set_bytes [STABLE] Current working set of the container in bytes
- # TYPE container_memory_working_set_bytes gauge
- container_memory_working_set_bytes{container="coredns",namespace="kube-system",pod="coredns-55968cc89d-bhhbx"} 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
- container_start_time_seconds{container="coredns",namespace="kube-system",pod="coredns-55968cc89d-bhhbx"} 1.6913618235901163e+09 1691361823590
- # HELP node_cpu_usage_seconds_total [STABLE] Cumulative cpu time consumed by the node in core-seconds
- # TYPE node_cpu_usage_seconds_total counter
- node_cpu_usage_seconds_total 514578.636 1691361887931
- # HELP node_memory_working_set_bytes [STABLE] Current working set of the node in bytes
- # TYPE node_memory_working_set_bytes gauge
- node_memory_working_set_bytes 1.9501084672e+10 1691361887931
- # HELP pod_cpu_usage_seconds_total [STABLE] Cumulative cpu time consumed by the pod in core-seconds
- # TYPE pod_cpu_usage_seconds_total counter
- pod_cpu_usage_seconds_total{namespace="kube-system",pod="coredns-55968cc89d-bhhbx"} 1.30598 1691361880003
- # HELP pod_memory_working_set_bytes [STABLE] Current working set of the pod in bytes
- # TYPE pod_memory_working_set_bytes gauge
- pod_memory_working_set_bytes{namespace="kube-system",pod="coredns-55968cc89d-bhhbx"} 1.6715776e+07 1691361880003
- # HELP resource_scrape_error [STABLE] 1 if there was an error while getting container metrics, 0 otherwise
- # TYPE resource_scrape_error gauge
- resource_scrape_error 0
- # HELP scrape_error [ALPHA] 1 if there was an error while getting container metrics, 0 otherwise
- # TYPE scrape_error gauge
- scrape_error 0
这个 KEP 的主要目的是为了让每个组件暴露它们自己的健康状态,以便于可以根据其健康状态的 SLI 计算集群的 SLO。
很久之前 Kubernetes 中存在一个 ComponentStatus,可以用于查看集群中组件的状态。但正如下方所示,在 v1.19 已经实际上废弃了。
- moelove@k8s-test:~$ kubectl get cs
- Warning: v1 ComponentStatus is deprecated in v1.19+
- NAME STATUS MESSAGE ERROR
- scheduler Healthy ok
- etcd-0 Healthy ok
- controller-manager Healthy ok
我们期望能通过这个 KEP 使用各个组件的健康状态作为 SLI,采集聚合后,计算出集群的 SLO。进而可以给出 SLA。(关于它们之间的关系有兴趣的小伙伴可以搜索下相关内容)
以下是一个示例的输出:
- tao@moelove:/$ kubectl get --raw "/metrics/slis"
- # HELP kubernetes_healthcheck [STABLE] This metric records the result of a single healthcheck.
- # TYPE kubernetes_healthcheck gauge
- kubernetes_healthcheck{name="etcd",type="healthz"} 1
- kubernetes_healthcheck{name="etcd",type="livez"} 1
- kubernetes_healthcheck{name="etcd",type="readyz"} 1
- kubernetes_healthcheck{name="etcd-readiness",type="readyz"} 1
- kubernetes_healthcheck{name="informer-sync",type="readyz"} 1
- kubernetes_healthcheck{name="ping",type="healthz"} 1
- kubernetes_healthcheck{name="ping",type="livez"} 1
- kubernetes_healthcheck{name="ping",type="readyz"} 1
EventedPLEG
这个特性在 v1.27 中升级到了 Beta,但是在新版本的测试中发现了比较多的问题,所以现在将它默认禁用了,待社区修复后会再打开。建议在 v1.29 中先关闭此特性
KEP-2495: PV/PVC ReadWriteOncePod
达到 GA
NodeExpandSecret 特性达到 GA
kube-proxy 有了个 nftables 的新后端
这就是我觉得 Kubernetes v1.29 中主要值得关注的内容了。下次再见!
本文转载自:「MoeLove」,原文:https://url.hi-linux.com/pE0fV,版权归原作者所有。欢迎投稿,投稿邮箱: editor@hi-linux.com。
最近,我们建立了一个技术交流微信群。目前群里已加入了不少行业内的大神,有兴趣的同学可以加入和我们一起交流技术,在 「奇妙的 Linux 世界」 公众号直接回复 「加群」 邀请你入群。
你可能还喜欢
点击下方图片即可阅读
GitHub 星标 2.6K,一款高颜值的 Cron 替代程序 Cronicle
点击上方图片,『美团|饿了么』外卖红包天天免费领
更多有趣的互联网新鲜事,关注「奇妙的互联网」视频号全了解!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。