导读:本期聚焦于天穹小白创作的《从 Docker 迁移到 containerd 难吗?手把手教你完成容器运行时切换》,敬请观看详情。Kubernetes 从 1.24 版本起正式移除 dockershim,直接使用 containerd 作为默认容器运行时,不少团队因此面临迁移问题。其实 containerd 本身就是 Docker 内部的核心组件之一,从 Docker 切换到 containerd 并不是推倒重来,而是剥离上层封装、直接对接标准运行时的过程。本文将带你理清 Docker 与 containerd 的架构关系,梳理迁移前需要确认的镜像格式、日志配置、构建工具链等兼容性事项,并给出 Ubuntu 与 CentOS 环境下的完整安装配置步骤、crictl 常用命令对照,以及镜像从 docker sha256 格式转换的方法,最后总结迁移后的验证与回退方案,帮助你平滑完成运行时切换。

Kubernetes 宣移除 dockershim 之后,containerd 成了容器编排领域事实上的标准运行时。虽然 Docker 创建的容器依然可以正常使用,但如果你在搭建新的 Kubernetes 集群,或者希望精简节点上的组件,直接使用 containerd 是更主流的选择。这篇文章会把 Docker 和 containerd 的关系讲清楚,再一步步演示如何完成迁移。

从 Docker 迁移到 containerd 难吗?手把手教你完成容器运行时切换

一、先搞清楚 Docker 和 containerd 是什么关系

很多人以为 containerd 是 Docker 的替代品,是从零开始写的一个新项目,这个理解有偏差。containerd 最早就是 Docker 公司捐给 CNCF 的项目,它原本就是 Docker 架构中的一个核心组件,负责容器生命周期管理、镜像存储和网络命名空间的创建。Docker 引擎本质上是在 containerd 之上加了一层封装,包括 Docker CLI、Docker API、镜像构建、日志管理、卷管理等用户体验层面的功能。

换句话说,你日常使用的 docker run,最终执行容器创建的其实就是底层的 containerd。Docker 引擎内部还有一个叫 containerd-shim 的进程,它负责守护每个容器的运行,即使 Docker 守护进程重启,容器也不会被杀掉,这就是所谓的热升级能力。

迁移到 containerd,相当于把 Docker 这层外壳剥掉,直接操作内核组件。好处是明显的:节点上少了一个常驻的 Docker 守护进程,资源占用更低,容器启动链路更短,与 Kubernetes 的 CRI 接口对接也更直接。代价是失去了一部分便利功能,比如 docker build 构建镜像、docker logs 查看日志,这些需要换成新的工具来替代。

二、迁移前必须确认的兼容性问题

1. 镜像格式差异

Docker 默认存储的镜像是 Docker V2 格式,而 containerd 通过 CRI 插件使用的是 OCI 标准格式。两者在镜像清单层面有细微差别,最直接的表现是镜像列表不互通:切换运行时后,原来 Docker 拉取的镜像不能被 containerd 直接使用,需要重新拉取或转换。

2. 日志驱动配置

Kubernetes 依赖容器运行时输出日志文件到指定目录,然后由 kubelet 所在节点的日志收集器统一处理。Docker 默认的日志驱动是 json-file,而 containerd 的 CRI 插件要求日志输出到 /var/log/pods/var/log/containers 目录。如果你的监控体系依赖特定日志路径,迁移时要同步调整采集配置。

3. 镜像构建工具链

containerd 本身不提供 docker build 能力,官方推荐使用 BuildKit 或者 nerdctl 这类工具。BuildKit 可以独立运行,通过 buildctl 命令构建镜像并直接推送到仓库;nerdctl 则是一个模仿 Docker CLI 的工具,用起来几乎和 Docker 一样,学习成本很低。迁移前建议先在测试环境把这些工具跑通。

4. 监控指标接口

Docker 提供了自己的 metrics 接口,很多监控系统直接采集 Docker 的 API 数据。containerd 的监控指标需要通过 CRI 接口或者 Prometheus 插件获取,原来针对 Docker 写的采集脚本需要改造。这一点在生产环境迁移中经常被忽略,需要提前盘点。

三、安装和配置 containerd 完整步骤

下面以 Ubuntu 系统为例演示完整流程,CentOS 的操作基本一致,只是包管理命令不同。开始之前,建议先在测试节点演练一遍。

第一步,安装 containerd 软件包。推荐从官方仓库安装,这样能获取较新的稳定版本:

# 安装依赖并添加 Docker 官方仓库
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

# 安装 containerd
sudo apt-get update
sudo apt-get install -y containerd.io

第二步,生成默认配置并修改。默认配置文件是不存在的,需要先导出一份:

sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml

然后编辑 /etc/containerd/config.toml,重点关注两处配置。一是把 SystemdCgroup 设置为 true,让容器使用 systemd 管理 cgroup,这是 Kubernetes 官方推荐的做法,可以避免 cgroup 驱动不一致导致的资源统计问题:

[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
  ...
  [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
    SystemdCgroup = true

二是配置镜像加速器。如果节点在国内,拉取镜像时配置一个加速地址能明显提升速度:

[plugins."io.containerd.grpc.v1.cri".registry]
  [plugins."io.containerd.grpc.v1.cri".registry.mirrors]
    [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
      endpoint = ["https://registry.example-cn.ipipp.com"]

第三步,重启服务并设置开机自启:

sudo systemctl restart containerd
sudo systemctl enable containerd
sudo systemctl status containerd

第四步,安装 crictl 工具。crictl 是 CRI 运行时的命令行客户端,作用相当于之前的 docker 命令。它需要一个配置文件指定运行时 endpoint:

cat <<'EOF' | sudo tee /etc/crictl.yaml
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: false
EOF

配置完成后,执行 sudo crictl info 能正常返回运行时信息,就说明安装成功了。

四、常用命令对照与镜像处理

切换到 containerd 后,日常操作习惯需要调整。下面这个对照表能帮你快速上手:

操作Docker 命令containerd 环境命令
查看镜像docker imagescrictl images
拉取镜像docker pull nginxcrictl pull nginx
查看容器docker pscrictl ps
查看所有容器docker ps -acrictl ps -a
进入容器docker exec -it 容器 bashcrictl exec -it 容器 bash
查看日志docker logs 容器crictl logs 容器
查看详情docker inspect 容器crictl inspect 容器

有一点要特别说明:crictl 操作的是 CRI 命名空间下的镜像和容器,而 containerd 本身支持多命名空间。如果你想直接管理 containerd 的原生资源,需要用 ctr 命令并指定命名空间,例如 ctr -n k8s.io images list。两个命令看到的镜像列表不同,这是初学者最容易困惑的地方。

至于本地已有 Docker 镜像的处理,最简单的方案是导出再导入。Docker 导出的 tar 包可以通过 ctr 命令导入到 k8s.io 命名空间:

# 在原环境导出
docker save -o app.tar myapp:1.0

# 导入到 containerd 的 k8s.io 命名空间
sudo ctr -n k8s.io images import app.tar

如果镜像数量多,或者来源环境不可用,直接配置镜像加速重新拉取往往更省事。

五、迁移后的验证与回退方案

切换运行时后不要急着下线 Docker,先做完整验证。第一步验证容器网络,创建一个测试 Pod 确认 DNS 解析和服务访问正常;第二步验证日志采集,检查 /var/log/pods 目录下是否正常生成日志文件,日志收集器能否正确读取;第三步验证监控指标,确认 cAdvisor 或 Prometheus 采集到的容器指标没有中断。

对于 Kubernetes 集群节点,迁移顺序建议是先驱逐节点上的工作负载,修改 kubelet 配置中的 --container-runtime 参数和对应的 endpoint,再让节点重新加入集群:

# 修改 /var/lib/kubelet/kubeadm-flags.env
CONTAINER_RUNTIME="containerd"
CONTAINER_RUNTIME_ENDPOINT="unix:///run/containerd/containerd.sock"

# 重启 kubelet
sudo systemctl restart kubelet

回退方案也要提前准备。只要不卸载 Docker 包,把 kubelet 的运行时参数改回 docker 的 endpoint 并重启,节点就能恢复原状。所以生产环境迁移时,建议保留 Docker 一到两周作为观察期,确认日志、监控、告警链路全部稳定后,再彻底清理 Docker 环境和相关的镜像存储目录,释放磁盘空间。

整体来看,从 Docker 迁移到 containerd 的技术难度并不高,真正的挑战在于周边工具链的适配。把镜像构建、日志采集、监控指标这几个依赖点提前梳理清楚,按照测试节点、工作节点、控制节点的顺序分批操作,整个迁移过程可以做到业务无感知。

containerdDocker迁移容器运行时修改时间:2026-09-05 00:16:47

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/20260905/50557.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。