Der angegebene Podman ist auf einem Linux-System und einer Systemd-Einheit namens baz.service installiert:
# /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
Und der baz.service hat begonnen:
# systemctl daemon-reload
# systemctl start baz.service
Wenn ich dann den Status des Geräts überprüfe, wird der Prozess sh
oder sleep
in der Gruppe /system.slice/baz.service nicht angezeigt
# 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
# ...
Ich hatte erwartet, die sh
und sleep
Kinder in meinem baz.service-Status zu sehen, weil ich von Redhat gehört habe, dass Podman ein traditionelles Fork-Exec-Modell verwendet.
Wenn Podman Fork und Exec gemacht hätte, wären meine sh
und sleep
Process dann nicht Kinder von Podman und würden in derselben Gruppe wie der ursprüngliche Podman-Prozess sein?
Ich hatte erwartet, systemd und podman verwenden zu können, um meine Container verwalten zu können, ohne dass die Kinder zu einem anderen Elternteil gehen und aus meiner baz.service ssystemd-Einheit entkommen.
Wenn ps
ich mir die Ausgabe von ansehe, kann ich das sehen sh
und bin sleep
tatsächlich Kinder eines anderen Prozesses namens conmon
. Ich bin nicht sicher, woher conmon kam oder wie es gestartet wurde, aber systemd hat es nicht erfasst.
# ps -Heo user,pid,ppid,comm
# ...
root 17254 1 podman
root 17331 1 conmon
root 17345 17331 sh
root 17380 17345 sleep
Aus der Ausgabe geht hervor, dass meine baz.service-Einheit die conmon -> sh -> Schlafkette nicht verwaltet.
- Wie unterscheidet sich podman vom Docker-Client-Server-Modell?
- Wie unterscheidet sich Podmans Conmon von Dockers Containerd?
Vielleicht sind sie beide Container-Laufzeiten und der dockerd
Daemon ist das, was die Leute loswerden wollen.
Vielleicht ist Docker wie folgt:
- Dockerd Daemon
- Docker Cli
- Containerd Container Laufzeit
Und Podman ist wie:
- podman cli
- Conmon Container Laufzeit
Vielleicht verwendet Podman ein traditionelles Fork-Exec-Modell, aber es ist nicht das Podman-Cli, das Forking und Exec ist, sondern der Conmon-Prozess.
Ich bin verwirrt.
quelle
Antworten:
Die ganze Idee dahinter
podman
ist, sich von der zentralisierten Architektur mit dem übermächtigen Aufseher (z. B.dockerd
) zu entfernen , bei dem der zentralisierte Dämon eine einzige Fehlerquelle darstellt. Es gibt sogar einen Hashtag dazu - " #nobigfatdaemons ".Wie vermeide ich das zentralisierte Containermanagement? Sie entfernen den einzelnen Hauptdämon (erneut
dockerd
) und starten die Container unabhängig voneinander (am Ende des Tages sind Container nur Prozesse, sodass Sie den Dämon nicht benötigen, um sie zu erzeugen).Sie brauchen jedoch noch den Weg zu
stdout
undstderr
des Behälters;wait(2)
die PID 1 des Containers eingeben ;Zu diesem Zweck wird jeder Podman-Container weiterhin von einem kleinen Daemon
conmon
überwacht , der (vom "Container-Monitor") aufgerufen wird . Der Unterschied zum Docker-Daemon besteht darin, dass dieser Daemon so klein wie möglich ist (überprüfen Sie die Größe des Quellcodes ) und pro Container erzeugt wird. Wennconmon
ein Container abstürzt, bleibt der Rest des Systems davon unberührt.Wie wird der Container als nächstes erzeugt?
In Anbetracht der Tatsache, dass der Benutzer den Container möglicherweise wie bei Docker im Hintergrund ausführen möchte, wird der
podman run
Prozess zweimal verzweigt und erst dann ausgeführtconmon
:Der mittlere Prozess zwischen
podman run
undconmon
(dh das direkte übergeordnete Element vonconmon
- im obigen Beispiel ist es PID 8484) wird beendet und vonconmon
repariertinit
, wodurch ein selbstverwalteter Dämon wird. Danach gibt esconmon
auch die Laufzeit ab (z. B.runc
) und schließlich führt die Laufzeit den Einstiegspunkt des Containers aus (z/bin/sh
. B. ).Wenn der Container ausgeführt wird,
podman run
ist er nicht mehr erforderlich und wird möglicherweise beendet. In Ihrem Fall bleibt er jedoch online, da Sie ihn nicht aufgefordert haben, sich vom Container zu lösen.Als nächstes werden
podman
cgroups verwendet, um die Container zu begrenzen. Dies bedeutet, dass neue Gruppen für neue Container erstellt und die Prozesse dorthin verschoben werden . Nach den Regeln von cgroups kann der Prozess jeweils nur Mitglied einer cgroup sein, und wenn Sie den Prozess zu einer cgroup hinzufügen, wird er aus einer anderen cgroup (wo er zuvor war) innerhalb derselben Hierarchie entfernt. Wenn der Container gestartet wird, sieht das endgültige Layout von cgroups wie folgt aus:podman run
Bleibt in cgroups vonbaz.service
, erstellt vonsystemd
, wird derconmon
Prozess in seinen eigenen cgroups platziert, und containerisierte Prozesse werden in ihren eigenen cgroups platziert:Hinweis: PID 13075 oben ist eigentlich ein
sleep 1
Prozess, der nach dem Tod von PID 13043 ausgelöst wurde.Hoffe das hilft.
quelle
stdout
/stderr
Streams -podman
besitzt wiederum den Container und erfasst die Streams des containerisierten Prozesses.systemd
besitzt den Dienst und erfasst die Streams des Hauptprozesses des Dienstes (in Ihrem Fallsystemd
tatsächlichstdout
/stderr
despodman run
Prozesses). Dies funktioniert genau so, wie es funktionieren sollte, daconmon
die Streams des Containers erfasst ,podman run
angehängtconmon
undsystemd
erfasst werdenpodman run
, sodass schließlich alle Protokolle des Containers erfasst werdensystemd
und Sie sie in sehensystemctl status baz.service
.