在 Docker 的后台测试无限循环?

sim*_*905 6 shell bash background-process docker

我想在我的 docker 镜像中运行一个后台队列:

\n\n
php artisan queue:work --daemon --sleep=1 --tries=3 &\n
Run Code Online (Sandbox Code Playgroud)\n\n

之后它立即启动httpd运行 PHPlaravel应用程序的 Apache。该laravel应用程序将推送通知发送到 Redis。后台队列工作程序从 Redis 收集消息并通过推送服务发送它们。

\n\n

这有效并且每秒都会注销。如果后台命令崩溃,我希望它重新启动。根据这个答案https://unix.stackexchange.com/a/223780/72040我可以在后台无限运行命令,如下所示:

\n\n
while true; do php $QUEUE_WORK; done &\n
Run Code Online (Sandbox Code Playgroud)\n\n

为了测试这一点,我运行了我的容器,docker run然后docker exec -it登录并查看:

\n\n
UID        PID  PPID  C STIME TTY          TIME CMD\n100000       1     0  0 19:55 ?        00:00:00 httpd -D FOREGROUND\n100000      21     1  0 19:55 ?        00:00:00 /bin/sh -e /tmp/scripts/run\n100000      22    21  1 19:55 ?        00:00:01 php artisan queue:work --sleep=1 --tries=3\n100000      43     1  0 19:55 ?        00:00:00 /usr/bin/cat\n100000      50     1  0 19:55 ?        00:00:00 /usr/bin/cat\n100000      51     1  0 19:55 ?        00:00:00 /usr/bin/cat\n100000      52     1  0 19:55 ?        00:00:00 /usr/bin/cat\n100000      53     1  0 19:55 ?        00:00:00 httpd -D FOREGROUND\n...\n100000     130     0  1 19:57 pts/0    00:00:00 /bin/bash\n100000     144   130  0 19:57 pts/0    00:00:00 ps -efww\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后我运行kill 22查看输出docker run

\n\n
/tmp/scripts/run: line 10:    22 Killed                  php $QUEUE_WORK\n
Run Code Online (Sandbox Code Playgroud)\n\n

循环不能保持进程的运行。我已经仔细检查循环是否是图像中运行的代码。如果我让循环运行 \xe2\x80\x9decho x: sleep 1\xe2\x80\x9d 它运行正常。

\n\n

当我杀死它时,为什么循环没有替换命令?

\n\n

注意:该应用程序在 Kubernetes 上部署为多个 Pod,并在运行httpd状况检查 URL 返回错误或超时时进行监控和自动重新启动。

\n\n

我不想将队列工作人员部署为单独的 pod 或 sidecar 容器,我想将其作为容器中的后台进程运行,httpd以便它以httpd零配置共享应用程序代码。

\n\n

我对运行进程监视器或其他工具或技术来保持 \xe2\x80\x9d 保持活动\xe2\x80\x9d 不感兴趣。

\n\n

我的问题是为什么 Bash 循环会退出kill它正在运行的进程?

\n

slm*_*slm 5

设置

我设置了以下内容Dockerfile

$ more Dockerfile
From centos
ADD run.sh /tmp/run.sh
RUN chmod +x /tmp/run.sh
ENTRYPOINT ["/tmp/run.sh"]
Run Code Online (Sandbox Code Playgroud)

设置脚本,run.sh

$ cat run.sh
while true; do sleep 15 ; echo "background"; done &

while true; do sleep 12 ; echo "foreground"; done
Run Code Online (Sandbox Code Playgroud)

建造它:

$ 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
Run Code Online (Sandbox Code Playgroud)

例子

然后启动它:

$ docker run -dit sleeper
28c19c338e6e6177529cf989f42c7f14b17f1c705a61f5244d5350f0ab8f8364
Run Code Online (Sandbox Code Playgroud)

然后它重复运行并显示:

foreground 
background 
foreground 
background
Run Code Online (Sandbox Code Playgroud)

现在,当我观看它时,我可以看到它仍在运行,尽管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
Run Code Online (Sandbox Code Playgroud)

从上面我们可以看到这个容器已经启动超过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
Run Code Online (Sandbox Code Playgroud)

sleep 15现在,如果我们像这样取消背景:

$ kill 56
Run Code Online (Sandbox Code Playgroud)

并运行另一个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
Run Code Online (Sandbox Code Playgroud)

我们可以看到保护后台进程的 while 循环sleep 15已经完成了它的工作并重新启动了另一个sleep 15.