Étant donné que podman est installé sur un système linux et une unité systemd nommée 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
Et le baz.service a commencé:
# systemctl daemon-reload
# systemctl start baz.service
Ensuite, lorsque je vérifie l'état de l'unité, je ne vois pas le processus sh
ou sleep
dans le groupe de contrôle /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
# ...
Je m'attendais à voir le sh
et les sleep
enfants dans mon statut baz.service parce que j'ai entendu des gens de redhat dire que podman utilise un modèle traditionnel de fork-exec.
Si podman a fait fork et exec, alors mon processus sh
et ne seraient-ils pas des sleep
enfants de podman et seraient-ils dans le même groupe de contrôle que le processus podman d'origine?
Je m'attendais à pouvoir utiliser systemd et podman pour pouvoir gérer mes conteneurs sans que les enfants partent vers un parent différent et s'échappent de mon unité baz.service ssystemd.
En regardant la sortie de ps
je peux voir cela sh
et sleep
sont en fait des enfants d'un processus différent appelé conmon
. Je ne sais pas d'où vient Conmon, ni comment il a été démarré, mais SystemD ne l'a pas capturé.
# ps -Heo user,pid,ppid,comm
# ...
root 17254 1 podman
root 17331 1 conmon
root 17345 17331 sh
root 17380 17345 sleep
D'après la sortie, il est clair que mon unité baz.service ne gère pas la chaîne conmon -> sh -> sleep.
- En quoi podman est-il différent du modèle de serveur client docker?
- En quoi le conmon de podman est-il différent du containerd de docker?
Peut-être sont-ils tous deux des runtimes de conteneurs et le dockerd
démon est ce dont les gens veulent se débarrasser.
Alors peut-être que docker est comme:
- démon dockerd
- docker cli
- exécution du conteneur containerd
Et podman est comme:
- podman cli
- exécution du conteneur conmon
Donc peut-être que podman utilise un modèle traditionnel de fork fork, mais ce n'est pas le podman cli qui forge et exécute, c'est le processus conmon.
Je suis confus.
la source
Réponses:
L'idée derrière
podman
est de s'éloigner de l'architecture centralisée avec le superviseur super puissant (par exempledockerd
), où le démon centralisé est un point de défaillance unique. Il y a même un hashtag à ce sujet - " #nobigfatdaemons ".Comment éviter la gestion centralisée des conteneurs? Vous supprimez le démon principal unique (à nouveau
dockerd
) et démarrez les conteneurs indépendamment (à la fin de la journée, les conteneurs ne sont que des processus, vous n'avez donc pas besoin du démon pour les générer).Cependant, vous avez toujours besoin du moyen de
stdout
etstderr
du conteneur;wait(2)
utiliser le PID 1 du conteneur;A cet effet, chaque conteneur podman est toujours supervisé par un petit démon, appelé
conmon
(depuis "container monitor"). La différence avec le démon Docker est que ce démon est aussi petit que possible (vérifiez la taille du code source ), et il est généré par conteneur. Siconmon
un conteneur tombe en panne, le reste du système reste inchangé.Ensuite, comment le conteneur est généré?
Étant donné que l'utilisateur peut vouloir exécuter le conteneur en arrière-plan, comme avec Docker, le
podman run
processus se déroule deux fois et n'exécute ensuite queconmon
:Le processus intermédiaire entre
podman run
etconmon
(c'est-à-dire le parent direct deconmon
- dans l'exemple ci-dessus c'est le PID 8484) se terminera etconmon
sera réparé parinit
, devenant ainsi un démon autogéré. Après cela,conmon
bifurque également le runtime (par exemplerunc
) et, enfin, le runtime exécute le point d'entrée du conteneur (par exemple/bin/sh
).Lorsque le conteneur est en cours d'exécution,
podman run
n'est plus requis et peut se fermer, mais dans votre cas, il reste en ligne, car vous ne lui avez pas demandé de se détacher du conteneur.Ensuite,
podman
utilise des groupes de contrôle pour limiter les conteneurs. Cela signifie qu'il crée de nouveaux groupes de contrôle pour de nouveaux conteneurs et y déplace les processus . Selon les règles des cgroups, le processus peut être membre d'un seul cgroup à la fois, et l'ajout du processus à certains cgroup le supprime des autres cgroup (où il était précédemment) dans la même hiérarchie. Ainsi, lorsque le conteneur est démarré, la disposition finale des cgroups ressemble à ceci:podman run
reste dans les cgroups debaz.service
, créé parsystemd
, leconmon
processus est placé dans ses propres cgroups et les processus conteneurisés sont placés dans leurs propres cgroups:Remarque: le PID 13075 ci-dessus est en fait un
sleep 1
processus, né après la mort du PID 13043.J'espère que cela t'aides.
la source
stdout
/stderr
streams - à nouveau,podman
possède le conteneur et capture les flux du processus conteneurisé.systemd
est propriétaire du service et capture les flux du processus principal du service (dans votre cas,systemd
capturestdout
/stderr
dupodman run
processus). Cela fonctionne exactement comme il devrait fonctionner, carconmon
capture les flux du conteneur, s'ypodman run
attacheconmon
,systemd
capture les flux depodman run
, donc, finalement, tous les journaux du conteneur sont capturés parsystemd
, et vous les voyez danssystemctl status baz.service
.