在 Docker 的後台測試無限循環?
我想在我的 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 上部署為多個 pod,並在
httpd
執行狀況檢查 URL 返回錯誤或超時時進行監控和自動重啟。我不想將隊列工作人員部署為單獨的 pod 或邊車容器,我想將其作為
httpd
容器中的後台程序執行,以便它httpd
與零配置共享應用程式碼。我對執行程序監視器或其他工具或技術來“保持活力”不感興趣。
我的問題是為什麼 Bash 循環會退出
kill
它正在執行的程序?
設置
我設置了以下內容
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
.