前言
在等待了三个月之后,kubernetes 1.26 如期发布,这个版本引入了很多新功能,让我们通过这篇文章一睹为快。推荐读者将自己的测试集群升级到 1.26 体验这些新功能,因为这是一个十分值得尝试的版本!V1.26总计带来了37项增强功能。在这37项增强功能中,有11项功能成为稳定版,有10项是对现有功能的改进,有多达16项功能是全新的,有1项功能被废弃。
在此版本中,在各个领域都有诸多引人注目的更新,比如VolumeSnapshot支持跨命名空间使用、对高性能计算类应用的持续优化、windows支持主机网络模式等等。在众多的功能增强中,本文挑选了十项值得关注的新特性与大家分享
新功能介绍
Dynamic resource allocation
这是个更灵活的资源调度方式,在之前 pod 申请的资源一般都是 cpu、内存,或者 gpu,所以 kubernetes 默认的资源调度方式并不灵活。随着kubernetes的使用越来越广泛,pod所需的硬件资源种类也越来越多,例如通过网络获取的硬件资源,或者 FPGA 等硬件资源。
这个特性通过定义一些新的 api,为 pod 引入了动态的资源分配方式,用户只需要创建一个定义资源的ResourceClaim
,并且在创建pod时绑定此资源,pod就可以使用这个资源。并且新api在设计时,就提供了足够多的语义,使得当前所有的 device plugin都可以与动态分配资源功能兼容。下面是一个样例:
apiVersion: gpu.example.com/v1
kind: GPURequirements
metadata:
name: device-consumer-gpu-parameters
memory: "2Gi"
---
apiVersion: resource.k8s.io/v1alpha1
kind: ResourceClaimTemplate
metadata:
name: device-consumer-gpu-template
spec:
metadata:
spec:
resourceClassName: "acme-gpu"
parametersRef:
apiGroup: gpu.example.com
kind: GPURequirements
name: device-consumer-gpu-parameters
---
apiVersion: v1
kind: Pod
metadata:
name: device-consumer
spec:
resourceClaims:
- name: "gpu" # this name gets referenced below under "claims"
template:
resourceClaimTemplateName: device-consumer-gpu-template
containers:
- name: workload
image: my-app
command: ["/bin/program"]
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
claims:
- "gpu"
- name: monitor
image: my-app
command: ["/bin/other-program"]
resources:
requests:
memory: "32Mi"
cpu: "25m"
limits:
memory: "64Mi"
cpu: "50m"
claims:
- "gpu"
这个新的api为资源的分配带了了很多新的功能,例如:
- pod可以使用网络附加资源
- 资源可以在多个容器间或者多个pod间共享。
- 在多个pod中多次初始化资源
- 可以通过设置参数,自定义资源的申请大小和初始化方式
这个新功能的灵活性为资源分配带来了无限可能。相信在未来这个特性会令人瞩目。
Improved multi-numa alignment in Topology Manager
在高性能计算的场景中,服务器的性能大多都强的离谱,一台服务器中的cpu数量一般都会大于一个,这时候就需要 NUMA 技术,这种技术可以为程序更合理的分配不同的cpu,让 cpu 读取内存的速度更快,从而程序运行的更快。
在这个新的特性中,会根据NUMA优化pod的调度,让其运行的更快,在高性能计算中,性能非常敏感,因此这个功能也十分重要。
值得一提的是,在CNCF社区的批处理调度框架 Volcano项目 中,也已经支持了根据 NUMA 优化pod的调度的能力,博云的AI算力平台(BCC)底层也正是采用了 volcano,并在大量客户中进行了生产实践。在作业规模、性能等方面都取得了很大提升。在建设BCC的过程中,博云也已经将多个在生产实践中遇到的重要功能贡献到 volcano社区。
Kubelet evented PLEG for better performance
相信排查节点 notready
问题的同学,都会遇到过 kubelet 中有关PLEG的报错。PLEG是kubelet的一个关键功能,但是这个功能在性能和可靠性上又一言难尽,现在官方终于对其做出改变了,希望通过这个增强,能让kubelet更加健壮。在之前,kubelet为了掌握容器的状态,会以1秒为周期,轮询调用CRI,在容器的规模变大之后,轮询的开销也会随之变大。这个新功能主要优化的方式是,将之前的固定周期轮询改为kubernetes中久经考验的ListAndWatch机制,减少轮询频率,从而减少了开销。
Pod scheduling readiness
这是一个十分有趣的小功能。
有些时候,我们创建出了一些pod,但是可能还没准备好让这些pod被调度,我们想在合适的时机调度pod。目前缺少这么一个让pod“等待调度”的功能。
在 kubernetes 1.26 中,这个功能被添加了。如何使用呢?很简单,只要在pod.spec.schedulingGates字段添加键值对就可以了。下面具体演示
编写一个pod的yaml文件,在schedulingGates字段中添加两个元素
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
schedulingGates:
- name: testSchedulingGate
- name: addAnotherValue
containers:
- image: nginx
name: nginx
使用这个yaml创建pod,查看pod的状态,会得到以下结果,pod没有被调度
root@k8s126master:~# kubectl get po
NAME READY STATUS RESTARTS AGE
nginx 0/1 SchedulingGated 0 31s
查看pod的status字段,可以看到详细的未被调度的原因
status:
conditions:
- lastProbeTime: null
lastTransitionTime: null
message: Scheduling is blocked due to non-empty scheduling gates
reason: SchedulingGated
status: "False"
type: PodScheduled
当pod准备好被调度时,我们把schedulingGates字段中的内容删除,可以看到pod马上就会被调度
root@k8s126master:~# kubectl get po
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 3m30s
Allow StatefulSet to control start replica ordinal numbering
这也是个比较有趣的功能,可以让用户自定义的StatefulSet 副本的启动序号,使用过StatefulSet的同学都知道,通过StatefulSet创建出的pod,末尾的序号都是从0开始,这个功能可以让用户自己设定pod的启动序号,例如我用下面的yaml创建一个StatefulSet
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
ordinals:
start: 10
replicas: 5
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
可以看到设定的副本数为5,启动序号为10,当这个StatefulSet被创建出来后,查看pod的信息,可以看到pod是按照我们的预期被创建的
root@k8s126master:~# kubectl get po
NAME READY STATUS RESTARTS AGE
web-10 1/1 Running 0 3m23s
web-11 1/1 Running 0 3m18s
web-12 1/1 Running 0 3m13s
web-13 1/1 Running 0 3m8s
web-14 1/1 Running 0 3m3s
Kubernetes component health SLIs
这个功能为用户带来了一种直观的查看kubernetes集群组件是否健康的方式
其引入了一个指标 kubernetes_healthcheck
,返回标准的 prometheus格式的数据,告知用户kubernetes组件是否正常运行,方便用户更方便的监控集群状态。
Host network support for Windows pods
kubernetes 对 windows的支持一直都在稳步推进当中,之前的版本中,windows的容器已经可以使用特权容器,在kubernetes 1.26 版本,windows特权容器的功能已经达到稳定级别,并且windows容器终于可以使用主机网络模式了,虽然还是 alpha 阶段,但是kubernetes社区和微软合作的趋势是良好的。
博云也在大规模的生产环境中使用过部署在windows操作系统上的kubernetes集群,帮助客户实现了两个数量级级别的效率提升。博云自研的网络插件 fabric 的 windows 版也已经可以稳定运行在Windows生产环境中。
CEL for admission control
随着越来越多的CRD被创建,越来越多的准入控制器被创建,越来越多的webhook被创建。但其实很多时候,用户对于CRD的校验都是很简单的,不需要在集群中部署一个复杂的、浪费资源的webhook。例如只需要校验一个int类型的字段,它的值不能大于10。这种场景下,你就需要kubernetes 1.26 的这个新功能。
而且更优秀的是,这个功能不只为了CRD设计,它也可以用于kubernetes的内置资源,例如deployment
这个功能的使用也非常简单,下面是限制 deployment 的副本数的例子
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
name: "validate-xyz.example.com"
spec:
singletonPolicy: true
match:
resourceRules:
- apiGroups: ["apps"]
apiVersions: ["v1"]
operations: ["CREATE", "UPDATE"]
resources: ["deployments"]
defaultValidations:
- expression: "object.spec.replicas < 100"
Minimizing iptables-restore input size
这个优化说起来很简单,引用设计文档的一句话:
Improve the performance of kube-proxy in iptables mode, by optimizing its calls to
iptables-restore
by not including rules that haven’t changed.
通过优化 iptables-restore
的调用,优化 iptables 模式下 kube-proxy 的性能。kube-proxy 的性能也是总被用户提及的一个问题,kubernetes 官方也采取了很多措施优化 kube-proxy的性能,例如引入 ipvs。
博云在自研网络插件的过程中,也体会到了kube-proxy的性能瓶颈和一些bug带来的痛苦,所以在fabic的发布版本中正式推出了fabric-proxy。Fabric-proxy已经完全集成了kube-proxy的功能,并且做了性能优化,用户在使用fabric时,将不再需要部署kube-proxy,从根源避免了kube-proxy带来的一些问题。
Provision volumes from cross-namespace snapshots
这是kubernetes 1.26着重宣传的一个功能。命名空间是kubernetes中隔离用户、资源的一个核心方式,它有优点,但是使用上也有不便。在 Kubernetes 1.26 之前,用户可以使用VolumeSnapshot为卷创建快照,但是这个功能没办法跨命名空间创建快照,在kubernetes 1.26中这个限制被打破了,通过引入一个新的资源ReferenceGrant
,将允许用户跨命名空间为卷创建快照。
下面就是一个样例,这个名为bar的ReferenceGrant将命名空间test下的pvc和命名空间为prod的VolumeSnapshot关联到一起。
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: ReferenceGrant
metadata:
name: bar
namespace: prod
spec:
from:
- kind: PersistentVolumeClaim
namespace: test
to:
- group: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
name: foo-backup
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: foo-testing
namespace: test
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Mi
dataSourceRef2:
apiGroup: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
name: foo-backup
namespace: prod
volumeMode: Filesystem
总结
在经过了多年的发展之后,kubernetes已经是一个十分成熟的项目了,但经过上面的介绍,我们也可以看到,它依旧保持着充足的活力,引入很多新的功能,让用户在诸如高性能计算等领域看见大规模使用kubernetes的前景,这与开源社区的运作密切相关。博云愿与开源社区中的其他成员一起,共同建设kubernetes及其周边生态,为kubernetes创造更多可能!
参考链接
https://github.com/kubernetes/kubernetes/milestone/59 https://kubernetes.io/blog/2022/11/18/upcoming-changes-in-kubernetes-1-26/
https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/3063-dynamic-resource-allocation
https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/3545-improved-multi-numa-alignment
https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/3386-kubelet-evented-pleg
https://github.com/kubernetes/enhancements/blob/master/keps/sig-scheduling/3521-pod-scheduling-readiness
https://github.com/kubernetes/enhancements/tree/master/keps/sig-apps/3335-statefulset-slice
https://github.com/kubernetes/enhancements/tree/master/keps/sig-windows/3503-host-network-support-for-windows-pods
https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/3488-cel-admission-control
https://github.com/google/cel-spec
https://github.com/kubernetes/enhancements/tree/master/keps/sig-network/3453-minimize-iptables-restore
https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/3294-provision-volumes-from-cross-namespace-snapshots
https://sysdig.com/blog/kubernetes-1-26-whats-new