GNU/Linux >> LINUX-Kenntnisse >  >> Linux

So führen Sie Pods als systemd-Dienste mit Podman aus

Podman ist bekannt für seine nahtlose Integration in moderne Linux-Systeme, und die Unterstützung von systemd ist ein Eckpfeiler dieser Bemühungen. Linux verwendet üblicherweise das Systemd-Init-System, um lokale Dienste wie Webserver, Container-Engines, Netzwerk-Daemons und alle ihre gegenseitigen Abhängigkeiten zu verwalten. Die Erweiterung dieser traditionelleren Linux-Systemverwaltungspraktiken mit der modernen Welt der Container ist eine natürliche Entwicklung.

Es gibt zwei gängige Anwendungsfälle für die Kombination von systemd und Containern:

  • Systemd in einem Container ausführen
  • Systemd verwenden, um containerisierte Anwendungen auszuführen

Das erste Szenario ist das Ausführen von systemd innerhalb eines Containers. Wie Dan Walsh erklärt, ist das Ausführen von systemd in einem Container so einfach wie möglich, wenn Podman verwendet wird. Podman richtet automatisch mehrere Mounts im Container ein und systemd ist startklar. Obwohl es sich um ein vergleichsweise kleines Podman-Feature handelt, war es bei seiner Einführung ein großer Sprung für die Ausführung containerisierter Workloads.

In der Vergangenheit haben andere Container-Tools systemd nicht unterstützt. Benutzer standen vor der Herausforderung, benutzerdefinierte Init-Skripte zu schreiben, die fehleranfällig sind und eine Supportbelastung für Softwareanbieter darstellen. Mit Podman verschwinden all diese Probleme. Benutzer können systemd verwenden, um ihre Anwendungen in Containern zu installieren und auszuführen, genau wie anderswo, und Softwareanbieter werden nicht mit den Herausforderungen konfrontiert, mit benutzerdefinierten Init-Skripten umzugehen, die von ihren Benutzern geschrieben wurden.

Das zweite Szenario verwendet systemd zum Ausführen und Verwalten von containerisierten Anwendungen. Das bedeutet, dass systemd eine containerisierte Anwendung startet und ihren gesamten Lebenszyklus verwaltet. Podman vereinfacht dies mit dem podman generate systemd Befehl, der eine systemd-Unit-Datei für einen bestimmten Container oder Pod generiert. Podman v1.7 und höher unterstützen das Generieren solcher Einheiten. Im Laufe der Zeit hat unser Team diese Funktion verbessert und systemd-Unit-Dateien generiert, die auf anderen Computern ausgeführt werden können, ähnlich wie bei der Verwendung einer Kubernetes-YAML- oder einer Compose-Datei. Darüber hinaus legte die enge Integration mit systemd den Grundstein für automatische Updates und einfache Rollbacks, die seit Podman v3.4 unterstützt werden.

Während es viele frühere Blogs und Artikel zum Generieren von systemd-Einheiten für Container gibt, gibt es keine zum Generieren dieser Einheiten für Pods. Aber bevor ich auf diese Details eingehe, möchte ich noch einmal kurz erläutern, was ein Pod ist.

[ Erste Schritte mit Containern? Schauen Sie sich diesen kostenlosen Kurs an. Containerisierte Anwendungen bereitstellen:Eine technische Übersicht. ]

Was ist ein Pod?

Es gibt mehrere verschiedene Teile in einem Pod, und ich denke, Brent Baude erklärt es am besten mit der großartigen Abbildung unten:

Als Erstes fällt auf, dass ein Pod aus einem oder mehreren Containern besteht. Die Gruppe teilt sich Kontrollgruppen (cgroups) und bestimmte Namespaces wie den PID-, Netzwerk- und IPC-Namespace. Die gemeinsam genutzten Cgroups stellen sicher, dass alle Container die gleichen Ressourcenbeschränkungen haben. Die gemeinsam genutzten Namensräume ermöglichen es den Containern, einfacher miteinander zu kommunizieren (z. B. über localhost oder Kommunikation zwischen Prozessen).

Sie können auch einen speziellen Infra-Container sehen. Sein Hauptzweck besteht darin, bestimmte mit dem Pod verbundene Ressourcen wie Ports, Namespaces oder cgroups offen zu halten. Der Infra-Container ist der Top-Level-Container des Pods und wird vor anderen Containern erstellt und zuletzt zerstört. Sie verwenden den Infra-Container beim Generieren von systemd-Einheiten für einen Pod. Denken Sie also daran, dass dieser Container für die gesamte Lebensdauer des Pods ausgeführt wird. Es impliziert auch, dass Sie keine systemd-Einheiten für Pods ohne Infra-Container generieren können (z. B. --infra=false ).

Zu guter Letzt sehen Sie mehrere conmon laufende Prozesse, einer pro Container. „Common“ ist die Abkürzung für Container Monitor, was seine Hauptfunktionalität zusammenfasst. Es kümmert sich auch um die Weiterleitung von Protokollen und die Durchführung von Bereinigungsaktionen, sobald der Container beendet wurde. Der conmon Der Prozess beginnt vor dem Container und weist die zugrunde liegende Containerlaufzeit an (z. B. runc oder crun ), um den Container zu erstellen und zu starten. Es wird auch mit dem Exit-Code des Containers beendet, der es ermöglicht, ihn als Hauptprozess eines systemd-Dienstes zu verwenden.

Generieren von systemd-Einheiten für einen Pod

Podman erzeugt für einen Container genau eine Systemeinheit. Verwenden Sie nach der Installation systemctl um den Dienst zu starten, zu stoppen und zu überprüfen. Die Haupt-PID jeder Einheit ist der gemeinsame Prozess des Containers. Auf diese Weise kann systemd den Exit-Code des Containers lesen und gemäß der konfigurierten Neustartrichtlinie handeln. Weitere Einzelheiten zu den Einheiten finden Sie unter Container mit Podman und gemeinsam nutzbaren systemd-Diensten ausführen und verbesserter systemd-Podman mit Podman 2.0.

Das Generieren von Einheiten für einen Pod ist dem Starten eines Containers sehr ähnlich. Jeder Container im Pod hat eine dedizierte systemd-Einheit, und jede Einheit hängt von der Haupt-systemd-Einheit des Pods ab. Auf diese Weise können Sie systemctl weiterhin verwenden um den Hauptdienst des Pods zu starten, zu stoppen und zu inspizieren; systemd kümmert sich um das (Neu-)Starten und Stoppen der Dienste der Container zusammen mit dem Hauptdienst.

Dieses Beispiel erstellt einen Pod mit zwei Containern, generiert Unit-Dateien für den Pod und installiert dann die Dateien für den aktuellen Benutzer:

$ podman pod create --name=my-pod
635bcc5bb5aa0a45af4c2f5a508ebd6a02b93e69324197a06d02a12873b6d1f7

$ podman create --pod=my-pod --name=container-a -t centos top
c04be9c4ac1c93473499571f3c2ad74deb3e0c14f4f00e89c7be3643368daf0e

$ podman create --pod=my-pod --name=container-b -t centos top
b42314b2deff99f5877e76058ac315b97cfb8dc40ed02f9b1b87f21a0cf2fbff

$ cd $HOME/.config/systemd/user

$ podman generate systemd --new --files --name my-pod
/home/vrothberg/.config/systemd/user/pod-my-pod.service
/home/vrothberg/.config/systemd/user/container-container-b.service
/home/vrothberg/.config/systemd/user/container-container-a.service

Wie erwartet hat Podman drei .service generiert Dateien, eine für jeden Container plus die oberste Ebene für den Pod. Den gesamten Inhalt der Unit-Dateien finden Sie im Anhang am Ende des Artikels. Die für die beiden Container generierten Units sehen aus wie Standard-Container-Units plus die folgenden systemd-Abhängigkeiten:

  • BindsTo=pod-my-pod.service :Die Containereinheit ist an die Einheit des Pods "gebunden". Wenn die Einheit des Pods gestoppt wird, wird diese Einheit ebenfalls gestoppt.
  • After=pod-my-pod.service :Die Containereinheit beginnt nach der Einheit des Pods.

Die Abhängigkeiten des Hauptdienstes des Pods stellen außerdem sicher, dass die Haupteinheit des Haupt-Pods ebenfalls fehlschlägt, wenn eine Containereinheit nicht erfolgreich gestartet wird.

Das ist alles, was Sie über das Generieren von systemd-Einheiten für Pods mit Podman wissen müssen. Sobald Sie systemd über systemctl --user daemon-reload neu geladen haben , starten und stoppen Sie den pod.service nach Belieben. Schau mal:

# Reload the daemon
$ systemctl --user daemon-reload

# Start the pod service and make sure the service is running
$ systemctl --user start pod-my-pod.service

$ systemctl --user is-active pod-my-pod.service
active

# Make sure the pod and its containers are running
$ podman pod ps
POD ID    	NAME    	STATUS  	CREATED    	INFRA ID  	# OF CONTAINERS
6dd1090d4ca6  my-pod  	Running 	2 minutes ago  85f760a5cfe5  3
user $ podman container ps
CONTAINER ID  IMAGE                                	COMMAND 	CREATED    	STATUS        	PORTS   	NAMES
85f760a5cfe5  localhost/podman-pause:4.0.2-1646319369          	5 minutes ago  Up 5 minutes ago          	6dd1090d4ca6-infra
44a7e60b9563  quay.io/centos/centos:latest         	top     	5 minutes ago  Up 5 minutes ago          	container-b
31f24bdff747  quay.io/centos/centos:latest         	top     	5 minutes ago  Up 5 minutes ago          	container-a

Super, alles funktioniert wie erwartet. Sie können systemctl verwenden um die Dienste zu starten, und Podman listet die Pods und ihre Container korrekt auf. Sehen Sie sich der Einheitlichkeit halber abschließend an, wie Sie den Pod-Dienst stoppen können.

# Stop the pod service
$ systemctl --user stop pod-my-pod.service

# Make sure the pod and its containers are removed
$ podman pod ps -q

$ podman container ps -q

# Make sure the services are inactive
$ systemctl --user is-active pod-my-pod.service container-container-a.service container-container-b.service
inactive
inactive
inactive

Die Take-Home-Message lautet, dass Podman systemd-Einheiten für Pods genauso generiert wie für Container. Die Abhängigkeiten zwischen diesen Units sind so eingestellt, dass Sie nur mit der Haupt-Unit des Pods interagieren müssen, und systemd kümmert sich um das Starten und Stoppen der Container-Units.

Anhang

Podman generiert die folgenden Unit-Dateien für einen Pod und die beiden zugehörigen Container.

pod-my-pod.service

Description=Podman pod-my-pod.service
Documentation=man:podman-generate-systemd(1)
Wants=network-online.target
After=network-online.target
RequiresMountsFor=
Requires=container-container-a.service container-container-b.service
Before=container-container-a.service container-container-b.service

[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=on-failure
TimeoutStopSec=70
ExecStartPre=/bin/rm -f %t/pod-my-pod.pid %t/pod-my-pod.pod-id
ExecStartPre=/usr/bin/podman pod create --infra-conmon-pidfile %t/pod-my-pod.pid --pod-id-file %t/pod-my-pod.pod-id --name=my-pod --replace
ExecStart=/usr/bin/podman pod start --pod-id-file %t/pod-my-pod.pod-id
ExecStop=/usr/bin/podman pod stop --ignore --pod-id-file %t/pod-my-pod.pod-id -t 10
ExecStopPost=/usr/bin/podman pod rm --ignore -f --pod-id-file %t/pod-my-pod.pod-id
PIDFile=%t/pod-my-pod.pid
Type=forking

[Install]
WantedBy=default.target

container-container-a.service

[Unit]
Description=Podman container-container-a.service
Documentation=man:podman-generate-systemd(1)
Wants=network-online.target
After=network-online.target
RequiresMountsFor=%t/containers
BindsTo=pod-my-pod.service
After=pod-my-pod.service

[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=on-failure
TimeoutStopSec=70
ExecStartPre=/bin/rm -f %t/%n.ctr-id
ExecStart=/usr/bin/podman run --cidfile=%t/%n.ctr-id --cgroups=no-conmon --rm --pod-id-file %t/pod-my-pod.pod-id --sdnotify=conmon -d --replace --name=container-a -t centos top
ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id
ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id
Type=notify
NotifyAccess=all

[Install]
WantedBy=default.target

container-container-b.service

[Unit]
Description=Podman container-container-b.service
Documentation=man:podman-generate-systemd(1)
Wants=network-online.target
After=network-online.target
RequiresMountsFor=%t/containers
BindsTo=pod-my-pod.service
After=pod-my-pod.service

[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=on-failure
TimeoutStopSec=70
ExecStartPre=/bin/rm -f %t/%n.ctr-id
ExecStart=/usr/bin/podman run --cidfile=%t/%n.ctr-id --cgroups=no-conmon --rm --pod-id-file %t/pod-my-pod.pod-id --sdnotify=conmon -d --replace --name=container-b -t centos top
ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id
ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id
Type=notify
NotifyAccess=all

[Install]
WantedBy=default.target


Linux
  1. So verwalten Sie Systemd-Dienste mit Systemctl unter Linux

  2. So verwenden Sie Podman in einem Container

  3. Linux – Wie führe ich ein Skript mit Systemd direkt vor dem Herunterfahren aus?

  4. Wie führe ich einen Befehl in einem laufenden Systemd-Container aus?

  5. So führen Sie MySQL in einem Docker-Container aus

So führen Sie Podman unter Windows aus

Ausführen von Almalinux oder Rocky Linux 8 Docker-Container mit Systemd (systemctl)

So führen Sie PHPMyAdmin in einem Docker-Container aus

So führen Sie Grafana in einem Docker-Container aus

So führen Sie Docker-Container aus

So führen Sie einen Alias ​​mit Sudo in Linux aus