podman

zurück

(Die Seite ist schon älter, wurde nun überarbeitet bzw. Inhalte ergänzt)h

podman ist das neue docker. Vorteile:

  • läuft nicht als root
    • Großartiger Sicherheitsgewinn zur Laufzeit
    • Großartiger Sicherheitsgewinn zur Entwicklungszeit
    • einfacherer Umgang mit Volumes durch UID-Mapping
  • Handhabung sehr ähnlich zu docker
    • bloß besserer Unterbau ;)
  • funktioniert mit systemd, auch innerhalb des Containers
    • docker baut lieber "Parallelwelt" für Fehlerbehandlung auf
    • docker kann kein systemd in Containern
  • Antrieb kommt von Red Hat
    • vernünftige Projektführung
    • docker geht lieber eigenen Weg
    • docker lehnte einige gute PullRequest ab (was zu podman führte)

Hier ein paar simple Beispiel zum Einstieg:

podman run -it fedora /bin/bash
podman run fedora /usr/bin/cat /etc/hosts
podman cp fedora:/etc/hosts .
podman build -t hello-world .

1 Abgrenzung

Wie so oft: KISS. Also, kein compose, kein kubernetes, kein „dynamisches Skalieren“. Ich möchte hier zeigen wie ich podman nutze um eine definierte Umgebung (bspw. ein „dyndns“-Client, eine per Webbrowser erreichbar java-Anwendung oder eine „nextcloud“) beschrieben werden kann und erreichbar gemacht wird.

2 freedns-client („dyndns“)

früher nutze ich einen CLI-Client, inzwischen ein noch simpleres Skript, da sich die API (siehe freedns.afraid.org) stark vereinfacht hat. Besonderheit: braucht von außen nicht erreichbar sein, muss nur selbst das Internet erreichen können.

Hier mein Skript updateloop.bsh, dass einfach alle 5min die API aufruft.

#!/bin/bash
while true
do
    curl -s https://freedns.afraid.org/dynamic/update.php?Usd7v0xc098sdf0xc0v87sd87fsxßcvvs9d8df432DEx
    sleep 5m
done

und hier das Containerfile

FROM registry.fedoraproject.org/fedora:40
ADD updateloop.bsh /updateloop.bsh
CMD ["bash", "/updateloop.bsh"]

3 gitolite

gitolite, denn gitlab, github etc. sind mir alles viel zu viel.

Hierhinter läuft also

  • was mit git
  • auf port 8999 (-p)
  • gesichter in einem eigenen Volume (-v)

Ggf. kommt mal gitea.io, aber bisher stieß ich hier nicht an Grenzen. Also das Containerfile:

FROM registry.fedoraproject.org/fedora:40
RUN dnf -y install gitolite3 openssh-server hostname findutils glibc-locale-source \
 && dnf clean all \
 && localedef -v -c -i de_DE -f UTF-8 de_DE.UTF-8 || true
RUN ssh-keygen -A
RUN useradd git
EXPOSE 22/tcp
CMD ["/usr/sbin/sshd", "-D"]

Erwähnenswert ist hier, dass neben gitolite auch findutils etc. installiert wird und localedef ausgeführt, dass ist einfach um ins lokalisierte Umfeld (hier: Deutschland) zu kommen für hübschere Rückmeldungen. Also eigentlich schon Luxus.

Und so wird es gestartet:

#!/bin/bash
project="gitolite"
cd $base/$project
podman build -t $project .
podman run --rm -d \
       -p 8999:22 \
       -v=$project:/home/git \
       --name $project \
       $project

und schon ist es etwa so erreichbar

#!/bin/bash
ssh git@ip -p 7999 info

um von außen erreichbar zu werden, die Firewall anpassen:

#!/bin/bash
firewall-cmd --zone=FedoraServer --add-port=7999/tcp --permanent

4 Java-Anwendung

Im Java-Sourcecode selbst liegt, Überraschung, ein Containerfile.

Hier läuft

  • eine Java-Anwendung, LOL
  • erreichbar von außen auf Port 8018 (-p)
  • die ihre Anwendungsdaten, bspw. eine lokale Datenbank, im Volume (-v) ablegt

Besonderheit hier: ein FROM… zum bauen mit maven, ein zweites FROM darunter um das resultierende Package zu starten.

Besonderheit 2 die jar liegt direkt im Root /, das Volume für Daten separat /app. Denn die Jar braucht ja nicht mit gesichert zu werden.

4.1 Container beschreiben

FROM docker.io/library/maven:3-eclipse-temurin-17 AS mvnPackage
COPY pom.xml /tmp/
COPY src /tmp/src/
WORKDIR /tmp
RUN mvn package -DskipTests

FROM docker.io/library/eclipse-temurin:17-alpine
COPY --from=mvnPackage /tmp/target/*.jar /app.jar
WORKDIR /app
EXPOSE 8080
CMD ["java", \
    "-jar", \
    "-Duser.language=de", \
    "-Duser.country=DE", \
    "-Duser.timezone=Europe/Berlin", \
    "-Djava.security.egd=file:/dev/./urandom", \
    "../app.jar" ]

4.2 Container bauen, starten und erreichbar machen

#!/bin/bash
project="atom"
workDir=$(mktemp -d)
homeDir=$(echo ~)
cd ${workDir}
git clone ssh://git@ip/user/${project} .
git checkout develop
podman build -t $project \
       .
podman run --rm -d \
       -p 8018:8080 \
       -v=$project:/app \
       --name $project \
       $project

um von außen erreichbar zu werden, die Firewall anpassen:

#!/bin/bash
firewall-cmd --zone=FedoraServer --add-port=8018/tcp --permanent

5 Apache als Reverse Proxy

Damit nach außen sprechende Namen zu sehen sind anstatt fortlaufende Ports ist fix ein Apache angelegt, der auf eine Subdomain und alles darunter lauscht, um genau das zu ermöglichen.

5.1 https.conf

Hier läuft ein Webserver

  • erreichbar per HTTPS (Zertifikate siehe certbot unten)
  • der sprechende Namen wie news… weiterleitet …
  • auf IPs bzw. Ports im Netwerk (hier etwa: 192.168.xx.xx, Port 8018)
SSLEngine on
SSLCertificateFile /etc/pki/tls/certs/localhost.crt
SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
ServerName intern.frenger-it.de
<VirtualHost *:443>
  ServerName news.intern.frenger-it.de
  ProxyPass        /  http://192.168.xx.xx:8018/
  ProxyPassReverse /  http://192.168.xx.xx:8018/
</VirtualHost>
<VirtualHost *:443>
  ServerName plonk.intern.frenger-it.de
  ProxyPass        /  http://192.168.xx.xx:8019/
  ProxyPassReverse /  http://192.168.xx.xx:8019/
</VirtualHost>

Einzig für Nextcloud (bzw. für die dav-Funktionalität) mussten bei wenigen VirtualHosts Ergänzungen vorgenommen werden:

Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains"
RewriteEngine On
RewriteRule ^/\.well-known/carddav https://%{SERVER_NAME}/remote.php/dav/ [R=301,L]
RewriteRule ^/\.well-known/caldav https://%{SERVER_NAME}/remote.php/dav/ [R=301,L]

5.2 Containerfile

FROM registry.fedoraproject.org/fedora:40
RUN dnf -y install httpd mod_ssl \
 && dnf clean all
COPY http.crt /etc/pki/tls/certs/localhost.crt
COPY http.key /etc/pki/tls/private/localhost.key
COPY https.conf /etc/httpd/conf.d/https.conf
COPY .htaccess /etc/httpd/.htaccess
CMD ["httpd", "-DFOREGROUND"]

6 certbot

Ja, auch hier gibt es viele fertige Lösungen, die den certbot gleich im apache integrieren, dass ist mir aber schon wieder zu viel Verantwortung auf einmal. Daher ist der certbot bei mir getrennt vom Rest. Was er erstellt, wird extrahiert und separat in die apaches geschoben.

6.1 Containerfile

FROM registry.fedoraproject.org/fedora:40
RUN dnf -y install certbot \
 && dnf clean all

und wenn der läuft, starte ich (ja!) manuell (einmal alle 3 Monate, sind 5min Arbeit) innerhalb des pods:

#!/bin/bash
certbot -m myMail@mydomain.de \
        -d "intern.frenger-it.de,*.intern.frenger-it.de" \
        --manual \
        --preferred-challenges dns certonly

Folge den Anweisungen, und ziehe das Ergebnis raus um es in den Apacheg zu packen (den ich dann auch durchstarte):

#!/bin/bash
podman cp certbot:/etc/letsencrypt/live/intern.frenger-it.de/fullchain.pem fullchain.pem
podman cp certbot:/etc/letsencrypt/live/intern.frenger-it.de/privkey.pem privkey.pem
cp fullchain.pem ../http/http.crt
cp privkey.pem ../http/http.key