Kubernetes弃用Docker:从CRI标准到containerd迁移的深度解析

发布时间:2026/9/23 0:22:48

Kubernetes弃用Docker:从CRI标准到containerd迁移的深度解析 1. 项目概述一次技术栈的“和平分手”如果你在2020年底之后才开始接触Kubernetes可能会觉得“K8s放弃Docker”是个老生常谈的话题。但对于很多从Docker Swarm时代一路走来的老运维或者习惯了docker run、docker-compose up这套工作流的开发者来说这无疑是一次认知上的地震。当时社区里充满了困惑和不解“我Docker用得好好的K8s凭什么说不用就不用了”“是不是以后就不能用Docker镜像了”“我的CI/CD流水线是不是要重写了”事实上这并非一次突如其来的“决裂”而是一场酝酿已久、水到渠成的技术架构演进。K8sKubernetes并没有“放弃”容器本身它放弃的只是Docker作为一个容器运行时的默认集成。理解这场变革不仅能帮你厘清K8s与Docker如今的关系更能让你深入理解云原生基础设施的底层设计哲学。简单来说K8s需要的是一个更专注、更标准化的“发动机”容器运行时而Docker是一个功能丰富的“整车厂”。当K8s这个“智能驾驶平台”成熟后它更希望直接对接标准化的“发动机”而不是整合一个自带方向盘、座椅和音响的“整车厂”。接下来我们就从容器生态的演变、接口标准化的必然以及实际运维的视角彻底拆解这次“分手”背后的深层逻辑。2. 核心需求解析K8s到底需要什么要理解为什么“分手”首先要明白K8s和Docker各自的核心诉求是什么。这绝非简单的“谁更好”而是角色定位的根本不同。2.1 Docker的定位开发者友好的全能工具箱Docker的成功在于它极大地降低了容器技术的使用门槛。它提供了一站式解决方案Docker Daemon一个常驻后台的守护进程负责管理容器生命周期、镜像构建与分发。Docker CLI我们熟悉的docker命令是与Daemon交互的客户端工具。Docker Registry镜像仓库服务。Docker Compose用于定义和运行多容器应用的工具。Docker Desktop为Mac/Windows用户提供完整的桌面端体验。Docker把容器运行时、镜像构建、网络、存储、集群编排早期Swarm等众多功能打包在一起形成了一个强大的“全家桶”。对于开发者个人或小团队这个全家桶非常方便开箱即用。2.2 K8s的定位生产级编排系统的标准化诉求K8s的目标是成为数据中心的操作系统管理成千上万个容器化应用。它的核心诉求是稳定与可靠作为基础设施必须极其稳定任何组件的崩溃都不应导致集群大面积故障。标准化与可插拔希望底层组件网络、存储、运行时能通过标准接口接入避免被单一厂商绑定促进生态繁荣。轻量与高效每个组件职责单一减少不必要的开销和攻击面。安全的生命周期管理对容器的创建、运行、监控需要有更精细、更安全的控制能力。问题就出在这里。Docker Daemon作为一个大而全的单体守护进程与K8s的诉求产生了根本性冲突。3. 技术架构冲突与CRI的诞生矛盾的核心在于架构。在早期K8s是通过一个叫dockershim的组件来调用Docker的。3.1 “垫片”架构的固有缺陷dockershim的本质是一个适配器它把K8s定义的容器操作指令翻译成Docker Daemon能理解的APIDocker Engine API。这个架构带来了几个致命问题单点故障与稳定性风险Docker Daemon是一个独立的、有状态的守护进程。如果它崩溃了所有通过它创建的容器都会失去管理尽管容器本身可能还在运行。这对于K8s控制平面来说是不可接受的。K8s希望运行时是轻量的、无状态的即使运行时重启也不应影响现有容器的状态。额外的抽象层与性能损耗调用链变成了kubelet-dockershim-Docker Daemon-containerd-runc。每多一层就意味着更多的序列化/反序列化、进程间通信开销和潜在的故障点。功能冗余与维护负担Docker Daemon提供了很多K8s根本不需要的功能比如内置的镜像构建、Docker Swarm集群管理等。K8s只需要它最核心的容器生命周期管理能力。维护dockershim这个“胶水代码”成了K8s社区一个沉重的负担尤其是当Docker Engine API发生变化时。安全边界模糊Docker Daemon通常以root权限运行拥有巨大的权限。dockershim的存在使得攻击面增大。3.2 CRI容器运行时的“普通话”标准为了解决这些问题Kubernetes社区提出了容器运行时接口Container Runtime Interface, CRI。你可以把CRI想象成容器运行时的“普通话”标准。目标定义一套K8s具体是kubelet与任何容器运行时之间通信的通用API协议基于gRPC。好处任何实现了CRI的容器运行时都可以无缝接入K8s。K8s无需关心底层运行时是Docker、containerd还是CRI-O它只需要用“普通话”CRI发号施令即可。CRI的诞生标志着K8s在基础设施标准化上迈出了关键一步。它希望底层运行时是一个专注、高效、稳定的“引擎”而不是一个“整车厂”。3.3 Docker与CRI的“兼容性”问题那么Docker本身支持CRI吗不支持。Docker Daemon暴露的是自己的Docker Engine API而不是CRI。这就是最根本的“语言不通”。为了让Docker能在K8s 1.23版本之前继续工作社区不得不一直维护着dockershim这个“翻译官”。但随着CRI的成熟和替代方案如containerd的稳定继续维护这个多余的、有问题的翻译层就显得越来越不划算。最终K8s社区做出了一个合乎逻辑的决定废弃dockershim直接拥抱实现了CRI的标准化运行时。这被很多人解读为“K8s放弃Docker”准确地说是“K8s放弃通过非标准的、间接的方式dockershim来调用Docker所包含的容器运行时功能”。4. 替代方案containerd的崛起与实操迁移那么Docker“离开”后谁接替了它的位置答案是containerd。事实上它一直都在。4.1 containerd从幕后到台前很多人不知道的是从Docker 1.11版本开始Docker Daemon的底层容器运行时功能就已经被拆分成独立的containerd项目。Docker Daemon本身变成了一个更上层的管理工具它通过API调用containerd来实际创建和管理容器。containerd是一个专注于容器核心功能的工业级运行时镜像传输、容器执行、存储管理、网络命名空间管理。它比Docker Daemon更轻量、更专注并且原生实现了CRI接口通过一个叫cri-containerd的插件。所以当K8s移除dockershim后它并不是找了一个新朋友而是选择了直接和老朋友containerd“牵手”。架构从kubelet-dockershim-Docker Daemon-containerd简化为了kubelet-CRI-containerd少了两层更简洁、更高效、更稳定。4.2 对用户的实际影响镜像、命令与工作流这是大家最关心的问题改变之后对我们有什么影响镜像兼容性完全不受影响。Docker镜像遵循OCI开放容器倡议标准格式。containerd和所有其他主流容器运行时都完全支持OCI标准。你之前所有docker pull下来的镜像都可以继续在K8s中使用无需任何转换。镜像仓库如Docker Hub、Harbor也完全通用。构建工具不受影响。你仍然可以使用docker build来构建镜像。Docker作为一个强大的镜像构建工具和开发者桌面体验工具其地位并未改变。构建好的镜像推送到仓库K8s集群中的containerd会拉取并运行它。你的CI/CD流水线中关于镜像构建的部分通常无需改动。节点运维命令需要改变习惯。这是主要的变化点。以前在K8s节点上排查问题我们习惯用docker ps、docker logs、docker exec等命令。现在需要改用containerd提供的命令行工具crictlCRI兼容的工具或ctrcontainerd原生工具。重要提示crictl的命令设计刻意模仿了dockerCLI的使用习惯以降低迁移成本。例如docker ps-crictl psdocker logs container-id-crictl logs container-iddocker exec -it container-id sh-crictl exec -it container-id shdocker images-crictl imagesctr命令更底层功能更强但语法与docker差异较大一般用于更高级的调试。Docker Desktop等工具不受影响。Docker Desktop for Mac/Windows 在“启用Kubernetes”时内部早已使用containerd作为K8s的运行时。对于开发者本地环境一切照旧。4.3 迁移实操指南与注意事项如果你的集群是在K8s 1.24版本之前搭建的且仍在使用dockershim那么升级到1.24时需要迁移。主流K8s安装工具如kubeadm、k3s、RKE2的新版本默认都已使用containerd。以使用kubeadm的集群为例迁移的核心步骤准备工作备份所有重要数据和应用配置。逐节点操作确保应用有高可用或可在其他节点重建。清空节点使用kubectl drain node-name --ignore-daemonsets安全驱逐节点上的Pod。卸载Docker Engine# 停止Docker服务 sudo systemctl stop docker # 卸载Docker引擎包 (以Ubuntu为例) sudo apt-get purge -y docker-ce docker-ce-cli # 清理残留文件谨慎操作确保不需要旧镜像/容器数据 sudo rm -rf /var/lib/docker安装containerd# 安装containerd.io包 (具体版本需匹配K8s要求) sudo apt-get update sudo apt-get install -y containerd.io # 生成默认配置文件 sudo mkdir -p /etc/containerd sudo containerd config default | sudo tee /etc/containerd/config.toml # 修改配置启用Systemd Cgroup驱动与kubelet保持一致 sudo sed -i s/SystemdCgroup false/SystemdCgroup true/ /etc/containerd/config.toml # 重启containerd sudo systemctl restart containerd sudo systemctl enable containerd配置kubelet使用containerd修改kubelet参数通常位于/var/lib/kubelet/kubeadm-flags.env或/etc/default/kubelet。确保--container-runtime参数为remote且--container-runtime-endpoint指向containerd的CRI socket默认是unix:///run/containerd/containerd.sock。# 例如在kubeadm环境中编辑配置文件后重启kubelet sudo systemctl restart kubelet验证与恢复使用crictl ps查看容器是否正常运行。使用kubectl get nodes查看节点状态是否恢复为Ready。取消节点保护kubectl uncordon node-name。实操心得在生产环境迁移时强烈建议先在测试环境完整走通流程。重点关注自定义容器运行时配置如私有镜像仓库的认证、日志驱动等如何从Docker迁移到containerd。containerd的配置文件是/etc/containerd/config.toml其结构与Docker的daemon.json不同需要重新学习。5. 深入对比containerd vs Docker Daemon理解两者的区别能更好地把握这次架构变更的精髓。特性维度Docker Daemoncontainerd定位完整的容器平台面向开发者专注的容器运行时面向基础设施架构单体守护进程集成度高模块化设计通过插件扩展APIDocker Engine API (REST)CRI (gRPC) 为主低级API为辅功能范围容器生命周期、镜像构建、网络、存储、集群Swarm等核心的容器生命周期、镜像管理、存储管理资源占用相对较高更轻量内存和CPU占用更少启动速度较慢更快稳定性组件耦合一损俱损风险稍高职责单一更稳定故障影响面小安全性庞大的root进程攻击面大更小的攻击面支持rootless模式简单来说Docker Daemon是一个“瑞士军刀”而containerd是一把锋利的“主厨刀”。对于K8s这个需要高效、稳定、标准化后厨的“大酒店”来说一把专注的好刀比一个多功能工具更合适。6. 常见问题与排查技巧实录迁移到containerd后运维习惯需要改变。以下是一些常见问题和处理技巧。6.1 命令转换速查与技巧场景需要进入容器排查问题。旧习惯docker exec -it container-id bash新方法crictl exec -it container-id bash技巧如果容器内没有bash可以尝试sh。获取容器ID最快捷的方式是结合kubectlkubectl get pods -n namespace pod-name -o jsonpath{.status.containerStatuses[0].containerID} | cut -d/ -f3。这个命令能直接输出容器ID供crictl使用。场景查看容器日志。旧习惯docker logs -f container-id新方法crictl logs -f container-id技巧crictl logs默认输出所有日志。对于K8s Pod日志通常也被收集到/var/log/pods/和/var/log/containers/目录下你可以直接使用tail -f查看这些文件这在crictl不可用时是备选方案。场景检查容器内进程。旧习惯docker top container-id新方法首先用crictl inspect container-id获取容器的PID然后使用nsenter命令进入容器的命名空间查看或者直接用ps -ef | grep pid查看进程树。更简单的方法是使用crictl exec container-id ps aux。6.2 镜像拉取失败问题排查这是迁移后最常见的问题之一尤其是使用私有镜像仓库时。症状Pod状态为ImagePullBackOff事件显示Failed to pull image。排查思路第一步确认镜像地址和标签。使用kubectl describe pod pod-name查看事件详情。第二步在节点上手动拉取测试。使用crictl pull命令模拟拉取这能绕过K8s直接测试containerd的配置。sudo crictl pull myprivateregistry.com/myapp:v1第三步检查containerd的私有仓库配置。Docker的认证配置在~/.docker/config.json而containerd需要在其配置文件/etc/containerd/config.toml中配置[plugins.io.containerd.grpc.v1.cri.registry.mirrors]和[plugins.io.containerd.grpc.v1.cri.registry.configs]部分。这是与Docker最大的配置差异点。第四步重启containerd。修改配置后务必sudo systemctl restart containerd。第五步检查K8s的Secret。如果使用imagePullSecrets确保Secret在正确的命名空间且内容正确。避坑技巧对于私有仓库的HTTPS证书问题如果使用自签名证书需要在containerd配置中指定ca文件或者直接配置insecure_skip_verify true仅限测试环境。配置格式示例[plugins.io.containerd.grpc.v1.cri.registry.configs.myregistry:5000.tls] insecure_skip_verify true6.3 容器日志与存储路径变更Docker的默认工作目录是/var/lib/docker而containerd的默认目录是/var/lib/containerd。这带来两个变化日志路径容器标准输出日志不再位于/var/lib/docker/containers/.../*.log。K8s环境下容器日志被kubelet通过CRI接口获取后默认写入节点文件的/var/log/pods/namespace_pod_uid/container-name/目录下按序号分文件存储。同时在/var/log/containers/目录下有指向这些日志文件的符号链接方便查找。镜像存储镜像和容器层数据现在存储在/var/lib/containerd/io.containerd.content.v1.content/等子目录下结构更为复杂。一般不需要直接操作这些文件。磁盘空间清理以前用docker system prune现在可以用sudo crictl rmi --prune删除未被任何容器引用的镜像。清理容器sudo crictl rm删除已停止的容器。注意containerd没有一键清理所有缓存数据的命令需要手动结合crictl和ctr命令或定期清理/var/lib/containerd目录风险高需谨慎。6.4 crictl与ctr命令的选择crictl这是K8s项目维护的、兼容CRI的调试工具。它的命令和输出格式针对K8s环境做了优化能更好地显示与Pod、容器沙箱pause容器相关的信息。日常节点运维和问题排查首选crictl。ctr这是containerd原生的命令行客户端功能更强大可以操作所有containerd管理的命名空间而crictl只操作k8s.io命名空间。它可以管理镜像、容器、命名空间、快照等。当你需要进行底层操作或者crictl无法满足需求时如导入导出镜像、管理非K8s容器才使用ctr。例如导入一个离线镜像包# 使用ctr导入 sudo ctr -nk8s.io images import /path/to/image.tar # 使用crictl查看是否导入成功 sudo crictl images7. 总结与展望生态的必然选择回顾整个过程K8s放弃对Docker的默认集成不是一个针对Docker的“惩罚”而是云原生生态走向成熟和标准化的必然结果。CRI标准的确立就像为容器运行时定义了USB接口让K8s这个“主机”可以连接任何符合标准的“外设”运行时无论是containerd、CRI-O还是其他任何实现。对于用户而言这次变化带来的短期阵痛主要是运维命令的改变远小于其带来的长期收益更稳定的集群、更高效的资源利用、更清晰的架构边界。Docker本身作为容器技术的布道者和卓越的开发者工具其历史地位不可撼动它只是在一个更专业化的生产环境编排领域将核心的运行时职责交给了更专注的组件。现在当我们再部署一个K8s集群时标准栈已经变成了Kubernetes containerd runc。这是一个更清晰、更健壮、更面向未来的架构。理解这次变迁意味着你不仅跟上了技术的步伐更深入理解了云原生基础设施演进的底层逻辑——标准化、解耦和专注。下次再有人问起“K8s和Docker是什么关系”你可以清晰地告诉他它们是曾经亲密的合作伙伴如今在标准化道路上各自扮演着更专业、更高效的角色。Docker负责制造优秀的“集装箱”镜像和提供友好的“码头”开发体验而K8s和containerd则负责在庞大的“物流中心”数据中心里高效、自动化地调度和管理这些集装箱的运输与存放。
延伸阅读

更多相关文章

2026/9/23 0:21:37

彻底解决Windows 10/11启用.NET Framework 3.5报错0x80072F8F的七种方案

1. 项目概述:一个让无数运维和开发者头疼的经典“钉子户”问题如果你在Windows 10上安装或运行某个老旧的软件、游戏,或者配置一些开发环境(比如旧版的Visual Studio、某些企业级ERP客户端),系统大概率会弹出一个提示&…

2026/9/19 22:13:52

深度学习入门:三张图掌握核心原理与实战指南

1. 项目概述:为什么三张图就够了?很多朋友一听到“深度学习”,脑子里可能立刻浮现出复杂的数学公式、层层叠叠的网络结构图,还有那些让人望而生畏的学术论文。作为一个在这个领域摸爬滚打了十来年的从业者,我完全理解这…

2026/9/23 0:22:20

梦幻祥瑞从零搭建保姆级教程

梦幻祥瑞从零搭建保姆级教程 你是不是也卡在“学会语法却不知怎么搭项目”的坑里?看着文档里的Hello World很兴奋,一到真实场景就懵圈。这篇梦幻祥瑞保姆级教程,专门解决这个痛点。…

2026/9/23 0:22:20

3个技巧搞定滚轮交互:附完整示例与避坑指南

3个技巧搞定滚轮交互:附完整示例与避坑指南 官方文档里关于 wheel 事件的描述往往冗长且充满浏览器兼容性警告,让人抓不住重点。想直接上手写个平滑滚动的轮播图,却总卡在事件节流或默认行为阻止上。这里不堆砌理论,直接给出一套经过生产环境验证…

2026/9/23 0:22:20

情侣扎刀测验感情底层逻辑解析:新手避坑指南

情侣扎刀测验感情底层逻辑解析:新手避坑指南 面试被问原理答不上来,这种尴尬谁没经历过?特别是当面试官盯着你的眼睛,问“这个算法的时间复杂度怎么推导”或者“这个中间件高并发下怎么保证数据一致性”时,脑子瞬间一片空白。很多 新手避坑…

2026/9/23 0:22:20

3个关键帧优化:配置低的网络游戏手写实现渲染引擎

3个关键帧优化:配置低的网络游戏手写实现渲染引擎 看了一堆教程还是不会写项目?问题不在你不够努力,而在于你一直在用“造轮子”的思维去套“填坑”的场景。很多后端转前端,或者刚入行的开发,拿到一个需求就喜欢从头手写实现所有逻辑,哪怕是一个简单的…

2026/9/23 0:17:19

异光录屏入门到精通:3招优化卡顿,告别看教程不会写项目

异光录屏入门到精通:3招优化卡顿,告别看教程不会写项目 看了一堆教程还是不会写项目?这是无数开发者深夜盯着屏幕时的真实写照。你跟着视频敲代码,运行没报错,可一旦换成自己的业务场景,立马就崩。这不是你笨,是你没跨过从“异光录屏”这类工具使用到…

2026/9/22 10:02:42

GAMP 5 基于风险的计算机化系统验证:软件分类与审计追踪实践

简介:《A Risk-Based Approach to Compliant GxP Computerized Systems》即业内熟知的GAMP 5指南,面向制药企业质量与IT合规人员、验证工程师及计算机化系统管理者,用于解决GxP法规环境下系统合规性难以科学落地的问题。文档以风险管理为主线…

2026/9/22 9:07:39

安全托管MSSP实战:从静态防御到人机协同的攻防运营与应急响应

简介:这份PPT围绕互联网业务安全托管服务展开,面向企业安全负责人、IT运维人员及关注MSSP/MSS选型的读者,重点回应传统安全过度依赖人工、碎片化静态防御难以对抗产业化攻击等痛点。资源共1个pptx文件,包体约30.63MB,以…

2026/9/23 0:01:54

3个实战技巧搞定形式英语:从看教程到跑通性能优化

3个实战技巧搞定形式英语:从看教程到跑通性能优化 看了一堆教程还是不会写项目?别慌,这种“眼高手低”的困境在开发者圈子里太常见了。很多人以为卡点在语法,其实真正拦路虎是缺乏将知识点串联成完整链路的能力。今天咱们不聊虚的,直接拿【形式英语】这…

2026/9/22 16:34:32

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/22 20:01:30

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/22 13:25:41

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码