参考文章:
K8s 终将废弃 docker,TKE 早已支持 containerd
1、背景
对比 Kubernetes 集群使用不同的 docker 版本(1.18、1.19)作为容器运行时,发现底层实现上有些差异,在这里做个记录
2、现象分析
docker 1.18
容器进程树:
containerd 不是 system service,而是靠 dockerd 拉起的进程
kubelet 控制容器的路径:
kubelet —— docker-shim.sock —— dockerd —— containerd —(ttrpc通信)— containerd-shim —— 容器1号进程
各进程退出的影响:
- dockerd、containerd 进程退出会让 containerd-shim 直接被 systemd 1号进程接管,不影响容器进程
-
containerd-shim 进程退出会导致它的容器进程被回收
-
容器进程退出会导致它的父进程 containerd-shim 也被回收
-
docker restart 容器会让 containerd 重新创建 containerd-shim 进程和容器1号进程
docker 1.19
containerd 是单独的 system service
kubelet 控制容器的路径和1.18版本相同:
kubelet —— docker-shim.sock —— dockerd —— containerd —(ttrpc通信)— containerd-shim —— 容器1号进程
-
dockerd 重启不影响 pstree,不影响容器进程
-
containerd 进程退出会让 containerd-shim 直接被 systemd 1号进程接管,不影响容器进程
-
containerd-shim 进程退出会导致它的容器进程被回收
-
容器进程退出会导致它的父进程 containerd-shim 也被回收
-
docker restart 容器会让 containerd 重新创建 containerd-shim 进程和容器1号进程
3、补充说明
本文主要说明了 dockerd、docker-shim、containerd、containerd-shim 的关系。
除此之外,还有 runc 和 cotainerd-ctr 没有提到。
runc
containerd 是通过 containerd-shim 去调用 runc 来启动容器的,runc 启动完容器后本身会直接退出,containerd-shim 则会成为容器进程的父进程, 负责收集容器进程的状态, 上报给 containerd, 并在容器中 pid 为 1 的进程退出后接管容器中的子进程进行清理, 确保不会出现僵尸进程。
可以理解为 runc 是 containerd-shim 的 CLI 工具。
containerd-ctr
像 Docker CLI 工具一样,containerd 同样也提供一个对应的 CLI 工具:ctr,不过 ctr 的功能目前还没有 docker 完善,只有关于镜像和容器的基本功能。
- 镜像操作:
# 拉镜像(docker pull)
ctr image pull docker.io/library/nginx:alpine
# 查看镜像(docker images)
ctr image ls
# 删镜像(docker rmi)
ctr image rm docker.io/library/nginx:alpine
- 容器操作:
# 创建容器
# 创建后容器并没有处于运行状态,只是一个静态的容器。一个 container 对象只是包含了运行一个容器所需的资源及相关配置数据,表示 namespaces、rootfs 和容器的配置都已经初始化成功了,只是用户进程还没有启动。
ctr container create docker.io/library/nginx:alpine nginx
# 查看容器
ctr container ls
# 查看容器信息(docker inspect)
ctr container info nginx
# 删除容器(docker rm)
ctr container rm nginx
- 任务操作:
# 开始真正运行容器(docker run -d)
ctr task start -d nginx
# 查看容器进程(docker ps)
ctr -n moby task ls
# 进入容器(docker exec)
ctr task exec --exec-id 0 -t nginx sh
- 命名空间操作:
# 查看命名空间
ctr namespace ls
# 创建命名空间
ctr namespace create test
# 查看 docker 启动的容器(默认在 moby 命名空间下)
ctr -n moby container ls