Kubernetes 1.24 移除 Docker 运行时后要怎么换成 containerd?

文章导读
Kubernetes 1.24 版本正式移除了 Dockershim,不再支持直接使用 Docker Engine 作为容器运行时。生产环境必须迁移至兼容 CRI 标准的运行时,containerd 是目前最主流且稳定的替代方案。迁移过程涉及节点驱逐、运行时配置修改及 Kubelet 参数调整,操作不当会导致节点 NotReady 或容器启动失败。
📋 目录
  1. 命令速用版
  2. 为什么会这样
  3. 分步处理
  4. 怎么验证是否生效
  5. 常见坑
  6. 常见问题
  7. 参考来源
A A

Kubernetes 1.24 版本正式移除了 Dockershim,不再支持直接使用 Docker Engine 作为容器运行时。生产环境必须迁移至兼容 CRI 标准的运行时,containerd 是目前最主流且稳定的替代方案。迁移过程涉及节点驱逐、运行时配置修改及 Kubelet 参数调整,操作不当会导致节点 NotReady 或容器启动失败。

先说结论:Kubernetes 1.24 及以上版本必须使用 CRI 兼容运行时,containerd 是官方推荐的首选替代方案,迁移需逐节点进行以避免业务中断。

  • 适合场景:Kubernetes 1.24+ 集群,计划移除 Docker 依赖以提升维护性和兼容性。
  • 先准备:备份节点配置,确认 containerd 版本与 K8s 版本兼容,检查 cgroup 驱动类型。
  • 验收标准:节点状态恢复 Ready,容器能正常创建,crictl 命令可查询容器信息。

命令速用版

以下是核心配置与检查命令,操作前请根据实际路径调整:

Kubernetes 1.24 移除 Docker 运行时后要怎么换成 containerd?
# 生成 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 标准。

分步处理

迁移需逐节点执行,严禁同时操作所有节点,以免集群不可用。

Kubernetes 1.24 移除 Docker 运行时后要怎么换成 containerd?
  1. 驱逐节点负载:使用 kubectl drain 命令将 Pod 调度到其他节点,忽略 DaemonSet。
  2. 停止旧服务:依次停止 kubelet 和 Docker 服务,禁用 Docker 开机自启。
  3. 安装配置 containerd:安装 containerd 包,生成配置文件并启用 CRI 插件,确保 SystemdCgroup 设为 true。
  4. 修改 Kubelet 参数:更新 kubelet 启动参数,指定 `--container-runtime-endpoint` 为 containerd 的 socket 路径。
  5. 启动新服务:启动 containerd 和 kubelet 服务,检查日志无报错。
  6. 恢复节点:使用 kubectl uncordon 恢复节点调度,观察 Pod 是否正常运行。

怎么验证是否生效

操作完成后,需通过多维度确认运行时已切换且功能正常。

  • 节点状态:执行 kubectl get nodes,确保节点状态为 Ready,且 VERSION 列无异常。
  • 运行时信息:执行 kubectl get node -o wide,观察 CONTAINER-RUNTIME 列是否显示 containerd 版本信息。
  • 容器查询:在节点上执行 crictl podscrictl 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)和宿主机的数据目录,但建议操作前备份重要配置。

Kubernetes 1.24 移除 Docker 运行时后要怎么换成 containerd?

迁移后还能用 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 的世界