Kubernetes v1.24 正式移除了 Dockershim 组件,升级至此版本及以上前,必须将节点运行时从 Docker 迁移至 containerd,否则 kubelet 无法管理容器。
先说结论:升级至 1.24 及以上版本前,必须将节点运行时从 Docker 迁移至 containerd,否则 kubelet 无法管理容器。
- 适合:Kubernetes 1.24 及更高版本集群,或计划升级至此版本的场景
- 先准备:备份节点数据,确认工作负载不依赖节点上的 Docker 命令构建镜像,务必提前迁移或预热镜像
- 验收:检查节点运行时状态为 containerd,且业务 Pod 正常运行,Cgroup 驱动一致
迁移前准备
迁移过程建议先在测试环境验证,生产环境建议在业务低峰期操作。操作前请务必备份关键配置文件,以便出现问题时快速回滚。
# 备份 containerd 配置
cp /etc/containerd/config.toml /etc/containerd/config.toml.bak
# 备份 kubelet 配置
cp /etc/systemd/system/kubelet.service.d/10-kubeadm.conf /etc/systemd/system/kubelet.service.d/10-kubeadm.conf.bak步骤一:安装与配置 Containerd
安装 containerd 后,生成的默认配置通常不满足 Kubernetes 要求,特别是 Cgroup 驱动设置。直接使用默认配置可能导致节点 NotReady。
# 生成 containerd 默认配置
containerd config default | sudo tee /etc/containerd/config.toml修改配置说明:不建议直接使用 sed 替换,不同版本配置结构可能不同。请手动编辑 /etc/containerd/config.toml,找到 [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options] 部分,确保 SystemdCgroup 设置为 true。
[plugins."io.containerd.grpc.v1.cri"]
...
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true修改完成后重启服务:
systemctl daemon-reload
systemctl restart containerd
systemctl enable containerd步骤二:迁移容器镜像
Docker 与 containerd 镜像存储隔离,直接停止 Docker 未迁移镜像会导致 Pod 无法启动。需将 Docker 中的业务镜像导出并导入到 containerd 的 k8s.io 命名空间中。
# 1. 从 Docker 导出镜像
docker save -o my-app.tar my-app:latest
# 2. 导入到 containerd (注意指定 k8s.io 命名空间)
ctr -n k8s.io images import my-app.tar
# 3. 验证导入结果
ctr -n k8s.io images | grep my-app若集群规模较大,建议编写脚本批量处理所有业务镜像。
步骤三:修改 Kubelet 配置
需指定 Kubelet 使用 containerd 的 CRI Socket。根据安装方式不同,配置文件路径有所区别。
场景 A: Kubeadm 安装 (常见)
编辑 /etc/systemd/system/kubelet.service.d/10-kubeadm.conf,找到 KUBELET_EXTRA_ARGS 行。
# 修改前
KUBELET_EXTRA_ARGS=`--node-ip`=192.168.1.10
# 修改后 (添加 runtime-endpoint)
KUBELET_EXTRA_ARGS=`--node-ip`=192.168.1.10 `--container-runtime-endpoint`=unix:///run/containerd/containerd.sock场景 B: 二进制安装
修改 kubelet 启动脚本或 systemd service 文件,添加 `--container-runtime-endpoint`=unix:///run/containerd/containerd.sock 参数。
配置修改完成后重载并重启:
systemctl daemon-reload
systemctl restart kubelet怎么验证是否生效
检查节点运行时状态为 containerd,且业务 Pod 正常运行。
# 查看节点信息,确认 CONTAINER-RUNTIME 列显示 containerd
kubectl get nodes -o wide
# 查看 CRI 运行时信息
crictl info
# 检查 Pod 状态
kubectl get pods -A常见坑与排查
- 镜像缺失:containerd 与 Docker 镜像存储隔离,需重新拉取或导入镜像。若 Pod 处于 ImagePullBackOff,检查
ctr -n k8s.io images是否存在对应镜像。 - Cgroup 驱动不一致:会导致 Kubelet 启动失败。需确保 kubelet 与 containerd 一致(推荐 systemd)。查看 kubelet 日志
journalctl -u kubelet排查。 - Docker 特有功能依赖:工作负载若依赖 Docker 特有功能(如 docker.sock 挂载),需提前评估兼容性,改为使用 CRI 兼容方式。
- 配置格式错误:修改 config.toml 时注意 TOML 格式规范,缩进错误会导致 containerd 无法启动。