私はtini
コンテナのシェルスクリプトを介してJavaアプリケーションを起動し、コンテナが停止したときにアプリケーションがDockerからシグナルを受け取るようにinitプロセスとして使用します。問題は、コンテナ内のプロセスリストの内容を表示するだけで最もよく説明されているので、設定について簡単に説明します。
startup.sh
Javaアプリケーションを設定するために実行する必要があるシェルスクリプトがあります。これにより、アプリケーションが設定され実行されます。通常、このスクリプトはフォアグラウンドでJavaを起動します。デバッグのために、スクリプトはバックグラウンドでJavaアプリケーションを起動し、bashシェルを起動するようにしました。どちらにしても同じ問題がある動作を確認します。
私のDockerfileには2つの行があります。
ENTRYPOINT ["/tini", "-g", "--"]
CMD ["./bin/startup.sh"]
Startup.shスクリプトの一番下で、私のJavaアプリケーションは次のように起動します。
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005 -Dfilethis.root.dir=/home/fetch/fetchbase -jar bin/fetch.jar
私はbashが信号を透過的に伝えないことを常に知っていました。 Googleで解決策を見つけましたtini
。私が読んだことによれば、-g
toオプションを使用すると、直系のtini
子プロセスだけでなく、その子プロセスによって開始されたプロセスにも信号を渡す必要があります。なぜなら、すべてが同じプロセスグループにあるからです。
デバッグモードを使用してコンテナ内にシェルをインポートすると、プロセスリストに次のものが表示されます。
sh-4.2$ ps -ae -o pid,ppid,gid,cmd
PID PPID GID CMD
1 0 1000 /tini -g -- ./bin/startup.sh
8 1 1000 /bin/sh ./bin/startup.sh
16 8 1000 /usr/bin/Xvfb :15 -screen 0 1280x1024x24
42 1 0 /usr/sbin/sshd
44 8 1000 java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005 -Dfilethis.root.dir=/home/fetch/fetchbase -jar bin/fetch.jar
45 8 1000 /bin/sh
63 45 1000 ps -ae -o pid,ppid,gid,cmd
この程度が合うようです。 p#1は、tini
Javaアプリケーションであるp#44を起動するシェルスクリプトであるp#8を起動します。 3つのプロセスはすべて、ID 1000の同じプロセスグループにあります。
Javaプロセスにデバッガを配置し、分解コード(アプリケーションがTERM信号を受信したときに実行されるコード)のさまざまな場所にブレークポイントを設定しました。次に、次の2つのコマンドのいずれかを実行します。
1) kill -TERM 1
2) kill -TERM 44
最初の場合、Dockerがコンテナを閉じると(正しいですか)、アプリケーションはブレークポイントをヒットせず、コンテナはすぐに終了します。アプリケーションに入れたロギングで分解コードが実行されていないことを確認しました。この場合、tini
TERM信号をJavaアプリケーションに渡すべきではありませんか?
2番目のケースでは、デバッガはブレークポイントに到達し、ログに解体コードが実行されたことを示します。
コンテナの起動時にJavaアプリケーションがシェルスクリプトを介してフォアグラウンドで実行され、次にコンテナで実行されたdocker stop
ときに同じ動作が発生します。ブレークポイントとリリースコードはヒットされません。
私は何を見逃していますか?tini
信号電波の意味を誤解したのでしょうか?ティア!