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.
- Schopnosti:
--cap-add=sys_admin,mknod
Potřebujeme přidat dvě možnosti Linuxu.- 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ů.
- 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).
- 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. - 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
- Poznámka:Docker nepodporuje
--cap-add
oddělené čárkami příkaz, takže jsem musel přidat sys_admin a mknod samostatně - Stále potřeba
--device /dev/fuse
, protože výchozí kontejner je/dev/fuse
- 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ě.
- Jako vždy musím zakázat separaci SELinux
- 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
- 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
- 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 - Stále zakazuje SELinux, protože blokuje připojení
- 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č.
- Stále musíte zakázat separaci SELinux, protože SELinux by blokoval procesy kontejneru v používání soketů uniklých v
/run
. 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é nainstalovatpodman-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. ]