GNU/Linux >> Linux Esercitazione >  >> Linux

Come usare Podman all'interno di un contenitore

Uno degli argomenti più richiesti alle persone che lavorano su tecnologie di container a monte è l'esecuzione di Podman all'interno di un container. La maggior parte di questo è stata storicamente correlata a Docker in Docker (DIND), ma ora le persone vogliono anche eseguire Podman in Podman (PINP) o Podman in Docker (PIND).

Ma Podman può essere eseguito in più modi, rootful e rootless. Finiamo con le persone che vogliono eseguire varie combinazioni di Podman rootful e rootless:

  • Podman radicato in Podman radicato
  • Podman senza radice in Podman radicato
  • Podman Rootful in Podman senza radici
  • Podman senza radici in Podman senza radici

Ottieni l'immagine.

Questo blog tenterà di coprire ogni combinazione, iniziando con una discussione sui privilegi. Inizieremo con lo scenario PINP qui nella prima parte. Nella seconda parte della serie tratteremo un terreno simile, ma lo faremo nel contesto di Kubernetes. Assicurati di leggere entrambi gli articoli per un quadro completo.

I motori container richiedono privilegi

Per eseguire un motore di container come Podman all'interno di un container, la prima cosa che devi capire è che hai bisogno di una discreta quantità di privilegi.

  • I contenitori richiedono più UID. La maggior parte delle immagini del contenitore richiede più di un UID per funzionare. Ad esempio, potresti avere un'immagine con la maggior parte dei file di proprietà di root, ma alcuni di proprietà dell'utente apache (UID=60).
  • I motori container montano i file system e utilizzano il clone della chiamata di sistema per creare spazi dei nomi utente.

Nota:potrebbe essere necessaria una versione più recente di Podman. Gli esempi in questo blog sono stati eseguiti con Podman 3.2.

La nostra immagine di prova

Per gli esempi in questo blog, utilizzeremo quay.io/podman/stable image, che è stato creato con l'idea di trovare il modo migliore per eseguire Podman all'interno di un container. Puoi esaminare come costruiamo questa immagine dal Dockerfile e da containers.conf immagine nel repository 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=""

Esaminiamo il Dockerfile.

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.*

Prima l'ultima versione di fedora, quindi l'aggiornamento agli ultimi pacchetti. Nota che reinstalla shadow-utils , poiché esiste un problema noto in shadow-utils installa sull'immagine Fedora dove filecaps su newsubuid e newsubgid non sono impostati. Reinstallazione di shadow-utils risolve il problema. Quindi, installa Podman e fuse-overlayfs . Non installiamo container-selinux perché non è necessario all'interno del contenitore.

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

Quindi creo un utente podman e imposta il /etc/subuid e /etc/subgid file per utilizzare 5000 UID. Viene utilizzato per configurare lo spazio dei nomi utente all'interno del contenitore. 5000 è un numero arbitrario e potenzialmente troppo piccolo. Abbiamo scelto questo numero perché è inferiore ai 65.000 assegnati agli utenti rootless. Se avessi eseguito il container solo come root, 65k sarebbe stato un numero migliore.

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

Poiché possiamo eseguire container rootfull e rootless con questa immagine, creiamo due volumi. Rootfull Podman usa /var/lib/containers per lo storage di container e gli usi rootless /home/podman/.local/share/containers . L'overlay overlay è spesso negato dal kernel, quindi questo crea volumi non overlay da utilizzare all'interno del contenitore.

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

Ho preconfigurato due containers.conf file per assicurarsi che i contenitori vengano eseguiti più facilmente in ciascuna modalità.

L'immagine è impostata per funzionare con fuse-overlayfs per impostazione predefinita. In alcuni casi, potresti eseguire il file system di overlay del kernel per la modalità rootful e presto sarai in grado di farlo in modalità rootless. Tuttavia, per ora, utilizziamo fuse-overlayfs come spazio di archiviazione del contenitore all'interno del contenitore. Altre persone hanno utilizzato il driver di archiviazione VFS, ma non è così efficiente.

Il flag --privileged

Il modo più semplice per eseguire Podman all'interno di un container è utilizzare --privileged bandiera.

Rootful Podman in Rootful Podman con --privileged

# 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

Per risparmiare tempo, dato che farò molti esperimenti, ho creato una directory sul mio host ./mycontainers , che monterò del volume nel contenitore da utilizzare e non dovrò estrarre l'immagine ogni volta.

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

Podman senza radice in Podman radicato con --privileged

Il quay.io/podman/stable l'immagine è impostata con un podman utente che puoi utilizzare per eseguire container senza root.

# 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

Nota in questo caso, il Podman in esecuzione all'interno del contenitore è in esecuzione come utente podman . Questo perché il Podman containerizzato utilizza lo spazio dei nomi utente per creare un container confinato all'interno del container privilegiato.

Esegui Podman senza root in Docker con --privileged

Simile a Podman rootful, puoi anche eseguire Podman rootless all'interno di Docker con il --privileged opzione.

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

Podman senza radici con 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

Possiamo farlo in modo più sicuro?

Nota che anche se abbiamo eseguito i contenitori esterni --privileged sopra, i contenitori interni funzionano in modalità bloccata. Il Podman senza radici in esecuzione all'interno del container è davvero bloccato e avrebbe difficoltà a scappare. Detto questo, non sono un fan dell'utilizzo di --privileged bandiera. Credo che possiamo fare di meglio dal punto di vista della sicurezza.

In esecuzione senza il flag --privileged

Diamo un'occhiata a come rimuovere il --privileged flag per una maggiore sicurezza.

Rootful Podman in Rootful Podman senza --privileged

# 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

Possiamo eliminare il --privileged flag da Podman rootful ma devi comunque disabilitare alcune funzionalità di sicurezza per far funzionare Podman rootful all'interno del contenitore.

  1. Funzionalità:--cap-add=sys_admin,mknod Dobbiamo aggiungere due funzionalità Linux.
    1. CAP_SYS_ADMIN è necessario per il Podman in esecuzione come root all'interno del contenitore per montare i file system richiesti.
    2. CAP_MKNOD è necessario affinché Podman venga eseguito come root all'interno del contenitore per creare i dispositivi in ​​/dev . (Nota che Docker lo consente per impostazione predefinita).
  2. Dispositivi:il --device /dev/fuse flag deve utilizzare fuse-overlayfs all'interno del contenitore. Questa opzione dice a Podman sull'host di aggiungere /dev/fuse al container in modo che Podman containerizzato possa usarlo.
  3. Disabilita SELinux:il --security-opt label=disable opzione dice al Podman dell'host di disabilitare la separazione di SElinux per il contenitore. SELinux non consente ai processi containerizzati di montare tutti i file system necessari per essere eseguiti all'interno di un container.

Rootful Podman in Docker senza --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. Nota Docker non supporta la virgola separata --cap-add comando, quindi ho dovuto aggiungere sys_admin e mknod separatamente
  2. Ancora necessario --device /dev/fuse , poiché per impostazione predefinita il contenitore è /dev/fuse
  3. Docker crea sempre volumi incorporati di proprietà di root:root, quindi dobbiamo creare un volume da montare per Podman nel contenitore per poterlo utilizzare per l'archiviazione.
  4. Come sempre, devo disabilitare la separazione di SELinux
  5. Devi anche disabilitare seccomp , poiché Docker ha un seccomp leggermente più rigido politica rispetto a Podman. Potresti semplicemente usare una politica di sicurezza Podman usando--seccomp=/usr/share/containers/seccomp.json
# 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

Podman senza radice in Podman radicato senza --privileged

Esegui non -contenitore privilegiato con Podman all'interno utilizzando un utente non root utilizzando lo spazio dei nomi utente.

# 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. Nota che, a differenza del rooful all'interno del caso rootful prima, non dobbiamo aggiungere le pericolose funzionalità di sicurezza sys_admin e mknod
  2. In questo caso, sto utilizzando --user podman , che fa in modo che Podman all'interno del contenitore venga eseguito automaticamente all'interno dello spazio dei nomi utente
  3. Ancora disabilitando SELinux poiché blocca il montaggio
  4. Servo ancora --device /dev/fuse per utilizzare i fusibili di sovrapposizione all'interno del contenitore

Podman-remote in Podman rootful con una presa Podman trapelata dall'host

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

In questo caso, stiamo perdendo il /run directory dall'host nel contenitore. Ciò consente a podman --remote per comunicare con il socket Podman sull'host e avviare il contenitore sul sistema operativo host. Questo è spesso il modo in cui le persone eseguono Docker In Docker, in particolare le build Docker. Puoi anche eseguire le build Podman in questo modo e sfruttare le immagini precedentemente importate nel sistema.

Nota, tuttavia, questo è estremamente insicuro. I processi all'interno del container possono assumere totalmente il controllo della macchina host.

  1. Devi comunque disabilitare la separazione di SELinux perché SELinux bloccherebbe i processi del contenitore dall'uso di socket trapelati in /run .
  2. Il podman --remote viene aggiunto il flag per dire a Podman di lavorare in modalità remota. Nota che potresti anche installare il podman-remote eseguibile in un contenitore e usalo.

[ Iniziare con i container? Dai un'occhiata a questo corso gratuito. Distribuzione di applicazioni containerizzate:una panoramica tecnica. ]

Telecomando Podman in Docker con una presa Podman trapelata dall'host

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

Lo stesso esempio funziona per un contenitore Docker.

Questo esempio mostra un contenitore completamente bloccato, diverso da SELinux disabilitato, con il socket Podman trapelato nel contenitore. SELinux bloccherebbe questo accesso, come dovrebbe.

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

Podman senza radice con Podman pieno di radici containerizzato

$ 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

Podman senza radice che esegue Podman senza radice

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

Pensieri finali

Ora hai un po' di contesto per Podman nelle opzioni Podman, usando sia le modalità rootful che rootless. in varie combinazioni. Hai anche un'idea migliore dei privilegi necessari e delle considerazioni che circondano il --privileged bandiera.

La seconda parte di questa serie esamina l'uso di Podman e Kubernetes. L'articolo copre un territorio simile ma nel contesto di Kubernetes.

[ Vuoi testare le tue capacità di amministratore di sistema? Fai una valutazione delle abilità oggi. ]


Linux
  1. Come usare BusyBox su Linux

  2. Come uso cron in Linux

  3. Come usare il comando Su in Linux

  4. Come installare e utilizzare Podman in OpenSUSE Leap 15.3

  5. Come eseguire un comando all'interno di un contenitore Systemd in esecuzione?

Come utilizzare Instagram nel terminale

Come eseguire i pod come servizi di sistema con Podman

Come usare il comando PS

Come usare il comando TOP

Come installare e utilizzare Podman (alternativa Docker)

Come utilizzare Linux Bash Shell in Windows 10?