知识卡片
OCI标准化如何让Docker从不可或缺一步步变成可替代
内容
Docker的架构演进和Kubernetes调用链的变化,共同讲述了一个”主导标准化 反而稀释自己不可替代性”的故事。2014年Docker开源用Go写的libcontainer, 第一次绕过LXC直接操作namespaces和cgroups。2015年Docker主导多家公司 制定OCI(开放容器交互标准),涵盖运行时标准、镜像标准、分发标准;为 符合OCI,Docker把libcontainer独立重构成runC(捐给Linux基金会),又把 Daemon里与运行时交互的部分抽出来做成containerd(2016年捐给CNCF)。 与此同时Kubernetes这边:早期完全绑定Docker,调用链是Master→kubelet→ DockerManager→Docker Engine→containerd→runC;2016年Kubernetes 1.5 引入CRI(容器运行时接口)规范,DockerManager换成更通用的 KubeGenericRuntimeManager,Docker因为比CRI规范出现得早、不支持CRI, 只能靠DockerShim适配层接入;2017年CRI-O项目发布,完全遵循CRI、支持 任何OCI运行时,Red Hat的OpenShift 4已经不再需要Docker Engine;2018年 containerd 1.1原生支持CRI,Kubernetes从1.10起可以直接跳过DockerShim和 Docker Engine,调用链缩短两步,性能还有实测可观的收益。这条演化路径的 反讽之处在于:Docker当初主导制定OCI标准、拆分出runC和containerd是想 巩固生态地位,结果却让Kubernetes有了绕开Docker Engine本身的技术基础—— runC和containerd活了下来,但”Docker Engine”这个中间层正逐步被淘汰。
结构图:
flowchart LR
A["早期: 完全绑定<br/>kubelet→DockerManager→Docker Engine→containerd→runC"] -->|2016 CRI规范| B["DockerShim适配层<br/>kubelet→KubeGenericRuntimeManager→DockerShim→Docker Engine"]
B -->|2017 CRI-O原生支持CRI| C["可选任意OCI运行时<br/>如OpenShift不再需要Docker Engine"]
C -->|2018 containerd 1.1原生CRI| D["kubelet→KubeGenericRuntimeManager→containerd→runC<br/>Docker Engine被完全跳过"]