就目前来看(k8s 1.24以后),kubernetes 和 docker 应该是属于并列的关系,它们都是容器的一种管理方式。
而kubernetes重在集群的管理,docker则侧重单机的管理,但docker中有个docker swarm(见 https://blog.woyou.cool/post/653),也是侧重集群管理的,但显然,它并没有打赢k8s
首先需要明确的是,容器这个概念并不是docker创造的,在其之前就存在,docker只是将其发扬光大了,docker只是用来管理容器的。
OCI
容器的创建、销毁、查看等操作本身就有一个接口,名叫 OCI(开放容器接口),runc 就是该接口的一个实现。类似于java中接口与实现的关系。
Containerd
光有容器还不行,是你还需要对容器周边的一些东西进行管理,例如镜像、标签等,这个东西就是 containerd,你可以用它来拉取镜像,或者用它来调用 OCI 实现对容器的操作等。
例如:containerd 提供了 ctr 工具,你可以用该工具拉取镜像:
ctr image pull docker.io/library/nginx:alpine
给镜像打标签:
ctr image tag docker.io/library/nginx:alpine harbor.k8s.local/course/nginx:alpine
也可以使用 ctr 调用 OCI 操作容器,例如创建一个容器:
ctr container create docker.io/library/nginx:alpine nginx
查看容器:
ctr container info nginx
启动容器:
ctr task start -d nginx
进入容器:
ctr task exec --exec-id 0 -t nginx sh
也就是说,你可以不依赖 docker 而直接安装 containerd 进行容器和镜像的操作,由于 containerd 依赖 runc,故需先安装 runc
如果把容器比作虚拟机,那么 containerd 就相当于 VMware、VirtulBox 等软件,OCI 就相当于这些软件对虚拟机的操作,例如创建、删除、启动等。
docker 的作用就是对 containerd 的进一步增强
CRI-O
既然 OCI 只是一个容器操作接口,那 containerd 可以使用该接口,其他程序也就可以使用。kubernetes 为了减少容器操作的复杂性,就直接开发出另一套容器管理方案(container runtime),名为 CRI-O
CRI 和 kubernetes
既然 OCI 只是一个容器操作接口,containerd 可以用, CRI-O 可以用,那肯定还会有很多其他的方案会用。为了统一这些方案的使用方法,kubernetes又提出了一个统一的接口,名为 CRI,这就好比是 数据库的实现有很多种,例如mysql、sqlserver等,为了统一操作,先提出了 JDBC 的接口(类比 OCI),基于JDBC又出现了 Mybatis、Hibernate 等,为了统一他们的使用方式,又提出了 JPA 接口(类比 CRI)
不过由于 docker 出生比 CRI 还要早,故它并没有实现 CRI 接口,kubernetes 为了能使用docker,就开发出了 dockershim,它处于 CRI 和 docker 之间。kubernetes 仍然只需要调用 CRI,CRI 再通过 dockershim 将指令转换成 docker 支持的指令,然后docker再调用 containerd,containerd 再调用runc
为啥不直接让 CRI 调用 containerd,而是还需要通过docker调用呢?
这是因为早期docker影响力太大了,kubernetes早期就仅支持docker作为container runtime,并且将其硬编码写死在代码中了,后面才考虑设计出了CRI。不过自 1.24 版本后,kubernetes 就彻底将dockershim移除了。这也就意味着 docker 的生存面更窄了。
没了dockershim还能不能继续使用docker作为container runtime?
可以的,只不过你需要安装一个额外的服务,名为 cri-dockerd

cri-dockerd 和 dockershim 有什么区别?
个人理解是:dockershim 是 kubernetes 团队自己开发的,并且本身就是 kubernetes 代码的一部分。这么做也是无奈之举
cri-dockerd 则是由第三方开发的,类似于一个插件的东西,实现与 kubernetes 的解耦
参考
https://www.qikqiak.com/post/containerd-usage/
https://kubernetes.io/blog/2022/02/17/dockershim-faq/
https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/