Dado que o podman está instalado em um sistema Linux e em 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 verifico o status da unidade, não vejo o processo sh
nem sleep
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 as crianças sh
e sleep
no meu status baz.service porque ouvi pessoas de redhat dizer que podman usa um modelo tradicional de fork-exec.
Se o podman fez fork e exec, meu processo sh
e não sleep
seriam filhos do podman e estariam no mesmo cgroup do processo original do podman?
Eu esperava poder usar o systemd e o podman para gerenciar meus contêineres sem que os filhos fossem para um pai diferente e escapassem da minha unidade baz.service ssystemd.
Olhando para a saída de ps
, posso ver isso sh
e sleep
na verdade são filhos de um processo diferente chamado conmon
. Não sei de onde veio o conmon ou como ele 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 de sono conmon -> sh ->.
- Qual a diferença entre o podman e o modelo do servidor cliente docker?
- Como o conmon de podman é diferente do container de docker?
Talvez eles sejam ambos tempos de execução de contêiner e o dockerd
daemon é o que as pessoas querem se livrar.
Talvez o docker seja como:
- daemon dockerd
- docker cli
- tempo de execução do contêiner
E podman é como:
- podman cli
- tempo de execução do contêiner conmon
Então, talvez o podman use um modelo tradicional de exec fork, mas não seja o podman cli que é bifurcado e exec, é o processo de conmon.
Eu me sinto confuso.
fonte
Respostas:
A idéia por trás disso
podman
é afastar-se da arquitetura centralizada com o superintendente super poderoso (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, portanto você não precisa do daemon para gerá-los).No entanto, você ainda precisa do caminho para
stdout
estderr
do contêiner;wait(2)
o PID 1 do contêiner;Para esse propósito, cada contêiner do podman ainda é supervisionado por um pequeno daemon, chamado
conmon
(de "monitor de contêiner"). A diferença com o daemon do Docker é que ele é 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 contêiner em segundo plano, como no Docker, o
podman run
processo bifurca-se duas vezes e só então é executadoconmon
:O processo intermediário entre
podman run
econmon
(ou seja, o pai direto deconmon
- no exemplo acima, é PID 8484) será encerrado econmon
será reparadoinit
, tornando-se assim um daemon autogerenciado. Depois disso,conmon
também obtém o tempo de execução (por exemplorunc
) e, finalmente, o tempo de execução executa o ponto de entrada do contêiner (por exemplo/bin/sh
).Quando o contêiner está em execução,
podman run
não é mais necessário e pode sair, mas, no seu caso, permanece on-line, porque você não solicitou a desanexação do contêiner.Em seguida,
podman
utiliza 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 dos cgroups, o processo pode ser membro de apenas um cgroup de cada vez, e adicionar o processo a algum cgroup o remove de outro cgroup (onde estava anteriormente) dentro da mesma hierarquia. Portanto, quando o contêiner é iniciado, o layout final dos cgroups é semelhante ao seguinte:podman run
permanece em cgroups dobaz.service
, criado porsystemd
, oconmon
processo é colocado em seus próprios cgroups e os processos em contêineres são colocados em seus próprios cgroups:Nota: O PID 13075 acima é realmente um
sleep 1
processo, gerado após a morte do PID 13043.Espero que isto ajude.
fonte
stdout
/stderr
fluxos - novamente,podman
possui o contêiner e captura os fluxos do processo em contêiner.systemd
possui o serviço e captura os fluxos do processo principal do serviço (no seu caso,systemd
realmente capturastdout
/stderr
dopodman run
processo). Isso funciona exatamente como deveria funcionar, porqueconmon
captura os fluxos do contêiner,podman run
anexa aconmon
,systemd
captura os fluxos depodman run
modo que, finalmente, todos os logs do contêiner são capturadossystemd
e você os vêsystemctl status baz.service
.