Rekommendationer för att köra Buildah i en container

Vad är det fina med att koppla bort behållarens körtid till separata verktygskomponenter? I synnerhet kan dessa verktyg börja kombineras så att de skyddar varandra.

Rekommendationer för att köra Buildah i en container

Många människor attraheras av idén om att bygga containeriserade OCI-bilder inom Kubernetes eller liknande system. Låt oss säga att vi har en CI/CD som hela tiden samlar in bilder, då något liknande Red Hat OpenShift/Kubernetes skulle vara ganska användbart när det gäller lastbalansering under byggnader. Fram till nyligen gav de flesta människor helt enkelt behållare åtkomst till en Docker-socket och lät dem köra docker build-kommandot. För flera år sedan visade viatt detta är väldigt osäkert, faktiskt är det ännu värre än att ge lösenordslös root eller sudo.

Det är därför folk ständigt försöker köra Buildah i en container. Kort sagt, vi skapade exempel hur, enligt vår mening, är bäst att köra Buildah inuti en container, och postade motsvarande bilder på quay.io/buildah. Låt oss börja...

justering

Dessa bilder är byggda från Dockerfiles, som finns i Buildah-förrådet i mappen buildahimage.
Här ska vi titta på stabil version av 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

Istället för OverlayFS, implementerat på Linux-värdnivån, använder vi programmet inuti behållaren säkringsöverlägg, eftersom OverlayFS för närvarande bara kan monteras om du ger den SYS_ADMIN-behörigheter med Linux-funktioner. Och vi vill köra våra Buildah-containrar utan några root-privilegier. Fuse-overlay fungerar ganska snabbt och har bättre prestanda än VFS-lagringsdrivrutinen. Observera att när du kör en Buildah-behållare som använder Fuse, måste du tillhandahålla /dev/fuse-enheten.

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ärefter skapar vi en katalog för ytterligare lagring. Behållare/förråd stöder konceptet att ansluta ytterligare skrivskyddade bildarkiv. Du kan till exempel konfigurera ett överlagringsområde på en maskin och sedan använda NFS för att montera denna lagring på en annan dator och använda bilder från den utan att ladda ner via pull. Vi behöver den här lagringen för att kunna ansluta lite bildlagring från värden som en volym och använda den inuti behållaren.

# 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

Slutligen, genom att använda miljövariabeln BUILDAH_ISOLATION, säger vi till Buildah-behållaren att köras med chroot-isolering som standard. Ytterligare isolering krävs inte här, eftersom vi redan arbetar i en container. För att Buildah ska kunna skapa sina egna namnutrymmesseparerade behållare krävs SYS_ADMIN-privilegiet, vilket skulle kräva att behållarens SELinux- och SECCOMP-regler slappnas av, vilket strider mot vår preferens att bygga från en säker behållare.

Kör Buildah i en container

Bilddiagrammet för Buildah-behållare som diskuterats ovan gör att du flexibelt kan variera metoderna för att lansera sådana behållare.

Hastighet kontra säkerhet

Datorsäkerhet är alltid en kompromiss mellan processens hastighet och hur mycket skydd som lindas runt den. Detta påstående är också sant vid montering av behållare, så nedan kommer vi att överväga alternativen för en sådan kompromiss.

Behållarbilden som diskuteras ovan kommer att behålla sin lagring i /var/lib/containers. Därför måste vi montera innehållet i den här mappen, och hur vi gör detta kommer att i hög grad påverka hastigheten på att bygga behållarbilder.

Låt oss överväga tre alternativ.

1 alternativ. Om maximal säkerhet krävs kan du för varje behållare skapa din egen mapp för behållare/bild och koppla den till behållaren via volymfäste. Och dessutom, placera kontextkatalogen i själva behållaren, i /build-mappen:

# 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

Säkerhet. Buildah som körs i en sådan behållare har maximal säkerhet: den ges inga root-privilegier genom att använda kapacitet, och alla SECOMP- och SELinux-begränsningar gäller för den. En sådan behållare kan till och med köras med User Namespace-isolering genom att lägga till ett alternativ som —uidmap 0: 100000 10000:XNUMX XNUMX.

Prestanda. Men prestandan här är minimal, eftersom alla bilder från behållarregistren kopieras till värden varje gång, och cachelagring fungerar inte alls. När arbetet är klart måste Buildah-behållaren skicka bilden till registret och förstöra innehållet på värden. Nästa gång behållaravbildningen byggs måste den laddas ner från registret igen, eftersom det då inte finns något kvar på värden.

2 alternativ. Om du behöver prestanda på Docker-nivå kan du montera värdbehållaren/lagringen direkt i behållaren.

# 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

Säkerhet. Detta är det minst säkra sättet att bygga behållare eftersom det tillåter behållaren att modifiera lagringen på värden och potentiellt kan mata Podman eller CRI-O med en skadlig bild. Dessutom måste du inaktivera SELinux-separation så att processer i Buildah-behållaren kan interagera med lagringen på värden. Observera att det här alternativet fortfarande är bättre än en Docker-socket eftersom behållaren är låst av återstående säkerhetsfunktioner och inte bara kan köra en behållare på värden.

Prestanda. Här är det maximalt, eftersom caching används fullt ut. Om Podman eller CRI-O redan har laddat ner den önskade bilden till värden, kommer Buildah-processen inuti behållaren inte behöva ladda ner den igen, och efterföljande builds baserade på denna bild kommer också att kunna ta det de behöver från cachen .

3 alternativ. Kärnan i denna metod är att kombinera flera bilder till ett projekt med en gemensam mapp för behållarbilder.

# 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

I det här exemplet tar vi inte bort projektmappen (/var/lib/project3) mellan körningar, så alla efterföljande byggnader inom projektet drar nytta av cachning.

Säkerhet. Något mittemellan alternativ 1 och 2. Å ena sidan har behållare inte tillgång till innehåll på värden och kan följaktligen inte glida in något dåligt i Podman/CRI-O-bildlagringen. Å andra sidan, som en del av dess design, kan en behållare störa monteringen av andra behållare.

Prestanda. Här är det värre än när man använder en delad cache på värdnivå, eftersom man inte kan använda bilder som redan har laddats ner med Podman/CRI-O. Men när Buildah har laddat ner bilden kan bilden användas i alla efterföljande byggen inom projektet.

Ytterligare förvaring

У containrar/förråd Det finns en så cool sak som ytterligare butiker (ytterligare butiker), tack vare vilka containermotorer kan använda externa bildlager i skrivskyddat överlagringsläge när de lanserar och bygger containrar. I huvudsak kan du lägga till en eller flera skrivskyddade lagringar till filen storage.conf så att när du startar behållaren letar behållarmotorn efter den önskade bilden i dem. Dessutom kommer den bara att ladda ner bilden från registret om den inte hittar den i någon av dessa lagringar. Behållarmotorn kommer bara att kunna skriva till skrivbar lagring...

Om du bläddrar uppåt och tittar på Dockerfilen som vi använder för att bygga bilden quay.io/buildah/stable, så finns det rader så här:

# 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

På den första raden ändrar vi /etc/containers/storage.conf inuti behållaravbildningen och säger till lagringsdrivrutinen att använda "additionalimagestores" i mappen /var/lib/shared. Och på nästa rad skapar vi en delad mapp och lägger till ett par låsfiler så att det inte blir missbruk från containrar/lagring. I grund och botten skapar vi helt enkelt en tom behållarbildbutik.

Om du monterar behållare/lagring på en nivå högre än denna mapp kommer Buildah att kunna använda bilderna.

Låt oss nu återgå till alternativ 2 som diskuterats ovan, när Buildah-behållaren kan läsa och skriva till behållare/lager på värdar och följaktligen har maximal prestanda på grund av cachning av bilder på Podman/CRI-O-nivå, men ger ett minimum av säkerhet eftersom den kan skriva direkt till minnet. Låt oss nu lägga till ytterligare lagring här och få det bästa av två världar.

# 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

Observera att värdens /var/lib/containers/storage är monterad till /var/lib/shared inuti behållaren i skrivskyddat läge. Därför kan Buildah, när du arbetar i en container, använda alla bilder som tidigare laddats ner med Podman/CRI-O (hej, hastighet), men kan bara skriva till sin egen lagring (hej, säkerhet). Observera också att detta görs utan att inaktivera SELinux-separation för behållaren.

Viktig nyans

Du bör under inga omständigheter ta bort några bilder från det underliggande arkivet. Annars kan Buildah-behållaren krascha.

Och detta är inte alla fördelarna

Möjligheterna till ytterligare lagring är inte begränsade till ovanstående scenario. Du kan till exempel placera alla behållarbilder på en delad nätverkslagring och ge åtkomst till den till alla Buildah-behållare. Låt oss säga att vi har hundratals bilder som vårt CI/CD-system regelbundet använder för att bygga containerbilder. Vi koncentrerar alla dessa bilder på en lagringsvärd och sedan, med hjälp av de föredragna nätverkslagringsverktygen (NFS, Gluster, Ceph, ISCSI, S3...), öppnar vi allmän åtkomst till denna lagring för alla Buildah- eller Kubernetes-noder.

Nu räcker det att montera denna nätverkslagring i Buildah-behållaren på /var/lib/shared och det är allt - Buildah-behållare behöver inte längre ladda ner bilder via pull. Således kastar vi ut pre-populationsfasen och är omedelbart redo att rulla ut containrarna.

Och naturligtvis kan detta användas inom ett live Kubernetes-system eller containerinfrastruktur för att starta och köra containrar var som helst utan någon pull-nedladdning av bilder. Dessutom kan behållarregistret, som tar emot en push-begäran om att ladda upp en uppdaterad bild till det, automatiskt skicka denna bild till en delad nätverkslagring, där den omedelbart blir tillgänglig för alla noder.

Behållarbilder kan ibland nå många gigabyte i storlek. Funktionaliteten för ytterligare lagring gör att du kan undvika kloning av sådana bilder över noder och gör att behållare startas nästan omedelbart.

Dessutom arbetar vi för närvarande på en ny funktion som kallas överläggsvolymfästen, som kommer att göra att bygga containrar ännu snabbare.

Slutsats

Att köra Buildah i en container i Kubernetes/CRI-O, Podman eller till och med Docker är genomförbart, enkelt och mycket säkrare än att använda docker.socket. Vi har avsevärt ökat flexibiliteten i att arbeta med bilder, så att du kan köra dem på en mängd olika sätt för att optimera balansen mellan säkerhet och prestanda.

Funktionaliteten för ytterligare lagring gör att du kan påskynda eller till och med helt eliminera nedladdningen av bilder till noder.

Källa: will.com

Lägg en kommentar