Docker在进程管理上有一些特殊之处,如果不注意这些细节中的魔鬼就会带来一些隐患。
Docker鼓励“一个容器一个进程(one process per container)”的方式。
这种方式非常适合以单进程为主的微服务架构的应用,然而由于一些传统的应用是由若干紧耦合的多个进程构成的,这些进程难以拆分到不同的容器中,所以在单个容器内运行多个进程便成了一种折衷方案。
此外在一些场景中,用户期望利用Docker容器来作为轻量级的虚拟化方案,动态的安装配置应用,这也需要在容器中运行多个进程,而在Docker容器中的正确运行多进程应用将给开发者带来更多的挑战。
tini是能想到的最简单的init。
tini一般在容器中运行,用于生成子进程,等待它退出,reap僵尸进程,并执行信号转发。
如果我使用docker容器init 进程,是不是就是容器的第一个进程?
init进程就是容器里的第一个进程。
容器里的第一个进程大部分情况应该是我们自己的进程,除非有容器用户有意识的去使用其他如果tini进程作为init进程。
init 进程自己退出,还是会调用do_exit()的。所以呢,为了保证子进程先收到转发的SIGTERM, 类似tini的做法是,自己在收到SIGTERM的时候不退出,转发SIGTERM给子进程,子进程收到SIGTERM退出之后会给父进程发送SIGCHILD, tini是收到SIGCHILD之后主动整个程序退出。
我们一直都是应用程序作为PID1来运行的,感觉用tini这种方式改动有点大!
信号对容器中进程的影响的多少,也有多方面的原因,比如程序本身对错误的容忍度比较高, 容器建立删除的频率不高,那么也就看不出有什么影响。
如果你的程序的容器化程度较高,几乎是一个容器一个进程的程度,那么不需要考虑用tini来做改动。
我觉得容器里的init进程,应该是具备这些信号处理的能力:
1. 至少转发SIGTERM给容器里其他的关键子进程。
2. 能够接受到外部的SIGTERM信号而退出,(这里可以是通过注册SIGTERM handler, 也可以像tini一样先转发SIGTERM 给子进程,然后收到SIGCHILD后自己主动退出)
3. 具有回收zombie进程的能力。
参考
理解Docker容器的进程管理
https://www.cnblogs.com/ilinuxer/p/6188303.html
在entrypoint.sh中使用Tini的优势是什么?
https://zhuanlan.zhihu.com/p/59796137
网友评论