根本原因是kubelet的--container-runtime-endpoint和--cgroup-driver配置冲突,且systemd服务名易被覆盖;Docker安装脚本可能覆盖kubelet.service,containerd默认禁用CRI插件,CRI-O需显式指定socket路径,cgroup driver不一致会导致kubelet直接拒绝启动。

单机上同时装 Docker、containerd、CRI-O 会导致 kubelet 启动失败或 Pod 无法就绪——根本原因不是“多个运行时不能共存”,而是 kubelet 的 --container-runtime-endpoint 和 --cgroup-driver 配置冲突,且 systemd 服务名易被覆盖。
为什么 kubelet 会找不到运行时
默认情况下,kubelet 会尝试连接 unix:///var/run/containerd/containerd.sock(containerd)或 unix:///var/run/dockershim.sock(Docker,v1.24+ 已移除)。但当你手动安装多个运行时后:
- Docker 安装脚本可能覆盖
/etc/systemd/system/multi-user.target.wants/kubelet.service,导致kubelet启动时加载了错误的 socket 路径 - containerd 默认未启用 CRI 插件(
disabled_plugins = ["cri"]),即使 socket 存在,kubelet仍会报connection refused - CRI-O 的 socket 路径是
unix:///var/run/crio/crio.sock,但kubelet不会自动探测,必须显式指定 - 所有运行时若使用不同 cgroup driver(
cgroupfsvssystemd),而kubelet未对齐,会直接拒绝启动
如何让 kubelet 明确绑定到指定运行时
关键不是卸载其他运行时,而是锁定 kubelet 的配置入口。以 containerd 为例(推荐用于生产级单机):
- 确认 containerd 已启用 CRI:检查
/etc/containerd/config.toml中disabled_plugins不含"cri",并执行sudo systemctl restart containerd - 编辑
/var/lib/kubelet/kubeadm-flags.env,强制指定 endpoint 和 cgroup driver:KUBELET_KUBEADM_ARGS="--container-runtime-endpoint=unix:///run/containerd/containerd.sock --cgroup-driver=systemd"
- 确保
kubelet使用 systemd 驱动:运行cat /proc/1/cgroup | head -n1确认 init 进程用的是systemd,否则需统一修改内核参数systemd.unified_cgroup_hierarchy=0 - 重载并重启:
sudo systemctl daemon-reload && sudo systemctl restart kubelet
多运行时共存时最常踩的三个坑
这些不是理论风险,而是真实环境中反复出现的启动失败原因:
-
kubeadm init报错failed to run Kubelet: unable to load bootstrap kubeconfig:本质是kubelet还没起来,但kubeadm已开始等待;先用journalctl -u kubelet -n 100看首条 error,90% 是 socket 路径或 cgroup 不匹配 - Docker 安装后
kubelet自动降级为 dockershim 模式(即使你没用它):因为 Docker 的docker-ce包会写入/usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf并硬编码--container-runtime=docker,必须手动删掉该文件再 reload - containerd 升级到 2.0+ 后 socket 路径变为
/run/containerd/containerd.sock(不再是/var/run/...),但旧版kubelet配置仍指向旧路径,需同步更新
真正麻烦的从来不是“能不能装多个”,而是 kubelet 启动那一刻到底连谁、用哪个 cgroup、从哪读配置——这些细节一旦错位,日志里只显示“context deadline exceeded”,但根因藏在 socket 路径拼写或 config.toml 缩进里。


















