在做 Java 程序容器化时都会遇到一个问题,ENTRYPOINT ["java", "$JAVA_OPTS", "-jar", ...]
这样的写法 $JAVA_OPTS
就是个字符串无法在运行时展开。为了不把参数硬编码到容器里,每次调整参数重新构建镜像,可以有多种方案,先介绍几种不够好的方案。
-
ENTRYPOINT java $JAVA_OPTS -jar ...
,这种方式的问题是 java 不是容器主进程(至于为什么要保证 java 是主进程,又是一个话题,是容器化基本最佳实践之一); -
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar ..."]
,这种写法其实等价于上面一种方式,上面一种方式在运行时就是以/bin/sh -c "java $JAVA_OPTS -jar ..."
方式运行的,所以缺陷也是相同的; -
ENTRYPOINT ["entrypoint.sh"]
然后在脚本中启动 java,使用脚本对于需要在启动时做复杂操作的容器比较有用,但是对启动 java 来说未免小题大作,并且同样有 java 不是容器主进程的问题。
从 shell 角度出发,解决非主进程问题的方案是使用 exec
命令,exec
在启动其后参数中的指令时,不会创建子进程而是用指令进程替换自身,使指令进程占用自身的 PID(exec 其后的第一个指令替换了自身之后&#x