bigywater.tech
Docker · 32

containerd 与 runc:谁是容器进程的父进程

容器进程的父进程到底是谁?是 dockerd、containerd 还是 runc?这篇进入 Docker Desktop 的虚拟机,从容器的主进程一路往上看,并验证 shim 的数量、runc 是否常驻,以及 exec 的进程挂在哪里。

containerd-shim
容器主进程的父进程,命令行里的 -id 就是容器 ID
shim +3
多起 3 个容器,虚拟机里的 containerd-shim 进程数从 20 增加到 23
6 次都是 0
容器运行期间连续采样,虚拟机里 runc 进程的个数

父进程链

实测 · 本机执行输出
  docker inspect 的 State.Pid = 13063(这是虚拟机里看到的 PID;容器里它是 PID 1)
  /proc/13063/status 的 NSpid = NSpid:	13063	1(第一个是虚拟机里的 PID,第二个是容器里的 PID)
  13063 13039 sleep 600
    13039     1 /usr/bin/containerd-shim-runc-v2 -namespace moby -id 837a27d7cb26… -address /run/containerd/containerd.sock
      1     0 /initd
  容器进程的 PPID 是 containerd-shim 吗?True;shim 的参数里 -id 等于容器 ID 吗?True

容器里的 PID 1,在虚拟机里是另一个 PID(NSpid 显示 13063 和 1),它的父进程是 containerd-shim-runc-v2,shim 的命令行带着 -namespace moby -id <容器ID>;shim 的父进程是虚拟机的 PID 1(/initd),不是 dockerd 也不是 containerd。所以重启 dockerd 不会直接杀死容器进程(是否真的如此,我没有实验)。

一个容器一个 shim

实测 · 本机执行输出
  起 3 个容器前后,containerd-shim 进程数:20 → 23(增加 3)
  容器运行期间连续 6 次查看虚拟机里的 runc 进程个数(只统计命令行里含 runc、不是 containerd-shim-runc-v2 的进程):[0, 0, 0, 0, 0, 0];最后一次看到的:无
  dockerd 与 containerd 在虚拟机里是什么进程?265   146 /usr/bin/containerd --config /etc/containerd/containerd.toml ;   283   146 /usr/local/bin/dockerd --config-file /run/config/docker/daemon.json

多起 3 个容器,shim 进程从 20 个增加到 23 个。runc 只在创建容器时短暂出现,容器运行期间我连续采样 6 次,都没有 runc 进程;这个采样只能说明它没有常驻,不能证明启动瞬间的情形。

exec 的进程

实测 · 本机执行输出
  docker exec -d 起的 sleep 555:PID 14139,PPID 13039;它的父进程是容器主进程所在的那个 shim 吗?True;PPID 对应的进程:13039     1 /usr/bin/containerd-shim-runc-v2 -namespace moby -id 837a27d7cb26… -address /run/containerd/contai

docker exec -d 起的进程,父进程仍是该容器的 shim。

杀掉主进程

实测 · 本机执行输出
  kill -9 13063 之后:docker inspect Status=exited ExitCode=137;shim 进程还在吗?False
  docker stop 另一个容器之后,它的 shim 还在吗?False

从虚拟机里直接 kill -9 容器的主进程,Docker 看到的是 exited、ExitCode 137,shim 也退出了。

分步演示

containerd-shim
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / Docker Desktop(Engine 29.8.2,容器跑在 Docker Desktop 自带的 Linux 虚拟机里,内核与宿主机的 macOS 不同);镜像为 linux/arm64;需要看虚拟机内部时用特权容器 + nsenter;计时用 time / date +%s%N,数字每次运行会有小幅抖动。进入虚拟机的方法见 c19(特权容器加 nsenter -t 1);进程信息用虚拟机里的 ps 和 /proc 读取;PID 每次运行不同,文中数字取自最后一次运行;虚拟机里还有其它容器在运行(shim 的基数是 20),所以只看变化量;实验后已删除容器
    • 没有验证:重启 dockerd/containerd 对容器的影响(见后面的 live-restore 一篇)、容器启动瞬间 runc 的进程、shim 的内存占用、其它 OCI 运行时(如 gVisor、crun)、Linux 宿主机上 shim 的父进程(这里是 Docker Desktop 自己的 /initd)
    京ICP备2026067502号-1京公网安备11010502063487号