Kubernetes容器运行时弃用Docker转型Containerd
Kubernetes社区在2020年7月份发布的版本中已经开始了dockershim的移除计划,在1.20版本中将内置的dockershim进行分离,这个版本依旧还可以使用dockershim,但是在1.24中被删除。从1.24开始,大家需要使用其他受到支持的运行时选项(例如containerd或CRI-O);如果选择Docker Engine作为运行时,则需要使用cri-dockerd
文章目录
容器进行时调用过程

起因
<img alt>
<img alt>
圈子话题
Kubernetes 1.20 版本开始将弃用 Docker,是时候拥抱 Containerd 和 Podman 了!

当Docker要创建一个容器时,需要进行下面的步骤:

OCI (Open Container Initiative,开放容器标准) runC实际上就是参考OCI实现,OCI实际上就是一个标准文档,主要规定了容器镜像的结构、以及容器需要接收那些操作指令,比如create、start、stop、delete等
实际上我们是可以直接通过调用RunC来实现容器的创建,实际上RunC就是调用的我们内核来进行操作。但是我们直接调用Runc不是很方便,所以就有了OCI。不需要了解底层原理,也可以通过调用OCI来进行容器的创建 containerd-shim则会为容器进程的父进程,负责收集容器进程的状态,上报给containerd,并在容器中pid为1的进程退出后接管容器中的子进程进行清理,确保不会出现僵尸进程
[root@k8s-01 ~]# ps -ef|grep docker root 1100 1 1 Apr19 ? 05:43:15 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock root 1425 1043 0 Apr19 ? 00:00:50 containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/306ca6264fdd2bf673b65ba64ef91b9ec4357cb7a21545085199826ad991a3f1 -address /run/containerd/containerd.sock -containerd-binary /usr/bin/containerd -runtime-root /var/run/docker/runtime-runc -systemd-cgroup root 2120 1043 0 Apr19 ? 00:00:46 containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/b608189a56350e04d20057f4b4158fe1ef0e6521ecae4030fdc5b03d7cee55c2 -address /run/containerd/containerd.sock -containerd-binary /usr/bin/containerd -runtime-root /var/run/docker/runtime-runc -systemd-cgroup root 2121 1043 0 Apr19 ? 00:00:51 containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/847c04dc6aa2ba3e2df261629dee8ff934b27a548392d928c8737f29688ddd1f -address /run/containerd/containerd.sock -containerd-binary /usr/bin/containerd -runtime-root /var/run/docker/runtime-runc -systemd-cgroup ...
通过ps -ef过滤docker,我们可以看到docker中实际上就是通过containerd-shim来创建的
containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/306ca6264fdd2bf673b65ba64ef91b9ec4357cb7a21545085199826ad991a3f1 -address /run/containerd/containerd.sock -containerd-binary
containerd-shim垫片的主要作用是用于containerd与Runc的匹配CRI-shim垫片主要用于kubelet与containerd之间的匹配,并且两者之间没有任何关联
CRI 详解
为什么在Kubernetes 1.20之后不推荐使用docker了?可以继续往下看
在Kubernetes早起的时候,Kubernetes为了支持Docker,通过硬编码的方式直接调用Docker API。后面随着Docker的不断发展以及Google的主导,出现了更多容器运行时可以使用,Kubernetes为了支持更多精简的容器运行时,google就和redhat主导推出了OCI标准,用于将Kubernetes平台和特定的容器运行时解耦 CRI (Container Runtime Interface容器运行时接口)本质就是Kubernetes定义的一组与容器运行时进行交互的接口 CRI实际上就是一组单纯的gRPC接口,核心有如下:
可以通过kubelet中--container-runtime-endpoint和--image-service-endpoint来手动配置 官方文档:https://kubernetes.io/zh/docs/concepts/architecture/cri/https://kubernetes.io/blog/2016/12/container-runtime-interface-cri-in-kubernetes/ CRI大概通过了下面的几个项目构成了Kubernetes的Runtime生态
由于早期Kubernetes在市场没有主导地位,有一些容器运行时可能不会自身实现CRI接口,于是就有了shim,一个shim的职责就是作为适配器,将各种容器运行时的本身的接口适配到Kubernetes的CRI接口上

cri-runtime主要为了取消docker
cri-runtime和oci-runtime 容器运行时实际上调用步骤如下
Orchestration API -> Container API(cri-runtime) -> Kernel API(oci-runtime)
Kubelet通过gRPC 框架与容器运行时或shim进行通信,其中 kubelet 作为客户端,CRI shim(也可能是容器运行时本身)
Containerd 发展史
在Containerd 1.0中,对CRI的适配通过了一个单独的进程CRI-containerd来完成

containerd 1.1中,砍掉了CRI-containerd这个进程,直接把适配逻辑作为插件放进了containerd主进程中
containerd 1.1中做的事情,实际上Kubernetes社区做了一个更漂亮的cri-o,兼容CRI和OCI
Containerd与Docker区别?
实际上containerd只是一个精简版docker,为了更好的支持Kubernetes而已

哪些容器运行时引擎支持CRI?
Containerd | 谷歌 Kubernetes 引擎、IBM Kubernetes 服务、阿里巴巴 | 经过大规模测试,用于所有 Docker 容器。比 Docker 使用更少的内存和 CPU。支持 Linux 和 Windows | 没有 Docker API 套接字。缺少 Docker 方便的 CLI 工具。 |
CRI-O | 红帽 OpenShift,SUSE 容器即服务 | 轻量级,Kubernetes 所需的所有功能,仅此而已。类似 UNIX 的关注点分离(客户端、注册表、构建) | 主要在RedHat平台内使用不易安装在非RedHat操作系统上仅在Windows Server2019及更高版本中支持 |
Kata Containers | 开放堆栈 | 提供基于 QEMUI 的完全虚拟化改进的安全性与 Docker、CRI-O、containerd 和 Firecracker 集成支持 ARM、x86_64、AMD64 | 更高的资源利用率不适合轻量级容器用例 |
AWS Firecracker | 所有 AWS 服务 | 可通过直接 API 或使用 seccomp jailer 的 containerdTight 内核访问来访问 | 新项目,不如其他运行时成熟需要更多手动步骤,开发人员体验仍在不断变化 |