解决容器中的僵尸进程


今天遇到一个问题,是我们的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

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM