After my previous article on zombie processes I was curious to see if and how they can affect containers running in a Kubernetes (K8S) cluster.
A simple descriptor to deploy the container.
# zombie-init.yml apiVersion: v1 kind: Pod metadata: name: zombie-init spec: containers: - name: zombie-init image: zombie-init:latest imagePullPolicy: Never
$ k create -f zombie-init.yml # pod/zombie-init created $ k logs zombie-init # The zombie pid will be: 7 # USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND # root 1 0.0 0.5 13164 10676 ? Ss 20:09 0:00 python3 /root/test.py # root 7 0.0 0.0 0 0 ? Z 20:09 0:00 [python3] <defunct> # root 8 0.0 0.1 9392 2952 ? R 20:09 0:00 ps xawuf
We can observe the same behavior a already observed in the previous article. A zombie process (
defunct) has not been reaped since the
PID 1 process (it's parent) has not played this role.
To benefit from a proper
init process that will take care of reaping zombies, we have to tell Kubernetes to enable PID sharing between the containers that are running in the POD. This is done by specifying
shareProcessNamespace: true. So the deployment looks now like this.
apiVersion: v1 kind: Pod metadata: name: zombie-init spec: shareProcessNamespace: true containers: - name: zombie-init image: zombie-init:latest imagePullPolicy: Never
Here is the result obtained with this new configuration.
$ k logs zombie-init # The zombie pid will be: 21 # USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND # root 15 0.0 0.5 13156 10596 ? Ss 20:11 0:00 python3 /root/test.py # root 22 0.0 0.1 9392 3080 ? R 20:11 0:00 \_ ps xawuf # root 1 1.0 0.0 1024 4 ? Ss 20:11 0:00 /pause
In the log, we can see that the zombie process has been reaped without specifying an
init process or adding one in the container. In this case the
init process, which plays the parent role, is the
pause process (in fact it's a container). We can observe that it holds the
In Kubernetes, the pause container serves as the “parent container” for all of the containers in your pod. The pause container has two core responsibilities. First, it serves as the basis of Linux namespace sharing in the pod. And second, with PID (process ID) namespace sharing enabled, it serves as PID 1 for each pod and reaps zombie processes.
If namespace sharing is not enabled each container has to do it's own housekeeping—it could not be a problem at all if the process running in the container does not spawn other processes. The problem can also be solved by using an
init process inside each container like it has been demonstrated in the previous article.