一、项目背景
Jenkins-agent产生大量的僵尸进程, 主机的进程数达到了3w+. 导致agent服务无法正常提供服务
# 最大pid进程数
$ cat /proc/sys/kernel/pid_max
32768
top 命令的结果 (贴图为后补, 实际值已超过最大进程数)
ps aux结果
docker服务异常
$ docker ps
runtime/cgo: pthread_create failed: Resource temporarily unavailable
SIGABRT: abort
PC=0x7efca7dad387 m=0 sigcode=18446744073709551610
goroutine 0 [idle]:
runtime: unknown pc 0x7efca7dad387
stack: frame={sp:0x7ffdbda3a6c8, fp:0x0} stack=[0x7ffdbd23ba98,0x7ffdbda3aad0)
00007ffdbda3a5c8: 000055af6e558e7f <runtime.(*mheap).growAddSpan+271> 00007ffdbda3a600
00007ffdbda3a5d8: 000055af6e54fe0e <runtime.(*mTreap).end+78> 0000000000000000
00007ffdbda3a5e8: 00007efc00000001 0000000000000000
00007ffdbda3a5f8: 00007ffdbda3a630 000055af6e57e7d7 <runtime.step+327>
00007ffdbda3a608: 000055af708fbdf2 0000000000d08e00
00007ffdbda3a618: 0000000000d08e00 00007ffdbda3a658
00007ffdbda3a628: 000055af6e57e7a3 <runtime.step+275> 00007ffdbda3a6d8
00007ffdbda3a638: 000055af6e57daba <runtime.pcvalue+346> 000055af70918a3f
......
这里有一行报错是,runtime/cgo: pthread_create failed: Resource temporarily unavailable
二、原因分析
大量的僵尸进程由服务jenkins-agent引起, 子进程终止后会等待父进程发送wait
系统调用来收割(reap)子进程,若没有收到wait
会进程zombie
状态。
即父进程在子进程终止后并没有进程回收, 导致大量的僵尸进程堆积.
当僵尸进程达到pid_max最大进程数,主机pid资源耗尽, 导致 docker服务异常.
三、临时解决
因为docker服务已经异常, 无法正常提供服务, 所以直接重启docker服务即可
$ systemctl restart docker
修改最大pid_max值
$ echo "kernel.*pid_max*=65535" >> /etc/sysctl.conf
$ sysctl -p
此处修改后只能暂时处理问题, 但当僵尸进程数达到阈值, 问题依旧会发生
四、 永久解决
docker-compose.yaml 添加 init: true 参数, 让jenkins-agent父进程对僵尸进程进行处理
注意: version版本: 2.4+ 或者3.7+版本才可以使用init参数 (对应链接文档搜索关键字)
version: '3.7'
services:
jenkins_agent:
image: 'jenkins/agent:latest'
user: root
network_mode: host
environment:
TZ: "Asia/Shanghai"
container_name: jenkins_new
restart: always
init: true
volumes:
- '/data/server/jenkins_new:/home/jenkins'
- '/data/server:/data/server'
- '/usr/bin/docker:/usr/bin/docker'
- '/var/run/docker.sock:/var/run/docker.sock'
- '/data/server/.kube/kustomize:/usr/bin/kustomize'
- '/data/server/.kube/kubectl:/usr/bin/kubectl'
- '/data/server/.kube/config:/home/jenkins/.kube/config'
command: bash -c "apt-get update && apt-get install -y sudo && echo 'jenkins ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers && su jenkins -c 'sudo docker login --username devops --password devops harbor.baibu.la && java -jar /usr/share/jenkins/agent.jar -jnlpUrl http://192.168.20.144:8888/computer/ops-20-155/slave-agent.jnlp -secret 56cef3a131bddb2f472523fb24867b560757648bdaeaf2128792665f4935878f -workDir /home/jenkins'"
容器重新加载配置(修改yaml后需要down再up, restart无法重新加载新的配置文件)
docker-compose down
docker-compose up -d
Jenkins-agent启动命令前后对比
添加前
添加后
测试截图是否有僵尸进程产生
完成 !