Dumb-Init进程信号处理

http://blog.csdn.net/tiger435/article/details/54971929


随着docker及Kubernetes技术发展的越来越成熟稳定,越来越多的公司开始将docker用于生产环境的部署,相比起物理机上直接部署,多了一层docker容器的环境,这就带来一个问题:进程信号接收与处理。

相信有不少同学发现,在docker中捕获不到进程的结束信号,这就给我们的一些进程异常处理带来了麻烦,用Supervisor等进程管理工具也能够解决这一问题,不过太“重”了,在容器时代追求“轻”的我们是不能接受的,本文介绍一个超级小巧的容器初始化工具-Dumb-Init。

1 特性描述

1.1 进程信号传递

站在容器的角度,由其运行的第一个程序的PID为1,这个进程肩负着重要的使命:传递信号让子进程退出和等待子进程退出。对于第一点,如果pid为1的进程,无法向其子进程传递信号,可能导致容器发送SIGTERM信号之后,父进程等待子进程退出。此时,如果父进程不能将信号传递到子进程,则整个容器就将无法正常退出,除非向父进程发送SIGKILL信号,使其强行退出,这就会导致一些退出前的操作无法正常执行,例如关闭数据库连接、关闭输入输出流等。

1.2 僵尸进程处理

上边提到:PID为1的进程的一个重要使命是等待子进程退出,如果一个进程中A运行了一个子进程B,而这个子进程B又创建了一个子进程C,若子进程B非正常退出(通过SIGKILL信号,并不会传递SIGKILL信号给进程C),那么子进程C就会由进程A接管,一般情况下,我们在进程A中并不会处理对进程C的托管操作(进程A不会传递SIGTERM和SIGKILL信号给进程C),结果就导致了进程B结束了,倒是并没有回收其子进程C,子进程C就变成了僵尸进程。

1.3 进程信号模拟

父进程非正常退出(收到SIGKILL信号),若使用了Supervisor类工具,可以将SIGKILL信号传递给子进程,若子进程中想收到SIGTERM信号,就可以通过dumb-init来模拟。

2 安装Dumb-init

2.1 deb安装
RUN wget https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb
RUN dpkg -i dumb-init_*.deb
2.2 二进制安装
RUN wget -O /usr/local/bin/dumb-init https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64
RUN chmod +x /usr/local/bin/dumb-init
2.3 PyPI安装
pip install dumb-init

3 容器使用Dumb-init

在Dockerfile中增加entrypoint固定使用dumb-init为容器运行的第一个进程。

# Runs "/usr/bin/dumb-init -- /my/script --with --args"
ENTRYPOINT ["/usr/bin/dumb-init", "--"]

# or if you use --rewrite or other cli flags
# SIGTERM (number 15) to SIGQUIT (number 3)
# ENTRYPOINT ["dumb-init", "--rewrite", "15:3", "--"]

CMD ["/my/script", "--with", "--args"]

例如:

ENTRYPOINT ["/usr/bin/dumb-init", "--"]
CMD ["/usr/local/bin/docker-entrypoint.sh"]

4 最佳实践

如上配置,/usr/bin/dumb-init为PID为1的进程,/usr/local/bin/docker-entrypoint.sh作为其子进程,可以正常收到进程信号。但是/usr/local/bin/docker-entrypoint.sh中如果再运行子进程,如运行一个java进程,那java进程中就获取不到进程信号,此时可以加一个exec来提升子进程到PID进程下。

例如/usr/local/bin/docker-entrypoint.sh中:

#!/bin/bash
echo "Hello world!"
java hello.jar

java中无法获取进程信号,进程树如下:

/dumb-init
+--- /usr/bin/dumb-init
      +--- /bin/bash
            +--- java ...
dumb-init,1 -- /usr/local/bin/docker-entrypoint.sh
  └─java,7 -Xmx64m -Xms16m -Xmn8m -Xss1m -XX:ReservedCodeCacheSize=5m -XX:NewRatio=3 -jar /usr/local/agent/agent-1.0.1.jar WEX5-JAVA-IDE

调整为:

#!/bin/bash
echo "Hello world!"
exec java hello.jar

java中可以获取到进程信号,进程树如下:

/dumb-init
+--- /usr/bin/dumb-init
      +--- /bin/bash
+--- java ...
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值