はじめに
IBM Cloud Paks Advent Calendar 2021 22日目です。
CP4Dのカートリッジ製品であるDb2のネタについて書いていこうと思います。
まずは、Dockerの 「PID1問題」 ご存知でしょうか?
PID1問題とは、コンテナ上で実行されるアプリケーションのプロセスが PID1 で実行されることで、コンテナに対して SIGTERM などのシグナルを送信してもコンテナ内のプロセスが正常に終了しないというものです。
詳細は Docker PID1
で検索するとたくさんヒットしますので、検索してみてください。
本記事ではDb2のコンテナ(Client側)でこの問題に遭遇しましたので対処法についてお話しします。
何が発生していたのか?
Client側のコンテナの動作確認時の流れが下記となります。
コンテナ起動後、rootでDb2の環境設定とカタログ設定をシェルで実行し、
以降はユーザーを切り替えて、任意のタイミングでDb2を操作するシェルを実行する。
と一見問題なさそうな流れです。(有識者ならそうでもないのかもしれませんが…)
しかし、rootでDb2の環境設定とカタログ設定をシェルで実行ここが落とし穴で、rootでシェルを実行するとPPID1となり結果的に、PID1のプロセスが適切に終了できずDb2のプロセスがdefunctとして残ってしまいます。
どう回避するか
色々と試しました。
tiniの利用、停止シグナルの変換、Docker→Podmanに置き換え…
が、最終的には下記の様な対策に落ち着きました。
- DockerfileのCMDに、「Db2の環境設定とカタログ設定を行うシェル」を指定
- 指定したシェルの中の末尾に無限ループを追加
解説
1.は必ず必要な処理となるので言わずもがなCMDに指定…ですが、指定しているシェルは環境設定およびカタログ設定さえできれば良いので、逆にそれができれば終了する必要のないプロセスでもあるので、2.の無限ループを入れることで終了しない様にしてあげます。
こうすることでdefunctが残ることもなく、以降ユーザーを切り替えてDb2を操作するシェルを実行しても問題ない状況となります。
年末年始時間のある時に図などを追記できればと思います…