3. 容器运行时生态:对比 containerd、CRI-O、Docker(通过 dockershim)的架构差异与选型

Kubernetes 自 v1.24 正式移除 dockershim 后,容器运行时的选型从“默认 Docker”转变为“直接对接 CRI 的实现”。当前主流的生产级 CRI 实现包括 containerd、CRI-O 以及已退役的 Docker + dockershim。理解三者的架构差异,是进行运行时性能调优和集群规划的前提。

3.1 架构演进:从 dockershim 到原生 CRI

Docker 本身并未实现 CRI 接口,Kubernetes 通过 kubelet 内置的 dockershim 组件将 CRI 调用转换为 Docker API。这种“中间层”架构增加了调用链长度和资源开销。containerd 和 CRI-O 则直接实现 CRI gRPC 接口,无需额外适配层。

关键演进节点: Kubernetes v1.24 正式移除 dockershim,标志着容器运行时进入“原生 CRI 时代”。生产集群应避免使用 Docker + dockershim 模式。
三种容器运行时架构对比 Docker + dockershim(已退役) containerd(CNCF 毕业) CRI-O(OCI 原生) kubelet dockershim(内置) Docker Engine containerd(内部) runc / shim kubelet containerd (原生 CRI 实现) containerd-shim runc kubelet CRI-O (OCI 原生实现) conmon runc 说明:Docker 架构多一层 dockershim 适配层,containerd 和 CRI-O 直接实现 CRI gRPC 接口 containerd 使用 containerd-shim,CRI-O 使用 conmon 作为容器进程管理组件

3.2 核心差异对比

维度 containerd CRI-O Docker + dockershim
项目归属 CNCF 毕业项目,Docker 捐赠 CNCF 孵化项目,Red Hat 主导 Docker Inc.,已从 K8s 移除
CRI 实现方式 原生 CRI gRPC 接口 原生 CRI gRPC 接口 通过 dockershim 适配层转换
镜像管理 内置镜像存储、拉取、挂载 依赖 containers/image 库 Docker 镜像管理全套
容器进程管理 containerd-shim conmon docker-containerd-shim
OCI 兼容性 完全兼容 OCI 镜像和运行时 完全兼容 OCI,更早支持 通过 containerd 间接兼容
调用链长度 kubelet → containerd → shim → runc kubelet → CRI-O → conmon → runc kubelet → dockershim → Docker → containerd → shim → runc
资源占用 低(单一守护进程) 低(单一守护进程) 高(多守护进程 + 适配层)
CLI 工具 ctr / nerdctl crictl(通用) docker CLI

3.3 性能特征对比

在同等硬件条件下,三种运行时的性能差异主要体现在 Pod 启动延迟、镜像拉取吞吐 和 内存占用 三个维度。

性能指标 containerd CRI-O Docker + dockershim
Pod 启动延迟(P50) ~350ms ~380ms ~520ms
Pod 启动延迟(P99) ~800ms ~850ms ~1200ms
镜像拉取(500MB) ~4.2s ~4.5s ~5.8s
空闲内存占用 ~50MB ~45MB ~180MB
API 响应延迟 低 低 中
性能选型建议: 对于大规模集群(>500 节点)或对 Pod 启动延迟敏感的场景(如 Serverless、批量任务),优先选择 containerd 或 CRI-O。Docker + dockershim 在 v1.24 后已不再支持,不应在新集群中使用。

3.4 选型决策矩阵

根据集群规模、运维团队技术栈和业务场景,以下矩阵可辅助选型决策:

场景 推荐运行时 理由
通用生产集群(<500 节点) containerd 生态成熟、社区活跃、性能稳定、与 Docker 共享底层
大规模集群(>500 节点) containerd 或 CRI-O 资源占用低、启动延迟小、控制面压力小
Red Hat OpenShift 环境 CRI-O OpenShift 默认运行时,深度集成,安全策略支持好
边缘计算 / 资源受限环境 CRI-O 内存占用最低(~45MB),依赖组件少
需要 Docker CLI 调试 containerd + nerdctl nerdctl 提供与 docker CLI 几乎一致的体验
安全合规要求高(FIPS、SELinux) CRI-O Red Hat 主导,安全加固更完善

3.5 关键架构差异详解

3.5.1 containerd 架构特点

  • 单一守护进程: containerd 以单一 gRPC 服务对外提供 CRI 接口,内部通过插件架构管理镜像、容器、快照和元数据。
  • containerd-shim: 每个容器对应一个 shim 进程,负责管理容器生命周期、上报状态、处理 stdin/stdout 流。shim 在容器退出后仍存活,直到 kubelet 确认清理。
  • 镜像加速: 支持 stargz、estargz、nydus 等镜像加速格式,适合大规模镜像分发场景。
  • 调试工具链: ctr(低级 CLI)、nerdctl(Docker 兼容 CLI)、crictl(通用 CRI 调试)。

3.5.2 CRI-O 架构特点

  • OCI 原生: CRI-O 从设计之初就完全围绕 OCI 规范构建,不依赖任何 Docker 组件。
  • conmon: 容器监控组件,负责收集容器日志、监控容器进程、处理信号转发。conmon 在容器生命周期内持续运行。
  • 镜像管理: 使用 containers/image 库,支持多种镜像仓库协议,与 Podman、Buildah 共享底层库。
  • 安全特性: 默认集成 SELinux 标签、seccomp 策略、ReadOnlyRootFilesystem 等安全配置。

3.5.3 Docker + dockershim 架构(已退役)

  • 调用链过长: kubelet → dockershim → Docker API → dockerd → containerd → containerd-shim → runc,共 6 层调用。
  • 资源浪费: dockerd 作为独立守护进程,额外占用内存和 CPU;dockershim 作为 kubelet 内置组件,增加 kubelet 内存占用。
  • 版本耦合: dockershim 与 Docker 版本绑定,升级 Docker 可能引入兼容性问题。
  • 退役影响: Kubernetes v1.24 移除 dockershim 后,使用 Docker 作为运行时的集群必须迁移至 containerd 或 CRI-O。
迁移警告: 如果当前集群仍在使用 Docker + dockershim,请立即规划迁移。Kubernetes v1.24+ 不再支持 dockershim,继续使用将导致 kubelet 无法启动。建议使用 crictl 验证新运行时的 CRI 接口可用性后再进行全量迁移。

3.6 运行时组件对比总结

运行时组件堆栈对比 containerd CRI-O Docker + dockershim kubelet containerd (CRI) containerd-shim runc Linux Kernel kubelet CRI-O conmon runc Linux Kernel kubelet dockershim dockerd containerd containerd-shim runc Linux Kernel containerd 和 CRI-O 堆栈深度为 4 层(kubelet → 运行时 → shim/conmon → runc) Docker + dockershim 堆栈深度为 7 层,多出 dockershim、dockerd、containerd 三层 每增加一层调用,Pod 启动延迟增加约 15%-20%,内存占用增加约 30MB

3.7 选型检查清单

在最终确定运行时选型前,建议逐项确认以下条件:

  1. Kubernetes 版本兼容性: 确认所选运行时支持当前集群的 K8s 版本(建议 ≥ v1.24)。
  2. 操作系统支持: containerd 和 CRI-O 均支持主流 Linux 发行版;CRI-O 在 RHEL/CentOS 上集成更紧密。
  3. 镜像仓库兼容性: 确认运行时能正常拉取私有仓库镜像(含认证、TLS 配置)。
  4. 监控与日志集成: 确认运行时与 Prometheus、Fluentd、Filebeat 等组件的集成方式。
  5. 安全策略支持: 确认 PodSecurityPolicy(PSP)或 OPA/Kyverno 策略在目标运行时上的生效情况。
  6. 团队技术储备: 评估运维团队对 nerdctl(containerd)或 crictl(通用)的熟悉程度。
  7. 迁移成本: 评估从现有运行时迁移的停机时间、数据迁移和回滚方案。
生产建议: 对于新建集群,推荐默认使用 containerd。它拥有最广泛的社区支持、最成熟的生态工具链(nerdctl、ctr、crictl),且与 Docker 共享底层镜像格式,迁移成本最低。对于 Red Hat 技术栈或安全合规要求极高的场景,选择 CRI-O。