bigywater.tech
Docker · 37

tini:最小 init 进程做了哪几件事

docker run --init 到底往容器里放了什么?它是镜像的一部分吗,占多少内存,退出码和信号怎么穿过它,启动会慢多少?这篇逐项实测。

tini 0.19.0
docker run --init 放进容器的 PID 1(/sbin/docker-init),大小 601296 字节
508 kB
PID 1 的内存常驻(VmRSS)
175 vs 170 ms
docker run --rm alpine true 在 --init 与不用 --init 时的启动用时中位数

放进去的是什么

实测 · 本机执行输出
  容器里 /proc/1/cmdline:/sbin/docker-init -- sleep 600
  进程列表:PID   PPID  COMMAND          COMMAND |     1     0 docker-init      /sbin/docker-init -- sleep 600 |     7     1 sleep            sleep 600 |    14     0 ps               ps -o pid,ppid,comm,args
  /sbin/docker-init --version:tini version 0.19.0 - git.de40ad0
  /sbin/docker-init 文件(权限 大小):-rwxr-xr-x 601296;不加 --init 的同一个镜像里有它吗?ls: /sbin/docker-init: No such file or directory
  /sbin/docker-init 来自哪里(mountinfo):968 959 0:26 /usr/libexec/docker/docker-init /sbin/docker-init ro,relatime - overlay overlay rw,lowerdir=/,upperdir=/run/rootfs.upper,workdi
  PID 1 的内存 VmRSS:VmRSS:	     508 kB
  docker inspect 的 HostConfig.Init = true

--init 让 PID 1 变成 /sbin/docker-init -- 你的命令,它是 tini 0.19.0。这个文件不在镜像里,运行时从 Docker Desktop 虚拟机的 /usr/libexec/docker/docker-init 只读挂载进来,所以任何镜像都能用,也不改变镜像内容。你的程序变成 PID 7,父进程是 1。

退出码

实测 · 本机执行输出
  子进程 exit 3:docker run 退出码 3
  子进程 exit 3(不用 --init):docker run 退出码 3
  子进程被 SIGKILL(kill -9 $$):docker run 退出码 137
  子进程被 SIGTERM(kill -TERM $$):docker run 退出码 143
  子进程被 SIGTERM(不用 --init,PID 1 是 sh):docker run 退出码 0

子进程 exit 3,docker run 的退出码就是 3;被信号杀死则是 128 加信号编号(137、143)。

信号

实测 · 本机执行输出
  --init:日志 ready | 子进程收到 SIGUSR1;Status=exited ExitCode=0
  不用 --init:日志 ready | 子进程收到 SIGUSR1;Status=exited ExitCode=0

程序自己装了信号处理程序时,有没有 init 都能收到信号。init 的价值在没有处理程序的程序(c6)和孤儿进程收尸(c31)。

开销

实测 · 本机执行输出
  不用 --init:中位数 170 ms,最小 164,最大 191
  --init:中位数 175 ms,最小 167,最大 208

PID 1 的 VmRSS 只有 508 kB,启动用时中位数 175 ms 对 170 ms,各 10 次,差别在抖动范围内。

分步演示

tini 与 --init
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / Docker Desktop(Engine 29.8.2,容器跑在 Docker Desktop 自带的 Linux 虚拟机里,内核与宿主机的 macOS 不同);镜像为 linux/arm64;需要看虚拟机内部时用特权容器 + nsenter;计时用 time / date +%s%N,数字每次运行会有小幅抖动。docker-init 信息取自容器内 /proc 与 mountinfo;退出码和信号各情形运行一次;启动用时是 docker CLI 的整次调用,各 10 次取中位数;实验后已删除容器
    • 没有验证:自己用 apk / apt 安装的 tini 与 docker-init 的差别、tini 的 -g(进程组转发)和 -s 参数、compose 的 init: true、dumb-init、Linux 宿主机上 docker-init 的位置
    京ICP备2026067502号-1京公网安备11010502063487号