k8s集群,cgroup配置导致kubelet启动失败,一直重启
failed to initialize top level QOS containers: root container [kubepods] doesn't exist
### 问题记录:
1.在新节点执行kubeadm join后,kubelet启动失败,并且一直自动重启,journalctl -u kubelet -f 排查发现有如下报错:
Jul 31 10:16:10 k8s-slave91 kubelet[1217797]: E0731 10:16:10.672112 1217797 kubelet.go:1431] "Failed to start ContainerManager" err="failed to initialize top level QOS containers: root container [kubepods] doesn't exist"
Jul 31 10:16:10 k8s-slave91 systemd[1]: kubelet.service: Main process exited, code=exited, status=1/FAILURE
Jul 31 10:16:10 k8s-slave91 systemd[1]: kubelet.service: Failed with result 'exit-code'.
最初一直搜索 Failed to start ContainerManager" err="failed to initialize top level QOS containers: root container [kubepods] doesn't exist 这个报错,发现解决方案都无法处理
后来仔细阅读了所有报错信息,发现了关键的两行:
Failed to get the kubelet's cgroup. Kubelet system container metrics may be missing." err="cpu and memory cgroup hierarchy not unified. cpu: /system.slice, memory: /system.slice/kubelet.service"
Jul 31 17:41:43 k8s-slave91 kubelet[1737867]: I0731 17:41:43.378073 1737867 server.go:669] "Failed to get the container runtime's cgroup. Runtime system container metrics may be missing." err="failed to get container name for docker process: cpu and memory cgroup hierarchy not unified. cpu: /system.slice, memory: /system.slice/docker.service"
核心原因:
cpu 和 memory cgroup 层级不一致,导致 kubelet 无法初始化 QOS 容器,也无法正确收集 system container metrics。
具体错误如下:
cpu and memory cgroup hierarchy not unified.
cpu: /system.slice
memory: /system.slice/kubelet.service
这代表:
cpu 控制组挂载到了 /system.slice
但 memory 控制组挂载到了 /system.slice/kubelet.service
两者不一致,kubelet 无法将它们统一视为同一个 system container 的资源组。
这通常发生在:
操作系统使用的是 cgroup v1;
但 不同的子系统(如 cpu 和 memory)被挂载在不同的 cgroup 层级;
这种混合挂载是合法的,但 kubelet 无法接受。
### 解决方案 ###
如果你系统支持 cgroup v2 直接切换。使用如下脚本直接执行。
#!/bin/bash
# openEuler 24.03 切换系统为 cgroup v2 模式
set -e
echo "🔍 当前系统:$(cat /etc/os-release | grep PRETTY_NAME)"
echo "🔍 当前内核版本:$(uname -r)"
CGROUP_TYPE=$(stat -fc %T /sys/fs/cgroup)
if [[ "$CGROUP_TYPE" == "cgroup2fs" ]]; then
echo "✅ 当前已是 cgroup v2,无需更改。"
exit 0
fi
GRUB_FILE="/etc/default/grub"
BACKUP_FILE="/etc/default/grub.bak.$(date +%Y%m%d_%H%M%S)"
echo "📝 备份 grub 文件到 $BACKUP_FILE"
cp -v "$GRUB_FILE" "$BACKUP_FILE"
# 添加/更新参数
echo "🔧 修改 grub 配置参数,启用 cgroup v2 ..."
if grep -q "systemd.unified_cgroup_hierarchy" "$GRUB_FILE"; then
sed -i 's/systemd\.unified_cgroup_hierarchy=[01]/systemd.unified_cgroup_hierarchy=1/g' "$GRUB_FILE"
else
sed -i 's/GRUB_CMDLINE_LINUX="/GRUB_CMDLINE_LINUX="systemd.unified_cgroup_hierarchy=1 systemd.legacy_systemd_cgroup_controller=0 /' "$GRUB_FILE"
fi
# 判断启动方式(BIOS 还是 EFI)
EFI_PATH="/boot/efi/EFI"
if [[ -d "$EFI_PATH" ]]; then
GRUB_CFG=$(find "$EFI_PATH" -name grub.cfg | head -n 1)
echo "⚙️ EFI 系统,生成 grub 配置: $GRUB_CFG"
grub2-mkconfig -o "$GRUB_CFG"
else
echo "⚙️ BIOS 系统,生成 grub 配置: /boot/grub2/grub.cfg"
grub2-mkconfig -o /boot/grub2/grub.cfg
fi
echo -e "\n✅ grub 配置修改完成。"
echo -e "\n⚠️ 需要重启系统才能生效。重启后再次执行:\n\n stat -fc %T /sys/fs/cgroup\n\n应输出:cgroup2fs"
read -p "🔁 是否立即重启系统?[y/N]: " confirm
if [[ "$confirm" == "y" || "$confirm" == "Y" ]]; then
echo "🔄 正在重启..."
sleep 2
reboot
else
echo "⏸️ 请稍后手动执行 reboot 命令完成切换。"
fi
### 重启后验证
执行:
stat -fc %T /sys/fs/cgroup
期望输出:
cgroup2fs
进一步验证:
mount | grep cgroup2
输出应该包含:
cgroup2 on /sys/fs/cgroup type cgroup2 (rw,...)
然后重启kubelet:
systemctl restart kubelet
观察日志输出:
journalctl -u kubelet -f
更多推荐
所有评论(0)