私のDockerイメージからバックグラウンドキューを実行したいと思います。
php artisan queue:work --daemon --sleep=1 --tries=3 &
その直後に、httpd
PHPlaravel
アプリケーションを実行するApacheが起動します。アプリケーションがlaravel
Redisにプッシュ通知を送信します。バックグラウンドキューワーカーはRedisからメッセージを収集し、プッシュサービスを介して送信します。
これは毎秒動作し、ログアウトされます。バックグラウンドコマンドがクラッシュした場合は、再起動したいと思います。この回答によるとhttps://unix.stackexchange.com/a/223780/72040次のようにバックグラウンドでコマンドを無限に実行できます。
while true; do php $QUEUE_WORK; done &
これをテストするためにコンテナを実行したdocker run
後、docker exec -it
ログインして次のことを確認しました。
UID PID PPID C STIME TTY TIME CMD
100000 1 0 0 19:55 ? 00:00:00 httpd -D FOREGROUND
100000 21 1 0 19:55 ? 00:00:00 /bin/sh -e /tmp/scripts/run
100000 22 21 1 19:55 ? 00:00:01 php artisan queue:work --sleep=1 --tries=3
100000 43 1 0 19:55 ? 00:00:00 /usr/bin/cat
100000 50 1 0 19:55 ? 00:00:00 /usr/bin/cat
100000 51 1 0 19:55 ? 00:00:00 /usr/bin/cat
100000 52 1 0 19:55 ? 00:00:00 /usr/bin/cat
100000 53 1 0 19:55 ? 00:00:00 httpd -D FOREGROUND
...
100000 130 0 1 19:57 pts/0 00:00:00 /bin/bash
100000 144 130 0 19:57 pts/0 00:00:00 ps -efww
その後、実行してkill 22
出力を確認しますdocker run
。
/tmp/scripts/run: line 10: 22 Killed php $QUEUE_WORK
ループはプロセスを実行し続けません。ループがイメージで実行されているコードであることを再確認しました。ループを "echo x: sleep 1" で実行すると正常に動作します。
コマンドを終了してもループがコマンドを置き換えないのはなぜですか?
メモ:アプリケーションは Kubernetes で複数のポッドにデプロイされ、ヘルスチェックhttpd
URL がエラーを返すかタイムアウトすると監視され、自動的に再起動されます。
キューワーカーを別のポッドやサイドカーコンテナとしてデプロイしたくなく、まったく構成されていないアプリケーションコードを共有するようにhttpd
コンテナでバックグラウンドプロセスとして実行したいと思います。httpd
私はプロセスモニタや他のツールや技術を実行して「状態を維持する」ことに興味がありません。
私の質問は、Bashループがkill
実行中のプロセスを終了するのはなぜですか?
答え1
設定
次のように設定されていますDockerfile
。
$ more Dockerfile
From centos
ADD run.sh /tmp/run.sh
RUN chmod +x /tmp/run.sh
ENTRYPOINT ["/tmp/run.sh"]
設定スクリプトrun.sh
:
$ cat run.sh
while true; do sleep 15 ; echo "background"; done &
while true; do sleep 12 ; echo "foreground"; done
ビルドしてください:
$ docker build -t sleeper .
Sending build context to Docker daemon 7.791 MB
Step 1/4 : FROM centos
---> 49f7960eb7e4
Step 2/4 : ADD run.sh /tmp/run.sh
---> b4099de53780
Removing intermediate container 1ce8e3a1dac5
Step 3/4 : RUN chmod +x /tmp/run.sh
---> Running in e410429a6cba
---> 06789467e636
Removing intermediate container e410429a6cba
Step 4/4 : ENTRYPOINT /tmp/run.sh
---> Running in ad8b847b505f
---> a2415df63f99
Removing intermediate container ad8b847b505f
Successfully built a2415df63f99
はい
それから始めなさい。
$ docker run -dit sleeper
28c19c338e6e6177529cf989f42c7f14b17f1c705a61f5244d5350f0ab8f8364
その後、繰り返し実行され、以下を表示します。
foreground
background
foreground
background
これを見ると、sleep
コマンドは最終的に「終了」しますが、まだ実行中であることがわかります。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
28c19c338e6e sleeper "/tmp/run.sh" About a minute ago Up About a minute focused_lumiere
上記では、このコンテナが1分以上起動したことがわかります。ps auxf
コンテナの内部はこんな感じです。
$ ps auxf
...
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 24 0.0 0.1 11828 2964 pts/1 Ss 16:00 0:00 /bin/bash
root 58 0.0 0.1 51712 3432 pts/1 R+ 16:01 0:00 \_ ps auxf
root 1 0.0 0.1 11692 2572 pts/0 Ss+ 15:58 0:00 /bin/bash /tmp/
root 5 0.0 0.1 11696 2272 pts/0 S+ 15:58 0:00 /bin/bash /tmp/
root 56 0.0 0.0 4368 636 pts/0 S+ 16:01 0:00 \_ sleep 15
root 57 0.0 0.0 4368 664 pts/0 S+ 16:01 0:00 sleep 12
sleep 15
次のように背景をキャンセルすると:
$ kill 56
そして別のものを実行してくださいdocker ps
:
$ docker ps
...
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 24 0.0 0.1 11828 2964 pts/1 Ss 16:00 0:00 /bin/bash
root 60 0.0 0.1 51712 3344 pts/1 R+ 16:01 0:00 \_ ps auxf
root 1 0.0 0.1 11692 2572 pts/0 Ss+ 15:58 0:00 /bin/bash /tmp/
root 5 0.0 0.1 11696 2272 pts/0 S+ 15:58 0:00 /bin/bash /tmp/
root 59 0.0 0.0 4368 636 pts/0 S+ 16:01 0:00 \_ sleep 15
root 57 0.0 0.0 4368 664 pts/0 S+ 16:01 0:00 sleep 12
sleep 15
バックグラウンドプロセスを保護するwhileループがタスクを完了し、他のプロセスを再開したことがわかりますsleep 15
。