今天遇到一個問題,是我們的jenkins-node 突然出現好多僵屍進程
ps -ef |egrep defunct
sh [defunct]
基本都是這種進程
通過前述的 ps 命令,我們發現這些 zombies 的父進程基本都是 jenkins-agent 進程
通過網上搜索發現是我們啟動的父進程是1 的進程(我這里是jenkins-agent 進程)不具備init 系統的功能,也就不會將操作系統的信號轉發到子進程上,也不會回收孤兒進程,所以會產生大量的僵屍進程
這和我啟動jenkins-node的方式有關我構建的Dockerfile的啟動方式是直接CMD

這樣啟動的容器必然是jenkins-agent 的進程為1 ,不具備init 系統具備的功能,所以會產生大量的僵屍進程,又無法回收
這里介紹一下init 系統應該具備的功能
init 系統有以下幾個特點:
- 它是系統的第一個進程,負責產生其他所有用戶進程。
- init 以守護進程方式存在,是所有其他進程的祖先。
- 它主要負責:
- 啟動守護進程
- 回收孤兒進程
- 將操作系統信號轉發給子進程
所以解決方案是啟動一個具備init進程的進程來啟動相應的容器,按照網上的解決最終選擇tini


init 系統有很多種,這里推薦使用 tini,它是專用於容器的輕量級 init 系統
https://github.com/krallin/tini
如果你想直接通過 docker 命令來運行容器,可以直接通過參數 --init 來使用 tini,不需要在鏡像中安裝 tini。如果是 Kubernetes 就不行了,還得老老實實安裝 tini
所以最終的解決方案是
ENTRYPOINT ["/sbin/tini", "--", "/usr/local/bin/jenkins.sh"]


參考文檔
https://github.com/jenkinsci/docker/issues/54
https://github.com/jenkinsci/docker-inbound-agent/issues/51
https://zhuanlan.zhihu.com/p/145512162
