buildah: Docker und Kubernetes Images ohne Daemon
Docker ist die führende Umsetzung von Linux Containern - kein Wunder, hat Docker die Idee von Containern als leichtgewichtige Alternative zu Virtualisierung erst populär gemacht. Inzwischen hat sich das Ökosystem deutlich weiterentwickelt. Google hat mit dem Kubernetes Projekt den defacto Standard für Scheduling und Verwaltung von Containern und zugehörigen Resourcen geschaffen. Neben Docker existieren mit rkt (CoreOS) und CRI-O (Open Container Initiative) weitere Container Runtimes für das mittlerweile gesetzte OCI Image Format. Relativ neu dabei sind die Werkzeuge buildah zum Bauen von Containern und podman zur Ausführung mittels CRI-O (beide von Project Atomic, RedHat).
Warum entstehen unterschiedliche Runtimes und Build-Toolchains? Welche Vorteil für Nutzer im Kontext von Docker oder Kubernetes ergeben sich daraus?
Im Gegensatz zu Docker zeichnet sich rkt dadurch aus, dass kein zusätzlicher Dämon benötigt wird.
Bei buildah und podman werden die Verantwortlichkeiten stärker separiert:
Docker ist eine All-In-One-Lösung, die sowohl Netzwerk als auch Image-Erzeugung und Container Runtime beeinhaltet.
Weiterentwicklungen führen dann sehr schnell zu API-Brüchen, die vor allem in der Anfangszeit für Nutzer und insbesondere Werkzeughersteller schwierig zu handhaben waren.
Bei buildah ist die Motivation ohne separaten Daemon auszukommen und mit klassischen Werkzeugen der Kommandozeile wie cp
und make
zum Ziel zu gelangen.
Ein Zwang zur Nutzung von Dockerfiles entfällt damit, und bestehende Scripts und Konfigurationsmanagement kann auch für Container Images eingesetzt werden.
Damit soll die Integration in bestehende Buildprozesse und Umgebungen erleichtert werden.
Da kein Daemon existiert, müssen somit auch keine besonderen Kniffe angewendet werden, um beispielsweise in einem Container, wie in einem Kubernetes-Cluster, wiederum Images zu erstellen.
Ein schneller Blick auf buildah mit Ubuntu 18.04 ist leider nicht möglich - aktuell gibt es lediglich Pakete für Ubuntu 16.04 über das PPA von Project Atomic:
https://launchpad.net/~projectatomic/+archive/ubuntu/ppa
Bei RedHat, Fedora und CentOS sieht es, wie bei einem RedHat Projekt zu erwarten ist, besser aus: Ein yum install -y buildah
bzw. dnf install -y buildah
reicht hier aus.
Alternativ ist natürlich eine Installation auf Basis der Sourcen möglich, Details dazu finden sich hier: https://github.com/projectatomic/buildah/blob/master/install.md
Damit ist die Installation von buildah und podman unter Ubuntu sehr einfach:
$ sudo add-apt-repository ppa:projectatomic/ppa
$ sudo apt-get update
$ sudo apt-get install buildah
Anschließend kann buildah verwendet werden, um auf Basis eines Dockerfile ein Image zu bauen. Zunächst wird für das Image ein Dockerfile benötigt:
FROM ubuntu:latest
RUN apt-get update
RUN apt-get install -y fortune
CMD ["/usr/games/fortune"]
Damit Base-Images von DockerHub bezogen werden können, ist DockerHub als entsprechende Registry für buildah in /etc/containers/registries.conf
einzutragen:
[registries.search]
registries = ['docker.io']
[registries.insecure]
registries = []
[registries.block]
registries = []
Zu beachten ist, dass buildah als root laufen muss, daher werden die Beispiele mit sudo
gezeigt.
Steht kein runc
als Container-Laufzeitumgebung zur Verfügung, kann diese durch die Environmentvariable BUILDAH_RUNTIME
spezifiziert werden.
Die buildah Paketabhängigkeiten bringen eine runc Implementierung in Form von CRI-O runc mit.
Mittels buildah kann nun das Image gebaut werden.
$ sudo BUILDAH_RUNTIME=/usr/lib/cri-o-runc/sbin/runc \
buildah build-using-dockerfile -t fortune .
STEP 1: FROM ubuntu:latest
Getting image source signatures
Copying blob sha256:6b98dfc1607190243b0938e62c5ba2b7daedf2c56d7825dfb835208344705641
29.81 MiB / 29.81 MiB [====================================================] 2s
Copying blob sha256:4001a1209541c37465e524db0b9bb20744ceb319e8303ebec3259fc8317e2dec
843 B / 843 B [============================================================] 0s
Copying blob sha256:6319fc68c576d6bd3e469b0ae31e9a010bc9b71ed286cf4e632424d82dca70d8
...
Writing manifest to image destination
Storing signatures
ca76d9d1752e587471a7d37bbce6877e7f498cd408177a9c53bd9dec4e2cc693
Das erstellte Image liegt anschließend unter /var/lib/containers
.
Vorhandene Images können auch mit buildah angezeigt werden:
$ sudo buildah images
IMAGE ID IMAGE NAME CREATED AT SIZE
113a43faa138 docker.io/library/ubuntu:latest Jun 5, 2018 21:20 83.7 MB
ca76d9d1752e localhost/fortune:latest Jun 18, 2018 19:23 127 MB
Als Ergänzung zu buildah gibt es das Werkzeug podman.
Mit podman können Images analog zu docker run
als Container ausgeführt werden.
Das gebaute Image kann auch zu einer Docker-Registry oder einem Docker-Daemon gepusht werden.
Letzteres kann zum Beispiel sinnvoll sein, wenn man Build-Slaves verwendet, und diese erfolgreich gebaute Images einem Docker-Daemon zur Verfügung stellen sollen.
Eine Registry kann zum Beispiel im Kubernetes Kontext sinnvoll sein, wenn die Images dann in einem Cluster durch Kubernetes Nodes zur Ausführung bezogen werden.
Somit stellt buildah in diesem Kontext eine Alternative zum häufig eingesetzten Docker-in-Docker (DinD) dar.
Als Beispiel die Ausführung des mit buildah erzeugen Image durch podman:
$ sudo podman run fortune
You will be called upon to help a friend in trouble.
Das Image kann nun auch zu einem Docker-Daemon oder einer Registry gepusht werden:
$ sudo buildah push fortune docker-daemon:fortune:latest
Wer mit buildah und podman schnelle Experimente machen möchte, kann auf das folgende Vagrantfile zurückgreifen. Es verwendet ein Ubuntu 16.04 Basisimage und installiert darauf dann buildah und podman.
Vagrantfile für Ubuntu und buildah:
Vagrant.require_version ">= 1.8"
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/xenial64"
config.vm.provider :virtualbox do |vb|
vb.linked_clone = true
vb.name = "buildah demo"
vb.customize ["modifyvm", :id, "--memory", "4096"]
vb.customize ["modifyvm", :id, "--cpus", 2]
end
$setup = <<SCRIPT
sudo add-apt-repository -y ppa:projectatomic/ppa
sudo apt-get update
sudo apt-get install -y buildah podman
SCRIPT
config.vm.provision "shell", inline: $setup
end
Zusammen mit Vagrant lässt sich nun sehr schnell eine Experimentierumgebung für buildah erstellen:
$ vagrant up
$ vagrant ssh
vagrant@ubuntu-xenial:~$ sudo su -
vagrant@ubuntu-xenial:~# buildah -v
buildah version 1.2-dev (image-spec 1.0.0, runtime-spec 1.0.0)
Prinzipiell kann buildah auch innerhalb eines Docker Containers laufen.
Dieser muss dann jedoch mit erweiterten Rechten gestartet werden, um Zugriff auf die Container Mechanismen des Linux Kernel zu erhalten.
Außerdem muss das Verzeichnis /var/lib/containers
durch ein Filesystem bereitgestellt werden, dass außerhalb des Docker-Overlay-Filesystem liegt, da es sonst Konflikte gibt.
Im Beispiel ist zu sehen, wie buildah in Docker ausgeführt werden kann:
$ docker run --rm --privileged -v /tmp/containers:/var/lib/containers -it fedora bash
[root@50a40f6424b9 /]# yum install -y buildah
[root@50a40f6424b9 /]# buildah -version
buildah version 1.1 (image-spec 1.0.0, runtime-spec 1.0.0)
[root@50a40f6424b9 /]# buildah build-using-dockerfile -t fortune .
STEP 1: FROM ubuntu:latest
Getting image source signatures
...
Writing manifest to image destination
Storing signatures
[root@50a40f6424b9 /]# buildah images
IMAGE ID IMAGE NAME CREATED AT SIZE
113a43faa docker.io/library/ubuntu:latest Jun 5, 2018 21:20 83.7 MB
9a1705b70 localhost/fortune:latest Jun 19, 2018 19:21 127 MB
Zu den Themen Kubernetes, Docker und Cloud Architektur bieten wir sowohl Beratung, Entwicklungsunterstützung als auch passende Schulungen an:
Auch für Ihren individuellen Bedarf können wir Workshops und Schulungen anbieten. Sprechen Sie uns gerne an.