docker优雅退出

Docker中 shell 启动程序后优雅退出三种方式

本文来自转载

2021-11-09 08:55·云技术趣谈

之前的文章介绍了如何让容器优雅退出,但如果我们是通过shell 的方式启动我们的应用,那么pid 为1的进程就是shell 进程,无法将 kill -15 信号传递给我们的业务程序,进而执行优雅退出。比如下面写法

# Dockerfile
CMD ["/home/default/start.sh"]

# 启动脚本
#!/bin/bash
echo "[INFO] 开始运行"
java -jar app.jar

为了解决这个问题,有四种常用的方式:

Docker中 shell 启动程序后优雅退出三种方式

第一种方式是让shell 注册TERM信号,然后传递给子进程(业务进程)

#!/bin/bash
echo "[INFO] 开始运行"
java -jar app.jar &
pid="$!"

_kill() {
  echo "[INFO] Receive sigterm"
  kill $pid
  wait $pid
  exit 143
}
trap _kill SIGTERM
wait

第二种方式是通过exec 使用当前进程启动应用

#!/bin/bash
echo "[INFO] 开始运行"
exec java -jar app.jar

这里我们的java 进程pid 就为 1 了,如果对exec 不太了解,可以看一下 linux 系统调用 fork 和exec 系统调用,exec 主要是加载一个新的二进制到当前进程的内存空间。

第三种方式是使用 tini

ENTRYPOINT ["/tini", "--"]
CMD ["/home/default/start.sh"]

通过tini 可以回收僵尸进程以及传递信号

最后一种方式放弃shell 启动

直接把将启动命令放到cmd 里面。但如果启动脚本比较复杂可以放到initcontainer完成。

CMD ["java", "-jar", "app.jar"]