Was ist das Schöne daran, die Laufzeit von Containern in separate Instrumentenkomponenten zu unterteilen? Insbesondere die Tatsache, dass diese Tools kombiniert werden können, um sich gegenseitig zu schützen.

Viele Menschen
fühlen sich von der Idee angezogen, Container-
OCIs in
Kubernetes oder einem ähnlichen System zu
erstellen . Angenommen, wir haben eine CI / CD, die ständig Bilder sammelt, dann wäre etwas wie
Red Hat OpenShift / Kubernetes sehr nützlich für den Lastausgleich während der Montage. Bis vor kurzem gaben die meisten Benutzer den Containern einfach Zugriff auf den Docker-Socket und durften den Docker-Build-Befehl ausführen.
Wir haben vor einigen Jahren gezeigt, dass dies sehr unsicher ist. Es ist sogar noch schlimmer, als ein passwortloses root oder sudo anzugeben.
Daher versuchen die Leute ständig, Buildah in einem Container auszuführen. Kurz gesagt, wir haben
ein Beispiel dafür erstellt, wie es unserer Meinung nach am besten ist, Buildah im Container auszuführen und die entsprechenden Bilder auf
quay.io/buildah zu platzieren . Fangen wir an ...
Anpassung
Diese Bilder werden aus Docker-Dateien kompiliert, die sich im Buildah-Repository im Ordner
buildahimage befinden .
Hier sehen wir uns die
stabile Version von Dockerfile an .
# stable/Dockerfile # # Build a Buildah container image from the latest # stable version of Buildah on the Fedoras Updates System. # https://bodhi.fedoraproject.org/updates/?search=buildah # This image can be used to create a secured container # that runs safely with privileges within the container. # FROM fedora:latest # Don't include container-selinux and remove # directories used by dnf that are just taking # up space. RUN yum -y install buildah fuse-overlayfs --exclude container-selinux; rm -rf /var/cache /var/log/dnf* /var/log/yum.* # Adjust storage.conf to enable Fuse storage. RUN sed -i -e 's|^#mount_program|mount_program|g' -e '/additionalimage.*/a "/var/lib/shared",' /etc/containers/storage.conf
Anstelle von OverlayFS, das auf der Linux-Kernel-Ebene des Hosts implementiert ist, verwenden wir das
Fuse-Overlay- Programm im Container, da OverlayFS derzeit nur bereitgestellt werden kann, wenn ihm von Linux-Funktionen SYS_ADMIN-Berechtigungen gewährt werden. Und wir möchten unsere Buildah-Container ohne Root-Rechte ausführen. Fuse-Overlay ist ziemlich schnell und leistungsfähiger als der VFS-Speichertreiber. Beachten Sie, dass Sie beim Starten eines Buildah-Containers mit Fuse das Gerät / dev / fuse angeben müssen.
podman run --device /dev/fuse quay.io/buildahctr ... RUN mkdir -p /var/lib/shared/overlay-images /var/lib/shared/overlay-layers; touch /var/lib/shared/overlay-images/images.lock; touch /var/lib/shared/overlay-layers/layers.lock
Als nächstes erstellen wir ein Verzeichnis für zusätzlichen Speicher.
Container / Speicher unterstützt das Konzept, zusätzliche schreibgeschützte Bildspeicher anzuschließen. Sie können beispielsweise den Overlay-Speicherbereich auf einem Computer konfigurieren und dann NFS verwenden, um diesen Speicher auf einem anderen Computer bereitzustellen und Bilder von diesem zu verwenden, ohne ihn per Pull herunterzuladen. Wir benötigen diesen Speicher, um eine Art Image-Speicher vom Host als Volume verbinden und im Container verwenden zu können.
# Set up environment variables to note that this is # not starting with user namespace and default to # isolate the filesystem with chroot. ENV _BUILDAH_STARTED_IN_USERNS="" BUILDAH_ISOLATION=chroot
Unter Verwendung der Umgebungsvariablen BUILDAH_ISOLATION sagen wir schließlich, dass der Buildah-Container standardmäßig mit der Chroot-Isolierung beginnen sollte. Eine zusätzliche Isolierung ist hier nicht erforderlich, da wir bereits im Container arbeiten. Damit Buildah eigene Container mit Trennung von Namensräumen erstellen kann, ist das Privileg SYS_ADMIN erforderlich. Dazu müssen die SELinux- und SECCOMP-Regeln für den Container geschwächt werden, was unserer Installation zum Erstellen aus einem sicheren Container widerspricht.
Führen Sie Buildah im Container aus
Mit dem oben beschriebenen Buildah-Container-Image-Schema können Sie die Art und Weise, wie Sie solche Container ausführen, flexibel variieren.
Geschwindigkeit vs. Sicherheit
Computersicherheit ist immer ein Kompromiss zwischen der Geschwindigkeit des Prozesses und dem Umfang des Schutzes. Diese Aussage gilt auch für das Zusammenstellen von Containern. Im Folgenden werden Optionen für einen solchen Kompromiss betrachtet.
Das oben beschriebene Container-Image behält sein Repository in / var / lib / container. Daher müssen wir den Inhalt in diesem Ordner bereitstellen, und die Art und Weise, wie wir dies tun, wirkt sich stark auf die Assemblierungsgeschwindigkeit von Container-Images aus.
Betrachten wir drei Optionen.
Option 1. Wenn maximale Sicherheit erforderlich ist, können Sie für jeden Container einen eigenen Ordner für Container / Image erstellen und über Volume-Mount mit dem Container verbinden. Legen Sie außerdem das Kontextverzeichnis im Container selbst im Ordner / build ab:
# mkdir /var/lib/containers1 # podman run -v ./build:/build:z -v /var/lib/containers1:/var/lib/containers:Z quay.io/buildah/stable\ buildah -t image1 bud /build # podman run -v /var/lib/containers1:/var/lib/containers:Z quay.io/buildah/stable buildah push \ image1 registry.company.com/myuser # rm -rf /var/lib/containers1
Sicherheit Buildah, das in einem solchen Container ausgeführt wird, bietet maximale Sicherheit: Es werden keine Root-Berechtigungen mit Funktionstools zugewiesen, und alle SECOMP- und SELinux-Einschränkungen gelten für ihn. Ein solcher Container kann sogar mit Isolation des Benutzernamensraums ausgeführt werden, wobei eine Option wie --uidmap 0: 100000: 10000 hinzugefügt wird .
Leistung. Die Leistung hier ist jedoch minimal, da alle Bilder aus Containerregistern jedes Mal auf den Host kopiert werden und das Caching nicht mit dem Wort "no way" funktioniert. Nach Abschluss seiner Arbeit sollte der Buildah-Container das Image an die Registrierung senden und den Inhalt auf dem Host zerstören. Wenn das Container-Image das nächste Mal erfasst wird, muss es erneut aus der Registrierung heruntergeladen werden, da zu diesem Zeitpunkt nichts mehr auf dem Host verbleibt.
Option 2. Wenn Sie Leistung auf Docker-Ebene benötigen, können Sie den Container / Speicher des Hosts direkt in den Container einbinden.
# podman run -v ./build:/build:z -v /var/lib/containers:/var/lib/containers --security-opt label:disabled quay.io/buildah/stable buildah -t image2 bud /build # podman run -v /var/lib/containers:/var/lib/containers --security-opt label:disabled \ quay.io/buildah/stable buildah push image2 registry.company.com/myuser
Sicherheit Dies ist die am wenigsten sichere Methode zum Erstellen von Containern, da der Container hier den Speicher auf dem Host ändern darf und möglicherweise ein schädliches Image in Podman oder CRI-O übertragen kann. Darüber hinaus müssen Sie die SELinux-Trennung deaktivieren, damit die Prozesse im Buildah-Container mit dem Speicher auf dem Host interagieren können. Bitte beachten Sie, dass diese Option immer noch besser ist als der Docker-Socket, da der Container durch die verbleibenden Sicherheitsfunktionen blockiert wird und nicht einfach einen Container auf dem Host aufnehmen und ausführen kann.
Leistung. Hier ist es maximal, da das Caching voll involviert ist. Wenn Podman oder CRI-O es bereits geschafft haben, das gewünschte Image auf den Host herunterzuladen, muss der Buildah-Prozess im Container es nicht erneut herunterladen, und nachfolgende Assemblys, die auf diesem Image basieren, können auch das erforderliche Image aus dem Cache entnehmen.
Option 3. Im Wesentlichen besteht diese Methode darin, mehrere Bilder in einem Projekt mit einem freigegebenen Ordner für Containerbilder zu kombinieren.
# mkdir /var/lib/project3 # podman run --security-opt label:level=s0:C100, C200 -v ./build:/build:z \ -v /var/lib/project3:/var/lib/containers:Z quay.io/buildah/stable buildah -t image3 bud /build # podman run --security-opt label:level=s0:C100, C200 \ -v /var/lib/project3:/var/lib/containers quay.io/buildah/stable buildah push image3 \ registry.company.com/myuser
In diesem Beispiel wird der Projektordner (/ var / lib / project3) zwischen den Starts nicht gelöscht, sodass alle nachfolgenden Builds innerhalb des Projekts das Caching nutzen.
Sicherheit Etwas zwischen Option 1 und 2. Einerseits haben Container keinen Zugriff auf Inhalte auf dem Host und können dementsprechend nichts Schlechtes in den Podman / CRI-O-Image-Speicher schieben. Andererseits kann ein Container im Rahmen seines Projekts die Montage anderer Container stören.
Leistung. Hier ist es schlimmer als bei Verwendung eines gemeinsam genutzten Caches auf Hostebene, da Sie keine Bilder verwenden können, die bereits zuvor mit Podman / CRI-O heruntergeladen wurden. Nachdem Buildah das Image heruntergeladen hat, kann dieses Image jedoch in allen nachfolgenden Builds innerhalb des Projekts verwendet werden.
Zusätzlicher Speicher
Container / Speicher haben so coole Dinge wie zusätzliche Speicher, dank derer Container-Engines beim Starten und Erstellen von Containern externe Bildspeicher im schreibgeschützten Overlay-Modus verwenden können. Tatsächlich können Sie der Datei storage.conf einen oder mehrere schreibgeschützte Speicher hinzufügen, sodass die Container-Engine beim Starten des Containers nach dem gewünschten Image sucht. Darüber hinaus lädt er das Bild nur dann aus der Registrierung herunter, wenn er es in keinem dieser Repositories findet. Die Container-Engine kann nur in einen beschreibbaren Speicher schreiben ...
Wenn Sie nach oben scrollen und die Docker-Datei sehen, mit der wir das Image quay.io/buildah/stable erstellen, gibt es folgende Zeilen:
# Adjust storage.conf to enable Fuse storage. RUN sed -i -e 's|^#mount_program|mount_program|g' -e '/additionalimage.*/a "/var/lib/shared",' /etc/containers/storage.conf RUN mkdir -p /var/lib/shared/overlay-images /var/lib/shared/overlay-layers; touch /var/lib/shared/overlay-images/images.lock; touch /var/lib/shared/overlay-layers/layers.lock
In der ersten Zeile ändern wir /etc/containers/storage.conf im Container-Image und weisen den Speichertreiber an, "zusätzliche Bildspeicher" im Ordner / var / lib / shared zu verwenden. Erstellen Sie in der nächsten Zeile einen freigegebenen Ordner und fügen Sie einige Sperrdateien hinzu, damit kein Missbrauch durch Container / Speicher erfolgt. Grundsätzlich erstellen wir nur einen leeren Container-Image-Speicher.
Wenn Sie Container / Speicher über diesem Ordner bereitstellen, kann Buildah Images verwenden.
Zurück zu Option 2, die oben erläutert wurde, wenn ein Buildah-Container auf Hosts lesen und in Container / Speicher schreiben kann und dementsprechend aufgrund des Image-Caching auf Podman / CRI-O-Ebene maximale Leistung aufweist, jedoch ein Minimum an Sicherheit bietet, da er direkt schreiben kann im Lager. Und jetzt werden wir hier zusätzlichen Speicher befestigen und das Beste aus zwei Welten herausholen.
# mkdir /var/lib/containers4 # podman run -v ./build:/build:z -v /var/lib/containers/storage:/var/lib/shared:ro -v \ /var/lib/containers4:/var/lib/containers:Z quay.io/buildah/stable \ buildah -t image4 bud /build # podman run -v /var/lib/containers/storage:/var/lib/shared:ro \ -v >/var/lib/containers4:/var/lib/containers:Z quay.io/buildah/stable buildah push image4 \ registry.company.com/myuser # rm -rf /var/lib/continers4
Beachten Sie, dass der Host / var / lib / container / storage im schreibgeschützten Modus in / var / lib / shared im Container bereitgestellt wird. Daher kann Buildah in einem Container alle Bilder verwenden, die zuvor mit Podman / CRI-O heruntergeladen wurden (hi, speed), aber nur in sein eigenes Repository schreiben (hi, security). Beachten Sie auch, dass dies erfolgt, ohne die SELinux-Trennung für den Container zu deaktivieren.
Wichtige Nuance
In keinem Fall sollten Sie Bilder aus dem zugrunde liegenden Speicher entfernen. Andernfalls kann der Buildah-Container herausfliegen.
Und das sind nicht alle Vorteile.
Zusätzliche Speicherfunktionen sind nicht auf das obige Szenario beschränkt. Sie können beispielsweise alle Container-Images in einem gemeinsam genutzten Netzwerkspeicher platzieren und Zugriff auf alle Buildah-Container gewähren. Angenommen, wir haben Hunderte von Images, die unser CI / CD-System regelmäßig zum Erstellen von Container-Images verwendet. Wir konzentrieren alle diese Images auf einen einzelnen Speicherhost und öffnen dann mithilfe der bevorzugten Netzwerkspeicher-Tools (NFS, Gluster, Ceph, ISCSI, S3 ...) gemeinsam genutzten Speicher für alle Buildah- oder Kubernetes-Knoten.
Jetzt reicht es aus, diesen Netzwerkspeicher in den Buildah-Container unter / var / lib / shared zu mounten, und das ist alles - Buildah-Container müssen keine Bilder mehr per Pull herunterladen. Damit werfen wir die Vorbevölkerungsphase aus und sind sofort bereit, die Container auszurollen.
Und natürlich kann dies innerhalb des vorhandenen Kubernetes-Systems oder der Containerinfrastruktur verwendet werden, um Container überall zu starten und auszuführen, ohne Bilder per Pull herunterzuladen. Darüber hinaus kann die Containerregistrierung, die eine Push-Anforderung zum Laden eines aktualisierten Images empfängt, dieses Image automatisch an einen gemeinsam genutzten Netzwerkspeicher senden, wo es sofort allen Knoten zur Verfügung steht.
Die Größe von Container-Images kann manchmal viele Gigabyte erreichen. Die Funktionalität zusätzlicher Speicher ermöglicht es Ihnen, auf das Klonen solcher Bilder durch Knoten zu verzichten, und macht das Starten von Containern fast sofort.
Darüber hinaus arbeiten wir derzeit an einer neuen Funktion zur Bereitstellung von Overlay-Volumes, die die Montage von Containern noch schneller macht.
Fazit
Das Ausführen einer Buildah in einem Container in Kubernetes / CRI-O, Podman oder sogar Docker ist real und einfacher und viel sicherer als die Verwendung von docker.socket. Wir haben die Flexibilität bei der Arbeit mit Bildern erheblich verbessert. Jetzt können Sie sie auf verschiedene Arten starten, um ein optimales Gleichgewicht zwischen Sicherheit und Leistung zu erzielen.
Die Funktionalität zusätzlicher Speicher ermöglicht es Ihnen, das Herunterladen von Bildern auf Knoten zu beschleunigen oder sogar vollständig zu eliminieren.