SIGTERM is not received by the java process using ‘docker stop’ and the official JAVA image

I use Debian / Jessie based image Java: 7u79 to run the dropwizard Java application in the docker container

My java application handles SIGTERM signals and shuts down normally When I run an application without docker, SIGTERM processing function is perfect

When I run it in the docker container, SIGTERM will not reach the Java application when I issue the docker stop command After 10 seconds, it will die suddenly

My docker file:

FROM java:7u79

COPY dropwizard-example-1.0.0.jar /opt/dropwizard/
COPY example.keystore /opt/dropwizard/
COPY example.yml /opt/dropwizard/

WORKDIR /opt/dropwizard

RUN java -jar dropwizard-example-1.0.0.jar db migrate /opt/dropwizard/example.yml

CMD java -jar dropwizard-example-1.0.0.jar server /opt/dropwizard/example.yml

EXPOSE 8080 8081

What's wrong with this docker file? Is there any way to solve this problem?

Solution

Suppose you start a Java service by defining the following in dockerfile:

CMD java -jar ...

When you enter the container and list the process, you can see that your Java process is not the root process (not the process of PID 1), but the child process of / bin / sh process through docker exec - it < containername > PS AHF (I didn't try to use Java but used Ubuntu image):

UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 18:27 ?        00:00:00 /bin/sh -c java -jar ...
root         8     1  0 18:27 ?        00:00:00   java -jar ...

So basically you have a Linux shell, which is the main process of PID 1. It has a sub process (Java) with PID 8

For signal processing to work properly, you should avoid these shell parent processes This can be done by using the built - in shell command exec This will cause the child process to take over the parent process So in the end, the previous parent process no longer exists And the subprocess becomes the process of PID 1 Try the following in dockerfile:

CMD exec java -jar ...

The process list should be as follows:

UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 18:30 ?        00:00:00 java -jar ...

Now you have only one process with PID 1 Generally speaking, a good practice is to make the docker container contain only one process - a PID 1 (or if you really need more processes, you should use, for example, supervisor as PID 1, which itself takes care of the signal processing of its child processes)

With this setting, SIGTERM will be processed directly by the java process No shell processes may interrupt signal processing

Edit:

Implicitly achieve the same execution effect by using different CMD syntax (thank Andy for his comments):

CMD ["java","-jar","..."]
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>