Dies ist der letzte Artikel in meiner kleinen Reihe, über meinen Ausflug ins Container-Land, zur Bereitstellung der Anwendung Kanboard.
Wie meine Reise ins Container-Land begonnen hat, kann in „Kanboard im Container…“ nachgelesen werden. Wie man einen Reverse-Proxy vor einem Pod betreibt sowie mit dem Thema Backup und Restore habe ich mich inzwischen ebenso beschäftigt. Letzteres habe ich zum Glück implementiert und getestet, bevor ich mit der Dokumentation Datenverlust erlitten habe. Damit die Anwendung nach einem Neustart automatisch startet und für ein bisschen Komfort, habe ich Systemd-Service-Units generiert. In diesem Teil geht es nun um die Aktualisierung dieser Umgebung.
Umgebung
Aktuell läuft Kanboard 1.2.18 auf einer RHEL 8 VM. Zur Ausführung sind folgende Werkzeuge und Container-Images beteiligt.
$ podman --version
podman version 2.2.1
$ podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
registry.redhat.io/rhel8/postgresql-96 latest 4ce7daa6dc1d 7 weeks ago 451 MB
docker.io/kanboard/kanboard v1.2.18 e7ee6403944b 3 months ago 58.6 MB
k8s.gcr.io/pause 3.2 80d28bedfe5d 14 months ago 688 kB
Um mir die Erstellung eines Pods und das Einhängen von Podman-Volumes zu erleichtern, nutze ich folgendes kleines Skript:
#!/bin/bash
podman run -d --pod new:kanboardpod --name kanboard --privileged -p 127.0.0.1:8080:80 -v kanboard_datadir:/var/www/app/data:Z -v kanboard_pluginsdir:/var/www/app/plugins:Z kanboard/kanboard:v1.2.18
podman run -d --pod kanboardpod --name pgsql_db -e POSTGRESQL_USER=<USERNAME> -e POSTGRESQL_PASSWORD=<Verrate ich nicht> -e POSTGRESQL_DATABASE=kanboard -v pgsql_dbdir:/var/lib/pgsql/data:Z rhel8/postgresql-96:1-107
Mein Pod und die drei dazugehörigen Container werden während der folgenden Schritte noch normal ausgeführt.
Die Container selbst sind dabei zustandslos. Die persistent zu speichernden Daten werden in Podman-Volumes im lokalen Dateisystem der VM abgelegt.
Vorgehensweise
Ich verzichte in diesem Fall bewusst auf podman-auto-update(1), da ich mir erstmal einen Überblick verschaffen möchte, was denn generell zu tun ist und wie die einzelnen Schritte aussehen können. Die grundsätzliche Reihenfolge für ein Update sieht dabei wie folgt aus:
- Aktuelle Container-Images aus einer Registry holen (
podman-pull(1)
) - Laufende Pod-Instanz stoppen und entfernen (
podman-pod(1)
) - Neue Pod-Instanz mit angepasstem Wrapper-Skript erstellen
- Systemd-Service-Units erneut generieren (
podman-generate-systemd(1)
) - Pod-Instanz stoppen
- Generierte Systemd-Service-Unit starten
An dieser Stelle möchte ich vorweg nehmen, dass es genau so einfach war, wie es sich anhört. Die neuen Container-Images habe ich mit folgenden Kommandos heruntergeladen.
$ podman pull docker.io/kanboard/kanboard:v1.2.19
Trying to pull docker.io/kanboard/kanboard:v1.2.19...
Getting image source signatures
Copying blob 0c2b98bb5f7e done
Copying blob ca3cd42a7c95 done
Copying blob e994ab432c32 done
Copying blob 7b30337f40d2 done
Copying blob f58d66ecc40b done
Copying config 2cb48121b7 done
Writing manifest to image destination
Storing signatures
2cb48121b7437ba15cd984472754b300395026c3e09e7c659b4f9b62e5b5b4dd
$ podman pull registry.redhat.io/rhel8/postgresql-96:1-127
Trying to pull registry.redhat.io/rhel8/postgresql-96:1-127...
Getting image source signatures
Copying blob 64607cc74f9c done
Copying blob 320ae7fa06a7 done
Copying blob 13897c84ca57 done
Copying blob b3b2bbe848df done
Copying config 9c6ab01c14 done
Writing manifest to image destination
Storing signatures
9c6ab01c14748f7ff79483759122cb28e0f2c8b0310e5c8d9b5af8383e91f163
$ podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/kanboard/kanboard v1.2.19 2cb48121b743 4 days ago 61.3 MB
registry.redhat.io/rhel8/postgresql-96 1-127 9c6ab01c1474 2 weeks ago 449 MB
registry.redhat.io/rhel8/postgresql-96 latest 4ce7daa6dc1d 7 weeks ago 451 MB
docker.io/kanboard/kanboard v1.2.18 e7ee6403944b 3 months ago 58.6 MB
k8s.gcr.io/pause 3.2 80d28bedfe5d 14 months ago 688 kB
Mit den folgenden Befehlen werden Informationen zum laufenden Pod angezeigt, der Service wird gestoppt und der Pod inkl. seiner Container entfernt.
$ podman pod ls
POD ID NAME STATUS CREATED INFRA ID # OF CONTAINERS
2f3aa7d07e6e kanboardpod Running 4 weeks ago 34e8479a2847 3
$ systemctl --user stop pod-kanboardpod.service
$ podman pod ls
POD ID NAME STATUS CREATED INFRA ID # OF CONTAINERS
2f3aa7d07e6e kanboardpod Exited 4 weeks ago 34e8479a2847 3
$ podman pod rm kanboardpod
2f3aa7d07e6eb7d4c3a0c9927dac222be52b8992f95929c12af8ce4afafd4eb1
In mein Wrapper-Skript (siehe Abschnitt Umgebung) trage ich die neuen Versionsnummern bei den entsprechenden Aufrufen ein:
#!/bin/bash
podman run -d --pod new:kanboardpod --name kanboard --privileged -p 127.0.0.1:8080:80 -v kanboard_datadir:/var/www/app/data:Z -v kanboard_pluginsdir:/var/www/app/plugins:Z kanboard/kanboard:v1.2.19
podman run -d --pod kanboardpod --name pgsql_db -e POSTGRESQL_USER=<USERNAME> -e POSTGRESQL_PASSWORD=<Verrate ich nicht> -e POSTGRESQL_DATABASE=kanboard -v pgsql_dbdir:/var/lib/pgsql/data:Z rhel8/postgresql-96:1-127
Nachdem das obige Wrapper-Skript ausgeführt wurde, prüfe ich, ob die neue Pod-Instanz läuft, erstelle die Service-Units und aktiviere diese:
$ podman pod ls
POD ID NAME STATUS CREATED INFRA ID # OF CONTAINERS
85273ee9bb82 kanboardpod Running About a minute ago 82f45a722dff 3
$ podman container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6becc68a9c20 registry.redhat.io/rhel8/postgresql-96:1-127 run-postgresql About a minute ago Up About a minute ago 127.0.0.1:8080->80/tcp pgsql_db
82f45a722dff k8s.gcr.io/pause:3.2 About a minute ago Up About a minute ago 127.0.0.1:8080->80/tcp 85273ee9bb82-infra
e72ca46110be docker.io/kanboard/kanboard:v1.2.19 About a minute ago Up About a minute ago 127.0.0.1:8080->80/tcp kanboard
$ podman generate systemd --files --name kanboardpod
/home/bob/pod-kanboardpod.service
/home/bob/container-kanboard.service
/home/bob/container-pgsql_db.service
$ mv *.service .config/systemd/user/
$ podman pod stop kanboardpod
85273ee9bb82e49e236ae37d9320fd95af1eb186d7d965d72b9e2a270ca5cedf
$ systemctl --user daemon-reload
$ systemctl --user start pod-kanboardpod.service
Fazit
Das war einfacher als gedacht. Oder anders formuliert, es hat tatsächlich so funktioniert, wie ich es erwartet habe.
Mein kleines Wochenend-Projekt skaliert sicher nicht gut und ist als Beispiel für Produktionsumgebungen vermutlich weniger geeignet. Doch um Software als rootless-Container auszuführen und in kleinem Umfang zu testen, scheint dieser Weg durchaus geeignet zu sein.
Vielleicht schiebe ich in Zukunft noch einen Artikel unter Verwendung von podman-auto-update(1) nach.
Pingback: Kanboard im Container… | My-IT-Brain
Pingback: Nextcloud im Container – Teil 1: Der Plan | My-IT-Brain