Testando um loop infinito em segundo plano no Docker?

2

Eu quero executar uma fila em segundo plano funcionando na imagem do meu docker:

php artisan queue:work --daemon --sleep=1 --tries=3 &

Imediatamente depois disso, ele inicia o Apache httpd executando um aplicativo PHP laravel . O aplicativo laravel envia notificações push para o Redis. O funcionário da fila em segundo plano coleta as mensagens do Redis e as envia por meio de um serviço push.

Isso funciona e sai a cada segundo. Caso o comando background falhe, eu gostaria que ele fosse reiniciado. De acordo com essa resposta link , posso executar um comando infinitamente em segundo plano com algo como:

while true; do php $QUEUE_WORK; done &

Para testar isso, executei meu contêiner com docker run , em seguida, fiz docker exec -it para fazer login e ver:

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

Eu então executo kill 22 ver a saída no docker run de:

/tmp/scripts/run: line 10:    22 Killed                  php $QUEUE_WORK

O loop não mantém o processo ativo. Eu verifiquei duas vezes que o loop é o código que está sendo executado na imagem. Se eu tiver o loop executando um “echo x: sleep 1”, tudo corre bem.

Por que o loop não substitui o comando quando eu o mato?

OBSERVAÇÃO: O aplicativo é implantado como vários pods no Kubernetes com monitoramento e reinicializações automáticas se a URL de verificação de integridade httpd retornar um erro ou tempo limite.

Eu não quero implantar os trabalhadores da fila como um pod separado ou como um contêiner sidecar Eu quero executá-lo como um processo em segundo plano no contêiner httpd para que ele compartilhe o código do aplicativo com httpd com zero config.

Não estou interessado em executar monitores de processo ou outras ferramentas ou tecnologias para "manter-se vivo".

Minha pergunta é por que o loop de Bash sai em kill do processo em execução?

    
por simbo1905 13.07.2018 / 22:15

1 resposta

2

Configuração

Eu configurei o seguinte Dockerfile :

$ more Dockerfile
From centos
ADD run.sh /tmp/run.sh
RUN chmod +x /tmp/run.sh
ENTRYPOINT ["/tmp/run.sh"]

Configurar um script, run.sh :

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

while true; do sleep 12 ; echo "foreground"; done

Construído:

$ 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

Exemplo

Então começou:

$ docker run -dit sleeper
28c19c338e6e6177529cf989f42c7f14b17f1c705a61f5244d5350f0ab8f8364

Em seguida, ele é executado repetidamente mostrando:

foreground 
background 
foreground 
background

Agora, quando eu assisto, posso ver que ele continua, apesar dos comandos sleep eventualmente "morrerem":

$ 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

De cima, podemos ver que esse contêiner ultrapassou 1 minuto. Veja como é a ps auxf do interior do contêiner:

$ 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

Agora, se matarmos o plano de fundo sleep 15 da seguinte forma:

$ kill 56

E execute outro 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

Podemos ver que o loop while que está guardando nosso background sleep 15 process fez o seu trabalho e reiniciou outro sleep 15 .

    
por 14.07.2018 / 08:30