GNU/Linux >> Znalost Linux >  >> Linux

Jak používat Podman uvnitř kontejneru

Jedním z nejčastějších dotazů na témata lidí pracujících na upstream kontejnerových technologiích je spuštění aplikace Podman v kontejneru. Většina z toho historicky souvisela s Docker in Docker (DIND), ale nyní chtějí lidé také provozovat Podman in Podman (PINP) nebo Podman in Docker (PIND).

Ale Podman může být provozován několika způsoby, rootling a rootless. Skončíme s lidmi, kteří chtějí provozovat různé kombinace rootful a rootless Podman:

  • Rootful Podman v rootful Podman
  • Rootless Podman v rootful Podman
  • Rootful Podman v rootless Podman
  • Rootless Podman v rootless Podman

Dostanete obrázek.

Tento blog se pokusí pokrýt každou kombinaci, počínaje diskusí o právech. Začneme scénářem PINP zde v první části. Ve druhé části série se budeme zabývat podobnou oblastí, ale učiníme tak v kontextu Kubernetes. Pro úplný obrázek si nezapomeňte přečíst oba články.

Kontejnerové stroje vyžadují oprávnění

Aby bylo možné provozovat kontejnerový motor jako Podman v kontejneru, první věc, kterou musíte pochopit, je, že potřebujete slušnou dávku privilegií.

  • Kontejnery vyžadují více UID. Většina obrázků kontejnerů potřebuje ke svému fungování více než jedno UID. Můžete mít například obrázek s většinou souborů vlastněných rootem, ale některé vlastní uživatel apache (UID=60).
  • Kontejnerové stroje připojují systémy souborů a používají klon systémového volání k vytváření uživatelských jmenných prostorů.

Poznámka:Možná budete potřebovat novější verzi Podmana. Příklady v tomto blogu byly spuštěny s Podmanem 3.2.

Náš testovací obrázek

Pro příklady v tomto blogu použijeme quay.io/podman/stable image, který byl vytvořen s myšlenkou najít nejlepší způsob, jak spustit Podman v kontejneru. Můžete prozkoumat, jak vytváříme tento obrázek z Dockerfile a containers.conf obrázek v úložišti 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=""

Podívejme se na 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.*

Nejprve stáhněte nejnovější fedoru a poté aktualizujte na nejnovější balíčky. Všimněte si, že přeinstaluje shadow-utils , protože existuje známý problém v shadow-utils nainstalujte do obrazu Fedory, kde filecaps na newsubuid a newsubgid nejsou nastaveny. Přeinstalování shadow-utils řeší problém. Dále nainstalujte Podman a také fuse-overlayfs . Neinstalujeme container-selinux protože to není potřeba v kontejneru.

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

Dále vytvořím uživatele podman a nastavte /etc/subuid a /etc/subgid soubory používat 5000 UID. To se používá k nastavení prostoru uživatelských jmen v kontejneru. 5000 je libovolné číslo a potenciálně příliš malé. Vybrali jsme toto číslo, protože je menší než 65k přidělených uživatelům bez rootu. Pokud byste kontejner spouštěli pouze jako root, 65k by bylo lepší číslo.

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

Protože s tímto obrazem můžeme spouštět rootfull a rootless kontejnery, vytvoříme dva svazky. Rootfull Podman používá /var/lib/containers pro jeho úložiště kontejnerů a použití bez rootu /home/podman/.local/share/containers . Překrytí přes překrytí je jádrem často zakázáno, takže to vytváří nepřekrývající se svazky, které lze použít v kontejneru.

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

Předkonfiguroval jsem dva containers.conf soubory, abyste zajistili snazší běh kontejnerů v každém režimu.

Obrázek je ve výchozím nastavení nastaven tak, aby běžel s fuse-overlayfs. V určitých případech můžete spustit překryvný souborový systém jádra pro rootful režim a brzy to budete moci udělat v režimu rootless. Prozatím však používáme pojistkové překryvy jako naše kontejnerové úložiště v kontejneru. Jiní lidé používali ovladač úložiště VFS, ale to není tak efektivní.

Příznak --privileged

Nejjednodušší způsob, jak spustit Podman uvnitř kontejneru, je použít --privileged vlajka.

Rootful Podman v rootful Podman s --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

Abych ušetřil čas, protože budu dělat spoustu experimentů, vytvořil jsem na svém hostiteli adresář ./mycontainers , který objemově připojím do kontejneru, který se má použít, a nebudu muset pokaždé vytahovat obrázek.

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

Rootless Podman v rootful Podman s --privileged

quay.io/podman/stable obrázek je nastaven pomocí podmana uživatele, kterého můžete použít ke spouštění kontejnerů bez kořenů.

# 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

V tomto případě podman běžící uvnitř kontejneru běží jako uživatel podman . Je to proto, že kontejnerový Podman používá uživatelský jmenný prostor k vytvoření uzavřeného kontejneru v rámci privilegovaného kontejneru.

Spuštění rootless Podman v Dockeru s --privileged

Podobně jako rootful Podman můžete také spustit rootless Podman v Dockeru s --privileged možnost.

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

Rootless Podman s 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

Můžeme to udělat bezpečněji?

Všimněte si, že i když jsme spustili vnější kontejnery --privileged výše, vnitřní kontejnery běží v uzamčeném režimu. Podman bez kořenů běžící v kontejneru je skutečně uzamčen a jen velmi obtížně by unikal. Vzhledem k tomu nejsem příznivcem používání --privileged vlajka. Věřím, že z hlediska bezpečnosti můžeme být lepší.

Spuštění bez příznaku --privileged

Podívejme se, jak můžeme odstranit --privileged příznak pro lepší zabezpečení.

Rootful Podman v rootful Podman bez --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

Můžeme odstranit --privileged příznak z rootful Podman, ale stále musíte deaktivovat některé bezpečnostní funkce, aby rootovaný Podman v kontejneru fungoval.

  1. Schopnosti:--cap-add=sys_admin,mknod Potřebujeme přidat dvě možnosti Linuxu.
    1. CAP_SYS_ADMIN je vyžadován pro Podman běžící jako root uvnitř kontejneru k připojení požadovaných souborových systémů.
    2. CAP_MKNOD je vyžadován pro Podman spuštěný jako root uvnitř kontejneru k vytvoření zařízení v /dev . (Všimněte si, že Docker to ve výchozím nastavení umožňuje).
  2. Zařízení:--device /dev/fuse vlajka musí používat pojistkové překryvy uvnitř kontejneru. Tato možnost říká Podmanovi na hostiteli, aby přidal /dev/fuse do kontejneru, aby jej mohl kontejnerový Podman použít.
  3. Zakázat SELinux:--security-opt label=disable volba říká hostitelskému Podmanovi, aby zakázal separaci SElinux pro kontejner. SELinux neumožňuje kontejnerizovaným procesům připojit všechny souborové systémy potřebné ke spuštění uvnitř kontejneru.

Rootful Podman v Dockeru bez --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. Poznámka:Docker nepodporuje --cap-add oddělené čárkami příkaz, takže jsem musel přidat sys_admin a mknod samostatně
  2. Stále potřeba --device /dev/fuse , protože výchozí kontejner je /dev/fuse
  3. Docker vždy vytváří vestavěné svazky vlastněné uživatelem root:root, takže musíme vytvořit svazek, který pro Podman připojíme do kontejneru, aby jej bylo možné použít pro úložiště.
  4. Jako vždy musím zakázat separaci SELinux
  5. Je také potřeba zakázat seccomp , protože Docker má trochu přísnější seccomp politika než Podman. Můžete použít bezpečnostní politiku Podman pomocí --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

Rootless Podman v rootful Podman bez --privileged

Spustit ne -privilegovaný kontejner s Podmanem uvnitř pomocí uživatele bez oprávnění root pomocí uživatelského jmenného prostoru.

# 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. Upozorňujeme, že na rozdíl od předchozího rooful v rootful case nemusíme přidávat nebezpečné funkce zabezpečení sys_admin a mknod
  2. V tomto případě používám --user podman , což automaticky způsobí, že se Podman v kontejneru spustí v rámci uživatelského jmenného prostoru
  3. Stále zakazuje SELinux, protože blokuje připojení
  4. Stále potřebujete --device /dev/fuse k použití fuse-overlayfs v kontejneru

Vzdálené ovládání Podman v rootu Podman s uniklým socketem Podman z hostitele

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

V tomto případě uniká /run adresáře z hostitele do kontejneru. To umožňuje podman --remote komunikovat se socketem Podman na hostiteli a spustit kontejner na hostitelském OS. Lidé často spouštějí Docker v Dockeru, zejména sestavení Dockeru. Tímto způsobem můžete také spouštět sestavení Podmana a využívat obrázky, které byly dříve staženy do systému.

Všimněte si však, že je to extrémně nejisté. Procesy v kontejneru mohou zcela převzít hostitelský počítač.

  1. Stále musíte zakázat separaci SELinux, protože SELinux by blokoval procesy kontejneru v používání soketů uniklých v /run .
  2. podman --remote příznak je přidán, aby řekl Podmanovi pracovat ve vzdáleném režimu. Všimněte si, že můžete také nainstalovat podman-remote spustitelný do kontejneru a použijte toto.

[ Začínáte s kontejnery? Podívejte se na tento bezplatný kurz. Nasazení kontejnerových aplikací:technický přehled. ]

Podman-remote v Dockeru s uniklým socketem Podman z hostitele

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

Stejný příklad funguje pro kontejner Docker.

Tento příklad ukazuje plně uzamčený kontejner – jiný než deaktivovaný SELinux – se zásuvkou Podman unikla do kontejneru. SELinux by tento přístup zablokoval, jak by měl.

# /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 s kontejnerizovaným 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 běží rootless Podman

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

Poslední myšlenky

Nyní máte nějaký kontext pro Podman v možnostech Podman, používající jak rootful, tak rootless režimy. v různých kombinacích. Také máte lepší přehled o nezbytných oprávněních a úvahách souvisejících s --privileged vlajka.

Druhá část této série se zabývá používáním Podman a Kubernetes. Článek pokrývá podobné území, ale v kontextu Kubernetes.

[ Chcete si vyzkoušet své schopnosti správce systému? Proveďte hodnocení dovedností ještě dnes. ]


Linux
  1. Jak používat BusyBox na Linuxu

  2. Jak používám cron v Linuxu

  3. Náhled technologie:Spuštění kontejneru uvnitř kontejneru

  1. Jak používat Nginx k přesměrování

  2. Jak zjistit, zda proces běží uvnitř lxc/Docker?

  3. Jak spustit úlohu cron uvnitř kontejneru dockeru

  1. Jak používat Su Command v Linuxu

  2. Jak používat Podman uvnitř Kubernetes

  3. Jak nainstalovat a používat Podman v OpenSUSE Leap 15.3