GNU/Linux >> LINUX-Kenntnisse >  >> Linux

So verwenden Sie Podman in einem Container

Eines der am häufigsten nachgefragten Themen für Leute, die an Upstream-Containertechnologien arbeiten, ist das Ausführen von Podman in einem Container. Das meiste davon war in der Vergangenheit mit Docker in Docker (DIND) verbunden, aber jetzt möchten die Leute auch Podman in Podman (PINP) oder Podman in Docker (PIND) ausführen.

Aber Podman kann auf verschiedene Arten ausgeführt werden, wurzelbehaftet und wurzellos. Wir landen bei Leuten, die verschiedene Kombinationen von rootful und rootless Podman ausführen wollen:

  • Rootful Podman in Rootful Podman
  • Rootless Podman in Rootful Podman
  • Wurzeliger Podman in wurzellosem Podman
  • Rootless Podman in Rootless Podman

Sie erhalten das Bild.

Dieser Blog versucht, jede Kombination abzudecken, beginnend mit einer Diskussion über Privilegien. Wir beginnen hier in Teil eins mit dem PINP-Szenario. In Teil zwei der Serie behandeln wir ähnliche Themen, tun dies jedoch im Kontext von Kubernetes. Lesen Sie unbedingt beide Artikel, um sich ein vollständiges Bild zu machen.

Container-Engines erfordern Berechtigungen

Um eine Container-Engine wie Podman innerhalb eines Containers auszuführen, müssen Sie zunächst verstehen, dass Sie eine angemessene Menge an Berechtigungen benötigen.

  • Container erfordern mehrere UIDs. Die meisten Container-Images benötigen mehr als eine UID, um zu funktionieren. Beispielsweise könnten Sie ein Image mit den meisten Dateien im Besitz von root haben, aber einige im Besitz des Apache-Benutzers (UID=60).
  • Container-Engines mounten Dateisysteme und verwenden den Systemaufruf clone, um Benutzernamensräume zu erstellen.

Hinweis:Möglicherweise benötigen Sie eine neuere Version von Podman. Die Beispiele in diesem Blog wurden mit Podman 3.2 ausgeführt.

Unser Testbild

Für die Beispiele in diesem Blog verwenden wir quay.io/podman/stable image, das mit der Idee erstellt wurde, den besten Weg zu finden, Podman in einem Container auszuführen. Sie können untersuchen, wie wir dieses Image aus Dockerfile und containers.conf erstellen Bild im Repository von github.com.

# stable/Dockerfile
#
# Build a Podman container image from the latest
# stable version of Podman on the Fedoras Updates System.
# https://bodhi.fedoraproject.org/updates/?search=podman
# This image can be used to create a secured container
# that runs safely with privileges within the container.
#
FROM registry.fedoraproject.org/fedora:latest

# Don't include container-selinux and remove
# directories used by yum that are just taking
# up space.
RUN dnf -y update; yum -y reinstall shadow-utils; \
yum -y install podman fuse-overlayfs --exclude container-selinux; \
rm -rf /var/cache /var/log/dnf* /var/log/yum.*

RUN useradd podman; \
echo podman:10000:5000 > /etc/subuid; \
echo podman:10000:5000 > /etc/subgid;

VOLUME /var/lib/containers
VOLUME /home/podman/.local/share/containers

ADD https://raw.githubusercontent.com/containers/libpod/master/contrib/podmanimage/stable/containers.conf /etc/containers/containers.conf
ADD https://raw.githubusercontent.com/containers/libpod/master/contrib/podmanimage/stable/podman-containers.conf /home/podman/.config/containers/containers.conf

RUN chown podman:podman -R /home/podman

# chmod containers.conf and adjust storage.conf to enable Fuse storage.
RUN chmod 644 /etc/containers/containers.conf; sed -i -e 's|^#mount_program|mount_program|g' -e '/additionalimage.*/a "/var/lib/shared",' -e 's|^mountopt[[:space:]]*=.*$|mountopt = "nodev,fsync=0"|g' /etc/containers/storage.conf
RUN mkdir -p /var/lib/shared/overlay-images /var/lib/shared/overlay-layers /var/lib/shared/vfs-images /var/lib/shared/vfs-layers; touch /var/lib/shared/overlay-images/images.lock; touch /var/lib/shared/overlay-layers/layers.lock; touch /var/lib/shared/vfs-images/images.lock; touch /var/lib/shared/vfs-layers/layers.lock

ENV _CONTAINERS_USERNS_CONFIGURED=""

Sehen wir uns das Dockerfile an.

FROM registry.fedoraproject.org/fedora:latest

# Don't include container-selinux and remove
# directories used by yum that are just taking
# up space.
RUN dnf -y update; yum -y reinstall shadow-utils; \
yum -y install podman fuse-overlayfs --exclude container-selinux; \
rm -rf /var/cache /var/log/dnf* /var/log/yum.*

Ziehen Sie zuerst den neuesten Fedora und aktualisieren Sie dann auf die neuesten Pakete. Beachten Sie, dass shadow-utils neu installiert wird , da es ein bekanntes Problem in den shadow-utils gibt auf dem Fedora-Image installieren, wo die filecaps auf newsubuid und newsubgid sind nicht gesetzt. Neuinstallation von shadow-utils behebt das Problem. Als nächstes installieren Sie Podman sowie die fuse-overlayfs . Wir installieren container-selinux nicht weil es innerhalb des Containers nicht benötigt wird.

RUN useradd podman; \
echo podman:10000:5000 > /etc/subuid; \
echo podman:10000:5000 > /etc/subgid;

Als nächstes erstelle ich einen Benutzer podman und richten Sie die /etc/subuid ein und /etc/subgid Dateien, um 5000 UIDs zu verwenden. Dies wird verwendet, um den Benutzernamensraum innerhalb des Containers einzurichten. 5000 ist eine willkürliche Zahl und möglicherweise zu klein. Wir haben diese Zahl ausgewählt, weil sie kleiner ist als die 65.000, die Rootless-Benutzern zugewiesen werden. Wenn Sie den Container nur als Root ausführen würden, wären 65 KB eine bessere Zahl gewesen.

VOLUME /var/lib/containers
VOLUME /home/podman/.local/share/containers

Da wir mit diesem Image Rootfull- und Rootless-Container ausführen können, erstellen wir zwei Volumes. Rootfull Podman verwendet /var/lib/containers für seinen Containerspeicher und rootless verwendet /home/podman/.local/share/containers . Overlay over Overlay wird oft vom Kernel verweigert, so dass dies Nicht-Overlay-Volumes erstellt, die innerhalb des Containers verwendet werden.

ADD https://raw.githubusercontent.com/containers/libpod/master/contrib/podmanimage/stable/containers.conf /etc/containers/containers.conf
ADD https://raw.githubusercontent.com/containers/libpod/master/contrib/podmanimage/stable/podman-containers.conf /home/podman/.config/containers/containers.conf

Ich habe zwei containers.conf vorkonfiguriert Dateien, um sicherzustellen, dass Container in jedem Modus einfacher ausgeführt werden.

Das Image ist standardmäßig so eingerichtet, dass es mit Fuse-Overlayfs ausgeführt wird. In bestimmten Fällen könnten Sie das Overlay-Dateisystem des Kernels für den Rootful-Modus ausführen, und Sie werden dies bald im Rootless-Modus tun können. Im Moment verwenden wir jedoch Sicherungsüberlagerungen als unseren Containerspeicher innerhalb des Containers. Andere Leute haben den VFS-Speichertreiber verwendet, aber das ist nicht so effizient.

Das Flag --privilegiert

Der einfachste Weg, Podman innerhalb eines Containers auszuführen, ist die Verwendung von --privileged Flagge.

Rootful Podman in Rootful Podman mit --privilegiert

# podman run --privileged quay.io/podman/stable podman run ubi8 echo hello
Resolved "ubi8-minimal" as an alias (/etc/containers/registries.conf.d/shortnames.conf)
Trying to pull registry.access.redhat.com/ubi8:latest...
Getting image source signatures
Copying blob sha256:a591faa84ab05242a17131e396a336da172b0e1ec66d921c9f130b7c4c24586d
Copying blob sha256:76b9354adec626b01ffb0faae4a217cebd616661fd90c4b54ba4415f53392fb8
Copying config sha256:dc080723f596f2407300cca2c19a17accad89edcf39f7b8b33e6472dd41e30f1
Writing manifest to image destination
Storing signatures
hello

Um Zeit zu sparen, da ich viele Experimente durchführen werde, habe ich ein Verzeichnis auf meinem Host ./mycontainers erstellt , die ich per Volume in den zu verwendenden Container einbinden werde und das Image nicht jedes Mal abrufen muss.

# podman run --privileged -v ./mycontainers:/var/lib/containers quay.io/podman/stable podman run ubi8 echo hello
hello

Rootless Podman in rootful Podman mit --privilegiert

Die quay.io/podman/stable Bild wird mit einem Podman eingerichtet Benutzer, den Sie verwenden können, um Rootless-Container auszuführen.

# podman run --user podman --privileged quay.io/podman/stable podman run ubi8 echo hello
Resolved "ubi8" as an alias (/etc/containers/registries.conf.d/shortnames.conf)
...
hello

Beachten Sie, dass in diesem Fall der im Container ausgeführte Podman als Benutzer podman ausgeführt wird . Dies liegt daran, dass der containerisierte Podman den Benutzernamensraum verwendet, um einen eingeschränkten Container innerhalb des privilegierten Containers zu erstellen.

Podman ohne Root in Docker mit --privileged ausführen

Ähnlich wie bei rootful Podman können Sie auch rootless Podman innerhalb von Docker mit --privileged ausführen Option.

# docker run --privileged quay.io/podman/stable podman run ubi8 echo hello

Podman ohne Root mit Docker

# docker run --user podman --privileged quay.io/podman/stable podman run ubi8 echo hello
Resolved "ubi8" as an alias (/etc/containers/registries.conf.d/shortnames.conf)
...
hello

Können wir das sicherer machen?

Beachten Sie, dass, obwohl wir die äußeren Container --privileged ausgeführt haben oben laufen die inneren Container im gesperrten Modus. Der wurzellose Podman, der innerhalb des Containers läuft, ist wirklich gesperrt und hätte eine sehr schwierige Zeit zu entkommen. Angesichts dessen bin ich kein Fan der Verwendung von --privileged Flagge. Ich glaube, dass wir es aus Sicherheitssicht besser machen können.

Laufen ohne das Flag --privileged

Schauen wir uns an, wie wir --privileged entfernen können Flag für mehr Sicherheit.

Rootful Podman in Rootful Podman ohne --privilegiert

# podman run --cap-add=sys_admin,mknod --device=/dev/fuse --security-opt label=disable quay.io/podman/stable podman run ubi8-minimal echo hello
hello

Wir können --privileged eliminieren Flag von rootful Podman, müssen aber noch einige Sicherheitsfunktionen deaktivieren, damit rootful Podman innerhalb des Containers funktioniert.

  1. Fähigkeiten:--cap-add=sys_admin,mknod Wir müssen zwei Linux-Fähigkeiten hinzufügen.
    1. CAP_SYS_ADMIN wird benötigt, damit der Podman als root innerhalb des Containers läuft, um die erforderlichen Dateisysteme zu mounten.
    2. CAP_MKNOD ist erforderlich, damit Podman als Root innerhalb des Containers ausgeführt wird, um die Geräte in /dev zu erstellen . (Beachten Sie, dass Docker dies standardmäßig zulässt).
  2. Geräte:Das --device /dev/fuse Flagge muss Sicherungsüberlagerungen innerhalb des Containers verwenden. Diese Option weist Podman auf dem Host an, /dev/fuse hinzuzufügen in den Container, damit der containerisierte Podman ihn verwenden kann.
  3. SELinux deaktivieren:Der --security-opt label=disable -Option weist den Podman des Hosts an, die SElinux-Trennung für den Container zu deaktivieren. SELinux erlaubt es nicht, dass containerisierte Prozesse alle Dateisysteme einhängen, die für die Ausführung in einem Container erforderlich sind.

Rootful Podman in Docker ohne --privileged

# docker run --cap-add=sys_admin --cap-add mknod --device=/dev/fuse --security-opt seccomp=unconfined --security-opt label=disable quay.io/podman/stable podman run ubi8-minimal echo hello
hello
  1. Hinweis:Docker unterstützt nicht das durch Kommas getrennte --cap-add Befehl, also musste ich sys_admin hinzufügen und mknod separat
  2. Noch benötigter --device /dev/fuse , da Container standardmäßig /dev/fuse ist
  3. Docker erstellt immer eingebaute Volumes im Besitz von root:root, also müssen wir ein Volume erstellen, das für Podman im Container gemountet werden muss, damit es für die Speicherung verwendet werden kann.
  4. Wie immer muss ich die SELinux-Trennung deaktivieren
  5. Muss auch seccomp deaktivieren , da Docker einen etwas strengeren seccomp hat Politik als Podman. Sie könnten einfach eine Podman-Sicherheitsrichtlinie verwenden, indem Sie --seccomp=/usr/share/containers/seccomp.json verwenden
# docker run --cap-add=sys_admin --cap-add mknod --device=/dev/fuse --security-opt seccomp=/usr/share/containers/seccomp.json --security-opt label=disable quay.io/podman/stable podman run ubi8-minimal echo hello
hello

Rootless Podman in Rootful Podman ohne --privilegiert

Führen Sie nicht aus -privilegierter Container mit darin enthaltenem Podman, der einen Nicht-Root-Benutzer verwendet, der den Benutzernamensraum verwendet.

# podman run --user podman --security-opt label=disable --security-opt unmask=ALL --device /dev/fuse -ti quay.io/podman/stable podman run -ti docker.io/busybox echo hello
hello
  1. Beachten Sie, dass wir im Gegensatz zu dem Rooful im Rootful-Fall zuvor nicht die gefährlichen Sicherheitsfunktionen sys_admin hinzufügen müssen und mknod
  2. In diesem Fall verwende ich --user podman , wodurch der Podman innerhalb des Containers automatisch innerhalb des Benutzernamensraums ausgeführt wird
  3. Deaktiviere immer noch SELinux, da es das Mounten blockiert
  4. Benötige noch --device /dev/fuse Fuse-Overlayfs innerhalb des Containers zu verwenden

Podman-remote in rootful Podman mit einem geleakten Podman-Socket vom Host

# podman run -v /run:/run --security-opt label=disable quay.io/podman/stable podman --remote run busybox echo hi
hi

In diesem Fall lecken wir /run Verzeichnis vom Host in den Container. Dies ermöglicht podman --remote um mit dem Podman-Socket auf dem Host zu kommunizieren und den Container auf dem Host-Betriebssystem zu starten. Auf diese Weise führen Menschen häufig Docker in Docker aus, insbesondere Docker-Builds. Sie könnten auf diese Weise auch Podman-Builds ausführen und zuvor auf das System gezogene Images nutzen.

Beachten Sie jedoch, dass dies äußerst unsicher ist. Die Prozesse innerhalb des Containers können den Host-Rechner vollständig übernehmen.

  1. Sie müssen immer noch die SELinux-Trennung deaktivieren, da SELinux die Container-Prozesse daran hindern würde, Sockets zu verwenden, die in /run durchgesickert sind .
  2. Der podman --remote Flag wird hinzugefügt, um Podman anzuweisen, im Remote-Modus zu arbeiten. Beachten Sie, dass Sie auch einfach podman-remote installieren können ausführbar in einen Container und verwenden Sie diesen.

[ Erste Schritte mit Containern? Schauen Sie sich diesen kostenlosen Kurs an. Containerisierte Anwendungen bereitstellen:Eine technische Übersicht. ]

Podman-remote in Docker mit einem durchgesickerten Podman-Socket vom Host

# docker run -v /run:/run --security-opt label=disable quay.io/podman/stable podman --remote run busybox echo hi
hi

Dasselbe Beispiel funktioniert für einen Docker-Container.

Dieses Beispiel zeigt einen vollständig gesperrten Container – abgesehen davon, dass SELinux deaktiviert ist – mit dem Podman-Socket, der in den Container gelangt ist. SELinux würde diesen Zugriff blockieren, wie es sollte.

# /bin/podman run --security-opt=label=disable -v /run/podman:/run/podman quay.io/podman/stable podman --remote run alpine echo hi
hi

Rootless Podman mit containerisiertem Rootful Podman

$ podman run --privileged quay.io/podman/stable podman run ubi8 echo hello
Resolved "ubi8" as an alias (/etc/containers/registries.conf.d/shortnames.conf)
..
hello

Rootless Podman läuft auf Rootless Podman

$ podman run --security-opt label=disable --user podman --device /dev/fuse quay.io/podman/stable podman run alpine echo hello

Abschließende Gedanken

Jetzt haben Sie einen Kontext für Podman in den Podman-Optionen, der sowohl den Rootful- als auch den Rootless-Modus verwendet. in verschiedenen Kombinationen. Sie haben auch ein besseres Gefühl für die notwendigen Privilegien und die Überlegungen rund um --privileged Flagge.

Teil zwei dieser Serie befasst sich mit der Verwendung von Podman und Kubernetes. Der Artikel deckt ein ähnliches Gebiet ab, jedoch im Kontext von Kubernetes.

[ Möchten Sie Ihre Fähigkeiten als Systemadministrator testen? Machen Sie noch heute einen Kompetenztest. ]


Linux
  1. So verwenden Sie BusyBox unter Linux

  2. Wie ich Cron unter Linux verwende

  3. So installieren und verwenden Sie Podman in OpenSUSE Leap 15.3

  4. So führen Sie einen Cron-Job in einem Docker-Container aus

  5. Verwenden Sie perf in einem Docker-Container ohne --privilegiert

So verwenden Sie Instagram im Terminal

So führen Sie Pods als systemd-Dienste mit Podman aus

So verwenden Sie den PS-Befehl

So verwenden Sie den TOP-Befehl

So installieren und verwenden Sie Podman (Docker-Alternative)

Wie verwende ich die Linux-Bash-Shell in Windows 10?