کانتینر در برابر ماشین مجازی؛ راهنمای عملی اجرای کانتینرها

کانتینرها نمونه‌های اجرایی سبک‌وزنی از ایمیج‌ها هستند که رفتاری کاملاً متفاوت از ماشین‌های مجازی دارند، هرچند هر دو برای ایزوله‌سازی و اجرای برنامه‌ها به کار می‌روند. این مقاله این دو مدل را مقایسه می‌کند و نحوه راه‌اندازی، بررسی، دیباگ و اعمال سیاست‌های ریستارت روی کانتینرها با داکر را توضیح می‌دهد.

کانتینر داکرکانتینر در برابر VMRestart Policy

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

مقدمه

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

کانتینر در برابر ماشین مجازی

کانتینرها و ماشین‌های مجازی (VM) هر دو منابع را برای اجرای برنامه‌ها مجازی‌سازی می‌کنند، اما به روش‌هایی بنیادین متفاوت. VM ها سخت‌افزار را مجازی‌سازی می‌کنند: یک hypervisor منابع فیزیکی مانند CPU و RAM را در اختیار می‌گیرد و آن‌ها را به ماشین‌های مجازی تبدیل می‌کند که هرکدام به سیستم‌عامل کامل خود نیاز دارند. در مقابل، کانتینرها خود سیستم‌عامل را مجازی‌سازی می‌کنند، در حالی که kernel میزبان را به اشتراک می‌گذارند و کد برنامه را در واحدهای ایزوله و سبک بسته‌بندی می‌کنند.

از آنجا که هر VM به سیستم‌عامل مستقل خود نیاز دارد، VM ها منابع بیشتری مصرف کرده و دیرتر بالا می‌آیند. کانتینرها کاملاً از این سربار اجتناب می‌کنند، که به این معناست:

  • کانتینرها کوچک‌تر و قابل‌حمل‌ترند
  • روی یک زیرساخت یکسان، تعداد کانتینر بیشتری نسبت به VM قابل اجراست
  • کانتینرها بسیار سریع‌تر راه‌اندازی می‌شوند
  • تعداد سیستم‌عامل‌هایی که باید patch و مدیریت شوند کاهش می‌یابد
  • کانتینرها سطح حمله کوچک‌تری دارند

یکی از نگرانی‌های تاریخی درباره کانتینرها، مدل kernel مشترک است، زیرا یک آسیب‌پذیری در kernel می‌تواند به‌طور نظری همه کانتینرهای یک میزبان را تحت تأثیر قرار دهد. پلتفرم‌های مدرن کانتینری این ریسک را با فناوری‌های امنیتی مانند SELinux، AppArmor، seccomp و اسکن آسیب‌پذیری ایمیج کاهش می‌دهند.

ایمیج‌ها و کانتینرها

وقتی چندین کانتینر از یک ایمیج واحد راه‌اندازی می‌شوند، داکر به هر کانتینر یک لایه نوشتنی (R/W) نازک روی ایمیج مشترک و فقط‌خواندنی می‌دهد. تغییرات ایجادشده داخل کانتینر روی همین لایه نوشته می‌شوند. توقف یک کانتینر این لایه را حفظ می‌کند، اما حذف کانتینر آن را برای همیشه پاک می‌کند.

راه‌اندازی یک کانتینر

دستور docker run رایج‌ترین روش راه‌اندازی یک کانتینر جدید است:

docker run -d --name webserver -p 5005:8080 nigelpoulton/ddd-book:web0.1

در اینجا، -d کانتینر را در پس‌زمینه اجرا می‌کند، --name نامی به آن اختصاص می‌دهد و -p یک پورت هاست را به پورت کانتینر نگاشت می‌کند. اگر ایمیج به‌صورت محلی موجود نباشد، داکر به‌طور خودکار آن را از Docker Hub دریافت می‌کند.

نحوه شروع برنامه‌ها توسط کانتینر

داکر یکی از سه روش را برای تعیین اینکه چه چیزی داخل کانتینر اجرا شود انتخاب می‌کند: دستورالعمل Entrypoint تعبیه‌شده در ایمیج، دستورالعمل Cmd در ایمیج، یا دستوری که مستقیماً روی CLI پاس داده شود. دستورالعمل‌های Entrypoint از خط فرمان قابل بازنویسی نیستند، در حالی که دستورالعمل‌های Cmd قابل بازنویسی هستند.

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

دستور docker exec امکان اجرای دستورات داخل یک کانتینر در حال اجرا را فراهم می‌کند، چه به‌صورت تعاملی و چه به‌صورت اجرای مستقیم یک‌باره:

docker exec -it webserver sh

از آنجا که اکثر کانتینرها فقط شامل ابزارهای ضروری هستند، بسیاری از دستورات آشنا ممکن است داخل آن‌ها در دسترس نباشند.

فرآیندهای کانتینر و بررسی آن

اکثر کانتینرها یک فرآیند اصلی اجرا می‌کنند که همیشه PID 1 دارد. اگر این فرآیند کشته شود، کل کانتینر متوقف می‌شود، زیرا کانتینرها فقط تا زمانی اجرا می‌شوند که فرآیند اصلی آن‌ها در حال اجراست. دستور docker inspect اطلاعات پیکربندی و runtime دقیقی درباره یک کانتینر ارائه می‌دهد، از جمله وضعیت، نگاشت پورت‌ها و entrypoint آن.

ماندگاری و از دست رفتن تغییرات

تغییرات ایجادشده در فایل‌سیستم یک کانتینر در حال اجرا در لایه نوشتنی آن ذخیره می‌شوند و در برابر توقف و راه‌اندازی مجدد باقی می‌مانند. اما پس از حذف یک کانتینر با docker rm، این تغییرات برای همیشه از بین می‌روند و یک کانتینر جدید از همان ایمیج این تغییرات را نخواهد داشت. تغییر مستقیم کانتینرهای زنده به‌طور کلی یک anti-pattern محسوب می‌شود؛ روش توصیه‌شده ساخت یک ایمیج جدید با تغییرات لازم و جایگزینی کانتینر است.

دیباگ کانتینرهای سبک با Docker Debug

Docker Debug (که با اشتراک Pro، Team یا Business در دسترس است) مشکل رایج دیباگ ایمیج‌های حداقلی فاقد شل یا ابزار عیب‌یابی را حل می‌کند. این ابزار یک جعبه‌ابزار موقت به کانتینر یا ایمیج متصل می‌کند و امکان استفاده از ابزارهایی مانند ping، vim یا nslookup را فراهم می‌کند، حتی اگر نصب نباشند. تغییرات ایجادشده هنگام دیباگ یک کانتینر در حال اجرا باقی می‌مانند، اما تغییرات هنگام دیباگ کانتینر متوقف‌شده یا ایمیج، پس از پایان نشست حذف می‌شوند.

خودترمیمی با سیاست‌های ریستارت

داکر از چهار سیاست ریستارت (Restart Policy) پشتیبانی می‌کند که نحوه بازیابی کانتینرها از خرابی را کنترل می‌کنند:

  • no (پیش‌فرض) — هرگز به‌طور خودکار ریستارت نمی‌شود
  • on-failure — فقط در صورت کد خروج غیرصفر ریستارت می‌شود
  • always — همیشه ریستارت می‌شود، حتی پس از ریستارت daemon
  • unless-stopped — همیشه ریستارت می‌شود، مگر اینکه به‌صورت دستی متوقف شده باشد

یک سیاست ریستارت هنگام راه‌اندازی کانتینر اعمال می‌شود، برای مثال:

docker run --name neversaydie -it --restart always alpine sh

نتیجه‌گیری

کانتینرها روشی بسیار کارآمدتر برای مجازی‌سازی برنامه‌ها نسبت به VM ارائه می‌دهند و به‌جای سیستم‌عامل‌های اختصاصی، از ایزوله‌سازی مبتنی بر kernel مشترک استفاده می‌کنند. درک نحوه راه‌اندازی کانتینرها، ماندگاری تغییرات، امکان دیباگ آن‌ها و بازیابی از خرابی از طریق سیاست‌های ریستارت، برای کار قابل‌اعتماد با آن‌ها در محیط‌های واقعی ضروری است.

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

مقالات مرتبط

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

مدل امنیتی داکر بر پایه دفاع چندلایه ساخته شده و فناوری‌های شناخته‌شده 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 چندنودی، استقرار یک اپلیکیشن میکروسرویس به‌صورت اعلانی و انجام به‌روزرسانی‌های تدریجی بدون از دست دادن سازگاری با وضعیت مطلوب را بررسی می‌کند.

ادامه