Kubernetes 1.24 版本正式移除了 Dockershim,不再支持直接使用 Docker Engine 作为容器运行时。生产环境必须迁移至兼容 CRI 标准的运行时,containerd 是目前最主流且稳定的替代方案。迁移过程涉及节点驱逐、运行时配置修改及 Kubelet 参数调整,操作不当会导致节点 NotReady 或容器启动失败。
先说结论:Kubernetes 1.24 及以上版本必须使用 CRI 兼容运行时,containerd 是官方推荐的首选替代方案,迁移需逐节点进行以避免业务中断。
- 适合场景:Kubernetes 1.24+ 集群,计划移除 Docker 依赖以提升维护性和兼容性。
- 先准备:备份节点配置,确认 containerd 版本与 K8s 版本兼容,检查 cgroup 驱动类型。
- 验收标准:节点状态恢复 Ready,容器能正常创建,crictl 命令可查询容器信息。
命令速用版
以下是核心配置与检查命令,操作前请根据实际路径调整:
# 生成 containerd 默认配置
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
# 关键修改:启用 SystemdCgroup (必须与 kubelet 一致)
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml
# 配置 kubelet 指向 containerd socket
# 编辑 /etc/default/kubelet 或 kubelet.service
KUBELET_EXTRA_ARGS="`--container-runtime`=remote `--container-runtime-endpoint`=unix:///run/containerd/containerd.sock"
# 验证运行时状态
crictl info
kubectl get node -o wide为什么会这样
Kubernetes 移除 Docker 并非因为 Docker 无法运行容器,而是为了简化架构和维护负担。Dockershim 是 Kubernetes 与 Docker Engine 之间的适配层,移除后 Kubelet 直接通过 CRI 接口与 containerd 通信。这种变化减少了中间组件调用,降低了资源占用,但要求运行时必须原生支持 CRI 标准。
分步处理
迁移需逐节点执行,严禁同时操作所有节点,以免集群不可用。
- 驱逐节点负载:使用
kubectl drain命令将 Pod 调度到其他节点,忽略 DaemonSet。 - 停止旧服务:依次停止 kubelet 和 Docker 服务,禁用 Docker 开机自启。
- 安装配置 containerd:安装 containerd 包,生成配置文件并启用 CRI 插件,确保 SystemdCgroup 设为 true。
- 修改 Kubelet 参数:更新 kubelet 启动参数,指定
`--container-runtime-endpoint`为 containerd 的 socket 路径。 - 启动新服务:启动 containerd 和 kubelet 服务,检查日志无报错。
- 恢复节点:使用
kubectl uncordon恢复节点调度,观察 Pod 是否正常运行。
怎么验证是否生效
操作完成后,需通过多维度确认运行时已切换且功能正常。
- 节点状态:执行
kubectl get nodes,确保节点状态为 Ready,且 VERSION 列无异常。 - 运行时信息:执行
kubectl get node -o wide,观察 CONTAINER-RUNTIME 列是否显示 containerd 版本信息。 - 容器查询:在节点上执行
crictl pods或crictl ps,若能列出 Kubernetes 管理的容器则说明对接成功。 - 新 Pod 启动:尝试部署一个测试 Pod,确认镜像拉取和容器启动无超时或报错。
常见坑
- Cgroup 驱动不一致:若 kubelet 使用 systemd 而 containerd 使用 cgroupfs,容器启动后会立即退出。必须在 containerd 配置中显式设置 SystemdCgroup = true。
- 镜像拉取失败:containerd 默认配置可能缺少镜像加速地址,导致 pause 镜像拉取超时,需在 config.toml 配置 registry mirrors。
- Socket 路径错误:不同发行版 containerd socket 路径可能不同,常见为
/run/containerd/containerd.sock或/var/run/containerd/containerd.sock,需与实际文件一致。 - Docker 命令不可用:迁移后节点上无法直接使用
docker ps查看 K8s 容器,需改用crictl或单独安装 Docker CLI 仅用于构建镜像。
常见问题
迁移后原有容器数据会丢失吗?
不会丢失。容器运行时切换不影响持久化卷(PV/PVC)和宿主机的数据目录,但建议操作前备份重要配置。
迁移后还能用 docker build 构建镜像吗?
不能直接使用。containerd 不具备镜像构建功能,需在开发机使用 Docker 构建后推送仓库,或在节点单独安装 Docker 仅用于构建。
如何回滚到 Docker 运行时?
回滚较复杂且风险高。需恢复 kubelet 参数指向 dockershim,重新安装 Docker 并启动服务,建议操作前完整备份节点配置。
参考来源
- Kubernetes 怎么更换容器运行时为 Containerd K8s 环境组件切换详解
- 从 Docker 迁移到 Containerd:手把手教你配置 K8s 默认运行时
- K8s 从 Docker 到 Containerd 的迁移全流程实践
- Kubernetes 容器运行时迁移指南:从 Docker Engine 切换到 containerd
- K8S 集群管理避坑指南:从 Docker 迁移到 Containerd 的完整流程 (1.24+ 版本)
- K8s 1.24 与 Dockershim 分手:未来是 containerd 和 CRI-O 的世界