[اشاره به افسانه کودکان آمریکایی "موتور کوچکی که می توانست" - تقریبا. مسیر]*
چگونه به طور خودکار تصاویر کوچک Docker را برای نیازهای خود ایجاد کنید
وسواس غیر معمول
در چند ماه گذشته، من وسواس زیادی داشتم که یک تصویر Docker چقدر می تواند کوچک باشد و هنوز هم برنامه در حال اجرا باشد؟
می فهمم، ایده عجیبی است.
قبل از اینکه وارد جزئیات و نکات فنی بشوم، میخواهم توضیح دهم که چرا این مشکل اینقدر من را آزار میدهد و چگونه به شما مربوط میشود.
چرا اندازه مهم است
با کاهش محتویات تصویر داکر، لیست آسیبپذیریها را کاهش میدهیم. علاوه بر این، ما تصاویر را تمیزتر می کنیم، زیرا آنها فقط حاوی موارد مورد نیاز برای اجرای برنامه ها هستند.
یک مزیت کوچک دیگر وجود دارد - تصاویر کمی سریعتر بارگیری می شوند، اما، به نظر من، این خیلی مهم نیست.
لطفا توجه داشته باشید: اگر در مورد اندازه نگران هستید، ظاهر آلپاین به خودی خود کوچک است و احتمالاً مناسب شما خواهد بود.
تصاویر بدون توزیع
pip
и apt
کار نخواهد کرد:
FROM gcr.io/distroless/python3
RUN pip3 install numpy
Dockerfile با استفاده از تصویر بدون توزیع پایتون 3
Sending build context to Docker daemon 2.048kB
Step 1/2 : FROM gcr.io/distroless/python3
---> 556d570d5c53
Step 2/2 : RUN pip3 install numpy
---> Running in dbfe5623f125
/bin/sh: 1: pip3: not found
پیپ در تصویر نیست
معمولاً این مشکل با ساخت چند مرحله ای حل می شود:
FROM python:3 as builder
RUN pip3 install numpy
FROM gcr.io/distroless/python3
COPY --from=builder /usr/local/lib/python3.7/site-packages /usr/local/lib/python3.5/
مونتاژ چند مرحله ای
نتیجه تصویری با حجم 130 مگابایت است. نه خیلی بد! برای مقایسه: تصویر پیشفرض پایتون 929 مگابایت وزن دارد و تصویر «ناریکتر» (3,7-slim
) - 179 مگابایت، تصویر آلپاین (3,7-alpine
) 98,6 مگابایت است، در حالی که تصویر پایه بدون توزیع استفاده شده در مثال 50,9 مگابایت است.
منصفانه است که اشاره کنیم که در مثال قبلی ما در حال کپی کردن یک فهرست کامل هستیم /usr/local/lib/python3.7/site-packages
، که ممکن است حاوی وابستگی هایی باشد که ما به آنها نیاز نداریم. اگرچه واضح است که تفاوت اندازه تمام تصاویر پایه پایتون موجود متفاوت است.
در زمان نگارش، Google distroless بسیاری از تصاویر را پشتیبانی نمیکند: جاوا و پایتون هنوز در مرحله آزمایشی هستند و پایتون فقط برای نسخههای 2,7 و 3,5 وجود دارد.
تصاویر ریز
بازگشت به وسواس من برای ایجاد تصاویر کوچک.
به طور کلی، میخواستم ببینم تصاویر بدون توزیع چگونه ساخته میشوند. پروژه بدون توزیع از ابزار ساخت گوگل استفاده می کند bazel
. با این حال، نصب Bazel و نوشتن تصاویر خود کار زیادی را به خود اختصاص داد (و صادقانه بگویم، اختراع مجدد چرخ سرگرم کننده و آموزشی است). من می خواستم ایجاد تصاویر کوچکتر را ساده کنم: عمل ایجاد یک تصویر باید بسیار ساده باشد، پیش پا افتاده. به طوری که هیچ فایل پیکربندی برای شما وجود ندارد، فقط یک خط در کنسول وجود دارد: просто собрать образ для <приложение>
.
بنابراین، اگر می خواهید تصاویر خود را ایجاد کنید، بدانید: چنین تصویر داکر منحصر به فردی وجود دارد، scratch
. Scratch یک تصویر "خالی" است ، هیچ فایلی در آن وجود ندارد ، اگرچه به طور پیش فرض وزن دارد - وای! - 77 بایت
FROM scratch
تصویر خراش
ایده یک تصویر خراشیده این است که شما می توانید هر وابستگی را از ماشین میزبان در آن کپی کنید و یا از آنها در یک Dockerfile استفاده کنید (این مانند کپی کردن آنها در apt
و از ابتدا نصب کنید)، یا بعداً زمانی که تصویر Docker عملی شد. این به شما این امکان را می دهد که محتویات ظرف Docker را کاملاً کنترل کنید و در نتیجه اندازه تصویر را کاملاً کنترل کنید.
حال باید به نحوی این وابستگی ها را جمع آوری کنیم. ابزارهای موجود مانند apt
به شما امکان می دهد بسته ها را دانلود کنید، اما آنها به دستگاه فعلی متصل هستند و در نهایت، از ویندوز یا MacOS پشتیبانی نمی کنند.
بنابراین من تصمیم گرفتم ابزار خود را بسازم که به طور خودکار یک تصویر پایه با کوچکترین اندازه ممکن بسازد و همچنین هر برنامه ای را اجرا کند. من از بستههای Ubuntu/Debian استفاده کردم، انتخاب کردم (دریافت بستهها مستقیماً از مخازن) و به صورت بازگشتی وابستگیهای آنها را پیدا کردم. این برنامه قرار بود به طور خودکار آخرین نسخه پایدار بسته را دانلود کند و خطرات امنیتی را تا حد امکان به حداقل برساند.
اسم ابزار رو گذاشتم fetchy
، زیرا او ... می یابد و می آورد ... آنچه لازم است [از انگلیسی "واکشی"، "اوردن" - تقریبا. مسیر]. این ابزار از طریق یک رابط خط فرمان کار می کند، اما در عین حال یک API ارائه می دهد.
برای جمع آوری یک تصویر با استفاده از fetchy
(این بار یک تصویر پایتون می گیریم)، فقط باید از CLI به این صورت استفاده کنید: fetchy dockerize python
. ممکن است از شما سیستم عامل هدف و نام رمز خواسته شود زیرا fetchy
در حال حاضر فقط از بسته های مبتنی بر دبیان و اوبونتو استفاده می کند.
اکنون می توانید انتخاب کنید که کدام وابستگی ها اصلاً مورد نیاز نیستند (در زمینه ما) و آنها را حذف کنید. به عنوان مثال، پایتون به پرل وابسته است، اگرچه بدون نصب پرل به خوبی کار می کند.
یافته ها
تصویر پایتون با استفاده از دستور ایجاد شده است fetchy dockerize python3.5
وزن آن فقط 35 مگابایت است (من مطمئن هستم که در آینده می توان آن را حتی سبک تر کرد). به نظر می رسد که ما موفق شدیم 15 WW دیگر را از تصویر بدون توزیع حذف کنیم.
شما می توانید تمام تصاویر جمع آوری شده تا کنون را مشاهده کنید
پروژه -
اگر ویژگیهایی ندارید، فقط یک درخواست ایجاد کنید - خوشحال میشوم کمک کنم :) حتی بیشتر، من در حال حاضر روی ادغام سایر مدیران بسته در fetchy کار میکنم تا نیازی به ساختهای چند مرحلهای نباشد.
منبع: www.habr.com