docker容器优雅退出

163 阅读1分钟

dockerfile如下:

ARG compile-image
FROM compile-image as arti
WORKDIR /app
COPY ./ /app
RUN --mount=type=cache,target=/root/.m2,id=bo-m2-repos \
    mvn clean package -Dmaven.test.skip  -pl user -am -s settings.xml

FROM compile-image
WORKDIR /app
COPY --from=arti /app/user/target/user-2.0.0-SNAPSHOT.jar /app/app.jar
#CMD ["java" ,"-jar","--enable-preview","app.jar"]
#CMD exec java -jar --enable-preview app.jar
CMD java -jar --enable-preview app.jar

需要注意的是第11、12、13行的写法

  • CMD ["java" ,"-jar","--enable-preview","app.jar"] 这样写的时候,容器中pid为1的进程为cmd所指定的进程,此时java进程会收到容器信号,容器中的程序可以优雅退出
  • CMD java -jar --enable-preview app.jar 这样写的时候(注意没有exec),容器中pid为1的进程为 sh -c 进程,此时java进程收不到容器的信号,当执行docker stop的时候,容器不会立马退出,因为java进程还在运行且收不到退出信号。因此容器会等待10s左右,然后 强制杀死该容器。
  • CMD exec java -jar --enable-preview app.jar 这样写的时候,用到了shell中一个特殊的命令exec,该命令可以使用后面的java进程替换当前进程,从而从容器里面看pid为1的还是java进程,此时执行dcoker stop 容器也能够优雅的退出

总结

容器是否能优雅退出,主要看容器中pid为1的进程能否收到信号,并正常退出。因此推荐使用以下两种写法

  • CMD ["java" ,"-jar","--enable-preview","app.jar"]
  • CMD exec java -jar --enable-preview app.jar