Kubernetes 容器运行时从 Docker 升级到 Containerd 完整指南
适用场景:Kubernetes 1.24+ 及以上版本,计划将 Docker 替换为 Containerd,实现高效、原生 CRI 支持的容器运行时环境。
1️⃣ 核心概念澄清:为什么是"升级"?
-
这不是 Kubernetes 升级,而是容器运行时替换。
-
Docker 已被弃用(Deprecated),K8s 不再通过 dockershim 与 Docker 通信。
-
Containerd 是兼容 CRI 的高效运行时,K8s 可以直接与其对话。
-
Docker 本身也基于 Containerd,因此迁移实质上去掉中间层,K8s 直接和 Containerd 通信,集群更轻量高效。
2️⃣ 升级步骤(建议在测试环境充分验证后逐节点执行)
整体原则:逐节点迁移,先腾空节点 → 执行操作 → 恢复节点。
阶段一:准备工作(非常重要)
1、版本兼容性检查
-
Kubernetes 版本与 Containerd 版本是否兼容。
-
推荐:K8s 1.24+ 使用 Containerd 1.6+。
-
官方文档是最权威的参考。
2、备份
-
容器重要数据(确保持久化或备份)。
-
节点配置:
/etc/containerd/config.toml/var/lib/containerd/etc/docker/daemon.json
3、记录当前运行状态
kubectl get pods -o wide | grep <node-name>docker imagescrictl images # 如果已安装
4、安装 Containerd 与 CRI 工具
# Ubuntu/Debiansudo apt-get updatesudo apt-get install containerd cri-tools
# CentOS/RHELsudo yum install containerd cri-tools
5、配置 Containerd
sudo containerd config default | sudo tee /etc/containerd/config.toml
-
关键配置:
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]SystemdCgroup = true # 必须与 Kubelet cgroup driver 一致
-
配置私有镜像仓库(类似 Docker 的 /etc/docker/daemon.json)。
-
(可选)沙盒镜像通常无需修改。
6、加载必要内核模块
sudo modprobe overlaysudo modprobe br_netfilter
确保开机自动加载。
阶段二:节点切换
1、驱逐节点
kubectl drain <node-name> --ignore-daemonsets --delete-emptydir-data
2、停止 Docker 和 Kubelet
sudo systemctl stop kubeletsudo systemctl stop dockersudo systemctl disable docker
3、启动 Containerd
sudo systemctl enable containerdsudo systemctl start containerd
4、修改 Kubelet 配置
-
配置文件通常在 /var/lib/kubelet/kubeadm-flags.env 或指定的 --config 文件。
-
修改参数:
--container-runtime=remote--container-runtime-endpoint=unix:///run/containerd/containerd.sock
-
移除 Docker 相关参数
5、重启 Kubelet
sudo systemctl daemon-reloadsudo systemctl start kubelet
6、验证节点状态
kubectl get nodes <node-name>kubectl uncordon <node-name>
- 节点状态为 Ready 表示切换成功。
7、重复操作
集群其他节点依次迁移。
阶段三:后续验证与清理
1、验证 Pods 和功能
-
网络、存储、DNS 正常。
-
业务 Pods 正常重建。
2、可选:卸载 Docker
sudo apt-get remove docker-ce docker-ce-cli containerd.iosudo yum remove docker-ce docker-ce-cli containerd.io
- Docker 卸载不会影响 Containerd 管理的容器和镜像(存储在 /var/lib/containerd)
3、学习新的调试工具
-
crictl ps、crictl pods、crictl images、crictl logs <container-id>。
-
ctr 命令用于底层操作。
3️⃣ 主要注意点和常见坑
|---------------------------------|--------------------------------------------------------------------|
| 问题 | 解决方案 |
| Kubelet 启动失败(cgroup driver 不匹配) | 确保 /etc/containerd/config.toml 中 SystemdCgroup = true 与 Kubelet 一致 |
| 镜像需要重新拉取 | Docker 与 Containerd 存储路径不同,可提前 docker save 或推私有仓库 |
| 日志路径或格式变化 | 默认仍在 /var/log/pods/ 和 /var/log/containers/ 下,采集工具可能需调整 |
| 监控指标变化 | Prometheus 等需调整为 Containerd metrics 或依赖 Kubelet CRI metrics |
| 网络插件兼容性 | 大多数 CNI 插件与运行时无关,但需确认官方文档 |
| 调试体验差异 | docker ps/logs 改为 crictl ps/logs,ctr 更底层 |
| 安全策略(AppArmor/SELinux) | 可能需针对 Containerd 调整,但通常继承宿主机配置 |
4️⃣ 总结
-
核心:充分准备、逐节点操作、关键配置正确。
-
最大坑:cgroup driver 配置。
-
迁移后集群更轻量、高效,并符合 Kubernetes 未来发展方向。