Kubelete 创建容器步骤

  1. kubelet通过CRI接口(gRPC)调用dockershim,请求创建一个容器。这一步中,kubelet可以视作一个简单的CRI Client,而dockershim就是接收请求的server.目前dockershim的代码其实是内嵌在kubelet中的,所以接收调用就是kubelet进程。

  2. Dockershim接收到请求后,转化成docker daemon能听懂的请求,发到docker daemon上请求创建一个容器。

  3. Docke daemon早在1.12版本中就已经将针对容器的操作移到另一个守护进程containerd中,因此docker daemon仍然不能帮我们创建容器,而是要请求containerd创建一个容器。

  4. containerd收到请求后,并不会自己直接去操作容器,而是创建一个叫做containerd-shim的进程,让containerd-shim去操作容器。是因为容器进程需要一个父进程来做诸如收集状态,维持stdin等fd打开等工作。而假如这个父进程就是containerd,那每次containerd挂掉或升级,整个宿主机上所有的容器都得退出了。而引入了 containerd-shim 就规避了这个问题(containerd 和 shim 并不是父子进程关系)。

  5. 我们知道创建容器需要做一些设置 namespaces 和 cgroups,挂载 root filesystem 等等操作,而这些事该怎么做已经有了公开的规范,那就是 OCI。它的一个参考实现叫做 runC。于是,containerd-shim 在这一步需要调用 runC 这个命令行工具,来启动容器。

  6. runC 启动完容器后本身会直接退出,containerd-shim 则会成为容器进程的父进程,负责收集容器进程的状态,上报给 containerd,并在容器中 pid 为 1 的进程退出后接管容器中的子进程进行清理,确保不会出现僵尸进程。

猜你喜欢

转载自blog.csdn.net/qq_34939308/article/details/110674357