Aanbevelingen voor het uitvoeren van Buildah in een container

Wat is het mooie van het ontkoppelen van de containerruntime in afzonderlijke toolingcomponenten? In het bijzonder kunnen deze instrumenten worden gecombineerd, zodat ze elkaar beschermen.

Aanbevelingen voor het uitvoeren van Buildah in een container

Veel mensen voelen zich aangetrokken tot het idee om binnenin gecontaineriseerde OCI-afbeeldingen te bouwen Kubernetes of soortgelijk systeem. Laten we zeggen dat we een CI/CD hebben die voortdurend afbeeldingen verzamelt, en dan zoiets Red Hat OpenShift/Kubernetes zou behoorlijk nuttig zijn in termen van taakverdeling tijdens builds. Tot voor kort gaven de meeste mensen containers simpelweg toegang tot een Docker-socket en lieten ze het docker build-commando uitvoeren. Een aantal jaren geleden lieten we het ziendat dit erg onveilig is, sterker nog, het is zelfs erger dan het geven van een wachtwoordloze root of sudo.

Dat is de reden waarom mensen voortdurend proberen Buildah in een container te laten draaien. Kortom: wij hebben gecreëerd voorbeeld hoe je, naar onze mening, Buildah het beste in een container kunt laten draaien en de bijbehorende afbeeldingen erop kunt plaatsen quay.io/buildah. Laten we beginnen...

afstelling

Deze afbeeldingen zijn opgebouwd uit Dockerfiles, die te vinden zijn in de Buildah-repository in de map bouwbeeld.
Hier zullen we naar kijken stabiele versie van 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

In plaats van OverlayFS, geïmplementeerd op het Linux-kernelniveau van de host, gebruiken we het programma in de container zekering-overlay, omdat OverlayFS momenteel alleen kan worden geactiveerd als je het SYS_ADMIN-machtigingen geeft met behulp van Linux-mogelijkheden. En we willen onze Buildah-containers draaien zonder rootrechten. Fuse-overlay werkt vrij snel en levert betere prestaties dan het VFS-opslagstuurprogramma. Houd er rekening mee dat wanneer u een Buildah-container uitvoert die Fuse gebruikt, u het apparaat /dev/fuse moet opgeven.

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

Vervolgens maken we een map voor extra opslag. Container/opslag ondersteunt het concept van het verbinden van extra alleen-lezen beeldopslagplaatsen. U kunt bijvoorbeeld een overlay-opslaggebied op één machine configureren en vervolgens NFS gebruiken om deze opslag op een andere machine te koppelen en er afbeeldingen van te gebruiken zonder te downloaden via pull. We hebben deze opslag nodig om een ​​deel van de beeldopslag van de host als volume aan te kunnen sluiten en deze in de container te kunnen gebruiken.

# 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

Ten slotte vertellen we, door de omgevingsvariabele BUILDAH_ISOLATION te gebruiken, dat de Buildah-container standaard moet worden uitgevoerd met chroot-isolatie. Extra isolatie is hier niet nodig, omdat er al in een container wordt gewerkt. Om Buildah zijn eigen door naamruimte gescheiden containers te laten maken, is het SYS_ADMIN privilege vereist, wat een versoepeling van de SELinux- en SECCOMP-regels van de container zou vereisen, wat in strijd is met onze voorkeur om vanuit een veilige container te bouwen.

Buildah in een container laten draaien

Met het hierboven besproken Buildah-containerafbeeldingsdiagram kunt u de methoden voor het starten van dergelijke containers flexibel variëren.

Snelheid versus veiligheid

Computerbeveiliging is altijd een compromis tussen de snelheid van het proces en de hoeveelheid bescherming die eromheen zit. Deze verklaring geldt ook bij het assembleren van containers, dus hieronder zullen we opties voor een dergelijk compromis overwegen.

De hierboven besproken containerimage behoudt zijn opslag in /var/lib/containers. Daarom moeten we de inhoud in deze map mounten, en de manier waarop we dit doen zal grote invloed hebben op de snelheid van het bouwen van containerimages.

Laten we drie opties bekijken.

Optie 1. Als maximale beveiliging vereist is, kunt u voor elke container uw eigen map voor containers/image aanmaken en deze via volume-mount aan de container koppelen. En plaats bovendien de contextmap in de container zelf, in de map /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

Beveiliging. Buildah die in zo'n container draait, heeft maximale veiligheid: het krijgt geen root-privileges met behulp van mogelijkheden, en alle SECOMP- en SELinux-beperkingen zijn erop van toepassing. Zo'n container kan zelfs worden uitgevoerd met isolatie van de gebruikersnaamruimte door een optie toe te voegen zoals —uidmap 0: 100000:10000.

Prestaties. Maar de prestaties zijn hier minimaal, omdat alle afbeeldingen uit containerregisters elke keer naar de host worden gekopieerd en caching helemaal niet werkt. Wanneer zijn werk is voltooid, moet de Buildah-container de afbeelding naar het register sturen en de inhoud op de host vernietigen. De volgende keer dat de containerimage wordt gebouwd, moet deze opnieuw uit het register worden gedownload, omdat er tegen die tijd niets meer op de host staat.

Optie 2. Als u prestaties op Docker-niveau nodig heeft, kunt u de hostcontainer/opslag rechtstreeks in de container koppelen.

# 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

Beveiliging. Dit is de minst veilige manier om containers te bouwen, omdat de container hierdoor de opslag op de host kan wijzigen en Podman of CRI-O mogelijk een kwaadaardig beeld kan geven. Bovendien moet je de SELinux-scheiding uitschakelen, zodat processen in de Buildah-container kunnen communiceren met de opslag op de host. Merk op dat deze optie nog steeds beter is dan een Docker-socket, omdat de container is vergrendeld door de resterende beveiligingsfuncties en niet zomaar een container op de host kan draaien.

Prestaties. Hier is dit maximaal, aangezien caching volledig wordt benut. Als Podman of CRI-O de vereiste afbeelding al naar de host hebben gedownload, hoeft het Buildah-proces in de container deze niet opnieuw te downloaden, en kunnen daaropvolgende builds op basis van deze afbeelding ook uit de cache halen wat ze nodig hebben. .

Optie 3. De essentie van deze methode is om meerdere afbeeldingen in één project te combineren met een gemeenschappelijke map voor containerafbeeldingen.

# 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

In dit voorbeeld verwijderen we de projectmap (/var/lib/project3) niet tussen uitvoeringen, zodat alle volgende builds binnen het project profiteren van caching.

Beveiliging. Iets tussen optie 1 en 2. Aan de ene kant hebben containers geen toegang tot inhoud op de host en kunnen ze daarom niet iets slechts in de Podman/CRI-O-beeldopslag stoppen. Aan de andere kant kan een container, als onderdeel van zijn ontwerp, de montage van andere containers hinderen.

Prestaties. Hier is het erger dan bij het gebruik van een gedeelde cache op hostniveau, omdat je geen afbeeldingen kunt gebruiken die al zijn gedownload met Podman/CRI-O. Zodra Buildah de afbeelding heeft gedownload, kan de afbeelding echter worden gebruikt in eventuele volgende builds binnen het project.

Extra opslagruimte

У containers/opslag Er bestaat zoiets cools als extra winkels (extra winkels), waardoor containerengines bij het lanceren en bouwen van containers externe afbeeldingswinkels kunnen gebruiken in de alleen-lezen overlay-modus. In wezen kunt u een of meer alleen-lezen opslagplaatsen toevoegen aan het bestand storage.conf, zodat wanneer u de container start, de containerengine daarin naar de gewenste afbeelding zoekt. Bovendien zal het de afbeelding alleen uit het register downloaden als het deze niet in een van deze opslagplaatsen vindt. De containerengine kan alleen naar beschrijfbare opslag schrijven...

Als je omhoog scrollt en naar het Dockerbestand kijkt dat we gebruiken om de afbeelding quay.io/buildah/stable te bouwen, zijn er regels als deze:

# 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

In de eerste regel wijzigen we /etc/containers/storage.conf in de containerimage, waarbij we het opslagstuurprogramma vertellen om “additionalimagestores” te gebruiken in de map /var/lib/shared. En in de volgende regel maken we een gedeelde map en voegen we een paar lock-bestanden toe, zodat er geen misbruik van containers/opslag plaatsvindt. In wezen creëren we eenvoudigweg een lege containerimage-winkel.

Als u containers/opslag op een hoger niveau dan deze map koppelt, kan Buildah de afbeeldingen gebruiken.

Laten we nu terugkeren naar de hierboven besproken optie 2, wanneer de Buildah-container containers/opslag op de hosts kan lezen en schrijven en dienovereenkomstig maximale prestaties levert dankzij het cachen van afbeeldingen op Podman/CRI-O-niveau, maar een minimum aan beveiliging biedt omdat het rechtstreeks naar de opslag kan schrijven. Laten we hier nu extra opslagruimte toevoegen en het beste van twee werelden krijgen.

# 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

Merk op dat /var/lib/containers/storage van de host is aangekoppeld aan /var/lib/shared in de container in alleen-lezen modus. Daarom kan Buildah, terwijl hij in een container werkt, alle afbeeldingen gebruiken die eerder zijn gedownload met Podman/CRI-O (hallo, snelheid), maar kan hij alleen naar zijn eigen opslag schrijven (hallo, beveiliging). Merk ook op dat dit wordt gedaan zonder de SELinux-scheiding voor de container uit te schakelen.

Belangrijke nuance

In geen geval mag u afbeeldingen uit de onderliggende opslagplaats verwijderen. Anders kan de Buildah-container crashen.

En dit zijn nog niet alle voordelen

De mogelijkheden voor extra opslag zijn niet beperkt tot het bovenstaande scenario. U kunt bijvoorbeeld alle containerimages op een gedeelde netwerkopslag plaatsen en hier toegang toe geven aan alle Buildah-containers. Laten we zeggen dat we honderden images hebben die ons CI/CD-systeem regelmatig gebruikt om containerimages te bouwen. We concentreren al deze afbeeldingen op één opslaghost en vervolgens, met behulp van de gewenste netwerkopslagtools (NFS, Gluster, Ceph, ISCSI, S3...), openen we algemene toegang tot deze opslag voor alle Buildah- of Kubernetes-knooppunten.

Nu is het voldoende om deze netwerkopslag in de Buildah-container op /var/lib/shared te koppelen en dat is alles: Buildah-containers hoeven niet langer afbeeldingen te downloaden via pull. Zo gooien we de pre-populatiefase achter ons en zijn we meteen klaar om de containers uit te rollen.

En natuurlijk kan dit worden gebruikt binnen een live Kubernetes-systeem of containerinfrastructuur om containers overal te lanceren en uit te voeren zonder het downloaden van afbeeldingen. Bovendien kan het containerregister, dat een push-verzoek ontvangt om er een bijgewerkte afbeelding naar te uploaden, deze afbeelding automatisch naar een gedeelde netwerkopslag sturen, waar deze onmiddellijk beschikbaar wordt voor alle knooppunten.

Containerimages kunnen soms vele gigabytes groot zijn. Dankzij de functionaliteit van extra opslag kunt u het klonen van dergelijke afbeeldingen tussen knooppunten vermijden, waardoor het starten van containers vrijwel onmiddellijk kan plaatsvinden.

Daarnaast werken we momenteel aan een nieuwe functie genaamd overlay volume mounts, waardoor het bouwen van containers nog sneller gaat.

Conclusie

Het uitvoeren van Buildah in een container in Kubernetes/CRI-O, Podman of zelfs Docker is haalbaar, eenvoudig en veel veiliger dan het gebruik van docker.socket. We hebben de flexibiliteit bij het werken met afbeeldingen aanzienlijk vergroot, zodat u ze op verschillende manieren kunt uitvoeren om de balans tussen beveiliging en prestaties te optimaliseren.

Dankzij de functionaliteit van extra opslag kunt u het downloaden van afbeeldingen naar knooppunten versnellen of zelfs volledig elimineren.

Bron: www.habr.com

Voeg een reactie