Você não forneceu seu Dockerfile
e não está claro como você envia o sinal SIGTERM
para o contêiner.
No entanto, aqui está o que eu criei na tentativa de reproduzir o seu problema:
Meu Dockerfile
:
FROM ubuntu
ADD ./entrypoint.sh /opt/entrypoint.sh
# Using the exec form here, so that the process is assigned PID 1.
ENTRYPOINT ["/opt/entrypoint.sh"]
Compilar o contêiner:
$ docker build -f Dockerfile -t test_image .
Não se esqueça de reconstruir seu contêiner sempre que alterar o script do ponto de entrada.
Executar contêiner com este comando:
$ docker run --rm -it --name test_trap test_image
Agora, vamos ver o que está acontecendo em cada corrida.
1) Com a linha trap
no seu script Bash
:
# The main process will receive SIGTERM, trap it and exit.
$ docker stop test_trap
# The main process will receive SIGTERM, trap it and exit.
$ docker kill -s=TERM test_trap
# The main process will receive SIGKILL and will be stopped immediately.
$ docker kill -s=KILL test_trap
2) Sem a linha trap
:
# The main process will receive SIGTERM which will be ignored.
# After a grace period (10s by default) it will receive SIGKILL and will be stopped.
$ docker stop test_trap
# The main process will receive SIGTERM which will be ignored.
# Container will continue running.
$ docker kill -s=TERM test_trap
# The main process will receive SIGKILL and will be stopped immediately.
$ docker kill -s=KILL test_trap
O motivo é que o kernel trata um processo com PID 1
especialmente e não mata o processo que recebe o sinal SIGTERM
(e também SIGINT
).
Mais informações sobre este assunto:
Any process can register its own handlers for TERM and use them to perform cleanup before exiting. If a process hasn't registered a custom signal handler, the kernel will normally fall back to the default behavior for a TERM signal: killing the process.
For PID 1, though, the kernel won't fall back to any default behavior when forwarding TERM. If your process hasn't registered its own handlers (which most processes don't), TERM will have no effect on the process.
Fonte - link
UPDATE
Ainda não posso comentar, por isso deixarei um comentário aqui. Este é o mesmo problema PID 1
. Com -d
e -td
o tratamento de sinais funciona conforme o esperado: TERM
é ignorado, pois o processo de ponto de entrada é atribuído a PID 1
, enquanto KILL
finaliza o processo. Se você adicionar a linha trap
, o sinal TERM
ficará preso nos dois casos. Se não estiver funcionando para você por qualquer motivo, você deve postar seu Dockerfile
, os comandos exatos que você executa e atualizar sua pergunta de acordo.