K8S工作节点这块,从Docker开始慢慢变成CRI-O,过程和原因其实挺有意思的
- 问答
- 2026-01-25 04:54:55
- 2
K8S工作节点这块,从Docker开始慢慢变成CRI-O,过程和原因其实挺有意思的,这故事得从头说起。
最早的时候,Kubernetes(K8S)和Docker可以说是“黄金搭档”,Docker在2013年左右火起来,它把“容器”这个概念做得特别简单好用,一下子改变了大家打包和部署应用的方式,所以当Google在2014年推出K8S这个容器编排系统时,很自然地就选择了Docker作为底层运行容器的工具(也就是“运行时”),那时候,对很多用户来说,K8S几乎就等于“用Docker来跑容器”。(来源:Kubernetes早期文档及社区讨论)
蜜月期慢慢就过去了,K8S社区发现,直接绑定Docker带来了不少麻烦,Docker本身是个功能很全的“大家伙”,它不仅仅能运行容器(这是K8S最需要的核心功能),还自带构建镜像、网络、存储等等一大堆东西,而K8S作为一个编排平台,只想让它干一件事:按照我的指令,把容器启停管理好,更关键的是,Docker的接口不是为K8S专门设计的,K8S团队为了跟Docker打交道,不得不在内部维护一个叫“dockershim”的适配层,代码又复杂又难维护。(来源:Kubernetes项目维护者关于“dockershim”的论述)

这就好比你想用一个特别专业的发动机(容器运行时),但市面上只有一款功能繁多的豪华汽车(Docker),你不得不把整辆车买下来,再把其他没用的车门、音响都拆掉,才能用上发动机,非常别扭。
K8S社区就想:能不能定义一套标准的接口,只要任何容器运行时按照这个接口来提供功能,我K8S就能用,这样我就不用只绑在Docker一棵树上了,这个想法在2016年底变成了现实,也就是CRI(容器运行时接口),CRI就像是一个标准的电源插座,而不同的容器运行时就像是各种电器,只要插头匹配(实现CRI接口),就能通电工作。(来源:Kubernetes官方博客关于CRI的介绍)

CRI一出,局面就打开了,Docker当时没有直接实现CRI接口,所以K8S还得通过“dockershim”这个转换器来用它,但其他一些更轻量、更专注的项目看到了机会,由红帽公司牵头推动的CRI-O项目就是专门为K8S量身定做的,它的设计理念非常极端:“除了K8S需要的,我什么多余功能都不做”。(来源:CRI-O项目官方文档)
CRI-O只做一件事——完美地实现CRI接口,它不负责构建镜像,不提供额外的网络方案,所有K8S不需要的组件统统砍掉,它的架构非常清晰和精简,就是接收K8S通过CRI发来的命令(运行这个容器”),然后调用底层的runc(一个实际创建容器的低层工具)去执行,这样一来,它比Docker轻量得多,启动更快,资源占用更少,而且因为代码结构简单,出问题的可能性也小了,和K8S的升级步调也能更容易保持一致。
那为什么大家会慢慢转向CRI-O呢?原因有几个:
- 轻量与专注:对于生产环境的K8S节点来说,稳定和高效是第一位的,CRI-O没有多余功能,攻击面小,更符合“单一职责”的原则。
- 社区驱动与契合度:CRI-O是K8S原生生态的一部分,完全围绕K8S的需求开发,和K8S的发布周期配合得更好,而Docker有自己的发展重点。
- 摆脱锁定:使用标准接口CRI,让用户有了选择权,即使未来CRI-O不合适了,也可以轻松换另一个实现CRI的运行时,避免了被单一技术绑定。
- 关键的催化剂事件:Docker公司后来将容器运行时部分捐献出来,成立了containerd项目,而containerd也是一个优秀的、实现了CRI的运行时,但containerd本身也相对轻量,更重要的是,K8S社区在2020年底宣布,未来将弃用内置的“dockershim”,这意味着K8S将不再直接照顾与Docker的兼容性,这个决定促使整个社区认真考虑并迁移到真正的CRI运行时,无论是containerd还是CRI-O。(来源:Kubernetes官方博客关于弃用dockershim的公告)
这个过程并不是说Docker不好,而是生态发展的必然,从早期借助Docker的东风快速崛起,到后来为了自身的健康发展和用户的选择权,K8S社区通过定义CRI标准,催生了像CRI-O这样更专一的“伴侣”,在新部署的K8S集群中,containerd和CRI-O已经成为更常见的选择,这个转变,生动地展示了一个平台如何从依赖一个具体实现,走向定义开放接口、拥抱多元生态的成熟过程。
本文由太叔访天于2026-01-25发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:https://haoid.cn/wenda/85521.html
