Kubernetes v1.24 版本正式移除了 Dockershim 组件,集群节点不再能直接使用 Docker Engine 作为容器运行时,必须迁移到符合 CRI 标准的运行时,如 containerd。迁移过程涉及运行时配置、Kubelet 参数调整及镜像处理,需严谨操作以避免业务中断。
先说结论:升级至 1.24 及以上版本前,必须将节点运行时从 Docker 迁移至 containerd,否则 kubelet 无法管理容器。
- 适合:Kubernetes 1.24 及更高版本集群,或计划升级至此版本的场景
- 先准备:备份节点数据,确认工作负载不依赖节点上的 Docker 命令构建镜像,务必提前迁移或预热镜像
- 验收:检查节点运行时状态为 containerd,且业务 Pod 正常运行,Cgroup 驱动一致
- 风险:直接停止 Docker 未迁移镜像会导致 Pod 无法启动;Cgroup 驱动不一致会导致 Kubelet 启动失败
1. 配置 Containerd(重点修正 Cgroup)
安装 containerd 后,生成的默认配置通常不满足 Kubernetes 要求,特别是 Cgroup 驱动设置。直接使用默认配置可能导致节点 NotReady。
步骤:
- 生成默认配置文件:
mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml- 关键修改:启用 systemd cgroup 驱动。Kubernetes 推荐使用 systemd 驱动,需确保 kubelet 与 containerd 一致。
# 将 SystemdCgroup = false 修改为 true
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml
# 验证修改是否生效
grep SystemdCgroup /etc/containerd/config.toml- 重启 containerd 服务:
systemctl daemon-reload
systemctl restart containerd
systemctl enable containerd2. 修改 Kubelet 启动参数
需指定 Kubelet 使用 containerd 的 CRI Socket。根据安装方式不同,配置文件路径有所区别。
场景 A:Kubeadm 安装(常见)
通常通过 systemd drop-in 文件配置。编辑 /etc/systemd/system/kubelet.service.d/10-kubeadm.conf:
# 找到 KUBELET_EXTRA_ARGS 行,添加或修改 runtime-endpoint
Environment="KUBELET_EXTRA_ARGS=`--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 kubelet3. 镜像迁移与预热
风险警告:containerd 与 Docker 镜像存储隔离。直接停止 Docker 服务会导致原有本地镜像不可用,Pod 无法启动。必须在停止 Docker 前完成镜像迁移或确保镜像可从 registry 拉取。
方案一:从 Registry 拉取(推荐)
使用 crictl 预拉取业务所需镜像:
# 配置 crictl 使用 containerd socket
crictl config runtime-endpoint unix:///run/containerd/containerd.sock
# 拉取镜像
crictl pull <image-name>:<tag>方案二:离线导入(无 Registry 场景)
若镜像仅存在于本地 Docker 中,需导出并导入 containerd:
# 1. 从 Docker 导出镜像
docker save -o image.tar <image-name>:<tag>
# 2. 导入到 containerd (注意命名空间 k8s.io)
ctr -n k8s.io images import image.tar
# 3. 验证镜像存在
ctr -n k8s.io images | grep <image-name>4. 验证与回滚
验证步骤:
- 检查节点状态:
kubectl get nodes -o wide
# 确认 CONTAINER-RUNTIME 列显示 containerd://...- 检查运行时信息:
crictl info | grep cgroup
# 确认 cgroupDriver 为 systemd- 检查 Pod 状态:
kubectl get pods -A
# 确认业务 Pod 处于 Running 状态故障回滚方案:
若迁移后节点异常且无法快速修复,可回滚至 Docker 运行时:
- 修改 Kubelet 参数,移除
`--container-runtime-endpoint`或指向 Docker shim(若版本支持)。 - 启动 Docker 服务:
systemctl start docker。 - 重启 Kubelet:
systemctl restart kubelet。 - 注意:回滚后需重新调度 Pod 以确保镜像可用。
常见故障排查
- 节点 NotReady:检查
journalctl -u kubelet日志。若报错 cgroup 驱动不一致,请确认 containerd 配置中SystemdCgroup = true且 kubelet 启动参数包含`--cgroup-driver`=systemd。 - Pod 镜像拉取失败:确认镜像已导入 containerd 命名空间(
k8s.io)。使用ctr -n k8s.io images查看。 - Sandbox 镜像问题:containerd 默认可能使用较新的 pause 镜像,若与集群预期不符,需在
config.toml中指定sandbox_image并与 kubelet 配置一致。 - 网络插件异常:部分 CNI 插件依赖特定运行时接口,迁移后建议重启 CNI Pod(如 Calico、Flannel)。