Anbefalinger til at køre Buildah inden i en beholder

Hvad er fordelen ved at opdele containerudførelsesmiljøet i separate værktøjer? Især at disse værktøjer kan kombineres for at beskytte hinanden.

Anbefalinger til at køre Buildah inden i en beholder

Mange tiltrækkes af ideen om at udføre bygning af OCI-containere inden for Kubernetes eller et lignende system. Lad os sige, at vi har CI/CD, der konstant bygger billeder, så noget som Red Hat OpenShift/Kubernetes было бы весьма полезно с точки зрения распределения нагрузки при сборке. До недавних пор большинство людей просто давали контейнерам доступ к Docker-сокету и разрешали выполнять команду docker build. Vi viste allerede for flere år siden, at dette er meget usikkert, faktisk er det endda værre end at give root- eller sudo-adgang uden adgangskode.

Derfor forsøger folk konstant at køre Buildah i en container. Kort sagt, vi har skabt eksempel hvordan vi mener, at man bedst kører Buildah inden i en container, og vi har lagt de relevante billeder på quay.io/buildah. Lad os komme i gang…

Indstillinger

Disse billeder er bygget fra Dockerfiles, som kan findes i Buildah-repositoriet i mappen buildahimage.
Her vil vi se på den stabile version af 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

I stedet for OverlayFS, der er implementeret på niveauet for værtens Linux-kerne, bruger vi inde i containeren programmet fuse-overlay, da OverlayFS i øjeblikket kun kan montere, hvis det gives SYS_ADMIN-rettigheder via Linux-capabilities. Og vi ønsker at køre vores Buildah-containere uden nogen root-rettigheder. Fuse-overlay fungerer ret hurtigt og har bedre ydeevne end storage-driveren VFS. Vær opmærksom på, at når man kører en Buildah-container, der bruger Fuse, er det nødvendigt at give adgang til enhed "/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

Dernæst opretter vi en mappe til yderligere lagringsområder. Container/storage understøtter konceptet med at tilslutte yderligere skrivebeskyttede lagringsområder af billeder. For eksempel kan man konfigurere overlay storage-område på én maskine og derefter montere dette lager på en anden maskine via NFS og bruge billederne derfra uden at downloade dem via pull. Vi har brug for dette lager for at kunne tilslutte et eller andet lagringssted med billeder fra værten og bruge det inde i containeren.

# 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

Og endelig, ved hjælp af miljøvariablen BUILDAH_ISOLATION, fortæller vi, at Buildah-containeren som standard skal køre med chroot-isolering. Yderligere isolering er ikke nødvendig her, da vi allerede arbejder i en container. For at Buildah kan oprette sine egne containere med namespaces, kræves SYS_ADMIN-privilegiet, og for dette skal SELinux- og SECCOMP-reglerne lempes for containeren, hvilket strider imod vores opsætning for at udføre bygning fra en sikker container.

Kører Buildah inde i containeren

Den ovenfor nævnte Buildah-containerbillede skema giver fleksibilitet til at variere måderne at starte sådanne containere.

Hastighed kontra sikkerhed

Computersikkerhed er altid et kompromis mellem hastigheden på processen og hvor meget beskyttelse der er bygget omkring den. Dette udsagn gælder også ved opbygning af containere, så nedenfor vil vi se på mulighederne for dette kompromis.

Den ovenfor beskrevne containerbillede vil opbevare sit lager i /var/lib/containers. Derfor skal vi montere indholdet i denne mappe, og måden vi gør dette på, vil have stor indflydelse på hastigheden ved opbygning af containerbilleder.

Lad os overveje tre muligheder.

Mulighed 1. Hvis der kræves maksimal sikkerhed, kan der oprettes en særskilt mappe til hver container for containers/image og tilsluttes den til containeren via volume-mount. Derudover kan kontekstmappen placeres i selve containeren, i mappen /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

Sikkerhed. Buildah, der kører i en sådan container, har maksimal sikkerhed: det gives ingen root-rettigheder via capabilities, og alle SECOMP- og SELinux-begrænsninger anvendes. En sådan container kan endda køre med User Namespace-isolering ved at tilføje en mulighed som —uidmap 0:100000:10000.

Ydeevne. Men ydeevnen her er minimal, da enhver billeder fra containerregistrene hver gang kopieres til værten, og caching virker slet ikke. Når Buildah-containeren er færdig, skal den sende billedet til registreret og destruere indholdet på værten. Når containerbilledet skal opbygges næste gang, skal det downloades igen fra registreret, da der på værten i mellemtiden ikke vil være noget tilbage.

Mulighed 2. Hvis der er brug for Docker-niveau-ydeevne, kan man montere container/storage fra værten direkte ind i containeren.

# 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

Sikkerhed. Dette er den mindst sikre metode til at bygge containere, da containeren her har tilladelse til at ændre lageret på værten, og den kan potentielt indsætte et ondsindet billede i Podman eller CRI-O. Derudover kræver det, at SELinux-separationen deaktiveres, så processerne i Buildah-containeren kan interagere med lageret på værten. Vær opmærksom på, at denne mulighed stadig er bedre end Docker-socketen, da containeren er beskyttet af de resterende sikkerhedsfunktioner og ikke bare kan tage og køre en hvilken som helst container på værten.

Ydeevne. Her er den maksimal, da caching udnyttes fuldt ud. Hvis Podman eller CRI-O allerede har downloadet det nødvendige billede til værten, behøver Buildah-processen inde i containeren ikke at downloade det igen, og efterfølgende bygninger baseret på dette billede kan også hente det nødvendige fra cachen.

Mulighed 3. Essensen af denne metode er at kombinere flere billeder i et projekt med en fælles mappe til containerbilleder.

# 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 dette eksempel sletter vi ikke projektmappen (\/var\/lib\/project3) mellem kørslerne, så alle efterfølgende bygninger inden for projektet drager fordel af cachen.

Sikkerhed. En mellemting mellem mulighederne 1 og 2. På den ene side har containerne ikke adgang til indholdet på værten og kan derfor ikke indsætte noget dårligt i Podman/CRI-O's lager. På den anden side kan containeren inden for sit projekt blande sig i bygningen af andre containere.

Ydeevne. Her er den dårligere end ved at bruge en fælles cache på niveau med værten, da det ikke er muligt at bruge billeder, der allerede er downloadet tidligere ved hjælp af Podman/CRI-O. Men efter at Buildah har downloaded billedet, kan dette billede bruges i enhver efterfølgende bygning inden for projektet.

Yderligere lagre

Ved containers\/storage Der er en fantastisk ting som yderligere lagre (additional stores), som gør det muligt for containermotorer at bruge eksterne lagre af billeder i read-only overlay mode, når der startes og bygges containere. I princippet kan man tilføje et eller flere "kun læse" lagre i filen storage.conf, så containermotoren kan lede efter det nødvendige billede, når en container startes. Den vil kun downloade billedet fra registreret, hvis det ikke findes i noget af disse lagre. Containermotoren kan kun skrive i skrivebeskyttede lagre…

Hvis vi ruller op og ser på Dockerfile, som vi bruger til at bygge billedet quay.io/buildah/stable, så er der linjer som disse:

# 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

I den første linje modificerer vi /etc/containers/storage.conf inde i containerbilledet, og instruerer storage-driveren om at bruge "additionalimagestores" i mappen /var/lib/shared. I den næste linje opretter vi en fælles mappe og tilføjer et par lock-filer, for at undgå klager fra containers/storage. I princippet opretter vi blot et tomt lager for containerbilleder.

Hvis man monterer containers/storage et niveau over denne mappe, kan Buildah bruge billederne.

Lad os nu vende tilbage til ovenstående Variant 2, hvor Buildah-containeren kan læse og skrive til containers/store på værter, og derfor opnår maksimal ydeevne gennem caching af billeder på Podman/CRI-O niveau, men giver minimum sikkerhed, da den kan skrive direkte til lagre. Og så kan vi tilføje yderligere lagre og få det bedste fra to verdener.

# 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ær opmærksom på, at /var/lib/containers/storage på værten er monteret i /var/lib/shared inde i containeren i read-only mode. Derfor kan Buildah, mens den arbejder i containeren, bruge alle billeder, som tidligere er blevet downloadet af Podman/CRI-O (hej, hastighed), men kan kun skrive til sit eget lager (hej, sikkerhed). Vær også opmærksom på, at dette gøres uden at deaktivere SELinux separation for containeren.

Vigtig detalje

Man må under ingen omstændigheder slette nogen billeder fra det underliggende lager. Ellers kan Buildah-containeren falde ud.

Og det er bestemt ikke alle fordelene

Mulighederne for ekstra lagre begrænser sig ikke kun til det ovenfor beskrevne scenarie. For eksempel kan man placere alle containerbilleder i et fælles netværkslager og give adgang til det for alle Buildah-containere. Antag, at vi har hundrede billeder, som vores CI/CD-system regelmæssigt bruger til at bygge containerbilleder. Vi koncentrerer alle disse billeder på et enkelt host-lager og åbner derefter, ved hjælp af foretrukne netværkslagermidler (NFS, Gluster, Ceph, ISCSI, S3…), det fælles lager for alle Buildah- eller Kubernetes-noder.

Nu er det nok at montere dette netværkslager i Buildah-containeren på /var/lib/shared, og så – Buildah-containere behøver slet ikke at downloade billeder via pull. Dermed fjerner vi fasen for forudfyldning (pre-population) og er straks klar til at udrulle containere.

Og selvfølgelig kan dette bruges inden for et eksisterende Kubernetes-system eller containerinfrastruktur for at køre og udføre containere hvor som helst uden at downloade billeder via pull. Desuden, når containerregisteret modtager et push-anmodning om at uploade et opdateret billede, kan det automatisk sende dette billede til det fælles netværkslager, hvor det straks bliver tilgængeligt for alle noder.

Størrelsen på containerbilleder kan nogle gange nå mange gigabyte. Funktionaliteten af ekstra lager muliggør, at man undgår at klone sådanne billeder til noderne og gør containeropstarten næsten øjeblikkelig.

Desuden arbejder vi i øjeblikket på en ny funktion til overlay volume mounts, som vil gøre opbygningen af containere endnu hurtigere.

Konklusion

At køre Buildah inde i en container i et Kubernetes/CRI-O, Podman eller endda Docker-miljø er helt muligt, og det er desuden enkelt og meget sikrere end at bruge docker.socket. Vi har betydeligt øget fleksibiliteten i arbejdet med billeder, og nu kan du køre dem på forskellige måder for at opnå den optimale balance mellem sikkerhed og ydeevne.

Funktionaliteten af ekstra lager gør det muligt at accelerere eller endda helt eliminere download af billeder til noder.

Kilde: habr.com

Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere 🔥 Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere | ProHoster