前面在知识星球里面也分享了这一篇关于 Kubelet资源预留的文章,最近又有一些朋友遇到这个问题,所以这里再次分享给大家。
关于如何规划 Node 的 Cgroup 结构,请参考官方建议: https://github.com/kubernetes/community/blob/master/contributors/design-proposals/node/node-allocatable.md#recommended-cgroups-setup
以如下的kubelet资源预留为例,Node Capacity为memory=32Gi, cpu=16, ephemeral-storage=100Gi,我们对kubelet进行如下配置:
NodeAllocatable = NodeCapacity - Kube-reserved - system-reserved - eviction-threshold = cpu=14.5,memory=28.5Gi,ephemeral-storage=98Gi
Scheduler 会确保 Node 上所有的Pod Resource Request不超过NodeAllocatable。Pods所使用的memory和storage之和超过NodeAllocatable后就会触发kubelet Evict Pods。
kube-reserved-cgroup及system-reserved-cgroup配置 最开始,我只对kubelet做了如下配置—kube-reserved, —system-reserved,我就以为kubelet会自动给kube和system创建对应的Cgroup,并设置对应的cpu share, memory limit等,然后高枕无忧了。
然而实际上并非如此,直到在线上有一次某个TensorFlow worker的问题,无限制的使用节点的cpu,导致节点上cpu usage持续100%运行,并且压榨到了kubelet组件的cpu使用,导致kubelet与APIServer的心跳断了,这个节点便Not Ready了。
接着,Kubernetes会在其他某个最优的Ready Node上启动这个贪婪的worker,进而把这个节点的cpu也跑满了,节点Not Ready了。
如此就出现了集群雪崩,集群内的Nodes逐个的Not Ready了,后果非常严重。
把kublet加上如下配置后,即可保证在Node高负荷时,也能保证当kubelet需要cpu时至少能有—kube-reserved设置的cpu cores可用。
--enforce-node-allocatable=pods,kube-reserved,system-reserved
--kube-reserved-cgroup=/kubelet.service
--system-reserved-cgroup=/system.slice
注意,因为kube-reserved设置的cpu其实最终是写到kube-reserved-cgroup下面的cpu shares。 了解cpu shares的同学知道,只有当集群的cpu跑满需要抢占时才会起作用,因此你会看到Node的cpu usage还是有可能跑到100%的,但是不要紧,kubelet等组件并没有收到影响,如果kubelet此时需要更多的cpu,那么它就能抢到更多的时间片,最多可以抢到kube-reserved设置的cpu nums。
在Kubernetes 1.7版本,Kubelet启动会检查以下cgroup subsystem的存在:
在Kubernetes 1.8及1.9版本,Kubelet启动会检查以下cgroup subsystem的存在:
对于Centos系统,cpuset和hugetlb subsystem是默认没有初始化system.slice,因此需要手动创建,否则会报Failed to start ContainerManager Failed to enforce System Reserved Cgroup Limits on “/system.slice”: “/system.slice” cgroup does not exist的错误日志。
我们可以通过在kubelet service中配置ExecStartPre来实现。
本文转载至 https://my.oschina.net/jxcdwangtao/blog/1629059