توصیه هایی برای اجرای بیلدا در داخل کانتینر

زیبایی جدا کردن زمان اجرا کانتینر به اجزای ابزار جداگانه چیست؟ به طور خاص، این ابزارها می توانند شروع به ترکیب شوند تا از یکدیگر محافظت کنند.

توصیه هایی برای اجرای بیلدا در داخل کانتینر

بسیاری از مردم جذب ایده ساختن تصاویر OCI کانتینری شده در داخل می شوند کوبرنیتس یا سیستم مشابه فرض کنید یک CI/CD داریم که دائماً تصاویر را جمع آوری می کند، سپس چیزی شبیه به آن سرخپوش OpenShift/Kubernetes از نظر تعادل بار در طول ساخت بسیار مفید خواهد بود. تا همین اواخر، اکثر مردم به سادگی به کانتینرها دسترسی به سوکت داکر می دادند و به آنها اجازه می دادند دستور ساخت docker را اجرا کنند. چندین سال پیش نشان دادیمکه این بسیار ناامن است، در واقع، حتی بدتر از دادن root یا sudo بدون رمز است.

به همین دلیل است که مردم دائماً سعی می کنند بیلدا را در یک کانتینر اجرا کنند. خلاصه ما ایجاد کردیم مثال چگونه، به نظر ما، بهتر است Buildah را در داخل یک ظرف اجرا کنیم و تصاویر مربوطه را در آن پست کنیم quay.io/buildah. بیا شروع کنیم...

تنظیم

این تصاویر از Dockerfiles ساخته شده اند که می توانید آنها را در مخزن Buildah در پوشه پیدا کنید. buildahimage.
در اینجا به بررسی خواهیم پرداخت نسخه پایدار 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

به جای OverlayFS که در سطح هسته لینوکس میزبان پیاده سازی شده است، از برنامه داخل کانتینر استفاده می کنیم. فیوز پوشش، زیرا در حال حاضر OverlayFS تنها زمانی می تواند نصب شود که با استفاده از قابلیت های لینوکس به آن مجوز SYS_ADMIN بدهید. و ما می خواهیم کانتینرهای Buildah خود را بدون هیچ گونه امتیاز root اجرا کنیم. Fuse-overlay خیلی سریع کار می کند و عملکرد بهتری نسبت به درایور ذخیره سازی VFS دارد. لطفاً توجه داشته باشید که هنگام اجرای یک کانتینر Buildah که از Fuse استفاده می کند، باید دستگاه /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

سپس یک دایرکتوری برای ذخیره سازی اضافی ایجاد می کنیم. ظرف / انبار از مفهوم اتصال فروشگاه های تصویر فقط خواندنی اضافی پشتیبانی می کند. به عنوان مثال، می‌توانید یک فضای ذخیره‌سازی همپوشانی را روی یک دستگاه پیکربندی کنید، و سپس از NFS برای نصب این فضای ذخیره‌سازی روی دستگاه دیگر و استفاده از تصاویر آن بدون دانلود از طریق کشش استفاده کنید. ما به این ذخیره سازی نیاز داریم تا بتوانیم مقداری ذخیره تصویر را از هاست به عنوان حجم متصل کنیم و از آن در داخل کانتینر استفاده کنیم.

# 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 که در بالا مورد بحث قرار گرفت به شما امکان می دهد روش های پرتاب چنین کانتینری ها را به طور انعطاف پذیر تغییر دهید.

سرعت در مقابل ایمنی

امنیت رایانه همیشه بین سرعت فرآیند و میزان حفاظتی که در اطراف آن پیچیده شده است، مصالحه است. این عبارت هنگام مونتاژ کانتینرها نیز صادق است، بنابراین در زیر گزینه هایی را برای چنین مصالحه ای در نظر خواهیم گرفت.

تصویر کانتینر مورد بحث در بالا ذخیره خود را در /var/lib/containers نگه می دارد. بنابراین، ما باید محتوا را در این پوشه قرار دهیم و نحوه انجام این کار بر سرعت ساخت تصاویر کانتینر تأثیر زیادی خواهد داشت.

بیایید سه گزینه را در نظر بگیریم.

گزینه 1 اگر حداکثر امنیت مورد نیاز است، برای هر کانتینر می توانید پوشه مخصوص کانتینرها/تصویر خود را ایجاد کنید و آن را از طریق ولوم مونت به ظرف متصل کنید. و علاوه بر این، دایرکتوری متن را در خود ظرف، در پوشه 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 داده نمی شود و تمام محدودیت های SECOMP و SELinux برای آن اعمال می شود. چنین کانتینری حتی می تواند با انزوا فضای نام کاربری با افزودن گزینه ای مانند —uidmap 0 اجرا شود: 100000:10000.

کارایی. اما عملکرد در اینجا حداقل است، زیرا هر تصویری از رجیستری کانتینر هر بار در هاست کپی می شود و کش اصلا کار نمی کند. کانتینر بیلدا هنگام تکمیل کار خود باید تصویر را به رجیستری ارسال کند و محتوای موجود در هاست را از بین ببرد. دفعه بعد که تصویر کانتینر ساخته می شود، باید دوباره از رجیستری بارگیری شود، زیرا تا آن زمان چیزی روی هاست باقی نخواهد ماند.

گزینه 2 اگر به عملکرد در سطح Docker نیاز دارید، می توانید کانتینر/ذخیره میزبان را مستقیماً در ظرف نصب کنید.

# 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 را غیرفعال کنید تا فرآیندهای موجود در کانتینر 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 تصویر را دانلود کرد، تصویر را می توان در هر بیلد بعدی در پروژه استفاده کرد.

ذخیره سازی اضافی

У ظروف / انبار چیز جالبی مانند فروشگاه های اضافی (فروشگاه های اضافی) وجود دارد که به لطف آن هنگام راه اندازی و ساخت ظروف ، موتورهای کانتینر می توانند از فروشگاه های تصویر خارجی در حالت همپوشانی فقط خواندنی استفاده کنند. اساساً، می‌توانید یک یا چند ذخیره‌سازی فقط خواندنی را به فایل storage.conf اضافه کنید تا زمانی که ظرف را روشن می‌کنید، موتور ظرف به دنبال تصویر مورد نظر در آنها بگردد. علاوه بر این، تنها در صورتی که آن را در هیچ یک از این حافظه ها پیدا نکند، تصویر را از رجیستری دانلود می کند. موتور کانتینر فقط می‌تواند در ذخیره‌سازی قابل نوشتن بنویسد...

اگر به بالا بروید و به Dockerfile که برای ساختن تصویر استفاده می‌کنیم نگاه کنید، خطوطی مانند این وجود دارد:

# 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 را در داخل تصویر کانتینر تغییر می‌دهیم و به درایور ذخیره‌سازی می‌گوییم که از "additionalimagestores" در پوشه /var/lib/shared استفاده کند. و در خط بعدی یک پوشه به اشتراک گذاشته شده ایجاد می کنیم و چند فایل قفل اضافه می کنیم تا هیچ سوء استفاده ای از کانتینرها / ذخیره سازی وجود نداشته باشد. در اصل، ما به سادگی یک ذخیره‌سازی تصویر ظرف خالی ایجاد می‌کنیم.

اگر ظروف/ذخیره را در سطحی بالاتر از این پوشه نصب کنید، Buildah می‌تواند از تصاویر استفاده کند.

اکنون اجازه دهید به گزینه 2 که در بالا مورد بحث قرار گرفت برگردیم، زمانی که کانتینر Buildah می تواند در کانتینرها بخواند و بنویسد/ روی هاست ذخیره کند و بر این اساس، حداکثر کارایی را به دلیل ذخیره تصاویر در سطح 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 در داخل ظرف در حالت فقط خواندنی نصب شده است. بنابراین، با کار در یک کانتینر، Buildah می‌تواند از هر تصویری که قبلاً با استفاده از Podman/CRI-O دانلود شده است (سلام، سرعت) استفاده کند، اما فقط می‌تواند در حافظه خود بنویسد (سلام، امنیت). همچنین توجه داشته باشید که این کار بدون غیرفعال کردن جداسازی SELinux برای کانتینر انجام می شود.

نکات مهم

تحت هیچ شرایطی نباید هیچ تصویری را از مخزن اصلی حذف کنید. در غیر این صورت، کانتینر بیلدا ممکن است سقوط کند.

و این همه مزیت نیست

امکانات ذخیره سازی اضافی به سناریوی فوق محدود نمی شود. به عنوان مثال، می توانید تمام تصاویر کانتینر را در یک ذخیره سازی شبکه مشترک قرار دهید و به همه کانتینرهای Buildah دسترسی به آن را بدهید. فرض کنید صدها تصویر داریم که سیستم CI/CD ما به طور مرتب از آنها برای ساخت تصاویر کانتینر استفاده می کند. ما همه این تصاویر را روی یک میزبان ذخیره سازی متمرکز می کنیم و سپس با استفاده از ابزارهای ذخیره سازی شبکه ترجیحی (NFS، Gluster، Ceph، ISCSI، S3...)، دسترسی عمومی به این ذخیره سازی را برای همه گره های Buildah یا Kubernetes باز می کنیم.

اکنون کافی است این فضای ذخیره سازی شبکه را در کانتینر Buildah در /var/lib/shared نصب کنید و تمام - کانتینرهای Buildah دیگر نیازی به دانلود تصاویر از طریق pull ندارند. بنابراین، ما مرحله پیش از جمعیت را بیرون می اندازیم و بلافاصله آماده می شویم تا ظروف را باز کنیم.

و البته، این می‌تواند در یک سیستم زنده Kubernetes یا زیرساخت کانتینر برای راه‌اندازی و اجرای کانتینرها در هر نقطه‌ای بدون هیچ بارگیری کششی تصاویر استفاده شود. علاوه بر این، رجیستری کانتینر، با دریافت یک درخواست فشار برای آپلود یک تصویر به روز شده در آن، می تواند به طور خودکار این تصویر را به یک ذخیره سازی شبکه مشترک ارسال کند، جایی که فوراً در دسترس همه گره ها قرار می گیرد.

اندازه تصاویر کانتینر گاهی اوقات می تواند به چندین گیگابایت برسد. عملکرد ذخیره سازی اضافی به شما امکان می دهد از شبیه سازی چنین تصاویری در سراسر گره ها جلوگیری کنید و پرتاب ظروف را تقریباً فوری می کند.

علاوه بر این، ما در حال حاضر روی یک ویژگی جدید به نام نصب‌کننده‌های حجمی روی هم کار می‌کنیم که ساخت کانتینرها را سریع‌تر می‌کند.

نتیجه

اجرای Buildah در داخل یک کانتینر در Kubernetes/CRI-O، Podman یا حتی Docker امکان پذیر، ساده و بسیار امن تر از استفاده از docker.socket است. ما انعطاف‌پذیری کار با تصاویر را بسیار افزایش داده‌ایم، بنابراین می‌توانید آنها را به روش‌های مختلفی اجرا کنید تا تعادل بین امنیت و عملکرد را بهینه کنید.

عملکرد ذخیره سازی اضافی به شما امکان می دهد سرعت بارگیری تصاویر را در گره ها افزایش دهید یا حتی به طور کامل حذف کنید.

منبع: www.habr.com

اضافه کردن نظر