导读:本期聚焦于崔健创作的《containerd 和 Docker 是什么关系?两者区别与联系全解析》,敬请观看详情。Docker 并不是一个单独的软件,而是一整套容器工具生态,containerd 正是其中负责容器生命周期管理的核心运行时组件。本文从架构演进讲起,梳理 Docker 从自研 daemon 到拆分出 containerd 再到 containerd 成为 CNCF 毕业项目的过程,详细对比两者的职责边界、常见使用命令差异,并结合 Kubernetes 场景分析 CRI 接口下 kubelet 如何直接对接 containerd。读完这篇内容,你就能彻底理清 Docker、containerd、runc、CRI、 OCI 这些概念之间的关系。

不少刚接触容器技术的同学都会有一个困惑:containerd 和 Docker 到底是什么关系?为什么装了 Docker 之后会看到 containerd 的进程,而在 Kubernetes 集群里又常常被建议直接使用 containerd 而不装 Docker?要回答这些问题,得从容器技术这几年的架构演进说起。简单来讲,Docker 是一套面向开发者的完整容器工具集,而 containerd 是从 Docker 中拆分出来、专门负责容器生命周期管理的一个工业级运行时,两者不是竞争关系,而是上下游的分工协作关系。

containerd 和 Docker 是什么关系?两者区别与联系全解析

一、从架构演进看两者的渊源

Docker 早期的架构非常简单:一个 monolithic 的 docker daemon 包揽所有事情,包括镜像构建、镜像分发、容器网络、容器存储、容器生命周期管理等。这种设计在初期跑得很顺,但随着容器生态的膨胀,问题逐渐暴露。一方面 Kubernetes 这类编排系统只需要「创建容器、管理容器」这个核心能力,不需要 Docker 的构建和 CLI 体验;另一方面所有功能堆在一个 daemon 里,任何一个模块出问题都可能拖垮整个服务。

于是 Docker 在 2016 年底把容器管理核心拆了出来,捐赠给 CNCF,这就是 containerd 的由来。拆分后的链路变成了:docker CLI 把请求发给 dockerd,dockerd 处理构建、网络、卷等上层逻辑,真正启动容器时调用 containerd,containerd 再调用更底层的 runc 去创建容器进程。runc 是 OCI 运行时标准的参考实现,负责和内核的 namespace、cgroup 打交道,是真正「生出」容器的那一层。

后来 containerd 独立发展,2019 年从 CNCF 正式毕业,如今已经是不依赖 Docker 也能独立部署的通用容器运行时。所以准确地说:Docker 内置了 containerd,但 containerd 不属于 Docker。

二、职责边界:Docker 做了哪些 containerd 不做的事

两者的核心差异在于功能覆盖面。Docker 在 containerd 之上补齐了大量面向开发者体验的能力,比如 docker build 镜像构建、docker-compose 编排、docker network 提供的 bridge 网络和端口映射、数据卷管理,以及一套非常好用的命令行工具。这些能力让 Docker 成为本地开发和持续集成场景的事实标准。

而 containerd 只关注容器运行时最核心的部分:镜像的拉取与存储、容器生命周期的管理、快照管理、任务监控等。它刻意不做构建、不做复杂网络、不做卷的高级抽象,保持小而稳。这种克制恰恰是 Kubernetes 需要的——编排系统希望自己掌控网络、存储和调度,运行时只需要老老实实把容器跑起来就行。

在容器的层级结构上可以这样理解:

docker CLI        # 用户交互入口
  └── dockerd     # 处理构建、网络、卷等上层逻辑
        └── containerd            # 容器生命周期管理、镜像管理
              └── containerd-shim # 容器与守护进程解耦的中间层
                    └── runc      # 真正创建容器进程(OCI 运行时)

其中 containerd-shim 值得一提:它让每个容器对应一个独立的 shim 进程,即使 containerd 重启或崩溃,正在运行的容器也不会被杀死。dockerd 不再直接管理容器进程,这正是当年架构拆分带来的最大好处之一。

三、Kubernetes 场景下的选择:为什么要弃用 dockershim

熟悉 Kubernetes 的同学应该知道,Kubernetes 从 1.24 版本开始移除了内置的 dockershim 组件。这并不意味着 Docker 构建的镜像不能用了,而是说 kubelet 不再通过 Docker 这条链路来管理容器。

在这之前,kubelet 通过 CRI(容器运行时接口)和容器运行时通信。但 Docker 早期并没有实现 CRI,于是 Kubernetes 在 kubelet 里塞了一个 dockershim 做协议转换:CRI 请求先转成 Docker API 调用 dockerd,dockerd 再转给 containerd。一条链路上堆了两层转换,既低效又难维护。而 containerd 从 1.1 版本起原生实现了 CRI 插件,kubelet 可以直接对接 containerd,中间环节全部省掉。

两条链路的对比大致是:

# 旧链路(已废弃)
kubelet -> dockershim -> dockerd -> containerd -> runc

# 现行链路
kubelet -> CRI 插件 -> containerd -> runc

切换到 containerd 后,日常操作命令也发生了变化。比如查看容器不再用 docker ps,而是使用官方提供的 nerdctl 工具,或者 crictl

# 使用 crictl 查看运行中的容器
crictl ps

# 使用 nerdctl 拉取镜像并运行容器,体验接近 docker
nerdctl pull nginx:latest
nerdctl run -d --name web -p 8080:80 nginx:latest

# 查看 containerd 的命名空间,k8s 的容器在 k8s.io 命名空间下
ctr namespaces list
ctr -n k8s.io containers list

需要特别说明的是,containerd 引入了 namespace(命名空间)的概念来隔离不同客户端的镜像和容器。Docker 使用的镜像默认放在 moby 命名空间下,而 Kubernetes 放在 k8s.io 命名空间下。这就是为什么在一台机器上同时装了 Docker 和 containerd 时,用 docker images 看到的镜像和 crictl images 看到的可能完全不同,它们物理上都在 containerd 的存储里,但逻辑上互不可见。

四、实际场景中该如何选择

如果你是应用开发者,日常需要在本地构建镜像、调试服务、跑 docker-compose,那么继续用 Docker 是最省心的选择,Docker Desktop 一装全都有。此时 containerd 会在后台默默工作,你不需要直接和它打交道。

如果你是运维或平台工程师,负责 Kubernetes 集群,那么直接部署 containerd 是当前的主流方案。更少的中间层意味着更少的故障点和资源开销,集群节点上少跑一个 dockerd 进程,内存占用和攻击面都会降低。生产环境中也可以配合 ctr、nerdctl 这类工具完成日常的镜像排查和容器诊断。

总结成一句话:Docker 是给「人」用的容器工具套件,containerd 是给「平台」用的容器运行时。Docker 底下跑着 containerd,Kubernetes 直接跑在 containerd 上,两者共享同一套 OCI 镜像标准和 runc 运行时。理解了这条分层脉络,再看容器生态里的各种组件,就不会再混淆了。

containerdDocker容器运行时修改时间:2026-09-03 06:26:34

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