این یک پست مهمان از Docker Captain Adrian Mouat است که دانشمند ارشد راه حل های کانتینر ، مشاوره در زمینه ابر و ارائه دهنده خدمات مجاز Kubernetes است. آدریان نویسنده "استفاده از داکر" است که توسط O'Reilly Media منتشر شده است. وی در حال حاضر در حال ایجاد Trow است که یک رجیستری برای تصاویر کانتینر برای مدیریت ایمن جریان تصاویر در یک خوشه Kubernetes طراحی کرده است. آدریان یک سخنران و مربی منظم کنفرانس است و وی در چندین رویداد از جمله KubeCon EU ، DockerCon ، CraftConf ، TuringFest و GOTO Amsterdam صحبت کرده است.
تصاویر داکر به ابزاری استاندارد برای آزمایش و استقرار نرم افزارهای جدید و شخص ثالث تبدیل شده است. من توسعه دهنده اصلی رجیستری منبع باز Trow و تصاویر Docker اصلی ترین روش نصب ابزار توسط مردم است. اگر من تصاویر را ارائه نمی کردم ، دیگران به پایان می رسیدند که می توانند کارهای خود را تکرار کنند و مشکلات مربوط به تعمیر و نگهداری را ایجاد کنند.
به طور پیش فرض ، تصاویر داکر که ما ایجاد می کنیم روی پلت فرم linux / amd64
اجرا می شوند. این برای اکثر دستگاه های توسعه و ارائه دهندگان ابری کار می کند اما باعث می شود تا کاربران سیستم عامل های دیگر در سرما نباشند. این مخاطب قابل توجهی است – به آزمایشگاه های خانگی ساخته شده از Raspberry Pis ، شرکت هایی که دستگاه های IoT تولید می کنند ، سازمان هایی که از طریق صفحه اصلی IBM و ابرهایی که از تراشه های کم توان 64 استفاده می کنند ، استفاده کنند. کاربران این سیستم عامل ها به طور معمول تصاویر خود را می سازند یا راه حل دیگری را پیدا می کنند.
بنابراین چگونه می توانید برای این سیستم عامل های دیگر تصاویر بسازید؟ بدیهی ترین راه ، ساختن تصویر بر روی پلت فرم هدف است. این می تواند در بسیاری موارد کار کند ، اما اگر شما s390x را هدف قرار داده اید ، امیدوارم که به یک صفحه اصلی IBM دسترسی پیدا کنید (Phil Estes را امتحان کنید ، زیرا من شنیده ام که او چندین گاراژ در خود دارد). سیستم عامل های رایج تر مانند دستگاه های Raspberry Pis و IoT به طور معمول از نظر قدرت محدود هستند و از نظر ساختاری آهسته یا ناتوان هستند.
بنابراین به جای آن چه می توانیم انجام دهیم؟ دو گزینه دیگر وجود دارد: 1) شبیه سازی سکوی هدف یا 2) کامپایل کردن متقابل. جالب است که ، من فهمیدم که ترکیبی از دو گزینه می تواند به بهترین وجه کار کند.
Emulation
بیایید با نگاه کردن به گزینه اول ، شبیه سازی شروع کنیم. یک پروژه فوق العاده به نام QEMU وجود دارد که می تواند مجموعه ای کامل از سیستم عامل را تقلید کند. با کار اخیر buildx ، استفاده از QEMU با Docker راحت تر از همیشه است.
ادغام QEMU به ویژگی هسته هسته لینوکس با اسم کمی رمزنگارنده binfmt_misc متکی است. هنگامی که لینوکس با یک قالب پرونده اجرایی روبرو می شود که آن را تشخیص نمی دهد (به عنوان مثال یکی از معماری های مختلف) ، در صورت وجود "برنامه های کاربردی فضای کاربر" که برای مقابله با این قالب تنظیم شده است ، وجود دارد. اگر وجود دارد ، آن را اجرا به برنامه منتقل می کند.
برای این کار ، ما باید سکوهای مورد علاقه خود را با هسته ثبت کنیم. اگر از Docker Desktop استفاده می کنید ، این کار قبلاً برای رایج ترین سیستم عامل ها برای شما انجام شده است. اگر از لینوکس استفاده می کنید ، می توانید با اجرای آخرین docker / binfmt
docker ، نام کاربری docker / binfmt: a7996909642ee92942dcd6ff
شما ممکن است نیاز به راه اندازی مجدد داکر پس از انجام این کار. اگر می خواهید کمی کنترل بیشتری روی این سیستم عامل داشته باشید که می خواهید ثبت نام کنید یا می خواهید از یک سیستم عامل باطنی تر استفاده کنید (به عنوان مثال PowerPC) به پروژه qus نگاهی بیندازید.
چند روش مختلف برای استفاده از buildx وجود دارد ، اما ساده ترین کار ممکن است فعال کردن ویژگی های آزمایشی در Docker CLI اگر قبلاً نبوده اید – فقط edit / .docker / config.json
را ویرایش کنید تا موارد زیر را شامل شود:
{ ... "آزمایشی": "فعال شده" }
اکنون باید بتوانید docker buildx ls
را اجرا کنید و باید خروجی مشابه موارد زیر بدست آورید:
$ docker buildx ls نامگذاری / راننده NODE / ENDPOINT STATUS PLATFORMS داکر پیش فرض به طور پیش فرض در حال اجرا linux / amd64 ، linux / arm64 ، linux / riscv64 ، linux / ppc64le ، linux / s390x ، linux / 386 ، linux / arm / v7 ، linux / arm / v6
بیایید سعی کنیم تصویری را برای یک سکوی دیگر ایجاد کنیم. با این Dockerfile شروع کنید:
از debian: buster CMD uname -m
اگر آن را بطور عادی بسازیم و آن را اجرا کنیم:
docker buildx build -t محلی ساخت. ... docker run - rm local-build x86_64
اما اگر ما صریحاً یک سکو را بنویسیم:
$ docker buildx build - ساخت پارچه linux / arm / v7 -t بازوی ساخت. ... docker run - rm arm-build armv7l
موفقیت! ما با کار اندک توانستیم یک تصویر armv7 را روی یک لپ تاپ x86_64 بسازیم و اجرا کنیم. این تکنیک موثر است اما ممکن است در ساختهای پیچیده تر آن را خیلی آهسته اجرا کنید یا در QEMU به اشکال برخوردید. در این موارد ، باید به این نکته توجه کرد که آیا می توانید تصویر خود را کاملاً کامپایل کنید.
Cross-Compilation
چندین کامپایلر قادر به انتشار دودویی برای سیستم عامل های خارجی هستند که مهمترین آنها شامل Go و Rust است. با پروژه رجیستری Trow ، دریافتیم که جمع آوری متقابل سریعترین و مطمئن ترین روش برای ایجاد تصاویر برای سیستم عامل های دیگر است. به عنوان مثال ، در اینجا Dockerfile برای تصویر Trow armv7 وجود دارد. مهمترین خط عبارت است از:
RUN محموله ساخت - هدف armv7-ناشناخته-linux-gnueabihf -Z ناپایدار - گزینه ها --out-dir ./out
که صریحاً به Rust می گوید چه سکویی را می خواهیم که باینری ما اجرا شود. سپس می توانیم از یک ساختمان چند مرحله ای استفاده کنیم تا این دوتایی را در یک تصویر پایه برای معماری هدف کپی کنیم (در صورت تهیه کردن به صورت استاتیک نیز می توانیم از خراش استفاده کنیم) و ما انجام شده ایم. با این حال ، در مورد رجیستری Trow ، چند مورد دیگر وجود دارد که می خواهم در تصویر نهایی تنظیم کنم ، بنابراین مرحله نهایی در واقع با این شروع می شود:
FRO --platform = linux / arm / v7 debian: stabil- باریک
به همین دلیل ، من در واقع از ترکیبی از تقلید و تلفیق متقابل استفاده می کنم – تلفیقی متقاطع برای ایجاد باینری و تقلید برای اجرای و پیکربندی تصویر نهایی ما.
Manifest Lists
مشاوره در مورد شبیه سازی ، شاید شما متوجه شده اید که از آرگومان - platform
برای تنظیم سکوی ساخت استفاده کرده ایم ، اما ما تصویر مشخص شده در خط FROM را به عنوان debian رها کردیم: buster
. به نظر می رسد این معنی ندارد – مطمئناً بستر های نرم افزاری به تصویر پایه و نحوه ساخت آن بستگی دارد ، نه آنچه که کاربر در مرحله بعدی تصمیم می گیرد؟
Docker آنچه در اینجا اتفاق می افتد ، از چیزی به نام لیست های آشکار استفاده می کند. اینها لیست هایی برای یک تصویر مشخص است که حاوی نشانگرهایی برای تصاویر برای معماری های مختلف است. از آنجا که تصویر debian رسمی دارای یک لیست مشخص است ، وقتی تصویر را روی لپ تاپ می کشم ، به طور خودکار تصویر amd64 را می گیرم و وقتی آن را روی Raspberry Pi می کشم ، تصویر armv7 را می گیرم.
برای اینکه کاربران خود را راضی نگه داریم. ما می توانیم برای تصاویر خود لیست های آشکار ایجاد کنیم. اگر به مثال قبلی خود برگردیم ، ابتدا باید تصاویر را به مخزن بازسازی و هل دهیم:
$ docker buildx build --platform linux / arm / v7 -t amouat / arch-test: armv7. ... $ docker push amouat / آزمون قوس: armv7 ... $ docker buildx build -t amouat / arch-test: amd64. ... docker push amouat / test-arch: amd64
در مرحله بعدی ، ما یک لیست آشکار ایجاد می کنیم که به این دو تصویر جداگانه اشاره می کند و فشار می دهیم که:
$ docker manifest ایجاد amouat / arch-test: blog amouat / arch-test: amd64 amouat / arch-test: armv7 ایجاد لیست مانیفست docker.io/amouat/arch-test:blog $ docker manifest push amouat / arch-test: وبلاگ sha256: 039dd768fc0758fbe82e3296d40b45f71fd69768f21bb9e0da02d0fb28c67648
اکنون Docker تصویر مناسب برای سکوی فعلی را بکش و اجرا خواهد کرد:
docker run amouat / arch-test: blog یافتن تصویر "amouat / test-arch: blog" به صورت محلی امکان پذیر نیست وبلاگ: در حال کشیدن از amouat / test-arch هضم: sha256: 039dd768fc0758fbe82e3296d40b45f71fd69768f21bb9e0da02d0fb28c67648 وضعیت: بارگیری تصویر جدیدتر برای amouat / arch-test: blog x86_64
شخصی که یک تمشک پی به دست دارد می تواند تصویر را امتحان کند و تأیید کند که در واقع روی آن سکو نیز کار می کند!
برای گرفتن مجدد. همه کاربران تصاویر Docker amd64 را اجرا نمی کنند. با استفاده از buildx و QEMU ، می توان با مقدار کمی کار اضافی از این کاربران پشتیبانی کرد.
تولدت مبارک ، داکر!