داکر چیست؟
داکر یک Container واحد استانداردی از نرم افزار است که در کنار کد اپلیکیشن، تمام ملزومات اجرای آن را نیز به همراه دارد تا بتوان آن را به سادگی از یک محیط پردازشی به محیط پردازشی دیگر منتقل کرد.
این مفهوم اولین بار در سال ۲۰۰۰ معرفی شد ولی در سال ۲۰۱۳ و با ظهور پروژه Docker بهشکل جدی مورد توجه قرار گرفت.
Docker Container Image یک بسته سبک قابل اجرای نرم افزاری است که تمام آنچه برای اجرای یک برنامه لازم است را در خود دارد.
این بسته شامل مواردی مانند Code, Runtime, System Tools, System Libraries و تنظیمات میشود.
پیش از این، زمانی که توسعهدهنده تکه کدی را برای تستکننده ارسال میکرد، یکسان نبودن کتابخانههای دو طرف باعث به مشکل برخوردن فرایندمیشد. با استفاده از داکر و با ضمیمه کردن تمام ملزومات اجرای کد در Container، مشکلاتی مانند این از بین رفته است.
از نظر فنی، Container یک یا مجموعهای از پردازههای ایزوله شده است. از این نظر، Container از یک سیستم عامل مستقل مانند آنچه در ماشین مجازی وجود دارد، متفاوت است.
برای این ایزولهسازی از دو قابلیت Namespaces و Control Groups کرنل لینوکس استفاده می شود. با Container می توان از توزیعهای مختلف لینوکس بهشکل همزمان روی یک Host که کرنل لینوکس را در اختیار قرار میدهد، استفاده کرد.
پیکربندی و مدیریت Container بدون استفاده از داکر و بهوسیلهی Namespaceها و Control Groupها کار بسیار دشواری است، اما به کمک از داکر، بدون آنکه درگیر جزییات ریز فنی ماجرا شویم، میتوانیم از قابلیت Container به بهترین شکل استفاده کنیم.
اجزای داکر
داکر در آغاز بهشکل یکپارچه طراحی شده بود، اما اکنون به سه بخش اصلی Docker Engine ، Docker-containered و Docker-runc ، به همراه تعدادی بخشهای جانبی تقسیم شده است.
در این قسمت، به معرفی بخشهای مختلف داکر میپردازیم.
- Docker Engine یا dockerd: شامل daemon، API interface و CLI میشود که بهشکل خاص Daemon مسوول ساخت Docker Images است.
- Docker-containerd یا containerd: یک Daemon دیگر که مسوول دانلود کردن Docker Images و اجرای آنها به عنوان یک Container است.
- Docker-runc یا runc: همان Container Runtime که مسوول ایجاد Namespaces و Control groups مورد نیاز Container است.
در کنار اجزای اصلی داکر، برای ساختن، اجرا کردن و به اشتراک گذاشتن Container موارد زیر لازم است:
- Docker Daemon (همان dockerd): معماری کلاینت-سرور دارد و مسوول تمام موارد مرتبط با Containerها است.
- Docker Client: وظیفهی ارتباط با Docker Daemon را بر عهده دارد و بهوسیلهی آن میتوان دستورات را ارسال کرد.
- Docker Images: پایهای ترین بخش Docker است. برای اجرای Docker Container به یک Image نیاز داریم که شامل کتابخانهی سیستمعامل، ملزومات و ابزارهای اجرای هر برنامه است.
برای مثال اگر بخواهیم Nginx Web Server را بهعنوان Ubuntu Container اجرا کنیم، باید یک Docker Image با Nginx Binary و تمام کتابخانههای لازم سیستمعامل برای اجرای Nginx بسازیم.
برای ساختن Imageها نیز میتوان از Dockerfile استفاده کرد که یک فایل متنی شامل دستورات اجرایی در هر خط است.
Docker Imageها ساختاری لایهای دارند و هر دستور Dockerfile یک لایه به Image اضافه می کند.
بالاترین لایهی قابل نوشتن Image یک Container است. هر Image از یک Base Image ایجاد می شود و میتواند مجددن بهوسیلهی Dockerfile یک لایهی جدید به خود بگیرد و به یک Image دیگر تبدیل شود.
برای مثال، میتوان از یک Base Image دارای Ubuntu استفاده کرد و یک Image دیگر با Nginx Application در آن ایجاد کرد.
- Docker Containers: بهشکل کلی، Container از Image ساخته میشود و کاربر میتواند برنامهاش را در آن قرار دهد. Containerها میتوانند Start ،Stop ،Commit و Terminate شوند. دو یا چند Container را میتوان برای ایجاد معماری مخصوص به یکدیگر متصل کرد. برای مدیریت این کار باید از ابزارهای Container Orchestration مانند Kubernetes استفاده کرد.
- Docker Registry: یک مخزن از Docker Imageها است که میتوان بهشکل خصوصی یا عمومی با آن کار کرد. Docker Inc یک سرویس Docker Registry را پشتیبانی میکند که به Docker Hub معروف است و به کاربران اجازه آپلود و دانلود Image میدهد.
اگر یک مخزن عمومی باشد، سایر کاربران Docker Hub به Imageهای آن دسترسی خواهند داشت. با استفاده از Docker Registry به سادگی میتوان Docker Imageها را جابجا کرد.
با دستور Docker Build میتوان از روی Dockerfile یک Image ساخت. سپس آن را با استفاده از دستور docker run اجرا کرد. برای تعریف و اجرای برنامه های Multi-Container نیز از docker compose استفاده می شود. بهوسیلهی یک فایل YAML میتوان سرویسهای مورد نیاز برنامه را تعریف و پیکربندی کرد، به گونهای که هر کدام از یک Container مستقل ایجاد شده باشند.
تفاوت Container با ماشین مجازی
بهشکل کلی بوت شدن VM چند دقیقه طول میکشد، در حالیکه برای Docker چند ثانیه زمان لازم است. همچنین، از آنجا که اجرای VM نیاز به بارگذاری کامل سیستمعامل دارد، از نظر استفاده از حافظه بهینه نیست اما استفاده از Docker نیازی به مجازی سازی ندارد و از این نظر بهینهتر است.