1. cgroup v1 与 v2 接口路径差别
1
2
3
4
| /sys/fs/cgroup/cpu/cpu.cfs_quota_us
/sys/fs/cgroup/cpu/cpuacct.usage
/sys/fs/cgroup/memory/memory.limit_in_bytes
/sys/fs/cgroup/memory/memory.usage_in_bytes
|
1
2
3
4
| /sys/fs/cgroup/cpu.max
/sys/fs/cgroup/cpu.stat
/sys/fs/cgroup/memory.max
/sys/fs/cgroup/memory.current
|
cgroup v2 是 v1 的升级版本,具有更统一的资层级管理、精准的资源隔离等优点。但也导致了,写代码时,读取相关接口文件时路径不一样,需要做兼容处理。另外,一个思路就是,统一到一个 cgroup 版本。
Kubernetes 默认支持 cgroup v2,但 Pod 实际使用哪种 cgroup,取决于宿主机内核挂载的 cgroup 类型。
2. 查看全部节点的 cgroup 配置
找一个 DaemonSet,查看全部节点上 Pod 的 cgroup 配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| for pod in $(kubectl -n monitoring get pod -l k8s-app=node-exporter -o jsonpath='{.items[*].metadata.name}'); do
node=$(kubectl -n monitoring get pod $pod -o jsonpath='{.spec.nodeName}')
runtime=$(kubectl get node $node -o jsonpath='{.status.nodeInfo.containerRuntimeVersion}')
os=$(kubectl get node $node -o jsonpath='{.status.nodeInfo.osImage}')
echo "===== Pod: $pod | Node: $node | Runtime: $runtime | OS: $os ====="
if kubectl -n monitoring exec $pod -- test -f /sys/fs/cgroup/cpu.max 2>/dev/null; then
echo "cgroup v2"
kubectl -n monitoring exec $pod -- cat /sys/fs/cgroup/cpu.max
else
echo "cgroup v1"
if kubectl -n monitoring exec $pod -- test -f /sys/fs/cgroup/cpu/cpu.cfs_quota_us 2>/dev/null; then
kubectl -n monitoring exec $pod -- cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us
else
echo "cpu.cfs_quota_us not found"
fi
fi
done
|
我发现,Ubuntu 20 默认使用的是 cgroup v1,而 Ubuntu 22 默认使用的是 cgroup v2。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| ===== Pod: node-exporter-2d7q2 | Node: node-4090-76 | Runtime: containerd://1.6.31 | OS: Ubuntu 20.04.1 LTS =====
cgroup v1
-1
===== Pod: node-exporter-2z9ts | Node: node-4090-53 | Runtime: containerd://1.6.31 | OS: Ubuntu 20.04.1 LTS =====
cgroup v1
-1
===== Pod: node-exporter-462mh | Node: node-4090-ywd-04 | Runtime: containerd://1.6.31 | OS: Ubuntu 22.04.2 LTS =====
cgroup v2
max 100000
===== Pod: node-exporter-4bskd | Node: k8s-cpu-2 | Runtime: containerd://1.6.31 | OS: Ubuntu 22.04.3 LTS =====
cgroup v2
max 100000
===== Pod: node-exporter-4kz4s | Node: node-a800-52 | Runtime: containerd://1.6.31 | OS: Ubuntu 20.04.1 LTS =====
cgroup v1
-1
===== Pod: node-exporter-4lvsm | Node: node-4090-d2r1-25 | Runtime: containerd://1.6.31 | OS: Ubuntu 20.04.1 LTS =====
cgroup v1
-1
===== Pod: node-exporter-592wh | Node: node-a800-gc-09 | Runtime: containerd://1.6.31 | OS: Ubuntu 20.04.1 LTS =====
cgroup v1
|
3. 升级节点的 cgroup 版本
虽然 4.5 就开始引入了 cgroup v2,但是推荐在 5.4 及之后版本才需要考虑生产启用。
1
| stat -fc %T /sys/fs/cgroup/
|
输出 cgroup2fs
-> cgroup v2,输出 tmpfs
-> cgroup v1
在 GRUB_CMDLINE_LINUX
一行引号内添加参数 systemd.unified_cgroup_hierarchy=1
4. 检查 Containerd cgroup 配置
1
| cat /etc/containerd/config.toml | grep SystemdCgroup
|
SystemdCgroup
设置为 true
时,Containerd 使用 cgroup v2。
5. 检查 Kubelet cgroup 配置
1
| cat /var/lib/kubelet/config.yaml |grep cgroupDriver
|
cgroupDriver
设置为 systemd
时,Kubelet 使用 cgroup v2。
6. 遇到的问题
1
| Warning Failed 6s (x5 over 91s) kubelet Error: failed to create containerd task: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: error setting cgroup config for procHooks process: open /sys/fs/cgroup/kubepods.slice/kubepods-besteffort.slice/kubepods-besteffort-podd427dc62_807d_4218_b638_ddf5a6c6f7e7.slice/cri-containerd-node-exporter.scope/cpuset.cpus: no such file or directory: unknown
|
在内核 4.15 的主机上遇到这个报错,尝试清理 Pod、清空 Containerd 数据均无法解决。