https://github.com/Yelp/dumb-init
dumb-init is a simple process supervisor and init system designed to run as PID 1 inside minimal container environments (such as Docker). It is deployed as a small, statically-linked binary written in C.
Lightweight containers have popularized the idea of running a single process or service without normal init systems like systemd or sysvinit. However, omitting an init system often leads to incorrect handling of processes and signals, and can result in problems such as containers which can’t be gracefully stopped, or leaking containers which should have been destroyed.
dumb-init enables you to simply prefix your command with dumb-init. It acts as PID 1 and immediately spawns your command as a child process, taking care to properly handle and forward signals as they are received.
为了防止容器中直接使用ENTRYPOINT或CMD指令启动命令或应用程序产生PID为1的进程无法处理传递信号给子进程或者无法接管孤儿进程,进而导致产生大量的僵尸进程。对于没有能力处理以上两个进程问题的PID进程,建议使用dumb-int或tini这种第三方工具来充当1号进程。
Linux系统中,PID为1的进程需要担任两个重要的使命:
传递信号给子进程
如果pid为1的进程,无法向其子进程传递信号,可能导致容器发送SIGTERM信号之后,父进程等待子进程退出。此时,如果父进程不能将信号传递到子进程,则整个容器就将无法正常退出,除非向父进程发送SIGKILL信号,使其强行退出,这就会导致一些退出前的操作无法正常执行,例如关闭数据库连接、关闭输入输出流等。
接管孤儿进程,防止出现僵尸进程
如果一个进程中A运行了一个子进程B,而这个子进程B又创建了一个子进程C,若子进程B非正常退出(通过SIGKILL信号,并不会传递SIGKILL信号给进程C),那么子进程C就会由进程A接管,一般情况下,我们在进程A中并不会处理对进程C的托管操作(进程A不会传递SIGTERM和SIGKILL信号给进程C),结果就导致了进程B结束了,倒是并没有回收其子进程C,子进程C就变成了僵尸进程。
dumb-int是一个用C写的轻量级进程管理工具。类似于一个初始化系统,
它充当PID 1,并立即以子进程的形式允许您的命令,注意在接收到信号时正确处理和转发它们
dumb-init 解决上述两个问题:向子进程代理发送信号和接管子进程。
默认情况下,dumb-init 会向子进程的进程组发送其收到的信号。原因也很简单,前面已经提到过,像 bash 这样的应用,自己接收到信号之后,不会向子进程发送信号。当然,dumb-init 也可以通过设置环境变量DUMB_INIT_SETSID=0来控制只向它的直接子进程发送信号。
另外 dumb-init 也会接管失去父进程的进程,确保其能正常退出。
https://github.com/krallin/tini
https://mp.weixin.qq.com/s/g6I9AoNMlo7Le1LubT_4og