The process and reason of the zombie process generated by the exit of the process under the container

foreword

Recently, container deployment has been standardized. Originally, it was very simple and there were no special requirements. However, in the container, due to the temporary need to start the process, a zombie process appeared after stopping.

java application

Take the Java application as an example, adoptopenjdk/openjdk11 is used as the template here

docker pull adoptopenjdk/openjdk11

Java code example, simple processing, no package name, run through java Demo 

public class Demo {
    public static void main(String[] args) throws InterruptedException {
        System.out.println("start>>>>>>>>>>>>");
        Thread.sleep(500000000000l);
    }
}

Write Dockerfile

FROM adoptopenjdk/openjdk11:latest

WORKDIR /opt

ADD Demo.class .

ENTRYPOINT ["java","Demo","> /opt/demo.log"]

docker build . -t java-demo:1.0

after compilation

docker run -d --name java-demo java-demo:1.0

 

docker exec -it java-demo bash

 

Simulation needs to temporarily start some processes, which is very common on virtual machines. 

echo 'java Demo' > start.sh

Execute chmod +x start.sh 

./start.sh &

Enter the container through another bash, you can see the parent-child relationship of the process, and a zombie process appears

 The creation of a zombie process is related to the ID of the parent process being 1, and the ID of the parent process is 1. Killing the container will generate a zombie process.

 

rust application

In order to verify whether there is a relationship between the zombie process and the language, I wrote another rust code

fn main() {
    println!("Hello, world!》》》》》》》》》》");
    use std::{thread, time};
    let ten_millis = time::Duration::from_millis(10000000000000);
    thread::sleep(ten_millis);
}

Install the cross-compilation environment, taking macOS as an example

# macOS
rustup target add x86_64-unknown-linux-musl
brew install filosottile/musl-cross/musl-cross

#win

rustup target add x86_64-pc-windows-gnu
brew install mingw-w64

configure config

vim ~/.cargo/config or in the project's .cargo/config, generally compile the Linux environment, the local environment does not need cross-compilation

[target.x86_64-unknown-linux-musl]

linker = "x86_64-linux-musl-gcc" 

cargo build --release --target x86_64-unknown-linux-musl

 

under target

 

 run on ubuntu

Mirror image preparation, control variables, or use the original base.

FROM adoptopenjdk/openjdk11:latest

WORKDIR /opt

ADD hello .

RUN chmod +x hello

ENTRYPOINT ["./hello","> /opt/demo.log"]

 Execute additional process operations

 Exec again

 Execute kill -9, and a zombie process appears.

 

 The conclusion is that the generation of zombie processes actually has nothing to do with the language.

 

cause

The process whose process id is 1 under the container cannot be killed, and the id is 0 is the parent process id of all processes

When killing, in fact, kill -15 will appear, it has nothing to do with -9

1. Kill the process, when the parent process id is 1, a zombie process appears

2. Kill the process. If the parent process is killed first (including normal exit), the parent process id of the current process will be set to 1 under the container, that is, the running process of the base container

 

Solution

According to the two results summarized, it is also very simple to solve. The process of killing can install the reverse process of creating a process.

First kill the child process, then kill the parent process, until all are killed.

Try java-demo, and sure enough, there is no zombie process in the reverse process created. This design actually often appears in the release process of Kubernetes

 rust-demo

 

Summarize

The process whose process id is 1 under the container cannot be killed. When a process needs to be created under the container and started at runtime, the process of creating the process is very important, because the destruction requires the reverse process, otherwise a zombie process will appear. When the parent process of a newly created process (except the process with id 1) under the container is killed or exits naturally, the parent process id of the current process will be set to 1, that is, the process under the container cannot be killed, resulting in the generation of zombie processes .

Guess you like

Origin blog.csdn.net/fenglllle/article/details/127591851