ساخت چندمرحله‌ای در داکر و تولید ایمیج برای چند معماری

ایمیج‌های کانتینری بزرگ به معنای استقرار کندتر و سطح حمله بزرگ‌تر هستند. این مقاله توضیح می‌دهد که ساخت چندمرحله‌ای (Multi-Stage Build) چگونه ایمیج‌های نهایی را سبک نگه می‌دارد، و Buildx و BuildKit چطور امکان ساخت هم‌زمان ایمیج برای چند معماری CPU را فراهم می‌کنند.

Multi-Stage BuildBuildxBuildKit

~4 دقیقه مطالعه · آخرین به‌روزرسانی ۱۴ شهریور ۱۴۰۵

مقدمه

وقتی صحبت از ایمیج‌های کانتینری می‌شود، کوچک‌تر بودن تقریباً همیشه بهتر است — ایمیج‌های کوچک‌تر سریع‌تر pull می‌شوند، آسیب‌پذیری‌های بالقوه کمتری دارند و سطح حمله کوچک‌تری ارائه می‌دهند. ساخت چندمرحله‌ای (Multi-Stage Build) اصلی‌ترین تکنیکی است که داکر برای سبک نگه‌داشتن ایمیج‌های تولیدی ارائه می‌دهد.

ساخت چندمرحله‌ای چگونه کار می‌کند

یک ساخت چندمرحله‌ای از یک Dockerfile واحد با چند دستورالعمل FROM استفاده می‌کند که هرکدام نماینده یک مرحله ساخت مجزا هستند. این روش امکان می‌دهد ابزارهای سنگین ساخت و کامپایلرها در یک مرحله اولیه و بزرگ‌تر باقی بمانند، در حالی که فقط خروجی کامپایل‌شده به یک ایمیج نهایی حداقلی برای تولید — که اغلب slim image نامیده می‌شود — کپی می‌شود.

FROM golang:1.23.4-alpine AS base
WORKDIR /src
COPY go.mod go.sum .
RUN go mod download
COPY . .

FROM base AS build-client
RUN go build -o /bin/client ./cmd/client

FROM base AS build-server
RUN go build -o /bin/server ./cmd/server

FROM scratch AS prod
COPY --from=build-client /bin/client /bin/
COPY --from=build-server /bin/server /bin/
ENTRYPOINT [ "/bin/server" ]

هر مرحله نام‌گذاری‌شده یک ایمیج میانی تولید می‌کند که مراحل بعدی می‌توانند به آن ارجاع دهند، اما داکر این ایمیج‌های میانی را پس از اتمام مرحله نهایی حذف می‌کند. مراحلی که به یکدیگر وابسته نیستند، مانند build-client و build-server در این مثال، می‌توانند به‌صورت موازی اجرا شوند و فرآیند ساخت را سریع‌تر کنند.

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

ساخت چند ایمیج از یک Dockerfile

یک Dockerfile واحد همچنین می‌تواند چند ایمیج مجزا تولید کند، با تقسیم مرحله نهایی و استفاده از فلگ --target برای انتخاب اینکه کدام مرحله ساخته شود:

docker build -t multi:client --target prod-client -f Dockerfile-final .
docker build -t multi:server --target prod-server -f Dockerfile-final .

Buildx و BuildKit

سیستم ساخت داکر به یک کلاینت و یک سرور تقسیم شده است: Buildx کلاینت است که به‌صورت یک پلاگین CLI پیاده‌سازی شده، و BuildKit سروری است که واقعاً ساخت را انجام می‌دهد. از نسخه Docker v23.0 به بعد، Buildx کلاینت پیش‌فرض ساخت برای هر دستور docker build بوده است.

Buildx می‌تواند برای ارتباط با چند نمونه BuildKit، که builder نامیده می‌شوند، پیکربندی شود؛ این builderها می‌توانند به‌صورت محلی، در یک ابر خصوصی، یا روی سرویس Build Cloud خود داکر اجرا شوند. builderهای محلی معمولاً از درایور docker-container استفاده می‌کنند، در حالی که ساخت‌های راه‌دور از درایور cloud استفاده می‌کنند.

docker buildx ls

ساخت چندمعماری

داکر می‌تواند ایمیج‌هایی برای معماری‌های CPU متفاوت از دستگاه محلی بسازد — برای مثال، ساخت ایمیج ARM روی یک سیستم AMD. این کار با فلگ --platform انجام می‌شود:

docker buildx build --builder=container \
  --platform=linux/amd64,linux/arm64 \
  -t nigelpoulton/ddd-book:ch8.1 --push .

هر دستورالعمل Dockerfile یک‌بار به ازای هر معماری هدف اجرا می‌شود و ایمیج‌های حاصل تحت همان تگ منتشر می‌شوند، به‌طوری که یک دستور docker pull به‌طور خودکار نسخه صحیح را برای هر پلتفرمی دریافت می‌کند.

شیوه‌های مناسب

دو شیوه تأثیر قابل‌توجهی بر کارایی ساخت و اندازه ایمیج دارند. اول، ساختاردهی Dockerfile به‌گونه‌ای که دستورالعمل‌های احتمالاً پرتغییرتر در انتها قرار بگیرند، به حفظ build cache کمک می‌کند، زیرا یک miss در کش برای یک دستورالعمل، کش تمام دستورالعمل‌های بعدی را نیز باطل می‌کند. دوم، نصب فقط بسته‌های ضروری — با استفاده از فلگ‌هایی مانند no-install-recommends در صورت وجود — می‌تواند به‌طور چشمگیری تعداد وابستگی‌های وارد‌شده به ایمیج را کاهش دهد.

نتیجه‌گیری

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

نوشته و پژوهش‌شده توسط دکتر شاهین صیامی

مقالات مرتبط

داکر چگونه از فناوری‌های امنیتی لینوکس استفاده می‌کند

مدل امنیتی داکر بر پایه دفاع چندلایه ساخته شده و فناوری‌های شناخته‌شده kernel لینوکس را با تنظیمات پیش‌فرض معقول ترکیب می‌کند. این مقاله توضیح می‌دهد که namespaceها، control groupها، capabilityها، Mandatory Access Control و seccomp چگونه در کنار هم کانتینرها را ایزوله و ایمن می‌کنند.

ادامه

مدیریت داده‌های ماندگار در داکر با Volume

کانتینرها به‌طور پیش‌فرض یک لایه نوشتنی موقت دریافت می‌کنند که با حذف کانتینر از بین می‌رود — این برای داده‌های موقتی خوب است، اما برای هر چیزی که ارزش نگهداری دارد ریسک‌آور است. این مقاله توضیح می‌دهد که volumeهای داکر چگونه داده‌های ماندگار را از چرخه حیات کانتینر جدا می‌کنند و نحوه ساخت، استفاده و اشتراک‌گذاری امن آن‌ها را بررسی می‌کند.

ادامه

شبکه‌های Overlay در داکر چگونه کار می‌کنند؛ نگاهی به VXLAN

شبکه‌های overlay امکان می‌دهند کانتینرهای روی هاست‌های مختلف طوری با هم ارتباط برقرار کنند که گویی یک شبکه مسطح مشترک دارند، و ستون فقرات بیشتر اپلیکیشن‌های میکروسرویس ابرمحور را تشکیل می‌دهند. این مقاله نحوه ساخت، رمزنگاری و تست یک شبکه overlay داکر روی یک کلاستر Swarm را بررسی کرده و فناوری تونل‌زنی VXLAN پشت آن را توضیح می‌دهد.

ادامه

اتصال کانتینرهای داکر به VLAN و توزیع بار با Swarm

فراتر از شبکه‌های ساده bridge، داکر امکاناتی برای اتصال مستقیم کانتینرها به VLANهای فیزیکی موجود، تفکیک خودکار نام سرویس‌ها و توزیع ترافیک در سراسر یک کلاستر Swarm ارائه می‌دهد. این مقاله درایور macvlan، سرویس داخلی Service Discovery و مکانیزم Ingress Load Balancing در Swarm را بررسی می‌کند.

ادامه

شبکه‌سازی در داکر؛ آشنایی با CNM، Libnetwork و شبکه‌های Bridge

شبکه‌سازی در داکر بر پایه یک طراحی باز به نام Container Network Model ساخته شده که توسط libnetwork پیاده‌سازی و با درایورهای قابل‌جایگزینی گسترش می‌یابد. این مقاله تئوری پشت شبکه داکر را بررسی کرده و نحوه ساخت و تست شبکه‌های bridge تک‌هاست، از جمله تفکیک نام و نگاشت پورت را توضیح می‌دهد.

ادامه

استقرار و مدیریت کلاستر چندنودی با Docker Swarm

Docker Swarm گروهی از نودهای داکر را به یک کلاستر امن و بسیار در دسترس با قابلیت ارکستریشن داخلی تبدیل می‌کند. این مقاله ساخت یک swarm چندنودی، استقرار یک اپلیکیشن میکروسرویس به‌صورت اعلانی و انجام به‌روزرسانی‌های تدریجی بدون از دست دادن سازگاری با وضعیت مطلوب را بررسی می‌کند.

ادامه