容器进程解析

一、容器进程和宿主机进程的关系

容器在进程空间上和宿主机是隔离的,每创建一个容器都会创建一个与之对应的PID NameSpace。因此每个容器都有一个独属的进程空间简称PID NameSpace。
PID自然是进程编号,也就是说每个容器中的进程都会单独进行编号。

为啥每个容器中的PID要单独编号呢?如果所有容器中的进程都使用一个递增的进程ID不行吗,这样也不会保证重复。
一方面进程有容器的本质是资源隔离,PID也算是一种资源,很多进程相关的资源都和进程ID有关系,再者容器频繁的创建和重启也可以避免冲突。
相对而言,每个容器单独对进程id进行编号,更合适一些。

| 容器视角中的进程状态:

image.png

可以看见容器中仅有几个进程,看不见宿主机上的进程。
其中容器中的1号进程和linux中的1号进程其实是一样的,是init进程,是所有进程的父进程,其它的进程都由init进程来创建。init进程比较重要,担任着和宿主机上init进程同样的角色

| 宿主机中视角中的进程状态

image.png

通过grep httpd,可以查看到我们在容器中启动的那个httpd进程。
从图中也可以看到,容器中的进程其实也只是宿主机上的普普通通一个小进程。 因此可以在宿主机上随时停掉它。

那么就有问题了,不是PID隔离的吗,为什么在宿主机上可以看到容器中运行的进程呢?
其实宿主机上的PidNamespace相当于是所有容器的parent-Pid-Namespace。

image.png
容器中的init进程其实是宿主机上shim-runc 进程的一个子进程。
image.png

二、那能不能在容器中kill 掉容器中的init进程呢?

init进程是一个特殊的进程,进程的pid为1,是当前pidnamespace中所有进程的父进程。对其它进程的资源回收起到兜底作用。那能不能kill掉init进程呢?

kill的本质上是向进程发送一个信号,可用作进程间通信,那么具体是如何处理这个信号,完全是由进程本身决定的,进程一般有三种处理方式:

  • 忽略(不理睬)
  • 执行缺省(默认)的handler
  • 执行自定义的handler

其中对于sigkill和sigstop,不能注册自定义的hander,也不能忽略,因为这俩信号就是让超级用户停掉进程的。
因此对于sigkill和sigstop两个信号进程只能使用默认的handler进行处理。但是呢 init进程把只有默认handler的信号给忽略了,防止init进程被误杀。

因此不能在容器中使用kill -9 杀掉init进程。

但是可以通过kill其它信号中止init进程,前提要注册自己的handler。因为对于只有默认handler的信号,init进程就把这个信号给忽略掉了。
另外可以在宿主机中直接kill掉容器的init进程,因为容器中的init进程在宿主机上就是一个不同的进程了,当然可以随时kill掉。

总结:init进程,对于只有默认handler的信号会忽略,对于注册了handler的信号会响应,但是sigkill和sigstop不能自定义handler。

三、容器中最大进程数量问题

在linux中,进程的数量是有限制的,具体的数量可以在这个文件中看到:/proc/sys/kernel/pid_max
image.png
虽然容器pidnamespace和宿主姐pidnamespace是隔离的,但是容器中的每个进程最终还是会映射为宿主机的一个进程,因此容器中如果不断创建进程就会影响宿主机上的其它容器和宿主机。
因此需要限制每个容器的最大进程数量。这个功能由pid Cgroup实现。可以向pid Cgroup的pid.max文件中写入合适的参数值进行控制。
僵尸进程的产生,一个进程都是要占用一些资源状态的,而占用的这些资源状态进程在终止前是需要父进程对其进行回收的,如果父进程没有回收,那么这个子进程就称为僵尸进程其状态为Z。如果父进程退出了,会由init进程接管。
因此容器中也会产生僵尸进程,僵尸进程会占用容器中的进程数资源,容器中的进程数目是也是受限制的,因此对于容器中的僵尸进程要格外注意。
僵尸进程一定需要父进程调用wait()或者waitpid()系统调用来清理,这也是容器中init进程必须具备的一个功能。

四、容器中进程的优雅停机

在容器平台中停止一个容器,不论是k8s删除pod还是docker删除容器,最终都是由container向容器的init进程发送一个SIGTERM信号。
当 Docker 停止容器时,它会首先发送 SIGTERM 信号给主进程,应用程序应该捕获这个信号并优雅地关闭。

对于容器而言,init进程退出的时候还需要考虑同一个pidNamespace中的其它进程。
在这里插入图片描述
但是其它进程确收到的是SIGKILL信号,因此需要init信号特殊处理转发SIGTERM信号,而不是SIGKILL信号。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值