在 kubernetes 最近的一次更新中,有一个重要的变化,就是废弃了 docker 和 dockershim。这让我感到震惊,不知道发生了什么。于是开始探究了一番,之后就产生了这篇文章。
简介
为了防止docker一家独大,docker当年的实现被拆分出了几个标准化的模块,标准化的目的是模块是可被其他实现替换的,不由任何一个厂商控制。
docker由 docker-client ,dockerd,containerd,docker-shim,runc组成,所以containerd是docker的基础组件之一
关于docker
docker本身而言包括了,docker client和dockerd(docker daemon),dockerd本身实属是对容器相关操作的api的最上层封装,
直接面向操作用户。
关于docker1.12.x
该版本的docker由 docker-client ,dockerd,containerd,docker-shim,runc组成,现在来谈谈每个组件是用来干嘛的:
dockerd
dockerd本身实属是对容器相关操作的api的最上层封装,直接面向操作用户。
containerd
dockerd实际真实调用的还是containerd的api接口(rpc方式实现),containerd是dockerd和runc之间的一个中间交流组件。
docker-shim
docker-shim是一个真实运行的容器的真实垫片载体,每启动一个容器都会起一个新的docker-shim的一个进程,
他直接通过指定的三个参数:容器id,boundle目录(containerd的对应某个容器生成的目录,一般位于:/var/run/docker/libcontainerd/containerID),
运行是二进制(默认为runc)来调用runc的api创建一个容器(比如创建容器:最后拼装的命令如下:runc create 。。。。。)
runc
runc是一个命令行工具端,他根据oci(开放容器组织)的标准来创建和运行容器。
关系如下图:
调用链
从k8s的角度看,可以选择 containerd 或 docker 作为运行时组件:Containerd 调用链更短,组件更少,更稳定,占用节点资源更少
Docker 作为 k8s 容器运行时,调用关系如下:
kubelet –> docker shim (在 kubelet 进程中) –> dockerd –> containerdContainerd 作为 k8s 容器运行时,调用关系如下:
kubelet –> cri plugin(在 containerd 进程中) –> containerd