wordpressのコンテナでApacheを再起動しちゃダメな理由

docker

何が起きたのか

wordpressのコンテナイメージにexecで接続したあと、Apacheの再起動を実施しました。
そうしたら、コンテナ自体が落ちてしまいました。。。

[ホスト] # docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
406fb3408cb2        wordpress:latest    "docker-entrypoint.s…"   32 seconds ago      Up 30 seconds       0.0.0.0:8000->80/tcp   ec2-user_wordpress_1
9e52fcb191ac        mysql:5.7           "docker-entrypoint.s…"   32 seconds ago      Up 31 seconds       3306/tcp, 33060/tcp    ec2-user_db_1

[ホスト] # docker exec -it ec2-user_wordpress_1 /bin/bash
[コンテナ] # service apache2 restart
[....] Restarting Apache httpd web server: apache2Terminated

詳しい方からしたら当たり前のことを何言っているんだと思われるかもしれません。。。
素人の私はそもそもなんでそうなるのかがわからなかったので、調べてみました。

コンテナの動作仕様

コンテナは中に入ってみると、さもOSが存在して、そのOS上で操作しているように見えます。
ただし、実体としてはただのプロセスです。

ホスト側でps -efをすると、コンテナの上で動いているプロセスが確認できます。
ホスト上から見えるこれらのプロセスを各コンテナ間で干渉しないよう分離して動かしています。

[ホスト] # ps -ef | grep apache2
root      5072  5039  0 12:07 ?        00:00:00 apache2 -DFOREGROUND
33        5209  5072  0 12:07 ?        00:00:00 apache2 -DFOREGROUND
33        5210  5072  0 12:07 ?        00:00:00 apache2 -DFOREGROUND
33        5211  5072  0 12:07 ?        00:00:00 apache2 -DFOREGROUND
33        5212  5072  0 12:07 ?        00:00:00 apache2 -DFOREGROUND
33        5213  5072  0 12:07 ?        00:00:00 apache2 -DFOREGROUND
root      5309  3768  0 12:11 pts/0    00:00:00 grep --color=auto apache2

コンテナの中で確認すると、以下のように見えます。
ホストからすると親プロセスのPIDは5072だったのに、コンテナの中だと1になっています。

[コンテナ] # ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 12:07 ?        00:00:00 apache2 -DFOREGROUND
www-data    81     1  0 12:07 ?        00:00:00 apache2 -DFOREGROUND
www-data    82     1  0 12:07 ?        00:00:00 apache2 -DFOREGROUND
www-data    83     1  0 12:07 ?        00:00:00 apache2 -DFOREGROUND
www-data    84     1  0 12:07 ?        00:00:00 apache2 -DFOREGROUND
www-data    85     1  0 12:07 ?        00:00:00 apache2 -DFOREGROUND
root        86     0  9 12:13 pts/0    00:00:00 /bin/bash
root        91    86  0 12:13 pts/0    00:00:00 ps -ef

ここで、コンテナのPID1がApacheの親プロセスとなっています。
本来は、PID1にはinit、systemdが存在して、そこから色々な子プロセスが動きます。
ただし、コンテナだとPID1はApacheのプロセスとなっています。

このPID1のApacheがコンテナの実体となります。
そのため、このプロセスを再起動すると、コンテナ自身が再起動されることになります。

デーモン?プロセス?

Apacheは本来はデーモンとして稼働します。
コンテナの動作仕様として、プロセスとして存在していないと終了してしまいます。

そのため、Apacheをデーモンとして動かすだけのコンテナを開始すると、Apache起動直後にコンテナ自体が終了してしまいます。

ただし、wordpressのコンテナはApacheが-DFOREGROUNDとなっており、フォアグラウンドで動かしているため、コンテナが終了しない動作となっています。

wordpressのコンテナの終了条件はフォアグラウンドで稼働しているApahce2の停止となります。

attachとexec

コンテナの初心者向けサイトの説明で、exitするとコンテナが終了するよ!と見かけます。
昨日までの私は、特に何も考えず、「へ~そうなんだ」と思っていました。

実際の理由としては、以下だったからなんですね。納得。

  1. コンテナのPID1の親プロセスでシェルが動いている。
  2. exitをするとシェルが終了する。
  3. つまり、PID1の親プロセスが終了する。
  4. ということはコンテナが終了する。

じゃあ、wordpressのコンテナはPID1の親プロセスがApahceだから、exitしても問題ない?
と、初心者の私は思ったので、attachしてみました。

[ホスト] # docker attach ec2-user_wordpress_1


exit

ps -ef



^C[Mon Sep 07 12:25:39.804238 2020] [mpm_prefork:notice] [pid 1] AH00169: caught SIGTERM, shutting down

すると、シェルにアクセスができず、exitを入力しても無反応でした。
これは、そもそもコンテナ内でシェルが稼働していないからでした。

コンテナでシェルが起動していない場合には、execで接続してあげる必要があり、execで接続した場合にはexitをしても終了するシェルは別にPID 1の大本のプロセスではないので、コンテナは落ちないという動きになるみたいです。

[コンテナ] # ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 12:25 ?        00:00:00 apache2 -DFOREGROUND ← この子は落ちちゃダメ
www-data    81     1  0 12:25 ?        00:00:00 apache2 -DFOREGROUND
www-data    82     1  0 12:25 ?        00:00:00 apache2 -DFOREGROUND
www-data    83     1  0 12:25 ?        00:00:00 apache2 -DFOREGROUND
www-data    84     1  0 12:25 ?        00:00:00 apache2 -DFOREGROUND
www-data    85     1  0 12:25 ?        00:00:00 apache2 -DFOREGROUND
root        86     0  8 12:27 pts/0    00:00:00 /bin/bash ← exitで落ちるプロセスはこの子
root        91    86  0 12:27 pts/0    00:00:00 ps -ef
[コンテナ] # exit
exit
[ホスト]#

すっきりした!

コメント

タイトルとURLをコピーしました