Eu tenho o seguinte contêiner que criei usando o seguinte comando:
docker container create --name="my-service" ubuntu:latest sleep 120
Quando eu inicio docker container start my-service
este contêiner, ele é executado e sai após 120 segundos, tudo OK.
Agora, em um segundo experimento, inicio o contêiner e, enquanto ele é executado, executo:
docker exec -ti my-service /bin/bash
Pergunta
Após 120 segundos, o bash interativo termina, porque o próprio contêiner termina. Por que e qual é exatamente a lógica do mecanismo docker para fazer isso?
Cada contêiner tem sua própria hierarquia de processo e seu comando especificado é aquele que é executado como "PID 1" (o pai de toda a árvore do processo) dentro do contêiner. Sempre que o processo com PID 1 sai, todo o namespace do processo (e com ele, o contêiner) é destruído automaticamente pelo kernel ( não pelo mecanismo do Docker).
Em contêineres de sistema completo, o PID 1 seria o processo "init"; tê-lo encerrado é como o contêiner solicita que o sistema operacional host seja "desligado". Fora dos contêineres, o PID 1 não tem permissão para sair - se isso acontecer, o sistema travará deliberadamente (você terá um kernel panic), então o comportamento do contêiner é bastante semelhante a isso.
(Entre outras coisas, o que torna o PID 1 especial é que todos os processos que não têm mais um pai são automaticamente re-paternados sob o PID 1, portanto, ele sempre deve existir.)
Você pode experimentar namespaces PID usando ferramentas de baixo nível
unshare
ensenter
como equivalentes aproximados de seus dois comandos do Docker (você não precisa ter o Docker instalado). Você notará queps axf
dentro do namespace mostra 'sleep' como PID 1 e que sempre que ele sai, o resto do namespace é imediatamente eliminado.unshare --pid --fork --mount-proc sleep 120
nsenter --all --target=<pid_of_sleep> ps axf
,nsenter --all --target=<pid_of_sleep> /bin/bash