Container Images ohne root bauen
Sun 23 June 2019Mit Podman und Buildah existieren Tools um OCI Images und Container zu erstellen, verwalten und betreiben - ganz ähnlich zum bekannten Docker. Die meiner Meinung nach größte Besonderheit: Die beiden funktionieren ohne Daemon, und auch ohne root-Rechte auf einem Linuxsystem.
Während podman meinen docker noch nicht ganz ersetzt (kein Unterstützung für/von docker-compose, da etwas anderer Fokus des Projekts) plane ich meine Build-Pipeline für Container-Images durch buildah zu ersetzen. Dadurch spare ich mir das Mounten des Docker-Sockets in den Container der Images bauen soll. :)
Ein erster Test Images im Container zu bauen lief wunderbar problemlos, ich schreibe hier auf was ich dafür getan habe.
Buildah im Container
Buildah kann fuse-overlayfs als Storage-Treiber nutzen, so dass auch die Verwaltung der Layer keine erweiterten Rechte braucht. Dazu muss allerdings das fuse-Device vom Host in den Container gemountet werden. Um die User-Namespaces nutzen zu können braucht es ausserdem mehr erlaubte Syscalls als in der Standardkonfiguration erlaubt.
Start des Containers also:
$ podman run -ti --rm --security-opt seccomp=unconfined --device /dev/fuse fedora bash
Im Container Buildah installieren:
# dnf install -y buildah
Und Fuse-Overlay konfigurieren:
# sed -i -e 's|#mount_program = "/usr/bin/fuse-overlayfs"|mount_program = "/usr/bin/fuse-overlayfs"|' /etc/containers/storage.conf
Als Beispiel baue ich Alpine mit zusätzlichem VIM:
# mkdir alpinewithvim
# cat > alpinewithvim/Dockerfile <<EOF
FROM alpine
RUN apk add --no-cache vim
EOF
# buildah bud --isolation chroot -t alpinewithvim alpinewithvim/
Was sauber durch lief:
# buildah images
REPOSITORY TAG IMAGE ID CREATED SIZE
localhost/alpinewithvim latest 0ca4abc241e0 6 seconds ago 36.6 MB
docker.io/library/alpine latest 4d90542f0623 3 days ago 5.85 MB
Das gebaute Image lässt sich (genau wie bei Docker) in eine Registry schieben:
# buildah tag localhost/alpinewithvim reg.zknt.org/chris/alpinewithvim
# buildah push --creds chris reg.zknt.org/chris/alpinewithvim
Und damit kann das Image sonstwo geladen und als Container ausgeführt werden:
$ docker run --rm -ti reg.zknt.org/chris/alpinewithvim vim --version
VIM - Vi IMproved 8.1 (2018 May 18, compiled Jun 5 2019 08:37:43)
Included patches: 1-1365
Compiled by Alpine Linux
...
Buildah-Image
Als Image das automatisch ein Image baut und pusht sieht das ganze dann wie folgt aus.
Das Dockerfile:
FROM fedora
RUN dnf install -y buildah &&\
sed -i -e 's|#mount_program = "/usr/bin/fuse-overlayfs"|mount_program = "/usr/bin/fuse-overlayfs"|' /etc/containers/storage.conf &&\
mkdir /build
COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT /entrypoint.sh
und das Entrypoint-Skript:
#!/bin/bash
buildah bud --isolation chroot -t ${BUILDAH_IMAGE_TAG} /build
buildah images
buildah push --creds "${BUILDAH_USER}:${BUILDAH_PASSWORD}" ${BUILDAH_IMAGE_TAG}
Mit diesem Image (als buildah
getaggt) lassen sich jetzt (wie ich finde recht elegant) Images bauen und pushen:
podman run --rm -t --security-opt seccomp=unconfined --device /dev/fuse -v $(pwd)/alpinewithvim:/build -e BUILDAH_IMAGE_TAG=reg.zknt.org/chris/alpinewithvim -e BUILDAH_USER=chris -e BUILDAH_PASSWORD=hunter2 buildah
In ./alpinewithvim
liegt das sinnfreie Dockerfile von weiter oben.
…jetzt das Ganze nur noch in Jenkins einbauen :)