Rekomandime për ekzekutimin e Buildah brenda një kontejneri

Çfarë është e veçanta në ndarjen e mjedisit të ekzekutimit të kontejnerëve në përbërës të veçantë? Në veçanti, është se këto mjete mund të fillojnë të kombinohen, në mënyrë që të mbrojnë njëra-tjetrën.

Rekomandime për ekzekutimin e Buildah brenda një kontejneri

Për shumë, ideja e ndërtimit të imazheve OCI të kontejnerëve brenda Kubernetes ose një sistemi të ngjashëm është errejtësuese. Le të supozojmë se kemi një CI/CD që vazhdimisht ndërton imazhe, atëherë diçka si Red Hat OpenShift/Kubernetes было бы весьма полезно с точки зрения распределения нагрузки при сборке. До недавних пор большинство людей просто давали контейнерам доступ к Docker-сокету и разрешали выполнять команду docker build. Kemi treguar disa vjet më parë, se kjo është shumë e pasigurt, në fakt, është akoma më keq se të japësh akses pa fjalëkalim root ose sudo.

Prandaj, njerëzit vazhdojnë të përpiqen të ekzekutojnë Buildah brenda një kontejneri. Në përmbledhje, ne krijuam shembull se si, sipas mendimit tonë, është më mirë të ekzekutohet Buildah brenda kontejnerit dhe publikuan përkatësisht imazhet në quay.io/buildah. Le të fillojmë...

Konfigurimi

Këto imazhe janë ndërtuar nga Dockerfile, të cilat mund të gjenden në repositorin e Buildah në dosjen buildahimage.
Këtu do të shqyrtojmë versionin stabil të 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

Në vend të OverlayFS, e cila është implementuar në nivelin e kernelit të hostit, ne përdorim brenda kontejnerit programin fuse-overlay, sepse aktualisht OverlayFS mund të kryejë montimin vetëm nëse i jepet autorizim SYS_ADMIN përmes kapaciteteve të Linux it. Ne duam të drejtojmë kontejnerët tanë Buildah pa ndonjë privilegj të nivelit root. Fuse-overlay funksionon mjaft shpejt dhe ka performancë më të mirë se drejtuesi i ruajtjes VFS. Vini re se kur drejtoni një kontejner Buildah që përdor Fuse, duhet të siguroni pajisjen /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

Për më tepër, ne krijojmë një каталог për ruajtjet shtesë. Container/storage mbështet konceptin e lidhjes së ruajtjeve shtesë vetëm për lexim. Për shembull, mund të konfiguroni një zonë ruajtëse overlay në një makinë, dhe më pas të montoni këtë ruajtje në një makinë tjetër përmes NFS dhe ta përdorni imazhin nga ajo pa e shkarkuar përmes pull. Ne kemi nevojë për këtë ruajtje për të qenë në gjendje të lidhim si një volum ndonjë ruajtje imazhesh nga host-i dhe ta përdorim atë brenda kontejnerit.

# 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

Dhe për më në fund, duke përdorur variablën e ambientit BUILDAH_ISOLATION, ne themi se si standard, kontenieri Buildah duhet të ekzekutohet me izolimin chroot. Izolimi shtesë këtu nuk është i nevojshëm, pasi ne tashmë po punojmë brenda një kontenieri. Për të krijuar kontenierët e tij vetë me ndarje emërimi, Buildah kërkon privilegjin SYS_ADMIN, dhe për këtë do të duhet të lehtësojmë rregullat SELinux dhe SECCOMP për kontenierin, gjë që është në kundërshtim me vendosjen tonë për të ndërtuar nga një kontenier të sigurt.

Startojmë Buildah brenda kontenierit

Skema e mësipërme e imazhit të kontenierit Buildah lejon variacione fleksibile në mënyrat e ekzekutimit të këtyre kontenierëve.

Shpejtësia kundër sigurisë

Siguria kompjuterike është gjithmonë një kompromis midis shpejtësisë së procesit të ekzekutimit dhe sasisë së mbrojtjes që është vendosur rreth tij. Kjo deklaratë është e vërtetë edhe gjatë ndërtimit të kontenierëve, prandaj më poshtë do të shqyrtojmë opsionet e këtij kompromisi.

Imagini që u shqyrtua më sipër do të mbajë ruajtjen e saj në /var/lib/containers. Prandaj, ne duhet të montojmë përmbajtjen në këtë dosje, dhe mënyra se si do ta bëjmë këtë do të ndikojë shumë në shpejtësinë e ndërtimit të imazheve të konteinerëve.

Le të shqyrtojmë tre mundësi.

Mundësia 1. Nëse kërkohet sigurim maksimal, për çdo kontejner mund të krijohet një dosje për containers/image dhe ta lidhim atë me kontejnerin përmes volume-mount. Për më tepër, mund të vendosim dosjen kontekstuale brenda kontejnerit, në dosjen /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

Siguria. Një kontejner i tillë që funksionon me Buildah ka sigurinë maksimale: nuk i jepen privilegje root përmes capabilities, dhe i zbatohen të gjitha kufizimet SECOMP dhe SELinux. Një kontejner i tillë madje mund të nisët me izolim të User Namespace, duke shtuar një opsion si —uidmap 0:100000:10000.

Performanca. Performanca është minimale këtu, pasi çdo imazh nga regjistrat e kontejnerëve kopjohet çdo herë në host, dhe caching nuk funksionon fare. Pasi të përfundojë punën e tij, kontejneri Buildah duhet të dërgojë imazhin në regjistër dhe të shkatërrojë përmbajtjen në host. Kur imazhi i kontejnerit do të grumbullohet sërish, do të duhet të shkarkohet nga regjistri, pasi në host deri atëherë nuk do të mbetet asgjë.

Varianti 2. Nëse nevojitet performancë në nivel Docker, atëherë mund të montoni direkt container/storage të hostit në kontejner.

# 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

Siguria. Ky është mënyra më e pak sigurta për të grumbulluar kontejnerë, pasi këtu kontejneri i lejohet të modifikojë ruajtjen në host, dhe potencialisht mund të dorëzojë një imazh keqdashës te Podman ose CRI-O. Për më tepër, do të kërkohet të çaktivizohet ndarja SELinux, në mënyrë që proceset në kontejnerin Buildah të mund të interaktojnë me ruajtjen në host. Vini re se ky variant është megjithatë më i mirë se sa Docker socket, pasi kontejneri është bllokuar nga funksione të tjera sigurie dhe nuk mund ta marrë thjesht një kontejner tjetër për ta nisur në host.

Performanca. Këtu ajo është maksimale, pasi e gjithë kapaciteti i cache-it shfrytëzohet plotësisht. Nëse Podman ose CRI-O tashmë kanë shkarkuar imazhin e nevojshëm në host, atëherë procesi Buildah brenda kontejnerit nuk do të duhet ta shkarkojë atë përsëri, dhe ndërtimet e mëvonshme mbi këtë imazh gjithashtu do të kenë mundësi ta marrin nga cache-i.

Opzioni 3. Thelbi i këtij metoda është të bashkojë disa imazhe në një projekt me një dosje të përbashkët për imazhet e kontejnerëve.

# 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

Në këtë shembull, ne nuk e fshijmë dosjen e projektit (/var/lib/project3) ndërmjet ekzekutimeve, prandaj të gjitha ndërtimet e ardhshme brenda projektit përfitojnë nga caching.

Siguria. Diçka mes opsioneve 1 dhe 2. Nga njëra anë, kontejnerët nuk kanë qasje në përmbajtjen e hostit dhe, për pasojë, nuk mund të fusin diçka të keqe në magazinën e imazheve të Podman/CRI-O. Nga ana tjetër, brenda projektit të tij, një kontejner mund të ndërhyjë në ndërtimin e kontejnerëve të tjerë.

Performanca. Këtu ndodh më keq se përdorimi i caches së zakonshme në nivel hosti, pasi nuk mund të përdoren imazhe që kanë shkarkuar më parë me ndihmën e Podman/CRI-O. Megjithatë, pasi Buildah të shkarkojë imazhin, ky imazh mund të përdoret në të gjitha ndërtimet e mëpasshme brenda projektit.

Të dhëna shtesë

Tek containers/storage ka një gjë kaq të shkëlqyer si të dhënat shtesë (additional stores), që e lejon motorët e kontejnerëve të përdorin depo të jashtme imazhesh në modalitetin read-only overlay kur janë duke filluar dhe ndërtuar kontejnerë. Në thelb, në skedarin storage.conf mund të shtoni një ose disa depo "vetëm për lexim" në mënyrë që motori i kontejnerëve të kërkojë imazhin e nevojshëm aty gjatë fillimit të kontejnerit. Ai do të shkarkojë imazhin nga regjistri vetëm në rast se nuk e gjen atë në asnjë nga këto depo. Motori i kontejnerëve mund të shkruajë vetëm në depo që janë të aksesueshme për shkrim...

Nëse rrotullohemi lart dhe shikojmë Dockerfile-in që ne përdorim për ndërtimin e imazhit quay.io/buildah/stable, atëherë ka disa rreshta të tillë:

# 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

Në rreshtin e parë modifikojmë /etc/containers/storage.conf brenda imazhit të enëve, duke thënë drejtorit të ruajtjes të përdorë "additionalimagestores" në dosjen /var/lib/shared. Ndërsa në rreshtin e ardhshëm krijojmë një dosje të përbashkët dhe shtojmë disa skedarë lock për të shmangur konflikth nga containers/storage. Në thelb, thjesht krijojmë një depo bosh të imazheve të enëve.

Nëse montoni containers/storage në një nivel më të lartë se kjo dosje, Buildah do të mund të përdorë imazhet.

Tani le të kthehemi te Variant 2 i përmendur më lart, kur kontenieri Buildah mund të lexojë dhe shkruajë në containers/store në hoste dhe, përkatësisht, ka performancën maksimale falë ruajtjes të imazheve në nivelin Podman/CRI-O, por ofron minimum sigurie, pasi mund të shkruajë drejtpërdrejt në depo. Tani do të shtojmë këtu depo shtesë dhe do të kemi më të mirën e të dy botëve.

# 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

Kujdes, që /var/lib/containers/storage i hostit është montuar në /var/lib/shared brenda kontejnerit në mënyrë read-only. Prandaj, gjatë punës në kontejner, Buildah mund të përdorë çdo imazh që është shkarkuar më parë nga Podman/CRI-O (përshëndetje, shpejtësi), por mund të shkruajë vetëm në depozitën e saj (përshëndetje, siguri). Gjithashtu, vini re se kjo bëhet pa shkyçjen e ndarjes SELinux për kontejnerin.

Një nuancë e rëndësishme

Asnjëherë nuk duhet të fshini ndonjë imazh nga depozita e poshtme. Në të kundërt, konteineri Buildah mund të dalë jashtë funksionit.

Dhe këto nuk janë të gjitha përfitimet

Mundësitë e ruajtjes së shtesave nuk kufizohen vetëm në skenarin e përshkruar më sipër. Për shembull, mund të vendosim të gjitha imazhet e kontejnerëve në një magazinë rrjetore të përbashkët dhe t'i japim akses të gjithë kontejnerëve Buildah. Le të supozojmë se kemi qindra imazhe që sistemi ynë CI/CD i përdor rregullisht për ndërtimin e imazheve të kontejnerëve. I përqendrojmë të gjithë këta imazhe në një host magazinë dhe pastaj, duke përdorur mjetet e preferuara të ruajtjes së rrjetit (NFS, Gluster, Ceph, ISCSI, S3…), hapim akses të përbashkët në këtë magazinë për të gjitha nodet Buildah ose Kubernetes.

Tani mjafton të montojmë këtë magazinë rrjetore në kontejnerin Buildah në /var/lib/shared dhe gjithçka – kontejnerët Buildah nuk do të kenë më nevojë të shkarkojnë imazhe përmes pull. Kështu ne heqim fazën e plotësimit të parakohshme (pre-population) dhe jemi gati të nxjerrim kontejnerët menjëherë.

Natyrisht, kjo mund të përdoret si pjesë e sistemit ekzistues Kubernetes ose infrastrukturës së konteinerëve, për të nisur dhe ekzekutuar kontejnerë kudo pa shkarkuar imazhe përmes tërheqjes. Më shumë se kaq, regjistri i kontejnerëve, duke marrë një kërkesë të shtytur për ngarkimin e një imazhi të azhurnuar, mund të dërgojë automatikisht këtë imazh në një magazinë të përbashkët në rrjet, ku ai bëhet menjëherë i disponueshëm për të gjitha nodet.

Madhësitë e imazheve të kontejnerëve ndonjëherë mund të arrijnë disa gigabajt. Funksionaliteti i magazinave shtesë lejon shmangien e klonimit të këtyre imazheve në nodet dhe bën që nisja e kontejnerëve të jetë praktikisht e menjëhershme.

Për më tepër, aktualisht po punojmë mbi një funksion të ri të montimeve overlay volume, i cili do ta bëjë ndërtimin e kontejnerëve edhe më të shpejtë.

Përfundimi

Të ekzekutosh Buildah brenda një kontejneri në mjedisin Kubernetes/CRI-O, Podman, apo madje në Docker është plotësisht e mundur; për më tepër, është e thjeshtë dhe shumë më e sigurt se përdorimi i docker.socket. Ne kemi rritur ndjeshëm fleksibilitetin në punën me imazhet, dhe tani mund t'i nisni ato në mënyra të ndryshme për një ekuilibër optimal midis sigurisë dhe performancës.

Funksionaliteti i magazinave shtesë lejon përshpejtimin ose edhe eliminimin e plotë të shkarkimit të imazheve në nodet.

Burimi: habr.com

Bli një hosting të besueshëm për faqet me mbrojtje DDoS, VPS VDS serverë 🔥 Bli një hosting të besueshëm për faqet me mbrojtje DDoS, VPS VDS serverë | ProHoster