kubernetes kubelet组件中cgroup的层层"戒备" (3)

--system-cgroups: 将所有系统进程都移动到该cgroup下,会进行统计资源使用。如果不指定该参数则不运行在容器中,对应的summary stat数据也不会统计。此处系统进程不包括内核进程, 因为我们并不想限制内核进程的使用。

--kubelet-cgroups: 如果指定改参数,则containerManager会确保kubelet在该cgroup内运行,同样也会做资源统计,也会调整OOM score值。 summaryProvider会定期同步信息,来获取stat信息。如果不指定该参数,则kubelet会自动地找到kubelet所在的cgroup, 并进行资源的统计。

--cgroup-root kubelet中所有的cgroup层级都会在该root路径下,默认是/,如果开启--cgroups-per-qos=true,则在kubelet containerManager中会调整为/kubepods

以上runtime-cgroups, system-cgroups, kubelet-cgoups的设置都是可选的,如果不进行指定也可以正常运行。但是如果显式指定后就需要与前面提到的--kube-reserved-cgroup和--system-reserved-cgroup搭配使用,如果配置不当难以达到预期效果:

如果在--enforce-node-allocatable参数中指定了kube-reserved来限制kubernetes组件的资源限制后,kube-reserved-cgroup的应该是:runtime-cgroups, kubelet-cgoups的父cgroup。只有对应的进程都应该运行该cgroup之下,才能进行限制, kubelet会设置kube-reserved-cgroup的资源限制但并不会将这些进程加入到该cgroup中,我们要想让该配置生效,就必须让通过制定--runtime-cgroups, --kubelet-cgoups来将这些进程加入到该cgroup中。同理如果上述--enforce-node-allocatable参数中指定了system-reserved来限制系统进程的资源,则--system-reserved-cgroup 的参数应该与--system-cgroups参数相同,这样系统进程才会运行到system-reserved-cgroup中起到资源限制的作用。

最后整个整个cgroup hierarchy 如下:

root | +- kube-reserved | | | +- kubelet (kubelet process) | | | +- runtime (docker-engine, containerd...) | +- system-reserved (systemd process: logind...) | +- kubepods | | | +- Pod1 | | | | | +- Container11 (limit: cpu: 10m, memory: 1Gi) | | | | | | | +- cpu.quota: 10m | | | +- cpu.share: 10m | | | +- mem.limit: 1Gi | | | | | +- Container12 (limit: cpu: 100m, memory: 2Gi) | | | | | | | +- cpu.quota: 10m | | | +- cpu.share: 10m | | | +- mem.limit: 2Gi | | | | | +- cpu.quota: 110m | | +- cpu.share: 110m | | +- mem.limit: 3Gi | | | +- Pod2 | | +- Container21 (limit: cpu: 20m, memory: 2Gi) | | | | | | | +- cpu.quota: 20m | | | +- cpu.share: 20m | | | +- mem.limit: 2Gi | | | | | +- cpu.quota: 20m | | +- cpu.share: 20m | | +- mem.limit: 2Gi | | | +- burstable | | | | | +- Pod3 | | | | | | | +- Container31 (limit: cpu: 50m, memory: 2Gi; request: cpu: 20m, memory: 1Gi ) | | | | | | | | | +- cpu.quota: 50m | | | | +- cpu.share: 20m | | | | +- mem.limit: 2Gi | | | | | | | +- Container32 (limit: cpu: 100m, memory: 1Gi) | | | | | | | | | +- cpu.quota: 100m | | | | +- cpu.share: 100m | | | | +- mem.limit: 1Gi | | | | | | | +- cpu.quota: 150m | | | +- cpu.share: 120m | | | +- mem.limit: 3Gi | | | | | +- Pod4 | | | +- Container41 (limit: cpu: 20m, memory: 2Gi; request: cpu: 10m, memory: 1Gi ) | | | | | | | | | +- cpu.quota: 20m | | | | +- cpu.share: 10m | | | | +- mem.limit: 2Gi | | | | | | | +- cpu.quota: 20m | | | +- cpu.share: 10m | | | +- mem.limit: 2Gi | | | | | +- cpu.share: 130m | | +- mem.limit: $(Allocatable - 5Gi) | | | +- besteffort | | | | | +- Pod5 | | | | | | | +- Container6 | | | +- Container7 | | | | | +- cpu.share: 2 | | +- mem.limit: $(Allocatable - 7Gi)

上述所有的操作在kubelet中是通过containerManager来实现的, containerManager启动的时候首先会setupNode初始化各种cgroup,具体包括:通过enforceNodeAllocatableCgroups来设置kubepods, kube-reserved,system-reserved三个cgroup的资源使用, 启动qosContainerManager来定期同步各个QoS class的资源使用,会在后台不断同步kubelet,docker,system cgroup。在每个pod启动/退出时候会调用podContainerManager来创建/删除pod级别的cgroup并调用 UpdateQoSCgroups 来更新QoS级别的cgroup。 上述所有更新cgroup的操作都会利用一个cgroupManager来实现。

Summary

可以看出kubelet是将cgroup使用到了极致的地步,通过层层限制提高node的隔离性、稳定性、可观测性。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpjwsf.html