Website-Suche

So führen Sie Podman-Container unter Systemd mit Quadlet aus


Quadlet ist ein kostenloses und in C geschriebenes Open-Source-Tool, mit dem wir Podman-Container unter Systemd erstellen und ausführen können. Mit dem Tool können wir Container, Volumes, Netzwerke und ihre Beziehungen mithilfe dedizierter Systemd-Einheiten deklarieren.

In diesem Tutorial erfahren Sie, wie Sie mit Quadlet Podman-Container, Netzwerke und Volumes erstellen und wie Sie Multi-Container-Stacks erstellen.

In diesem Tutorial lernen Sie:

  • So erstellen Sie Container, Volumes und Netzwerke mit den entsprechenden Systemd-Einheiten
  • So erstellen Sie mit Quadlet einen Stapel mit mehreren Containern

Ein einfaches Beispiel: Erstellen eines MariaDB-Containers

In diesem ersten, einfachen Beispiel definieren wir eine Einheit für einen MariaDB-Datenbankserver. So sieht es aus:

[Unit]
Description=MariaDB container

[Container]
Image=docker.io/mariadb:latest
Environment=MYSQL_ROOT_PASSWORD=rootpassword
Environment=MYSQL_USER=testuser
Environment=MYSQL_PASSWORD=testpassword
Environment=MYSQL_DATABASE=testdb

[Install]
WantedBy=multi-user.target

Mit diesen wenigen Zeilen haben wir einen Container definiert, der auf dem neuesten offiziellen MariaDB-Image basiert, das auf Dockerhub verfügbar ist. Wie Sie sehen können, ist ein „.container“ ein dedizierter Typ einer Systemd-Einheit. Das Besondere an diesem Einheitentyp ist der Abschnitt „Container“, in dem wir Optionen angeben können, die denen entsprechen, die wir an die Podman-Befehlszeile übergeben können. Die einzige erforderliche Option im Abschnitt „Container“ ist Image, um das Basisbild für den Container anzugeben.

Wenn wir möchten, dass der Container als Root ausgeführt wird, speichern wir die Datei im Verzeichnis /etc/containers/systemd; Um es als unseren eigenen unprivilegierten Benutzer auszuführen, speichern wir es stattdessen unter ~/.config/containers/systemd. In diesem Beispiel verwenden wir den letzteren Ansatz und speichern unsere „.container“-Einheit als ~/.config/containers/systemd/mariadb-service.container. Damit systemd einen Dienst basierend auf der Containereinheit generieren kann, führen wir den folgenden Befehl aus:

$ systemctl --user daemon-reload

Nachdem wir den Befehl ausgeführt haben, können wir uns den generierten Dienst ansehen, indem wir Folgendes ausführen:

$ systemctl --user cat mariadb-service

Um den Container zu starten, können wir wie jeden anderen Dienst Folgendes ausführen:

$ systemctl --user start mariadb-service

Beim ersten Start kann es eine Weile dauern, bis der Dienst startet, wenn das Container-Basisimage nicht auf unserem System vorhanden ist. Wir können die Podman-Befehlszeile verwenden, um den Status des Containers zu überprüfen:

$ podman ps

Der Befehl gibt die folgende Ausgabe zurück, die bestätigt, dass der Container betriebsbereit ist:

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
151226b10a1c docker.io/library/mariadb:latest mariadbd 59 seconds ago Up About a minute systemd-mariadb-service

Wie Sie vielleicht bemerkt haben, wird der Container standardmäßig nach der Unit-Datei „.container“ plus dem Präfix „systemd-“ (in diesem Fall „systemd-mariadb-service“) benannt. Um dem Container explizit einen Namen zuzuweisen, können wir ihn jedoch als Wert der Option ContainerName im Abschnitt „[Container]“ übergeben.

Erstellen einer „Volumen“-Einheit

Wir verwenden Volumes, um Containerdaten beizubehalten. In diesem Fall möchten wir, dass unsere Datenbankdaten auch dann bestehen bleiben, wenn wir den systemd-mariadb-service-Container löschen. Wir definieren ein benanntes Volume in der entsprechenden Einheit „.volume“. Im folgenden Beispiel geben wir nur eine Beschreibung für das Volume an. Volumespezifische Optionen können unter der Zeilengruppe [Volume] angegeben werden:

[Unit]
Description=MariaDB Volume

[Volume]

Wir speichern die Einheit als ~/.config/containers/systemd/mariadb-volume.volume. Um den MariaDB-Container anzuweisen, das Volume zu verwenden, verwenden wir die Option Volume im Abschnitt [Container] der Einheit „.container“ und ordnen das Volume dem zu Verzeichnis /var/lib/mysql im Container:

[Unit]
Description=MariaDB container

[Container]
Image=docker.io/mariadb:latest
Environment=MYSQL_ROOT_PASSWORD=rootpassword
Environment=MYSQL_USER=testuser
Environment=MYSQL_PASSWORD=testpassword
Environment=MYSQL_DATABASE=testdb
Volume=mariadb-volume.volume:/var/lib/mysql

[Install]
WantedBy=multi-user.target

Wenn wir ein benanntes Volume verwenden, weist Systemd ihm in der Serviceeinheit, die es für unseren Container generiert, automatisch eine Abhängigkeit zu. Damit systemd die erforderlichen Dienste noch einmal neu generieren kann, verwenden wir den Befehl daemon-reload. Sobald wir den MariaDB-Container (neu) starten, wird das Volume automatisch erstellt, wie wir mithilfe des Befehlszeilenprogramms podman überprüfen können:

$ podman volume ls

Wie erwartet erscheint unser Volume in der durch den Befehl generierten Liste:

DRIVER        VOLUME NAME
local         systemd-mariadb-volume

Wir können auch überprüfen, ob das Volume auf /var/lib/mysql im Container gemountet ist, indem wir den Befehl podman inspect verwenden, den Namen des Containers als Argument übergeben und einen Blick auf die „Mounts“ werfen. Abschnitt:

$ podman inspect systemd-mariadb-service

Hier ist der relevante Abschnitt der Ausgabe:

"Mounts": [
     {
         "Type": "volume",
         "Name": "systemd-mariadb-volume",
         "Source": "/home/doc/.local/share/containers/storage/volumes/systemd-mariadb-volume/_data",
         "Destination": "/var/lib/mysql",
         "Driver": "local",
         "Mode": "",
         "Options": [
              "nosuid",
              "nodev",
              "rbind"
         ],
         "RW": true,
         "Propagation": "rprivate"
     }
],

Verwendung von Bind-Mounts

Was ist, wenn wir Bind-Mounts anstelle benannter Volumes verwenden möchten? Bind-Mounts sind während der Entwicklung nützlich, da wir damit Hostdateien innerhalb des Containers mounten können. Der Nachteil der Verwendung von Bind-Mounts besteht darin, dass Container vom Host-Dateisystem abhängig werden. Um einen Bind-Mount innerhalb einer „.container“-Einheit zu verwenden, geben wir einfach den relativen oder absoluten Pfad der Hostdatei an, die wir mounten möchten. Angenommen, wir möchten beispielsweise das Verzeichnis /var/lib/mysql innerhalb des Containers an das Verzeichnis ~/mysql auf dem Host binden. Folgendes könnten wir in die Einheit „.container“ schreiben:

[Unit]
Description=MariaDB container

[Container]
Image=docker.io/mariadb:latest
Environment=MYSQL_ROOT_PASSWORD=rootpassword
Environment=MYSQL_USER=testuser
Environment=MYSQL_PASSWORD=testpassword
Environment=MYSQL_DATABASE=testdb
Volume=%h/mysql:/var/lib/mysql

[Install]
WantedBy=multi-user.target

Im obigen Beispiel sehen Sie, dass wir den Platzhalter %h verwendet haben, der von Systemd automatisch auf den absoluten Pfad unseres eigenen HOME-Verzeichnisses erweitert wird. Es ist auch möglich, relative Pfade zu verwenden, die relativ zur Position der Unit-Datei aufgelöst werden.

Netzwerke schaffen

Um einen Stapel aus mehreren Containern zu erstellen, müssen wir, ähnlich wie bei Docker-Compose, Container in dasselbe Netzwerk stellen, damit sie miteinander kommunizieren können. Um mit Quadlet ein Netzwerk zu erstellen, können wir Einheiten mit der Erweiterung „.network“ verwenden.

Wie bei Containern und Volumes werden Netzwerke standardmäßig nach der Unit-Datei benannt, in der sie definiert sind, plus dem Präfix „systemd-“. Wir können im Abschnitt [Netzwerk] der Datei explizit einen Namen oder eine andere netzwerkspezifische Option angeben. Im folgenden Beispiel geben wir das Subnetz und die Gateway-Adresse für das Netzwerk an (dies entspricht der Ausführung von podman mit --subnet 192.168.30.0/24 und --gateway 192.168.30.1). Optionen):

[Unit]
Description=MariaDB Network

[Network]
Subnet=192.168.30.0/24
Gateway=192.168.30.1

Wir speichern die Datei als ~/.config/containers/systemd/mariadb.network. Um einen Container in ein bestimmtes Netzwerk zu „platzieren“, verwenden wir die Option Netzwerk im Abschnitt „Container“ seiner Containereinheit. Der zuvor definierte MariaDB-Container wird zu:

[Unit]
Description=MariaDB container

[Container]
Image=docker.io/mariadb:latest
Environment=MYSQL_ROOT_PASSWORD=rootpassword
Environment=MYSQL_USER=testuser
Environment=MYSQL_PASSWORD=testpassword
Environment=MYSQL_DATABASE=testdb
Volume=mariadb-volume.volume:/var/lib/mysql
Network=mariadb.network

Erstellen eines Stapels mit mehreren Containern

Wir haben einen Container, auf dem unser MariaDB-Server läuft. Um eine einfache Möglichkeit zur Verwaltung unserer Datenbank über eine Weboberfläche hinzuzufügen, können wir einen Container basierend auf phpMyAdmin erstellen. Damit die beiden Container miteinander kommunizieren können, müssen wir sie in dasselbe Netzwerk einbinden.

Da der phpMyAdmin-Container, um ordnungsgemäß zu funktionieren, erfordert, dass der MariaDB-Server aktiv ist und läuft, können wir diese Abhängigkeit wie für jeden anderen Systemd-Dienst mit Requires und deklarieren Nach-Optionen im Abschnitt „[Einheit]“. Ersteres stellt eine feste Abhängigkeit von dem als Wert übergebenen Dienst her; Letzteres stellt sicher, dass unser Service danach beginnt. Wenn Sie mit Systemd nicht vertraut sind, können Sie sich übrigens unser Tutorial zum Erstellen eines Systemd-Dienstes ansehen. So sieht die Containereinheit für phpMyAdmin aus:

[Unit]
Description=phpMyAdmin container
Requires=mariadb-service.service
After=mariadb-service.service
 
[Container]
Image=docker.io/phpmyadmin:latest
Network=mariadb.network
Environment=PMA_HOST=systemd-mariadb-service
PublishPort=8080:80

[Install]
WantedBy=multi-user.target

Im obigen Beispiel haben wir auch die Option PublishPort verwendet, die dem podman -p (--publish) entspricht: Sie wird verwendet um einen Host-Port einem Container-Port zuzuordnen. In diesem Fall haben wir Port 8080 auf dem Hostsystem dem Port 80 innerhalb des Containers zugeordnet.

Wir haben auch einen Wert für die Umgebungsvariable PMA_HOST über die Option Environment bereitgestellt: Dieser wird verwendet, um die Adresse des Datenbankservers anzugeben (in diesem Fall haben wir den MariaDB-Containernamen verwendet, der in aufgelöst wird). tatsächliche Adresse). Beachten Sie, dass wir den Namen des MariaDB-Containers als Wert der Umgebungsvariablen verwendet haben, nicht den Namen der „.container“-Einheit. Um unser neues Setup noch einmal zu starten, führen wir Folgendes aus:

$ systemd --user daemon-reload

Anschließend können wir den generierten Dienst „phpmyadmin-service“ starten, der wiederum den phpMyAdmin-Container ausführt. Da eine starke Abhängigkeit von MariaDB besteht, wird letztere automatisch ebenfalls gestartet. Wir sollten phpMyadmin unter der Adresse „localhost:8080“ erreichen können. Zum Anmelden können wir die in der MariaDB-Containereinheit angegebenen Anmeldeinformationen verwenden:

Abschließende Gedanken

In diesem Tutorial haben wir gelernt, wie man mit Quadlet Podman-Container, Volumes und Netzwerke unter Systemd erstellt und ausführt. Anstatt Multi-Container-Stacks in einer einzigen Datei zu definieren, wie wir es bei der Verwendung von Docker-Compose tun, definieren wir mit Quadlet Container, Volumes und Netzwerke mithilfe dedizierter Systemd-Einheiten.

Verwandte Artikel: