Skip to content

docker 容器的 init 进程 (Tini)

Why do you need an init process inside your Docker container (PID 1)

1 - 简介

Tini 是一个用于在容器中运行进程的 init 进程。它提供了一些有用的功能,例如处理信号、自动处理僵尸进程和处理孤儿进程。

对于大多数应用而言,添加 Tini 并不需要对现有代码进行任何更改,它是完全透明的。

2 - 使用场景

2.1 处理信号

当你向容器发送信号 (SIGINT or SIGTERM) 时,Docker CLI 会将信号发送给容器内的 PID 1 进程。如果 PID 1 不是专门设计来处理信号的程序,那么这些信号可能不会被传递给应用程序本身,导致应用程序不能优雅地关闭。Tini 会接收这些信号并将它们转发给其子进程,确保容器内的应用程序能够正确响应这些信号。

2.2 自动处理僵尸进程

Tini 能够自动收割那些已经结束但尚未被父进程回收的僵尸进程。

3 - 如何使用

3.1 使用 --init 参数启动容器

--init 参数是 Docker (>=1.13) 提供的一个选项,用于在容器中运行一个 init 进程,通常是 tini)作为 PID 1 进程。

不使用 --init 参数时:

bash
docker run -it --rm ubuntu:16.04 /bin/bash
root@d740f7360840:/# ps -fA
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  1 03:30 ?        00:00:00 /bin/bash
root        11     1  0 03:30 ?        00:00:00 ps -fA

使用 --init 参数时:

bash
docker run -it --init --rm ubuntu:16.04 /bin/bash
root@5b5fe6ee71b5:/# ps -fA
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  1 03:30 ?        00:00:00 /dev/init -- /bin/bash
root         7     1  0 03:30 ?        00:00:00 /bin/bash
root        12     7  0 03:30 ?        00:00:00 ps -fA
bash
docker run --init -it --rm ubuntu:16.04 /bin/bash

3.2 Dockerfile 中显示指定 entrypoint

dockerfile
ENTRYPOINT ["/usr/local/bin/tini", "--"]
CMD ["your", "command", "here"]

3.3 docker-compose.yml 中显示指定 init

yaml
services:
  app:
    image: my-app:latest
    init: true

Released under the MIT License.