目录
kubelet+CRI+OCI工作流程(以containerd为例)
讨论 CRI、OCI、containerd和CRI-O、runc,其实就是一个概念问题,看图更易理解含义,所以先上两张图。
专有名词释义
CRI
CRI(Container Runtime Interface,容器运行时接口)是kubernetes定义的接口,定义了如何操作容器和镜像的统一规范,它主要包含ImageService和ContainerService。因为它已经是一个标准,所以你可以选择任何一个CRI的实现( containerd和CRI-O)来使用。
containerd和CRI-O
contianerd来自于docker,它通过CRI插件来实现了CRI,containerd可以说包含两部分:cri-plugin+runc。
CRI-O也是一个CRI的实现,它来自于Red Hat/IBM等
OCI
OCI(Open Container Initialtive)提供了容器镜像和运行容器的规范。runc是OCI的一个实现,它是一个创建和运行容器进程的工具。
runc
runc实际上是从libcontainer演化过来的,并且是docker贡献给社区的第一个OCI参考实现,它就是用来创建和运行容器进行的工具。
kubelet+CRI+OCI工作流程(以containerd为例)
通过上图我们大致了解了CRI、OCI的位置,加上上面的释义,我们知道了它们是两个标准,以及它们的典型实现(containerd、runc)。但是,总感觉还是比较虚,那么我们下面就落到实处去看看它们是怎样工作的。
下面代码块中展示的是containerd.io 1.6.6版本(截止2022/07/29最新) rpm包的文件列表,下面我们看一下这些文件都是干什么的。
- /usr/lib/systemd/system/containerd.service:systemd标准的Unit文件,被systemd管理:systemctl start|stop containerd.service
- /usr/bin/containerd:containerd的守护进程文件,在containerd.service Unit文件中通过ExecStart=/usr/bin/containerd调用,以启动containerd守护进程
- /etc/containerd/config.toml:在启动过程中加载此配置文件,我们可以在该配置文件中进行丰富多样的配置,以令containerd更贴合我们的实际需要。比如:私有镜像源等。
- /usr/bin/containerd-shim:containerd套件,其目的主要是隔离containerd和容器。containerd守护进程通过CRI plugin收到gRPC调用请求(来自kubelet或docker | 如:创建容器),便会启动/usr/bin/containerd-shim套件
- /usr/bin/containerd-shim-runc-v2:containerd-shim启动后会去启动/usr/bin/containerd-shim-runc-v2,然后立即退出,此时containerd-shim-runc-v2的父进程就变成了systemd(1),这样containerd-shim-runc-v2就和containerd脱离了关系,即便containerd退出也不会影响到容器(这也是containerd-shim套件的作用)。
- /usr/bin/runc:OCI标准的具体实现就是runc,真正创建和维护容器最终便是由runc来完成的。/usr/bin/containerd-shim-runc-v2会启动runc去create、start容器,然后runc立即退出,容器的父进程就变成了containerd-shim-runc-v2,这也是容器内部可以看到的PID=1的init进程。
- /usr/bin/ctr:容器管理的客户端工具,可以对标docker命令
rpm -ql containerd.io
/etc/containerd
/etc/containerd/config.toml
/usr/bin/containerd
/usr/bin/containerd-shim
/usr/bin/containerd-shim-runc-v1
/usr/bin/containerd-shim-runc-v2
/usr/bin/ctr
/usr/bin/runc
/usr/lib/systemd/system/containerd.service
docker、ctr、runc查看容器信息
# docker命令查看容器列表
docker ps -a
CONTAINER ID IMAGE COMMAND NAMES
3eb656566412 e57a417f15d3 "/metrics-server --c…" k8s_metrics-server_……
20d99aeeae9b 192.168.11.101/library/pause-amd64:3.0 "/pause" k8s_POD_metrics-……
f8bc54c1f151 a1a88662416b "/usr/bin/kube-contr…" k8s_calico-kube-……
22d29ed973aa 192.168.11.101/library/pause-amd64:3.0 "/pause" k8s_POD_calico-kube-……
1b4ec45dafdc 192.168.11.101/library/node "start_runit" k8s_calico-……
1514a05df57a 192.168.11.101/library/pause-amd64:3.0 "/pause" k8s_POD_calico-node-……
# ctr 命令查看容器列表
ctr -n moby c list
CONTAINER IMAGE RUNTIME
1514a05df57a532a2fa8d2652942d9f48a049067ff9a04aea15312f75ee24275 - io.containerd.runc.v2
1b4ec45dafdcf60db49ccf2fb07f7e278d442c9392b2240fd75a86fc2a971904 - io.containerd.runc.v2
20d99aeeae9b52a6bfd667491c8191b9e7c71c0003a76dc1c34a735d449ab46d - io.containerd.runc.v2
22d29ed973aaed983c2dbc987e3d828fde5a5e1d36f4057e5425dae0a4698b86 - io.containerd.runc.v2
3eb656566412b9efb422da375e3304e1680e30a7875832ac1750390498906228 - io.containerd.runc.v2
f8bc54c1f1512d5b8202b8de76a98e11edc71271e80a848013846f9933ba0bb6 - io.containerd.runc.v2
# runc 命令查看容器列表
runc --root /var/run/docker/runtime-runc/moby/ list -q
1514a05df57a532a2fa8d2652942d9f48a049067ff9a04aea15312f75ee24275
1b4ec45dafdcf60db49ccf2fb07f7e278d442c9392b2240fd75a86fc2a971904
20d99aeeae9b52a6bfd667491c8191b9e7c71c0003a76dc1c34a735d449ab46d
22d29ed973aaed983c2dbc987e3d828fde5a5e1d36f4057e5425dae0a4698b86
3eb656566412b9efb422da375e3304e1680e30a7875832ac1750390498906228
f8bc54c1f1512d5b8202b8de76a98e11edc71271e80a848013846f9933ba0bb6
上面我们粗略的讲述了云原生技术中的一些专有名词,并以containerd为例讲述了它们的工作流程。下一节,我会讲一下“Docker架构演进过程”,敬请期待。