# Podman

## Hvad det er

Podman er en containermotor til Linux, der bygger, henter og kører de samme OCI-images som Docker,
men uden en central server imellem. Hver `podman`-kommando gør sit arbejde i sin egen proces og
afslutter. En startet container kører videre under en lille overvågningsproces ved navn conmon, og
den proces er barn af det, der startede den: en skal, et script eller systemd. Projektet kalder selv
værktøjet dæmonløst, open source og Linux-nativt og skriver, at de fleste brugere bare kan lave et
alias fra `docker` til `podman` og fortsætte som før.

Navnet står for pod manager. En pod er et begreb lånt fra Kubernetes: en gruppe containere, der
deler netværksnavnerum og derfor når hinanden på localhost. Podman kan oprette pods direkte, og
`podman kube play` starter containere og pods ud fra en Kubernetes-YAML-fil. Det gør værktøjet til
et fornuftigt sted at afprøve et manifest, før det kommer i nærheden af en klynge.

To egenskaber skiller det ud i det daglige. Den første er rootless drift. En almindelig bruger kan
køre containere, fordi kernens user namespaces gør brugeren til UID 0 inde i containeren og lægger
alle andre UID'er ind i brugerens underordnede id-interval fra `/etc/subuid` og `/etc/subgid`.
Netværk til rootless containere går gennem pasta, en netværksstak i brugerrummet, eftersom en
uprivilegeret bruger ikke må omskrive værtens pakkefilter.

Den anden er Quadlet. En Quadlet-fil er en kort deklarativ beskrivelse af en container, en volume,
et netværk, en pod eller et image-build, skrevet i samme ini-syntaks som en systemd-unit og gemt
under `/etc/containers/systemd/` for hele systemet eller `~/.config/containers/systemd/` for en
enkelt bruger. Ved opstart og ved hver `systemctl daemon-reload` laver en systemd-generator filen
`web.container` om til en helt almindelig `web.service`. Den ældre kommando
`podman generate systemd` virker stadig, men projektet har erklæret den forældet til fordel for
Quadlet.

## Hvorfor det betyder noget

Podman tvinger et spørgsmål frem: hvem ejer procestræet? Under Docker er hver container en
efterkommer af `dockerd`, som har sine egne genstartsregler, sine egne logs og sin egen mening om,
hvornår en container er sund. På en server, der allerede kører systemd, er det en ekstra supervisor
ved siden af den første, og de to taler ikke samme sprog.

Med Podman og Quadlet er systemd den eneste supervisor. En container er en tjeneste som alle andre.
`systemctl status` viser den, journald gemmer dens output, `After=` og `Requires=` placerer den i
forhold til den database, den har brug for, og `Restart=` og de cgroup-grænser, systemd allerede
kender, gælder uændret. Den, der kan læse en unit-fil, kan også læse containerplanet.

Sikkerheden spiller også ind. Docker-dæmonen kører som root, medmindre man vælger dens
rootless-tilstand, og Dockers egen sikkerhedsvejledning siger, at kun betroede brugere bør have
kontrol over den, fordi en container kan få adgang til en hvilken som helst mappe på værten. Podman
holder ingen privilegeret dæmon kørende mellem kommandoerne. En rootless opsætning strammer
yderligere: en proces, der slipper ud af sin container, lander som en uprivilegeret bruger.

Docker vs Podman er derfor mindre en kamp om funktioner end et spørgsmål om, hvad der passer. Docker
er det glattere valg på en udviklers bærbare med Docker Desktop, for hold, hvis arbejdsgang er
bygget op om Compose, og for værktøjer, der forventer en Docker-socket, selv om Podman også kan
levere et kompatibelt API, når man beder om det. Podman vinder typisk på servere, hvor systemd
allerede er sandhedskilden, og hvor en dæmon, der omskriver firewallen, er en belastning snarere end
en bekvemmelighed.

## Sådan ser det ud i praksis

Podman bærer containerplanet i to nyere projekter, og før det var det fejlsøgningsværktøjet for en
flåde bygget på Docker.

På én vært
[kører containerne som Quadlet-units under systemd med Podman i stedet for Docker](/da/portfolio/deployed-a-container-plane-on-podman-and-quadlet-122/).
Grunden er firewallen. Dockers standard publicerer containerporte over de regler, hærdningsrollen
installerer, mens disse containere bruger værtens netværk helt uden publicerede porte. Units kører
på systemniveau og ikke rootless, og siden noterer det som en afvejning: enklere automatisering mod
den strengere isolation, rootless ville give, med en note om, hvilken vej man skal gå, hvis
containerudbrud en dag vejer tungere. Udrulning er skilt fra provisionering. Root forbereder
udrulningsstien én gang. Bagefter bygger en uprivilegeret bruger containerens image og genstarter
tjenesten med ét fast script, som en afgrænset regel tillader, og intet andet.

Samme opbygning holder på meget lidt hardware. En vært med én kerne og 512 MB hukommelse
[kører virksomhedens TLS-endepunkter, git-forge, onion-tjeneste og krypterede backups](/da/portfolio/ran-the-whole-company-on-one-512mb-host-109/),
og containerplanet er Quadlet-units under den samme supervisor som alt andet i stedet for en dæmon
med sin egen. Målt holdt den ledige hukommelse sig over omkring 310 MB af de 464 MB, der kan bruges.

Tidligere, på tværs af tyve Docker-pakkede applikationer fordelt på Google Cloud og AWS,
[gik fejlsøgningen gennem Podman](/da/portfolio/deployed-and-maintained-20-docker-containerized-applications-troubleshooting-19/),
mens Kubernetes tog sig af orkestreringen. Imagene var de samme, værktøjet omkring dem var et valg.

## Hvor det går galt

Det meste besvær med Podman opstår, når man forventer, at det opfører sig som Docker eller som en
almindelig systemd-unit, for det er lidt af begge.

**En rettet Quadlet-fil gør tilsyneladende intet.** Generatoren kører ved opstart og ved
`systemctl daemon-reload`, så en ændring på disken er usynlig, indtil en af delene sker. Dernæst
afviser `systemctl enable` den genererede tjeneste, fordi systemd betragter den som midlertidig.
Start ved opstart hører hjemme i filens egen `[Install]`-sektion:

```ini
# /etc/containers/systemd/web.container
[Unit]
Description=Web front end

[Container]
Image=docker.io/library/nginx:1.27
Network=host

[Service]
Restart=always

[Install]
WantedBy=multi-user.target
```

Når filen er gemt, kører man `systemctl daemon-reload` og `systemctl start web.service`.

**En rootless tjeneste stopper, når ejeren logger ud.** Bruger-units lever i brugerens egen
systemd-manager, som lukker sammen med den sidste session. `loginctl enable-linger` for den bruger
holder manageren i live fra opstart, og det kræver enhver rootless tjeneste, der skal overleve en
genstart.

**En rootless webserver beder om port 80 og bliver afvist.** Porte under 1024 kræver root eller
kapabiliteten `CAP_NET_BIND_SERVICE`, og den regel gælder også den bruger, Podman kører som.
Publicér en høj port og sæt en proxy foran, eller sænk kernens `ip_unprivileged_port_start` med
vilje, vel vidende at det gælder alle brugere på værten.

**Filer i en bind mount ejes af en fremmed.** I rootless-tilstand bliver brugerens eget UID til root
inde i containeren, og alle andre UID'er lægges ind i det underordnede interval. En proces, der
kører som UID 999 inde i containeren, skriver filer, som værten ser som ejet af UID 100998 eller
deromkring. `podman unshare` åbner en skal i den samme mapping, hvor `chown` virker, som containeren
forventer, og indstillingen `U` på en mount retter ejerskabet automatisk, så det passer til
containeren.

## Læs mere

- [What is Podman?](https://docs.podman.io/en/latest/) — projektets egen dokumentation, der begynder
  med dets definition af værktøjet.
- [podman-systemd.unit](https://docs.podman.io/en/latest/markdown/podman-systemd.unit.5.html) —
  opslagsværket for Quadlet: filtyper, søgestier og hver eneste nøgle.
- [Basic Setup and Use of Podman in a Rootless environment](https://github.com/podman-container-tools/podman/blob/main/docs/tutorials/rootless_tutorial.md)
  — underordnede id'er, user namespaces og netværk med pasta.
- [podman-unshare](https://docs.podman.io/en/latest/markdown/podman-unshare.1.html) — sådan træder
  man ind i det rootless navnerum for at se eller rette ejerskab.
- [podman-generate-systemd](https://docs.podman.io/en/latest/markdown/podman-generate-systemd.1.html)
  — den ældre måde at lave units på og dens udfasning til fordel for Quadlet.

<https://engineer.company/da/glossary/podman/>
