Dado que o podman está instalado em um sistema linux e uma unidade systemd chamada baz.service:
# /etc/systemd/system/baz.service
[Service]
ExecStart=/usr/bin/podman run --rm --tty --name baz alpine sh -c 'while true; do date; sleep 1; done'
ExecStop=/usr/bin/podman stop baz
E o baz.service começou:
# systemctl daemon-reload
# systemctl start baz.service
Então, quando eu verifico o status da unidade, não vejo o sh
ou sleep
processo no cgroup /system.slice/baz.service
# systemctl status baz
● baz.service
Loaded: loaded (/etc/systemd/system/baz.service; static; vendor preset: enabl
Active: active (running) since Sat 2019-08-10 05:50:18 UTC; 14s ago
Main PID: 16910 (podman)
Tasks: 9
Memory: 7.3M
CPU: 68ms
CGroup: /system.slice/baz.service
└─16910 /usr/bin/podman run --rm --tty --name baz alpine sh -c while
# ...
Eu esperava ver o sh
and sleep
children no meu status baz.service porque ouvi pessoas da redhat dizerem que o podman usa um modelo tradicional de fork-exec.
Se podman fizesse fork e exec, então my sh
e sleep
process não seriam filhos de podman e estariam no mesmo cgroup que o processo podman original?
Eu esperava poder usar o systemd e o podman para poder gerenciar meus contêineres sem que os filhos fossem para um pai diferente e escapassem da minha unidade ssystemd baz.service.
Olhando para a saída de ps
eu posso ver isso sh
e sleep
na verdade são filhos de um processo diferente chamado conmon
. Não tenho certeza de onde veio o conmon ou como foi iniciado, mas o systemd não o capturou.
# ps -Heo user,pid,ppid,comm
# ...
root 17254 1 podman
root 17331 1 conmon
root 17345 17331 sh
root 17380 17345 sleep
A partir da saída, fica claro que minha unidade baz.service não está gerenciando a cadeia conmon -> sh -> sleep.
- Como o podman é diferente do modelo de servidor cliente do docker?
- Como o conmon do podman é diferente do containerd do docker?
Talvez ambos sejam tempos de execução de contêiner e o dockerd
daemon seja o que as pessoas querem se livrar.
Então, talvez o docker seja como:
- daemon dockerd
- docker cli
- tempo de execução do contêiner containerd
E o podman é como:
- podman cli
- tempo de execução do contêiner comum
Então, talvez o podman use um modelo tradicional de fork exec, mas não é o podman cli que é bifurcação e exec, é o processo comum.
Eu me sinto confuso.
A ideia por trás disso
podman
é sair da arquitetura centralizada com o superpoderoso supervisor (por exemplodockerd
, ), onde o daemon centralizado é um ponto único de falha. Existe até uma hashtag sobre isso - " #nobigfatdaemons ".Como evitar o gerenciamento centralizado de contêineres? Você remove o daemon principal único (novamente,
dockerd
) e inicia os contêineres de forma independente (no final do dia, os contêineres são apenas processos, então você não precisa do daemon para gerá-los).No entanto, você ainda precisa do caminho para
stdout
estderr
do container;wait(2)
no PID 1 do container;Para isso, cada contêiner podman ainda é supervisionado por um pequeno daemon, chamado
conmon
(de "monitor de contêiner"). A diferença com o daemon do Docker é que esse daemon é o menor possível (verifique o tamanho do código-fonte ) e é gerado por contêiner. Seconmon
um contêiner travar, o restante do sistema não será afetado.Em seguida, como o contêiner é gerado?
Considerando que o usuário pode querer executar o container em background, como no Docker, o
podman run
processo bifurca duas vezes e só então executaconmon
:O processo intermediário entre
podman run
econmon
(ou seja, o pai direto deconmon
- no exemplo acima é o PID 8484) sairá econmon
será reparentado porinit
, tornando-se assim um daemon autogerenciado. Depois disso,conmon
também bifurca o runtime (egrunc
) e, finalmente, o runtime executa o entrypoint do container (eg/bin/sh
).Quando o container está rodando,
podman run
não é mais necessário e pode sair, mas no seu caso ele fica online, pois você não pediu para desanexar do container.Em seguida,
podman
faz uso de cgroups para limitar os contêineres. Isso significa que ele cria novos cgroups para novos contêineres e move os processos para lá . Pelas regras do cgroups, o processo pode ser membro de apenas um cgroup por vez, e adicionar o processo a algum cgroup o remove de outro cgroup (onde estava anteriormente) dentro da mesma hierarquia. Assim, quando o container é iniciado, o layout final dos cgroups se parece com o seguinte:podman run
permanece em cgroups dobaz.service
, criado porsystemd
, oconmon
processo é colocado em seus próprios cgroups, e os processos em container são colocados em seus próprios cgroups:Nota: O PID 13075 acima é na verdade um
sleep 1
processo, gerado após a morte do PID 13043.Espero que isto ajude.
podman com
--cgroups split
criará os cgroups de uma maneira mais amigável ao sistema. (Semelhante a como o systemd-nspawn faria isso, com um cgroup de "serviço" e sub-cgroups para processos de supervisor e contêiner)Exemplo - meu contêiner rwhod:
Eu fiz parte da adição desse método ao podman especificamente para esse propósito, como parte desta discussão de log. https://github.com/containers/podman/issues/6400