一文搞懂Docker、RunC、Containerd之间的关系

时间:2025-03-25 15:24:30

Containerd:Containerd 是容器运行时,从容器编排角度,Containerd 是容器运行时。

RunC:RunC 是容器运行工具,纯从系统角度,Runc才是底层运行时 。

Docker:我们常说的 docker 一般指的是 docker-shim,其也是一种容器运行时。

实际上不存在容器这个概念。 虚拟机是有的,当我们使用Linux内核技术实现了隔离,外加一些网络配置来实现互通。---- 我们把这个现象叫做容器。

能完成上述现象的 工具 叫做 运行时 ---runC (go写的)就是。 还有crun(c写的)  yuki(rust写的)都是。

但是光有容器还不够, 还需要镜像管理、网络配置、容器的启停这些,于是 Containerd、cri-o 这些 就是来干这种事的。

并且对于创建容器和镜像管理,包括分发(DockerHub),出现了OCI 规范 ,包括了容器规范、镜像规范和分发规范。

作为上游的容器编排工具,K8S 不可能直接调用 RunC,只能去调用 Containerd、cri-o。于是通过grpc调用的方式,并规定了 grpc 的接口方法和字段,各个厂商必须实现,也就是我们所谓的CRI(Container Runtime Interface)。

早期Docker比较火的时候,K8S不得不通过 docker-shim 来转换CRI方法。由于一些原因,K8S在1.19 版本提出要干掉 Docker,1.24版本已经正式废弃。但是实际上,Contaienrd 本身就是 Docker 分离出来的。至于 runC,本身也是 Docker 捐赠给 OCI 作为 OCI 容器运行时标准的参考实现。

实际的调用链路是:

K8S -> kubelet -> grpc call -> Containerd-> runC