У чым хараство падзелу асяроддзя выканання кантэйнераў на асобныя інструментальныя складнікі? У прыватнасці, у тым, што гэтыя прылады можна пачаць камбінаваць, каб яны абаранялі адзін аднаго.
Многіх прыцягвае ідэя выконваць зборку кантэйнерных OCI-вобразаў у рамках
Таму людзі ўвесь час спрабуюць запускаць Buildah у кантэйнеры. Карацей, мы стварылі
Настройка
Гэтыя выявы сабраны з Dockerfiles, якія можна знайсці ў рэпазітары Buildah у тэчцы
Тут мы разгледзім
# 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
Замест OverlayFS, рэалізаванай на ўзроўні Linux-ядра хаста, мы выкарыстоўваем усярэдзіне кантэйнера праграму
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
Далей мы ствараем каталог для дадатковых сховішчаў.
# 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
І нарэшце, выкарыстаючы зменную асяроддзі BUILDAH_ISOLATION, мы кажам, што па змаўчанні Buildah-кантэйнер павінен запускацца з ізаляцыяй chroot. Дадатковая ізаляцыя тут не патрабуецца, паколькі мы і так ужо працуем у кантэйнеры. Для таго, каб Buildah ствараў свае ўласныя кантэйнеры з падзелам прастор імёнаў, патрабуецца прывілей SYS_ADMIN, а для гэтага прыйдзецца прыслабіць для кантэйнера правілы SELinux і SECCOMP, што супярэчыць нашай усталёўцы выконваць зборку з бяспечнага кантэйнера.
Запускаем Buildah ўнутры кантэйнера
Разгледжаная вышэй схема выявы Buildah-кантэйнера дазваляе гнутка вар'іраваць спосабы запуску такіх кантэйнераў.
Хуткасць супраць бяспекі
Кампутарная бяспека - гэта заўсёды кампраміс паміж хуткасцю выканання працэсу і тым, колькі абароны вакол гэтага накручана. Гэтае сцвярджэнне справядліва і пры зборцы кантэйнераў, таму ніжэй мы разгледзім варыянты такога кампрамісу.
Разгледжаны вышэй кантэйнерны вобраз будзе трымаць сваё сховішча ў /var/lib/containers. Таму нам трэба падмантаваць кантэнт у гэтую тэчку, і тое, як мы гэта зробім, будзе моцна ўплываць на хуткасць зборкі кантэйнерных вобразаў.
Разгледзім тры варыянты.
Варыянт 1. Калі патрабуецца максімальная бяспека, то для кожнага кантэйнера можна ствараць сваю тэчку для containers/image і падлучаць яе да кантэйнера праз volume-mount. Акрамя таго, размяшчаць context directory у самым кантэйнеры, у тэчцы /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
Бяспеку. Які працуе ў такім кантэйнеры Buildah мае максімальную бяспеку: яму не даюць ніякіх root-прывілеяў сродкамі capabilities, і да яго ўжываюцца ўсе абмежаванні SECOMP і SELinux.Такі кантэйнер нават можна запускаць з ізаляцыяй User Namespace, дадаўшы опцыю накшталт -uidmap 0:100000:10000.
Прадукцыйнасць. А вось прадукцыйнасць тут мінімальная, паколькі любыя выявы з кантэйнерных рэестраў кожны раз капіююцца на хост, і кэшаванне не працуе ад слова "ніяк". Завяршаючы сваю працу, Buildah-кантэйнер павінен адпраўляць выяву ў рэестр і знішчаць кантэнт на хасце. Калі кантэйнерная выява будзе збірацца ў наступны раз, яго прыйдзецца нанова спампоўваць з рэестра, паколькі на хасце да таго моманту ўжо нічога не застанецца.
Варыянт 2. Калі патрэбна прадукцыйнасць узроўня Docker, то можна падмантаваць container/storage хаста прама ў кантэйнер.
# 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
Бяспеку. Гэта найменш бяспечны спосаб зборкі кантэйнераў, паколькі тут кантэйнеру дазволена мадыфікаваць сховішча на хасце, і патэнцыйна ён можа падсунуць Podman'у ці CRI-O шкоднасны лад. Акрамя таго, запатрабуецца адключыць SELinux separation, каб змешчаныя ў Buildah-кантэйнеры працэсы маглі ўзаемадзейнічаць з сховішчам на хасце. Звярніце ўвагу, што гэты варыянт усё роўна лепш Docker-сокета, паколькі кантэйнер блакуецца пакінутымі функцыямі бяспекі і не можа проста ўзяць і запусціць які-небудзь кантэйнер на хасце.
Прадукцыйнасць. Тут яна максімальная, паколькі поўнасцю задзейнічаецца кэшаванне. Калі Podman або CRI-O ужо паспелі спампаваць патрэбную выяву на хост, то Buildah-працэсу ўсярэдзіне кантэйнера не прыйдзецца спампоўваць яго зноўку, а наступныя зборкі на аснове гэтай выявы таксама змогуць узяць патрэбнае з кэша.
Варыянт 3. Сутнасць гэтага спосабу ў тым, каб аб'яднаць некалькі выяў у адзін праект з агульнай тэчкай для кантэйнерных выяў.
# 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
У гэтым прыкладзе мы не выдаляем тэчку праекту (/var/lib/project3) паміж запускамі, таму ўсе наступныя зборкі ў рамках праекту карыстаюцца перавагамі кэшавання.
Бяспеку. Нешта сярэдняе паміж варыянтамі 1 і 2. З аднаго боку, кантэйнеры не маюць доступу да кантэнту на хасце і, адпаведна, не могуць падсунуць нешта дрэннае ў сховішча выяў Podman/CRI-O. З іншага боку, у рамках свайго праекту кантэйнер можа ўмешвацца ў зборку іншых кантэйнераў.
Прадукцыйнасць. Тут яна горш, чым пры выкарыстанні агульнага кэша на ўзроўні хаста, паколькі нельга выкарыстоўваць выявы, ужо скачаныя раней сродкамі Podman/CRI-O. Аднак пасля таго, як Buildah запампуе выяву, гэта выява можна выкарыстоўваць у любых наступных зборках у рамках праекту.
Дадатковыя сховішчы
У
Калі пракруціць уверх і паглядзець Dockerfile, які мы выкарыстоўваем для зборкі выявы quay.io/buildah/stable, то там ёсць такія радкі:
# 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
У першым радку мы мадыфікуем /etc/containers/storage.conf усярэдзіне кантэйнернай выявы, кажучы storage-драйверу выкарыстаць “additionalimagestores” у тэчцы /var/lib/shared. А ў наступным радку ствараем агульную тэчку і дадаем пару lock-файлаў, каб не было лаянкі са боку containers/storage. Па сутнасці, мы проста ствараем пустое сховішча кантэйнерных вобразаў.
Калі змантаваць containers/storage узроўнем вышэй гэтай тэчкі, што Buildah зможа выкарыстаць выявы.
Цяпер вернемся да разгледжанага вышэй Варыянту 2, калі Buildah-кантэйнер можа чытаць і пісаць у containers/store на хастах і, адпаведна, мае максімальную прадукцыйнасці за рахунак кэшавання выяў на ўзроўні Podman/CRI-O, але дае мінімум бяспекі, паколькі можа пісаць прама у сховішчы. А зараз прыкруцім сюды дадатковыя сховішчы і атрымаем лепшае з двух міроў.
# 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
Звярніце ўвагу, што /var/lib/containers/storage хаста змантаваная ў /var/lib/shared усярэдзіне кантэйнера ў рэжыме read-only. Таму працуючы ў кантэйнеры, Buildah можа выкарыстоўваць любыя выявы, якія раней ужо былі запампаваны сродкамі Podman/CRI-O (прывітанне, хуткасць), але пісаць пры гэтым можа толькі ў сваё ўласнае сховішча (прывітанне, бяспека). Таксама звернеце ўвагу, што гэта робіцца без адключэння SELinux separation для кантэйнера.
важны нюанс
Ні ў якім разе не варта выдаляць ніякія выявы з ніжэйлеглага сховішча. У адваротным выпадку Buildah-кантэйнер можа вылецець.
І гэта зусім не ўсе перавагі
Магчымасці дадатковых сховішчаў не абмяжоўваюцца толькі вышэйапісаным сцэнарам. Напрыклад, можна размясціць усе кантэйнерныя выявы ў агульным сеткавым сховішчы і даць да яго доступ усім Buildah-кантэйнерам. Дапусцім, у нас ёсць сотні вобразаў, якія наша сістэма CI/CD рэгулярна выкарыстоўвае для зборкі кантэйнерных вобразаў. Канцэнтруем усе гэтыя выявы на нейкім адным хасце-сховішчы і затым, выкарыстаючы пераважныя сродкі сеткавага захоўвання (NFS, Gluster, Ceph, ISCSI, S3…), адчыняны агульны доступ да гэтага сховішча ўсім нодам Buildah або Kubernetes.
Зараз досыць падмантаваць гэтае сеткавае сховішча ў кантэйнер Buildah на /var/lib/shared і ўсё – Buildah-кантэйнерам больш наогул не прыйдзецца спампоўваць выявы праз pull. Такім чынам мы выкідваем фазу папярэдняга напаўнення (pre-population) і адразу гатовы выкочваць кантэйнеры.
І вядома ж, гэта можна выкарыстоўваць у рамках дзеючай сістэмы Kubernetes або кантэйнернай інфраструктуры, каб запускаць і выконваць кантэйнеры дзе заўгодна без якога-небудзь запампоўкі выяў праз pull. Больш таго, рэестр кантэйнераў, атрымліваючы push-запыт на загрузку ў яго абноўленай выявы, можа аўтаматычна адпраўляць гэтую выяву ў агульнае сеткавае сховішча, дзе ён імгненна становіцца даступны ўсім нодам.
Памеры кантэйнерных выяў часам могуць дасягаць шматлікіх гігабайт. Функцыянал дадатковых сховішчаў дазваляе абыйсціся без кланавання такіх выяў па нодах і робіць запуск кантэйнераў практычна імгненным.
Акрамя таго, у дадзены момант мы працуем над новай функцыяй overlay volume mounts, якая зробіць зборку кантэйнераў яшчэ хутчэй.
Заключэнне
Выконваць Buildah усярэдзіне кантэйнера ў асяроддзі Kubernetes/CRI-O, Podman ці нават у Docker суцэль рэальна, да таго ж гэта проста і значна бяспечней, чым выкарыстаць docker.socket. Мы значна павысілі гнуткасць працы з выявамі, і зараз вы можаце запускаць іх рознымі спосабамі для аптымальнага балансу паміж бяспекай і прадукцыйнасцю.
Функцыянал дадатковых сховішчаў дазваляе паскорыць ці нават цалкам ухіліць запампоўку выяў на ноды.
Крыніца: habr.com