Container-Workflows bestehen aus vielen kleinen Schritten – besonders wenn Images aus einer Backup- oder Build-Strecke geliefert werden und vorbereitet in eine Registry wandern sollen. Manuell ist das fehleranfällig und lästig. Umso schöner, wenn sich der Prozess mit einem einfachen Bash-Skript automatisieren lässt.
Hier ein kleiner Helfer aus dem Werkzeugkasten: Ein Skript, das aus einem Verzeichnis heraus Container-Images im .tar.gz
-Format entpackt, importiert, auf Basis des Dateinamens taggt – und optional auch gleich in eine Registry pusht.
.tar.gz
-Container-Backupsimagename_tag.hash.tar.gz
podman
mit eigenem Storage-Verzeichnis zum ImportierenEin wichtiger Aspekt: Das Skript basiert auf einem regulären Ausdruck zur Trennung von Image-Namen und Tags aus dem Dateinamen. Beispiel:
nginx_1.21.6.abc1234.tar.gz
wird zu:
nginx
1.21.6
Damit das funktioniert, muss der Dateiname dem Muster folgen: name_tag.hash.tar(.gz)
#!/bin/bash
set -e
REGISTRY=""
IMAGE_DIR=""
export TMP_DIR="$IMAGE_DIR/TEMP"
STORAGE_DIR="$IMAGE_DIR/storage"
mkdir -p "$TMP_DIR" "$STORAGE_DIR"
cd "$IMAGE_DIR"
# Entpacke alle .tar.gz-Dateien mit gunzip
if ls *.tar.gz 1> /dev/null 2>&1; then
for archive in *.tar.gz; do
gunzip "$archive"
done
else
echo "Keine .tar.gz-Dateien gefunden."
fi
# Importiere, tagge und pushe jedes Image
for tarfile in "$IMAGE_DIR"/*.tar; do
filename=$(basename "$tarfile" .tar)
if [[ $filename =~ ^([a-zA-Z0-9\-]+)_([0-9a-zA-Z._\-]+)\.[a-z0-9]{7,}$ ]]; then
name="${BASH_REMATCH[1]}"
tag="${BASH_REMATCH[2]}"
echo "Image-Name: $name"
echo "Tag: $tag"
else
echo "Dateiname $filename entspricht nicht dem erwarteten Muster"
continue
fi
image_local="${name}:${tag}"
echo $image_local
image_remote="${REGISTRY}/${image_local}"
echo $image_remote
image_id=$(podman --root "$STORAGE_DIR" load -i "$tarfile" 2>&1 | awk '/^Copying config / { print $3 }')
echo $image_id
podman --root "$STORAGE_DIR" tag "$image_id" "$image_remote"
podman --root "$STORAGE_DIR" push "$image_remote"
done
Manchmal braucht’s kein großes Servicemesh mit fancy features, keine fancy Sidecars und kein full-blown Istio, linkerd, consul oder so.
Manchmal reicht einfach nur stunnel – das gute alte Schweizer Taschenmesser für TLS-Tunnel.
Ein "Servicemesh des kleinen Mannes" eben. Einfach, stabil, unauffällig.
Wenn Services im internen Netz unverschlüsselt sprechen, aber man Transportverschlüsselung für eine ertifizierung braucht (und es eigentlich ohne nicht mehr Zeitgemäß ist – ohne alles neu zu erfinden –, dann hilft ein einfacher Trick:
Loopback + stunnel = TLS
Die Idee:
localhost
, denkt also, alles ist wie immer. stunnel
nimmt die Daten entgegen und tunnelt sie verschlüsselt zum Gegenüber. stunnel
, das den Datenstrom an den echten Dienst weitergibt.app1:supergeheimespasswort
lient = yes
foreground = no
[backend-tls]
accept = 127.0.0.1:23904
connect = backend.internal:23904
PSKsecrets = /etc/stunnel/psk.txt
PSKidentity = app1
client = no
foreground = no
[backend-tls]
accept = 0.0.0.0:23904
connect = 127.0.0.1:80
PSKsecrets = /etc/stunnel/psk.txt
Immer das gleiche Prinzip. Einfach PSK setzen, Config ausrollen, fertig.
was ich daran mag ist, das man entweder mit Hilfe von Zertifikaten oder eben mittels PSK arbeiten kann. Des Weiteren kann man auch zentral eine Konfig hinterlegen und so alle notwendigen Connections bereithalten. Klar, alles ausbaufähig. Aber wie oft kann eine Anwendung nicht ordentlich oder gradlinig mit TLS umgehen oder man will es einfacher haben. Da passt stunnel ganz gut in die Werkzeugkiste.
Benutzer sollen sich per SSH auf Linux-Servern anmelden können, ohne dass ihre Public Keys manuell auf jedem Server eingetragen werden müssen. Stattdessen signieren sie ihren eigenen Public Key bei einer zentralen SSH Certificate Authority (CA). Die Server akzeptieren dann automatisch alle gültigen, signierten Zertifikate.
OpenSSH unterstützt neben gewöhnlichen Public Keys auch sogenannte SSH-Zertifikate. Diese funktionieren ähnlich wie TLS-Zertifikate:
ssh-keygen -f /etc/ssh/ca_key -C "SSH CA" -t rsa
Erzeugt zwei Dateien:
CA Public Key auf den Server kopieren, z. B. nach /etc/ssh/ca_key.pub.
Dann in /etc/ssh/sshd_config folgenden Eintrag ergänzen:
TrustedUserCAKeys /etc/ssh/ca_key.pub
# Dienst neu starten
systemctl reload sshd
Jeder Benutzer generiert lokal einen eigenen Key:
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -C "user@example.com"
Der Benutzer sendet seinen Public Key zur Signierung an die CA. Die CA signiert den Key:
ssh-keygen -s /etc/ssh/ca_key \
-I user@example.com \
-n <username> \
~/.ssh/id_ed25519.pub
kurze Gedankenstütze: -I Identifier (frei wählbar, z. B. E-Mail) -n Principal (Benutzername auf dem Zielsystem)
Erzeugt: id_ed25519-cert.pub - die geht wieder zurückzum Benutzer.
ssh -i ~/.ssh/id_ed25519 \
-o CertificateFile=~/.ssh/id_ed25519-cert.pub \
user@zielserver
Oder dauerhaft in ~/.ssh/config:
Host zielserver
HostName server.example.com
User <username>
IdentityFile ~/.ssh/id_ed25519
CertificateFile ~/.ssh/id_ed25519-cert.pub
Warum? Weil es geil ist!
Bei der Signierung wird die Gültigkeit angegeben:
ssh-keygen -s ca_key -I user -n user -V +1h user.pub
Alternativ absolute Zeitspanne:
ssh-keygen -s ca_key -I user -n user -V "20250513T100000:20250513T180000" user.pub
Das wiederum würde sich auch ganz gut eigenen um sich automatisieren zu lassen. Webportal oder CLI für Benutzer, um ein Zertifikat per SSO oder Token zu erhalten