Doporučení pro spuštění Buildahu uvnitř kontejneru

Jaké výhody přináší rozložení prostředí pro spouštění kontejnerů na jednotlivé nástroje? Především to, že tyto nástroje lze kombinovat tak, aby se navzájem chránily.

Doporučení pro spuštění Buildahu uvnitř kontejneru

Mnohé láká myšlenka provádět sestavení kontejnerových OCI obrazů v rámci Kubernetes nebo podobného systému. Představme si, že máme CI/CD, které neustále vytváří obrazy, pak něco jako Red Hat OpenShift/Kubernetes было бы весьма полезно с точки зрения распределения нагрузки при сборке. До недавних пор большинство людей просто давали контейнерам доступ к Docker-сокету и разрешали выполнять команду docker build. Před několika lety jsme již ukázali, že to je velmi nebezpečné, vlastně je to ještě horší než dávat bez hesla root nebo sudo.

Proto se lidé neustále pokoušejí spouštět Buildah v kontejneru. Zkrátka, vytvořili jsme příklad jak, podle našeho názoru, nejlépe spouštět Buildah uvnitř kontejneru, a nahráli jsme příslušné obrazy na quay.io/buildah. Pojďme na to…

Nastavení

Tyto obrazy jsou sestaveny z Dockerfiles, které lze nalézt v repozitáři Buildah ve složce buildahimage.
Zde se podíváme na stabilní verzi Dockerfile.

# 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

Místo OverlayFS, implementovaného na úrovni jádra Linuxu hostitele, používáme uvnitř kontejneru program fuse-overlay, protože v současné době může OverlayFS provádět montáž pouze s pravomocemi SYS_ADMIN prostřednictvím linuxových schopností. A my chceme spouštět naše Buildah kontejnery bez jakýchkoli privilegovaných práv. Fuse-overlay funguje velmi rychle a má lepší výkon než storage driver VFS. Všimněte si, že při spuštění Buildah kontejneru, který používá Fuse, je nutné poskytnout zařízení /dev/fuse.

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

Dále vytvoříme katalog pro dodatečná úložiště. Container/storage podporuje koncept připojení dodatečných read-only úložišť obrazů. Například lze nastavit overlay storage area na jednom stroji a poté prostřednictvím NFS připojit toto úložiště na jiném stroji a používat obrazy z něj bez stahování přes pull. Toto úložiště potřebujeme, abychom mohli připojit jako svazek nějaké úložiště obrazů z hostitele a používat je uvnitř kontejneru.

# 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

A nakonec, pomocí proměnné prostředí BUILDAH_ISOLATION říkáme, že kontejnery Buildah by měly být ve výchozím nastavení spouštěny s izolací chroot. Další izolace zde není potřeba, protože už pracujeme v kontejneru. Aby Buildah vytvářel své vlastní kontejnery se sdílením jmenových prostorů, je potřeba privilegium SYS_ADMIN, což znamená, že budeme muset uvolnit pravidla SELinux a SECCOMP pro kontejner, což je v rozporu s naším nastavením provádět sestavení ze zabezpečeného kontejneru.

Spouštíme Buildah uvnitř kontejneru

Na schématu obrazu kontejneru Buildah uvedeném výše lze flexibilně variabilizovat způsoby spuštění těchto kontejnerů.

Rychlost versus bezpečnost

Počítačová bezpečnost je vždy kompromis mezi rychlostí provedení procesu a tím, kolik ochrany je kolem toho nařizováno. Toto tvrzení platí i při sestavování kontejnerů, proto se níže podíváme na možnosti tohoto kompromisu.

Výše uvedený obrazu kontejneru bude uchovávat své úložiště v /var/lib/containers. Proto musíme podmountovat obsah do této složky, a způsob, jakým to uděláme, bude mít značný vliv na rychlost sestavování kontejnerových obrazů.

Podívejme se na tři varianty.

Varianta 1. Pokud je vyžadována maximální bezpečnost, může být pro každý kontejner vytvořena vlastní složka pro containers/image a připojena ke kontejneru prostřednictvím volume-mount. Kromě toho lze umístit kontextový adresář přímo do kontejneru, do složky /build:

# 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

Bezpečnost. Pracující v takovém kontejneru má Buildah maximální bezpečnost: nemá žádná rootová privilegia prostřednictvím capabilities a vztahují se na něj všechna omezení SECOMP a SELinux. Takový kontejner lze dokonce spustit s izolací User Namespace, přidáním možnosti jako —uidmap 0:100000:10000.

Výkon. Výkon je zde však minimální, protože jakékoli obrazy z kontejnerových registrů jsou vždy znovu kopírovány na hostitele a kešování nefunguje vůbec. Po dokončení své práce musí Buildah-kontejner poslat obraz do registru a vymazat obsah na hostiteli. Když se kontejnerový obraz bude příště sestavovat, bude třeba ho znovu stáhnout z registru, protože na hostiteli do té doby už nic nezůstane.

Varianta 2. Pokud je potřeba výkon na úrovni Dockeru, je možné podmountovat container/storage hostitele přímo do kontejneru.

# 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

Bezpečnost. Toto je nejméně bezpečný způsob sestavení kontejnerů, protože kontejner má povolení modifikovat úložiště na hostitelském systému, což může potenciálně umožnit vložit Podmanu nebo CRI-O škodlivý obraz. Kromě toho je nutné vypnout separaci SELinux, aby procesy v Buildah kontejneru mohly interagovat s úložištěm na hostiteli. Všimněte si, že tato možnost je stále lepší než Docker socket, protože kontejner je blokován zbývajícími bezpečnostními funkcemi a nemůže jen tak vzít a spustit nějaký kontejner na hostiteli.

Výkon. Zde je to maximální, protože je plně využíváno caching. Pokud Podman nebo CRI-O již stáhli potřebný obraz na hostitelském systému, pak proces Buildah uvnitř kontejneru nebude muset stahovat znovu, a následné sestavy na základě tohoto obrazu také mohou vzít, co potřebují, z cache.

Možnost 3. Podstatou tohoto způsobu je kombinovat několik obrazů do jednoho projektu se společnou složkou pro kontejnerové obrazy.

# 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

V tomto příkladu mezitím nesmažeme složku projektu (/var/lib/project3) mezi spuštěními, takže všechny následující sestavy v rámci projektu využívají výhod caching.

Bezpečnost. Něco mezi možnostmi 1 a 2. Na jedné straně kontejnery nemají přístup k obsahu na hostiteli a tudíž nemohou vložit něco špatného do úložiště obrazů Podman/CRI-O. Na druhé straně v rámci svého projektu může kontejner zasahovat do sestavení jiných kontejnerů.

Výkon. Tady je to horší než při použití společného cache na úrovni hostitele, protože nelze použít obrazy, které byly dříve staženy pomocí Podman/CRI-O. Nicméně poté, co Buildah stáhne obraz, lze tento obraz využít v jakýchkoli následných sestavách v rámci projektu.

Další úložiště

V containers/storage Existuje skvělá věc jako dodatečné úložiště (additional stores), díky které při spuštění a sestavení kontejnerů mohou kontejnerové enginy používat externí úložiště obrazů v režimu pouze pro čtení overlay. V podstatě lze do souboru storage.conf přidat jedno nebo více úložišť "pouze pro čtení", aby kontejnerový engine při spuštění kontejneru hledal potřebný obraz v těchto úložištích. Přičemž obraz si stáhne z registru pouze v případě, že jej nenajde v žádném z těchto úložišť. Kontejnerový engine bude moci zapisovat pouze do dostupných úložišť pro zápis…

Pokud posuneme nahoru a podíváme se na Dockerfile, který používáme pro sestavení obrazu quay.io/buildah/stable, tak tam jsou takovéto řádky:

# 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

V prvním řádku modifikujeme /etc/containers/storage.conf uvnitř kontejnerového obrazu, říkáme storage driveru, aby používal "additionalimagestores" v adresáři /var/lib/shared. A v následujícím řádku vytváříme sdílenou složku a přidáváme pár souborů s uzamčením, aby nedocházelo k problémům ze strany containers/storage. V podstatě pouze vytváříme prázdné úložiště kontejnerových obrazů.

Pokud namontujeme containers/storage o úroveň výš než tato složka, Buildah bude moci používat obrázky.

Nyní se vraťme k výše uvedené variantě 2, kdy Buildah kontejner může číst a zapisovat do containers/store na hostitelích, a tedy má maximální výkon díky ukládání obrazů na úrovni Podman/CRI-O, ale má minimální bezpečnost, protože může psát přímo do úložišť. A nyní přidáme dodatečná úložiště a dostaneme to nejlepší z obou světů.

# 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

Všimněte si, že /var/lib/containers/storage hostitele je namontováno do /var/lib/shared uvnitř kontejneru v režimu pouze pro čtení. Proto při práci v kontejneru může Buildah používat jakékoli obrázky, které byly již dříve staženy prostřednictvím Podman/CRI-O (ahoj, rychlost), ale psát může pouze do svého vlastního úložiště (ahoj, bezpečnost). Také si všimněte, že to probíhá bez vypnutí oddělení SELinux pro kontejner.

Důležitý aspekt

V žádném případě nelze odstraňovat žádné obrázky z podřízeného úložiště. Jinak může Buildah kontejner selhat.

A to rozhodně nejsou všechny výhody

Možnosti dodatečných úložišť se neomezuje pouze na výše popsaný scénář. Například je možné umístit všechny kontejnerové obrazy do společného síťového úložiště a poskytnout k němu přístup všem kontejnerům Buildah. Představme si, že máme stovky obrazů, které náš CI/CD systém pravidelně používá k sestavení kontejnerových obrazů. Soustředíme všechny tyto obrazy na nějakém jednom hostitelském úložišti a poté, pomocí preferovaných prostředků síťového úložiště (NFS, Gluster, Ceph, ISCSI, S3…), otevřeme společný přístup k tomuto úložišti všem uzlům Buildah nebo Kubernetes.

Nyní stačí přimontovat toto síťové úložiště do kontejneru Buildah na /var/lib/shared a to je všechno – kontejnerům Buildah už nebude potřeba stahovat obrazy prostřednictvím pull. Tímto způsobem vynecháváme fázi předběžného naplnění (pre-population) a jsme ihned připraveni nasazovat kontejnery.

A samozřejmě, to lze použít v rámci stávajícího systému Kubernetes nebo kontejnerové infrastruktury, aby bylo možné spouštět a vykonávat kontejnery kdekoli bez jakéhokoli stahování obrazů prostřednictvím pull. Navíc může registr kontejnerů, který obdrží push požadavek na nahrání aktualizovaného obrazu, automaticky odeslat tento obraz do společného síťového úložiště, kde je ihned dostupný všem uzlům.

Velikosti kontejnerových obrazů mohou někdy dosahovat několika gigabajtů. Funkce dodatečných úložišť umožňuje obejít klonování těchto obrazů po uzlech a činí spuštění kontejnerů prakticky okamžitým.

Kromě toho v současnosti pracujeme na nové funkce montování overlay volume, která ještě více urychlí sestavování kontejnerů.

Závěr

Provádět Buildah uvnitř kontejneru v prostředí Kubernetes/CRI-O, Podman nebo dokonce v Dockeru je zcela reálné, navíc je to jednoduché a mnohem bezpečnější než používat docker.socket. Výrazně jsme zvýšili flexibilitu práce s obrazy, a nyní je můžete spouštět různými způsoby pro optimální rovnováhu mezi bezpečností a výkonem.

Funkce dodatečných úložišť umožňuje urychlit nebo dokonce zcela odstranit stahování obrazů na uzly.

Zdroj: habr.com

Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster