همه چیز درباره داکر

?What is Docker

تصویر اصلی Docker

پیش گفتار

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

Docker چیست؟

در سال 2010، سولومون هایکس و سباستین پهل داکر را ایجاد کردند. این پلتفرم در سال 2011 راه اندازی شد. در اصل، هایکس پروژه Docker را در فرانسه به عنوان بخشی از یک پروژه داخلی در dotCloud، یک شرکت PaaS که در سال 2016 تعطیل شد، آغاز کرد. Docker در آن زمان چیز زیادی به زمان‌ اجرای کانتینرها اضافه نکرد. CLI و مفاهیم آسان آن، استفاده از کانتینرها را برای توسعه دهندگان معمولی و نه تنها برای شرکت های هک عمیق که بنا به دلایلی به کانتینر نیاز داشتند، تغییر روش داد. پس از سال 2013، چندین شرکت شروع به استفاده از Docker به عنوان run time پیش فرض کانتینر کردند. در سال 2013، Red Hat همکاری با Docker را اعلام کرد، در سال 2014 نوبت به Microsoft، AWS، Stratoscale و IBM رسید.در سال 2016، اولین نسخه Docker برای سیستم عاملی متفاوت از لینوکس معرفی شد.

Windocks پورتی از پروژه OSS Docker را منتشر کرد که برای اجرا در ویندوز طراحی شده بود. و در پایان همان سال، مایکروسافت اعلام کرد که Docker اکنون به صورت بومی در ویندوز از طریق Hyper-V پشتیبانی می شود. در سال 2019، مایکروسافت WSL2 را معرفی کرد که امکان اجرای Docker را بر روی ویندوز بدون نیاز به ماشین مجازی در Hyper-V فراهم کرد. داکر اکنون به صورت بومی چند پلتفرمی است و در عین حال از رویکرد کانتینر لینوکس استفاده می کند. سرانجام، در سال 2020، داکر به انتخاب جهانی برای کانتینرها تبدیل شد. این اتفاق لزوما به این دلیل نیست که بهتر از سایرین است، بلکه به این دلیل است که همه پیاده‌سازی‌ها را تحت یک پلتفرم ساده با یک CLI و یک Daemon یکپارچه می‌کند. و همه این ها را با استفاده از مفاهیم ساده ای که در بخش های بعدی بررسی خواهیم کرد، انجام می دهد. Docker یک بستر برای توسعه، ترابری (shipping) و اجرای برنامه‌ها است.

Docker به شما کمک می کند برنامه ها را را از زیر ساختشان جدا کنید تا به این ترتیب بتوانید نرم افزار را به سرعت ارائه دهید. با Docker، می توانید زیرساخت خود را با همان روش مدیریت برنامه هایتان، مدیریت کنید. با استفاده از توانمندی های Docker در هنگام فرستادن، آزمایش و استقرار سریع کد، می‌توانید تاخیر بین نوشتن کد و اجرای آن را به میزان قابل توجهی کاهش دهید. بسیاری از مردم فکر می کنند که داکر اولین در نوع خود بوده است، اما این درست نیست. کانتینرهای لینوکس از دهه 1970 وجود داشته اند. Docker برای توسعه برنامه ها مهم است زیرا استفاده از کانتینرها را به قدری آسان کرد که همه شروع استفاده از آن کردند.

بستر Docker

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

Docker ابزار و بستر لازم را برای مدیریت چرخه حیات کانتینرهای شما فراهم می کند:

  • برنامه و اجزای پشتیبانی شده آن را می توانید با استفاده از کانتینرها توسعه دهید.
  • کانتینر واحدی برای توزیع و آزمایش برنامه شما خواهد بود.
  • هنگامی آماده شدن برنامه، آن را به عنوان یک کانتینر یا یک سرویس هماهنگ در محیط تولید (production) خود مستقر کنید. چه محیط تولید شما یک پایگاه داده محلی (local)، یک ارائه دهنده ابری یا ترکیبی از این دو باشد، روش کار یکسان است.

از Docker برای چه چیزهایی می توانم استفاده کنم؟

ارائه سریع و پایدار برنامه ها

Docker توسعه برنامه ها را برای کار در محیط های استاندارد شده با استفاده از کانتینرهای محلی که برنامه ها و خدمات شما را ارائه می دهند، ساده می کند. کانتینرها برای یکپارچه سازی و گردش کار تحویل مداوم CI/CD) ) عالی هستند.

مثال های زیر را در نظر بگیرید:

  • توسعه دهندگان کد را به صورت محلی می نویسند و کار خود را با استفاده از کانتینرهای Docker با همکاران خود به اشتراک می گذارند.
  • آن ها از Docker برای قرار دادن برنامه های خود در یک محیط آزمایشی و اجرای آزمایش های خودکار و دستی استفاده می کنند.
  • هنگامی که توسعه دهندگان اشکال ها را پیدا می کنند، می توانند آن ها را در محیط development (توسعه) برطرف کرده و دوباره آن ها را در محیط آزمایش و اعتبار سنجی قرار دهند.
  • وقتی آزمایش کامل شد، رفع اشکال برای کلاینت به سادگی قرار دادن ایمیج به روز شده در محیط production (تولید) است.

استقرار و مقیاس بندی واکنش گرا

پلت فرم (بستر) مبتنی بر کانتینر Docker امکان استفاده از بارهای کاری بسیار قابل حمل را فراهم می کند. کانتینرهای Docker می‌توانند روی لپ‌تاپ یک توسعه‌دهنده، روی ماشین‌های فیزیکی یا مجازی در مراکز داده، در ابرها یا در ترکیبی از این محیط‌ها اجرا شوند. حمل‌پذیری و ماهیت سبک Docker هم چنین مدیریت پویا بارهای کاری را آسان می‌کند، برنامه‌ها و سرویس‌ها را طبق نیازهای کسب ‌و کار، در زمان واقعی کاهش می‌دهد یا از بین می‌برد.

اجرای بارهای کاری بیش تر روی همان سخت افزار

داکر سبک و سریع است. یک جایگزین مناسب و مقرون به صرفه برای ماشین‌های مجازی مبتنی بر Hypervisor (ابر کارگزار) ارائه می‌کند، بنابراین می‌توانید از ظرفیت محاسباتی بیش تری برای دستیابی به اهداف تجاری خود استفاده کنید. Docker برای محیط‌های با تراکم بالا و برای استقرارهای کوچک و متوسط که در آن باید کارهای بیش تری با منابع کمتر انجام دهید، عالی است.

تکنولوژی زیربنایی

Docker به زبان برنامه نویسی Go نوشته شده است و از ویژگی های هسته لینوکس برای ارائه عملکرد آن بهره می برد. داکر از فناوری ای به نام فضا نام (NameSpace) برای ارائه یک فضای کاری مجزا به نام کانتینر استفاده می کند. هنگامی که یک کانتینر را اجرا می کنید، داکر مجموعه ای از فضاهای نام را برای آن کانتینر ایجاد می کند.این فضاهای نام لایه ای از انزوا را فراهم می کنند. هر جنبه از یک کانتینر در یک فضای نام جداگانه اجرا می شود و دسترسی به آن فضای نام محدود می شود.

معماری داکر

داکر از معماری کلاینت-سرور استفاده می کند. کلاینت داکر با دیمون (daemon) داکر ارتباط برقرار می کند، که کارهای سنگین ساخت، اجرا و توزیع کانتینرهای داکر شما را انجام می دهد. کلاینت داکر و دیمون می توانند بر روی یک سیستم اجرا شوند، یا می توان یک کلاینت داکر را به یک دیمون داکر از راه دور متصل کرد. کلاینت داکر و دیمون با استفاده از یک REST API، از طریق سوکت های یونیکس (UNIX) یا یک رابط شبکه با هم ارتباط برقرار می کنند. یکی دیگر از سرویس گیرندگان Docker با نام Docker Compose شناخته می شود که به شما امکان می دهد با برنامه هایی که از مجموعه ای از کانتینرها تشکیل شده اند کار کنید.

 

معماری داکر
معماری داکر

میزکار Docker

میزکار داکر یا Docker Desktop یک برنامه کاربردی با قابلیت نصب آسان برای محیط مک یا ویندوز است که به شما امکان می‌دهد برنامه‌های کانتینری و میکروسرویس‌ها را بسازید و به اشتراک بگذارید. Docker Desktop شامل Daemon Docker ،Docker Client، Docker Compose، Docker Content Trust ،Kubernetes و Credential Helper است. برای اطلاعات بیشتر، Docker Desktop را ببینید.

رجیستری های (ثبات های) داکر

یک رجیستری داکر ایمیج های داکر را ذخیره می کند. داکر هاب  (Docker Hub) یک رجیستری عمومی است که همه می توانند از آن استفاده کنند. داکر به طور پیش فرض برای جستجوی ایمیج در داکر هاب پیکربندی شده است. شما حتی می توانید رجیستری ویژه خود را اجرا کنید.هنگامی که از دستورات docker pull یا  docker run استفاده می کنید، ایمیج های مورد نیاز از رجیستری پیکربندی شده شما خارج می شوند. هنگامی که از دستور docker push استفاده می کنید، ایمیج تان به رجیستری پیکربندی شده شما فرستاده می شود.

اشیا داکر

هنگامی که از Docker استفاده می کنید، در حال ایجاد و استفاده از ایمیج، کانتینرها، شبکه ها، حجم ها، پلاگین (افزونه) ها و سایر اشیا هستید. در این بخش مروری کوتاه بر برخی از این اشیا خواهیم داشت.

تاریخچه کانتینرها

داکر
داکر

تاریخچه کانتینرها در سال 1979 با یونیکس نسخه  7 (Unix v7) آغاز می شود.در سال 1979، نسخه 7 یونیکس یک فراخوانی سیستمی به نام chroot را معرفی کرد که امروزه به عنوان مجازی سازی فرآیند می شناسیم. فراخوانی chroot به کرنل اجازه داد تا دایرکتوری ریشه (root)، پدر یک فرآیند و فرزندان آن را تغییر دهد. به طور خلاصه، فرآیند  به تنهایی در دستگاه اجرا می‌شود، زیرا سیستم فایل آن از همه فرآیندهای دیگر جدا است. در سال 2000، یک ارائه دهنده هاست به دنبال راه های بهتری برای مدیریت وب سایت های مشتریان خود بود، زیرا همه آن ها در یک دستگاه نصب شده بودند و برای منابع یکسان رقابت می کردند. برای رفع این مشکل، راه حل jails معرفی شد و یکی از اولین تلاش های واقعی برای جداسازی در سطح فرآیند بود. jails به هر کاربر FreeBSD اجازه می‌داد تا سیستم را به چندین سیستم مستقل و کوچک تر (که jails نامیده می‌شوند) تقسیم کنند. هر jails می تواند پیکربندی IP و پیکربندی سیستم خود را داشته باشد. (jails در انگلیسی به معنی زندان است). jails اولین راه حل برای گسترش استفاده از chroot بود تا نه تنها جداسازی در سطح فایل سیستم، بلکه مجازی سازی کاربران، شبکه، زیرسیستم ها و غیره را نیز مجاز کند. در سال 2008 LXC (LinuX Containers) راه اندازی شد. در آن زمان این اولین و کاملترین پیاده سازی سیستم مدیریت کانتینر بود. از گروه های کنترل، فضاهای نام و بسیاری از آنچه تا آن زمان ساخته شده بود استفاده می کرد. بزرگترین پیشرفت این بود که مستقیما از هسته یونیکس استفاده می شد و به هیچ پیش نیاز دیگری نیاز نداشت.

کانتینر چیست؟

کانتینر یک نمونه قابل اجرا از یک ایمیج است. می‌توانید با استفاده از Docker API یا CLI یک کانتینر را ایجاد، راه اندازی، متوقف، جا به جا یا حذف کنید. می‌توانید یک کانتینر را به یک یا چند شبکه متصل کنید، یا یک فضای ذخیره‌سازی را به آن متصل کنید یا حتی یک ایمیج جدید را بر اساس وضعیت فعلی آن به وجود آورید. به طور پیش فرض، یک کانتینر کاملا از سایر کانتینرها و ماشین میزبان خود جدا شده است. می‌توانید میزان جدا بودن شبکه یک کانتینر از کانتینرهای دیگر یا از ماشین میزبان، را کنترل کنید.یک کانتینر با ایمیج آن و هم چنین هر گزینه پیکربندی که هنگام ایجاد برای آن درنظر گرفته می شود، تعریف می شود.

مثال از دستور docker run: دستور زیر یک کانتینر اوبونتو را اجرا می کند. به صورت همکنشی به سشن خط فرمان محلی شما متصل می شود و /bin/bash را اجرا می کند.

$ docker run -i -t ubuntu /bin/bash

هنگامی که این دستور را اجرا می کنید، رویدادهای زیر اتفاق می افتد (با فرض این که از پیکربندی پیش فرض رجیستری استفاده می کنید):

1. اگر ایمیج اوبونتو را به صورت محلی ندارید، داکر آن را از رجیستری پیکربندی شده شما دانلود می کند. این دستور مانند دستور docker pull Ubuntu کار می کند.

2. این دستور یک کانتینر جدید ایجاد می کند.

3. Docker یک سیستم فایل (filesystem) خواندنی-نوشتنی را به کانتینر به عنوان لایه نهایی آن اختصاص می دهد. این کار به یک کانتینر در حال اجرا اجازه می دهد تا فایل ها و دایرکتوری ها را در سیستم فایل محلی خود ایجاد یا تغییر دهد.

4. Docker یک رابط شبکه برای اتصال کانتینر به شبکه پیش فرض را ایجاد می کند، زیرا از پیش هیچ گزینه شبکه ای را مشخص نکرده اید. این کار شامل اختصاص یک آدرس IP به کانتینر است. به طور پیش فرض، کانتینرها می توانند با استفاده از اتصال شبکه دستگاه میزبان به شبکه های خارجی متصل شوند.

5. داکر کانتینر را راه اندازی می کند و سپس دستور //bin/bash را اجرا می کند. از آن جایی که کانتینر به صورت هم کنشی کار می کند و به ترمینال شما متصل است (به دلیل وجود فلگ های -i  و -t )، می توانید ورودی را با استفاده از صفحه کلید خود در حالی که خروجی در ترمینال نوشته شده است، وارد کنید.

6. وقتی exit را برای پایان دادن به دستور  //bin/bash می نویسید، کانتینر متوقف می شود اما حذف نمی شود. می توانید آن را دوباره راه اندازی یا حذف کنید.

ماشین های مجازی و کانتینرها

برخلاف ماشین‌های مجازی، یک کانتینر می‌تواند هسته سیستم عامل را به اشتراک بگذارد در حالی که فقط کتابخانه‌های مختلف را با آن بارگذاری می‌کند. به عبارت دیگر، شما نیازی به نصب سیستم عامل های مختلف (به نام سیستم عامل مهمان) در داخل سیستم عامل (host) میزبان خود ندارید. شما می توانید چندین کانتینر را در یک سیستم عامل واحد اجرا کنید بدون این که چندین سیستم عامل مهمان در سیستم خود داشته باشید.

ماشین های مجازی و کانتینرها
ماشین های مجازی و کانتینرها

این باعث می شود کانتینرها کم حجم تر، سریعتر و کارآمدتر شوند. در حالی که راه اندازی یک ماشین‌ مجازی می تواند حدود یک دقیقه طول بکشد و می تواند چندین گیگابایت حافظه نیاز داشته باشد، یک کانتینر به طور متوسط بین 400 تا 600 وزن دارد. هم چنین راه اندازی آن ها فقط چند ثانیه طول می کشد. این بیشتر به این دلیل است که آن ها مجبور نیستند یک سیستم عامل کامل را قبل از اجرای فرآیند راه اندازی بکنند.

Docker چگونه کار می کند؟

Docker یک برنامه و تمام وابستگی های آن را در یک کانتینر مجازی بسته بندی می کند که می تواند بر روی هر سرور لینوکس اجرا شود. به همین دلیل است که ما آن ها را کانتینر می نامیم. زیرا آن ها همه وابستگی های لازم را در یک نرم افزار واحد دارند.

Docker از عناصر زیر تشکیل شده است:

  • یک Daemon که برای ساخت، اجرا و مدیریت کانتینرها استفاده می شود.
  • یک API سطح بالا که به کاربر اجازه می دهد با دیمون ارتباط برقرار کند.
  • و یک CLI، رابطی که ما برای در دسترس قرار دادن این اجزا استفاده می کنیم.

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

کانتینرها انتزاعی از لایه برنامه هستند. آن ها همه کدها، کتابخانه ها و وابستگی ها را با هم بسته بندی می کنند. این کار باعث می شود چندین کانتینر در یک میزبان اجرا شوند، بنابراین می توانید از منابع آن میزبان به خوبی استفاده کنید. هر کانتینر به‌عنوان یک فرآیند مجزا در فضای کاربر اجرا می‌شود و به دلیل معماری لایه‌ای خود، فضای کمتری نسبت به ماشین‌های مجازی معمولی اشغال می‌کند.این لایه ها ایمیج های میانی نامیده می شوند. به عنوان مثال، اگر Dockerfile مانند زیر باشند ایمیج زیر ایجاد می شود:

FROM node:stable

COPY . /usr/src/app

WORKDIR /usr/src/app

RUN npm install grpc

RUN npm install

ENTRYPOINT ["npm", "start"]

در هر دستوری مانند COPY یا RUN لایه دیگری در بالای ایمیج کانتینر خود ایجاد می کنید. این به Docker اجازه می دهد تا هر دستور را به یک بخش جداگانه تقسیم و جدا کند. بنابراین اگر در نهایت دوباره از این ایمیج node:stable استفاده کنید، نیازی به کشیدن تمام لایه های آن نخواهد بود، زیرا شما از پیش این ایمیج را نصب کرده اید. هم چنین، همه لایه‌ها هش می‌شوند، به این معنی که داکر می‌تواند آن لایه‌ها را کش کند و زمان ساخت را برای لایه‌هایی که در بین ساخت‌ها تغییر نکرده‌اند بهینه‌سازی کند.اگر مرحله COPY تغییر نکرده باشد، نیازی به بازسازی و کپی مجدد همه فایل ها نخواهید داشت که این امر زمان صرف شده در فرآیندهای ساخت را بسیار کاهش می دهد.

در پایان فرآیند ساخت، داکر یک لایه خالی جدید در بالای همه لایه ها ایجاد می کند که لایه نازک (thin writable layer) قابل نوشتن نامیده می شود. این لایه ای است که هنگام استفاده از docker exec -it <container> <command> به آن دسترسی دارید. به این ترتیب می‌توانید تغییرات تعاملی را در ایمیج انجام دهید و آن‌ها را با commit docker، مانند کاری که با فایل ردیابی Git انجام می‌دهید، commit کنید. این معماری لایه دارای هش به دلیل سیستم فایل AuFS امکان پذیر است. این یک FS لایه‌ای است که به فایل‌ها و دایرکتوری‌ها اجازه می‌دهد تا به‌صورت لایه‌های روی هم چیده شوند. AuFS هنگام برخورد با DnD (Docker in Docker) مشکلاتی ایجاد می کند، اما این موضوع برای مقاله های دیگر است! در این مقاله می توانید ژرف تر دراین مورد بیاموزید.

فایل سیستم لایه بندی شده
فایل سیستم لایه بندی شده

لایه ها را می توان بین نسخه ها هش کرد. به این ترتیب Docker می تواند بررسی کند که آیا یک لایه در هنگام ساخت یک ایمیج تغییر کرده است یا خیر و تصمیم می گیرد که آیا آن را بازسازی کند یا نه، و با این کار در زمان صرفه جویی می کند. بنابراین، اگر قبلا ایمیج اوبونتو را بر روی رایانه خود دانلود کرده اید، و در حال ساختن یک ایمیج جدید هستید که بر یک یا چند لایه از آن ایمیج متکی است، Docker آن ها را دوباره نمی سازد و دوباره از همان لایه ها استفاده می کند.

مرجع ایمیج
مرجع ایمیج

اگر می‌خواهید لایه‌ها را عمیق‌تر کنید، این مقاله جزئیات زیادی در مورد فهرست‌بندی و مدیریت آن‌ها ارائه می‌دهد.

چرا کانتینرهای داکر عالی هستند؟

احتمالا جمله "در دستگاه من کار می کند" را شنیده اید. این دقیقا همان مشکلی است که داکر و کانتینرها به طور کلی حل می کنند. کانتینرهای داکر مجموعه ای بسته بندی شده از تمام کتابخانه ها و وابستگی های برنامه است که از قبل ساخته شده و آماده اجرا هستند. بسیاری از شرکت‌ها از ماشین‌های مجازی به کانتینرها مهاجرت کرده‌اند، نه تنها به این دلیل که سبک‌تر و سریع‌تر قابل اجرا هستند، بلکه به این دلیل که نگهداری از آن ها نیز بسیار آسان است. یک کانتینر را می‌توان با استفاده از Dockerfile آن نسخه‌سازی کرد (در بخش بعدی به ایمیج ها می‌رسیم)، بنابراین اجرا و نگهداری کانتینر را برای یک توسعه‌دهنده (یا حتی تیم کوچکی از توسعه‌دهندگان) بسیار آسان می‌کند. از سوی دیگر، برای این که بتوانید ماشین های مجازی را راه اندازی و نگهداری کنید، فقط به یک زیرساخت نیاز دارید.

VPC
VPC

آیا دیگر به VM ها یا ماشین های مجازی نیازی نداریم؟ نه، برعکس، اگر می‌خواهید یک سیستم عامل کامل برای هر مشتری داشته باشید یا فقط به کل محیط به عنوان یک محیط آزمایشی نیاز دارید، ماشین‌های مجازی هنوز هم بسیار مورد نیاز هستند. هنگامی که شما یک سرور بزرگ و چندین کلاینت دارید که از آن استفاده می کنند، ماشین های مجازی معمولا از آن به عنوان لایه های میانی استفاده می کنند.سهولت استفاده و قابلیت نگهداری ما را به جنبه مهم دیگری از این که چرا کانتینرها بسیار عالی هستند هدایت می کند. استفاده از کانتینرها برای یک شرکت بسیار ارزان تر از ماشین های مجازی تمام عیار است.نه به این علت که زیرساخت یا سخت‌افزار ارزان‌تر است، بلکه به این دلیل است که به افراد کمتری برای نگهداری از کانتینرها نیاز دارید، و می‌توانید تیم خود را بهتر سازماندهی کنید. یک ماشین مجازی با اندازه متوسط می تواند حدود 3 تا 8 کانتینر را اجرا کند. به این بستگی دارد که کانتینرهای شما از چه تعداد منابع استفاده می کنند و به چه مقدار از سیستم عامل میزبان نیاز دارد تا راه اندازی شود.

برخی از زبان‌ها، مانند Go، به شما اجازه می‌دهند که تنها با باینری کامپایل شده و هیچ چیز دیگری یک ایمیج بسازید. به این معنی که کانتینر Docker بارگیری کمتری خواهد داشت و بنابراین از منابع کمتری استفاده می کند. به این ترتیب می توانید کانتینرهای بیشتری را در هر VM راه اندازی و از سخت افزار خود به طور موثرتری استفاده کنید. کانتینرها زودگذر ساخته شده‌اند، به این معنی که تمام داده‌های داخل آن‌ها هنگام حذف کانتینر از بین می‌رود. این عالی است، زیرا می‌توانیم از کانتینرها برای کارهایی مانند CI استفاده کنیم. استفاده از کانتینرها سطح جدیدی از پیشرفت های DevOps را به ارمغان آورده است. اکنون می‌توانید به سادگی تعداد زیادی کانتینر را راه اندازی کنید، که هر کدام یک مرحله کوچک از استقرار برنامه شما را انجام می‌دهند.

Docker Images چیست؟

ایمیج ها (Images)

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

وقتی Dockerfile را تغییر می‌دهید و ایمیج را بازسازی می‌کنید، تنها لایه‌هایی که تغییر کرده‌اند بازسازی می‌شوند. این تنها بخشی از کاری است که ایمیج را در مقایسه با سایر فناوری های مجازی سازی، بسیار سبک، کوچک و سریع می کند. ایمیج های Docker دستورالعمل هایی هستند که در یک فایل خاص به نام Dockerfile نوشته می شوند. این فایل سینتکس مخصوص خود را دارد و مشخص می کند که Docker چه مراحلی را برای ساخت کانتینر شما انجام خواهد داد. از آن جایی که کانتینرها فقط روی لایه تغییرات هستند، هر دستور جدیدی که در یک ایمیج داکر ایجاد می کنید، یک لایه جدید در کانتینر ایجاد می کند. آخرین لایه را لایه نازک قابل نوشتن می نامیم. یک لایه خالی که کاربر می تواند آن را تغییر داده و با استفاده از دستور docker commit آن را commit کند. مثال زیر یک نمونه از یک ایمیج ساده برای یک برنامه Node.js است:

FROM node:stable
COPY . /usr/src/app/
RUN npm install && npm run build
EXPOSE 3000
ENTRYPOINT ["npm", "start"]

در این مثال ساده، در حال ایجاد یک ایمیج جدید هستیم.این ایمیج ها از یک Container Registry، یک مخزن برای ذخیره ایمیج های کانتینرها دانلود می شوند. رایج ترین آن ها Docker Hub است، اما می توانید با استفاده از راه حل های ابری مانند Azure Container Registry نیز یک مخزن خصوصی ایجاد کنید.وقتی Docker build را اجرا می کنید در همان دایرکتوری Dockerfile، Daemon Docker شروع به ساخت ایمیج و بسته بندی آن می کند تا بتوانید از آن استفاده کنید. سپس می توانید docker run <image-name> را برای راه اندازی یک کانتینر جدید اجرا کنید. توجه داشته باشید که پورت های خاصی را در Dockerfile قرار می دهیم. Docker به ما اجازه می دهد تا شبکه ها را در سیستم عامل خود جدا کنیم، به این معنی که می توانید پورت ها را از رایانه خود به کانتینر و بالعکس نگاشت کنید. هم چنین، می توانید دستورها را در داخل کانتینرها با docker exec اجرا کنید.

نحوه استقرار (deploy) برنامه داکر شده

این یک راهنمای ساده و آسان در مورد نحوه ایجاد یک ایمیج Docker اولیه با استفاده از سرور Node.js و اجرای آن بر روی رایانه شما خواهد بود. ابتدا یک پروژه جدید را در دایرکتوری انتخابی خود ایجاد کنید و npm init -y را اجرا کنید تا یک فایل package.json جدید ایجاد کنید. سپس دایرکتوری دیگری به نام src ایجاد کنیم. در این دایرکتوری ما یک فایل جدید به نام server.js ایجاد می کنیم. (باید node js را در سیستم خود نصب کرده باشید). اکنون در فایل package.json خود، کلید main را به src/server.js تغییر دهید. هم چنین، اسکریپت آزمایشی ایجاد شده را حذف کرده و آن را با "start": "node src/server.js"  جایگزین کنید. فایل package.json شما باید به این صورت باشد:

{

  "name": "your-project",

  "version": "1.0.0",

  "description": "",

  "main": "src/server.js",

  "scripts": {

    "start": "node src/server.js"

  },

  "keywords": [],

  "author": "",

  "license": "ISC"

}

اکنون یک فایل دیگر به نام Dockerfile بدون پسوند ایجاد کنید و دستورهای زیر را در آن بنویسید:

FROM node:lts-alpine

COPY . /usr/src/app/

WORKDIR /usr/src/app

EXPOSE 8089

ENTRYPOINT ["npm", "start"]

توضیح دستورهای بالا:

  1. ابتدا ایمیج node را از داکر هاب دانلود می کنیم. از آن جایی که ایمیج ها با نام خود ذخیره می شوند، ایمیج ها را با برچسب شان (tag ها) متمایز می کنیم. در این جا می توانید همه tag ها را بررسی کنید.
  2. در مرحله بعد، از COPY برای کپی کردن همه فایل‌های موجود در dir فعلی (با استفاده از .) در یک dir جدید در کانتینر به نام /usr/src/app استفاده می‌کنیم. دایرکتوری به طور خودکار ایجاد می شود. این کار ضروری است زیرا ما به تمام فایل های برنامه خود در آن جا نیاز داریم.
  3. اکنون دایرکتوری شروع خود را به دایرکتوری /usr/src/app تغییر می دهیم. با این کار می توانیم از دایرکتوری ریشه، برنامه خود اجرا کنیم.
  4. port خود راexpose می کنیم.
  5. به محض این که کانتینر اجرا شود، "npm start" را اجرا می کنیم.
  6. با اجرای docker build . -t simple-node-image ایمیج خود را می سازیم. به این ترتیب ایمیج خود را تگ می کنیم و نامی برای آن می گذاریم.

این دستور ایمیج را همراه با تمام لایه های لازم ایجاد و دانلود می کند. این ایمیج را با دستور زیر اجرا کنیم:

docker run -p 80:8089 simple-node-image

در دستور بالا در حال نگاشت پورت 80 خود به پورت 8089 داخل کانتینر هستیم. می توانیم این کار را با تایپ کردن docker ps مانند زیر انجام بدهیم:اگر localhost:80 را باز کنیم تصویر زیر را خواهیم دید:

Docker برای چه مواردی استفاده می شود؟

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

پایگاه های داده زودگذر (Ephemeral)

آیا تا به حال برنامه ای ساخته اید که برای اجرا شدن به پایگاه داده نیاز داشته باشد؟ آیا سعی کردید برنامه شخص دیگری را اجرا کنید که به پایگاه داده ای نیاز دارد که شما آن را نصب نکرده اید؟ راه حل قدیمی این بود که ابتدا پایگاه داده را نصب کنید، سپس برنامه را اجرا کنید. ولی با داکر فقط باید کانتینر پایگاه داده را اجرا کنید. بیایید یک کانتینر ساده MongoDB را اجرا کنیم:

$ docker run -p 27017:27017 --name my-ephemeral-db mongo

با اجرای دستور بالا می توانید از طریق پورت 27017 رایانه خود به پایگاه داده دسترسی داشته باشید.

پایگاه های داده پایدار

مشکل مثال قبلی این است که اگر کانتینر را حذف کنید، تمام اطلاعات شما از بین می رود. بنابراین، اگر بخواهید یک پایگاه داده محلی را بدون نیاز به نصب آن اجرا کنید، اما داده ها را پس از حذف نگه دارید، چه اتفاقی می افتد؟ شما می توانید Docker را به یک حافظه متصل کنید! هنگامی که Docker را به یک حافظه محلی متصل می کنید، اساسا سیستم فایل خود را در کانتینر نصب می کنید و برعکس. به دستور زیر نگاه کنید:

$ docker run -p 27017:27017 -v /home/my/path/to/db:/data/db --name my-persistent-db mongo

در این دستور /data/db  را در /home/my/path/to/db نصب می کنیم. حال اگر از docker stop my-persistent-db  و docker rm my-persistent-db استفاده کنیم، تمام داده های ما هم چنان در آن جا ذخیره می شوند. بعدا اگر دوباره به پایگاه داده نیاز داشتیم، می‌توانیم آن را با همان دستور Mount کنیم و همه داده‌ها برمی‌گردند.

$ docker run --rm -it --network container:redis redis-cli -h 127.0.0.1

بسیاری از ابزارها از قبل دارای کانتینر Docker هستند، و شما می توانید از آن ها به این صورت استفاده کنید، بنابراین نیازی به نصب ابزار دیگری در نوت بوک خود ندارید. بهترین مثال Redis است. دارای redis-cli در یک کانتینر دیگر است، بنابراین اگر به سختی از آن استفاده می کنید، نیازی به نصب redis-cli در shell خود ندارید.

نتیجه گیری

امیدوارم این مقاله شما را با Docker آشنا کرده باشد. همان طور که می بینید، بیش تر کاربردهای Docker برای آسان کردن کار توسعه دهندگان در هنگام توسعه برنامه ها است. اما کاربردهای بسیار دیگری نیز وجود دارد، مانند لایه‌های زیرساختی و نگهداری برنامه‌ها.برای یادگیری بیش تر به وب سایت داکر سر بزنید.

نویسنده شوید
دیدگاه‌های شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.