توجه: این مقاله به مرور زمان، ویرایش و یا تکمیل میشود!
تقاضا: در صورتی که با مشکل تایپی، دستوری و یا مفهومی در این مقاله برخورد کردید، از شما دوست عزیز و گرامی، صمیمانه تقاضا میکنم که اینجانب را مطلع کرده، تا نسبت به تصحیح و یا تکمیل آن، در اسرع وقت، اقدام نمایم.
با کمال تشکر
داریوش تصدیقی
کانال تلگرام: IranianExperts@
شماره تلفن همراه: ۰۹۱۲۱۰۸۷۴۶۱
نشانی پست الکترونیکی: DariushT@GMail.com
فیلمهای آموزشی https://www.aparat.com/DariushT
آدرس سایتها: https://WebsiteAnalytics.ir - http://IranianExperts.ir - http://Date2Date.ir
نسخه مقاله: ۱.۰ - تاریخ بروزرسانی: ۱۳۹۹/۰۳/۱۹
قبل از مطالعه این قسمت، از شما خواننده عزیز تقاضا میشود که مقاله قبلی را حتما مطالعه نمایید:
توجه: در این آموزش، به دلیل استفاده مکرر از عبارت $(docker ps - aq)، به جای استفاده از محیط Windows Command Prompt از محیط Windows PowerShell استفاده میکنیم!
یادآوری: به سیستمی که Docker را بر روی آن نصب کردهایم، اصطلاحا Docker Host و یا به اختصار Host گفته میشود!
از آنجایی که در حال یادگیری دستورات جدید در Docker هستیم و میخواهیم محیط Docker خود برای تمرکز بیشتر به موضوع جدید، خلوت نماییم، قبل از هر قسمت از آموزشهای این مقاله، ابتدا از دستور ذیل استفاده کرده، تا تمام Container ها حذف شوند (اعم از آنکه Start بوده و یا Stop باشند):
docker rm -f $(docker ps -aq)
برای اطمینان از اینکه با استفاده از دستور فوق، همه Container ها حذف شدهاند، از دستور ذیل استفاده میکنیم:
docker ps -a
به طور کلی، در Docker، پنج نوع Network Driver وجود دارد:
که به ازای سه گزینه اول، یک Network به نامهای (به ترتیب) none و host و bridge در هنگام نصب Docker، به صورت پیشفرض، ساخته شده و وجود دارد!
برای مشاهده فهرست Network ها از دستور ذیل استفاده میکنیم:
docker network ls
برای حذف یک Network، میتوانیم از دستور ذیل استفاده نماییم:
docker network rm [NETWORK_ID_OR_NAME]
نکته: باید دقت داشته باشیم که استثنائا، امکان حذف این سه Network خاص وجود ندارد و صرفا میتوانیم Network هایی را که خودمان ایجاد کردهایم، حذف نماییم.
نکته: در مقاله قبل نیز اشاره کردیم که هرگاه میخواهیم OBJECT_ID_OR_NAME را بنویسیم، یا باید نام (Name) آنرا به طور کامل نوشته و یا دو یا چند حرف اول آیدی (ID) آنرا بنویسیم.
در صورتی که یک Container بر اساس Network Driver ای از نوع null و با نام none ایجاد نماییم، امکان دسترسی به آن Container از طریق دیگر Container ها وجود ندارد! چرا که نه تنها به آن Container، آیپی (IP) تخصیص داده نمیشود، بلکه Container مذکور از شبکه داخلی Host نیز استفاده نمیکند!
برای تست این موضوع، ابتدا یک Container از Imageای به نام alpine ایجاد میکنیم.
نکته: alpine یک لینوکس بسیار کم حجم، و در حدود ۶ (شش) مگابایت میباشد!
docker run -itd --network none --name my_alpine alpine:latest
نکته: به جای نوشتن پارامتری به صورت --network، میتوانیم به طور خلاصه از پارامتر –net استفاده نماییم.
با استفاده از دستور ذیل، چک میکنیم که آیا این Container به Network ای به نام none متصل شده است یا خیر؟
docker network inspect none
با اجرای دستور فوق، اطلاعاتی در خصوص Network ای به نام none نمایش داده شده و در قسمت Containers، خواهیم دید که Container مذکور، در داخل آن قرار داشته، ولی فاقد IP از هر نوع (IP4, IP6) میباشد! این بدان معنا است که به هیچ عنوان امکان برقراری ارتباط، با این Container، از طریق دیگر Container ها وجود ندارد!
قبل از هر اقدامی، تمام Container های ایجاد شده را با استفاده از دستور ذیل حذف میکنیم:
docker rm -f $(docker ps -aq)
این بار یک Container از Image ای به نام nginx، که یک Web Server میباشد، ایجاد میکنیم:
docker run -d --name myـwebserver --network host nginx:latest
همانگونه که مشخص شده است، این Container به Network ای از نوع host و با نام host متصل میشود.
برای اطمینان از این نوع اتصال، از دستور ذیل استفاده میکنیم تا اطمینان حاصل نماییم:
docker network inspect host
نکته مهمی که در خصوص Network ی از نوع host وجود دارد، آن است که بر خلاف Bridge، کانتینترهایی که به این نوع شبکه، متصل میشوند، دارای یک محیط شبکه ایزوله (Isolate) نبوده و مستقیما از شبکه Host استفاده میکنند. در خصوص Container اخیر، اگر از بیرون Host، به پورت ۸۰ آن، درخواستی ارسال نماییم، به طور خودکار، این درخواست، مستقیما به کانتینر my_webserver منتقل میشود.
اصولا همه Container ها، به صورت پیشفرض، به این شبکه متصل میشوند!
مجددا، قبل از هر اقدامی، تمام Container های ایجاد شده را با استفاده از دستور ذیل حذف میکنیم:
docker rm -f $(docker ps -aq)
حال دو Container ایجاد کرده و برای یکی از آنها، نام شبکه را مشخص نکرده و برای دومی، به صراحت نام شبکه bridge را مشخص میکنیم:
docker run -itd --name alpine1 alpine:latest docker run -itd --network bridge --name alpine2 alpine:latest
برای اطمینان از اینکه آیا هر دو Container از این شبکه bridge استفاده میکنند، از دستور ذیل استفاده میکنیم:
docker network inspect bridge
اگر در متن (JSON) ظاهر شده، به قسمت Containers توجه نماییم، خواهیم دید که هر دو Container اولا از این شبکه استفاده کرده و ثانیا به هر یک از این Container ها، یک IP اختصاص یافته است.
در این حالت، فرض میکنیم که Docker، به کانتینر alpine1، آیپی 172.17.0.2، و به کانتینر alpine2، آیپی 172.17.0.3 را اختصاص داده است.
نکته: در این روش، نمیتوانیم برای دسترسی به یک Container، از درون یک Container دیگر، از نام (Name) آن استفاده نماییم! و صرفا میتوانیم از طریق IP، این اتصال را برقرار نماییم!
با استفاده از دستور ذیل، وارد کانتینر alpine1 میشویم:
docker attach alpine1
با استفاده از دستور ذیل، IP کانتینر alpine2 را ping میکنیم:
ping 172.17.0.3
همانگونه که شاهد هستیم، این ping، به خوبی عمل کرده و نشان میدهد که بین این دو Container، از طریق IP ارتباط برقرار میباشد.
ولی اگر از دستور ذیل استفاده نماییم:
ping alpine2
با خطای ذیل روبرو میشویم:
ping: bad address 'alpine2'
نکته: خطای فوق نشان میدهد اگر از شبکه پیشفرض bridge استفاده نماییم، امکان استفاده از نام Container ها، برای دسترسی وجود نداشته و در داخل Container های دیگر، صرفا میتوانیم از طریق IP با Container مذکور ارتباط برقرار نماییم. این مساله اصلا خوب نیست! چرا که به عنوان مثال، در خیلی از موارد، مانند Restart و یا Reboot شدن Host، ممکن است که به Container ها IP دیگری اختصاص داده شود! و سیستمها بعد از راهاندازی مجدد، دچار اختلالات زیادی در خصوص ارتباط با یکدیگر خواهند شد!
پس راه حل چیست؟
برای حل این مشکل، یک Custom Bridge ایجاد کرده و از این پس، Container های خود را به این شبکه متصل میکنیم.
مجددا تمام Container های ایجاد شده را با استفاده از دستور ذیل حذف میکنیم:
docker rm -f $(docker ps -aq)
برای ایجاد یک Custom Bridge به نام my_bridge، یکی از دستورات ذیل را تایپ میکنیم:
docker network create --driver=bridge my_bridge docker network create -d=bridge my_bridge docker network create my_bridge
برای اینکه از ایجاد شدن این Custom Bridge اطمینان حاصل نماییم، از دستور ذیل استفاده میکنیم:
docker network ls
حال مشابه آخرین مرحله، دو Container ایجاد کرده و هر دو را به شبکه myـbridge متصل میکنیم:
docker run -itd -net my_bridge --name alpine1 alpine:latest docker run -itd -net my_bridge --name alpine2 alpine:latest
برای اطمینان از اینکه هر دو Container، به این شبکه متصل شدهاند، از دستور ذیل استفاده میکنیم:
docker network inspect my_bridge
با استفاده از دستور ذیل، وارد کانتینر alpine1 میشویم:
docker attach alpine1
با استفاده از دستور ذیل، IP کانتینر alpine2 را ping میکنیم:
ping 172.17.0.3
همانگونه که شاهد هستیم، مانند حالت قبل، این ping، به خوبی عمل کرده و نشان میدهد که بین این دو Container، از طریق IP ارتباط برقرار میباشد.
حال از دستور ذیل استفاده میکنیم:
ping alpine2
بر خلاف حالت قبل، دیگر با خطا مواجه نشده! و شاهد ارتباط این دو Container از طریق name آنها خواهیم بود.
در واقع زمانی که یک Custom Bridge ایجاد میکنیم و Container ها را به آن متصل میکنیم، در داخل Custom Bridge، یک DNS بر اساس نام Container ها ایجاد میشود.
در پایان، مجددا تمام Container های ایجاد شده را با استفاده از دستور ذیل حذف کرده:
docker rm -f $(docker ps -aq)
و Custom Bridge را نیز با استفاده از دستور ذیل حذف میکنیم:
docker network rm my_bridge
پایان