یکی از قسمتهای مهم داکر Networking هست، قسمتی که تعیین میکنه که Container ها چطوری باهم و با دنیای بیرون ارتباط برقرار میکنن. فهمیدن Docker Networking (نمی دونم چه معادل فارسی براش می تونم به کار ببرم!) برای Deploy کردن امن و scalable خیلی مهمه، برای همین تصمیم گرفتم توی این نوشته تا حدی که سرنخ های خوبی بهتون بده برای درک بهتر و عمیق شدن صحبت میکنیم.
خیلی ساده بخواییم بگیم، Docker Networking متدی رو تعریف میکنه که با استفاده از اون کانتینرها میتونن باهم دیگه و همینطور با دنیای بیرون ارتباط برقرار کنند.
وقتی داکر رو نصب میکنیم، به طور اتوماتیک یه شبکه مجازی default روی سخت افزار شبکه ماشینی که داکر روش نصب شده ایجاد میکنه و یه سطحی از ایزولیشن برای ارتباط اپلیکیشنهایی که containerized شدن ایجاد میکنه. یعنی به صورت پیشفرض همه کانتینرهایی که ایجاد میکنیم توی شبکه default رجیستر میشن و میتونن با هم ارتباط برقرار کنن.
نمودار بالا نشون میده که چطور کانتینرهایی که ساخته شدن به شبکه default به اسم bridge وصل شدن تا بتونن با هم ارتباط برقرار کنن. خب بیاییم یکم دست به آچار شیم ببینیم این اتفاق چطوری میافته و چطوری کار می کنه:
۱. برای شروع بیاییم ببینیم این شبکه دیفالت رو داکر ایجاد کرده یا نه؟
docker network ls
دستور بالا لیست شبکه های مجازی که داکر ایجاد کرده رو بهمون نشون میده، که شبکه با اسم bridge همون شبکهی پیشفرضی هست که اگه موقع ساختن کانتینر شبکهش رو مشخص نکنیم، روی کانتینر ست میشه.
۲. یه container جدید run کنیم
برای اینکه ببنیم کانتینر جدید به شبکه پیشفرض وصل میشه یا نه، یه کانتینر جدید ایجاد میکنیم ولی شبکهای بهش اختصاص نمیدیم:
docker run -dit --name container1 alpine ash
۳. بررسی کانتینر ایجاد شده
حالا بیاییم Container ایجاد شده رو بررسی کنیم تا ببینیم به چه شبکهای وصل شده، برای این کار از دستور زیر استفاده می کنیم:
docker inspect container1
برای دیدن اطلاعات شبکه دنبال پروپرتی Networks بگردین، باید یه چیزی مثل عکس زیر رو ببنید:
این تصویر نشون میده که Container جدید به شبکه پیشفرض که اسمش bridge هست کانکت شده و IP و اطلاعات دیگه رو هم می تونین ببینین. حالا هر کانتینر دیگهای که توی این شبکه باشه میتونن با هم ارتبط برقرار کنن. بیاییم اینم تست کنیم.
۴. ارتباط کانتینرها در یک شبکه
برای تست این ارتباط یه کانتینر جدید با اسم container2 میسازیم و سعی میکنیم ببنیم به میتونیم container1 که تو همین شبکه هست رو ببینیم؟
docker run -dit --name container2 alpine ash
خب این کانتینر جدید هم چون باید به شبکه پیشفرض (bridge) وصل شده باشه چون موقع ایجاد شبکهای بهش اختصاص ندادیم. پس باید بتونیم به container1 پینگ داشته باشیم، بیاییم اینم با دستور زیر تستش کنیم:
docker exec -it container2 ash
حالا ببینیم به اون container پینگ داریم؟ اگه یادتون باشه توی تصور مشخصات container1 مقدار آی پی 172.17.0.2 بود
ping 172.17.0.2
توی عکس زیر میتونیم ببینیم که به container1 پینگ داریم
خب تا اینجا دیدیم که همه کانتینرهایی که به صورت پیشفرض ایجاد میشن، به شبکه دیفالت که اسمش bridge بود اضافه میشن. ولی خب بهتره که کانتینرهایی که ایجاد میکنیم رو به شبکه دیفالت اضافه کنیم و از شبکهی کاستوم که خومون ایجاد می کنیم استفاده کنیم، چرا؟ اولا اینکه از لحاظ امنیتی کار درستی نیس چون همه کانتینرهای توی شبکهی دیفالت می تونن هم دیگه رو ببینن که میتونه مشکل امنیتی ایجاد کنه و دوم اینکه اگه یه وقت نیاز شد که بخواییم شبکه رو کاستوم کنیم و یا محدودیت هایی به شبکه ایجاد کنیم، این کار با استفاده از شبکه پیشفرض امکان پذیر نیست.
پس بهتره هر وقت که یه سیستمی رو داریم طراحی میکنیم همهی کانتینرهایی که نیاز دارن باهم در ارتباط باشن رو به یه شبکه کاستوم اضافه کنیم و در صورت نیاز محدودیت هایی بهش اضافه کنیم. خب حالا بریم سراغ اینکه چطوری یه شبکه کاستوم ایجاد کنیم و ازش استفاده کنیم.
ایجاد شبکه custom:
docker network create my_network
وقتی دستور بالا رو اجرا کنیم، مشخصا یه شبکه کاستوم ایجاد میشه (که از نوع bridge هست، جلوتر راجع بهش میگم). پس خروجی دستور زیر باید شبکه جدید رو نشون بده:
docker network ls
ایجاد کانتینر در شبکه کاستوم:
خب حالا بیاییم یه container جدید بسازیم و به این شبکه جدید وصلش کنیم، برای این کار از دستور زیر استفاده میکنیم:
docker run -dit --network=my_network --name container3 alpine ash
خب حالا باید container3 به شبکه my_network وصل شده باشه، با دستور زیر میتونیم بررسیش کنیم:
docker inspect container3
عکس بالا نشون میده که کانتینر جدید به شبکه my_network وصل شده و دیگه به شبکه دیفالت وصل نیست.
ویژگی کاربردی دیگهای که وقتی از custom network استفاده می کنیم و داکر در اختیارمون میزاره یه Embed DNS هست که با کمکش دیگه نیاز نیس برای دسترسی به کانتینرهای تو یه شبکه از IP شون استفاده کنیم و میتونیم صرفا از نام container بجای IP استفاده کنیم و اصلا استفاده از IP خودش مشکل جدیدی رو برایمون ایجاد میکنه، تو حالتهایی که زیر بهشون اشاره میکنم ممکنه IP تغییر کنه و اگه از اون IP توی کد یا config ها استفاده کرده باشین به مشکل می خورین:
نکته: البته جدا از تغییر IP استفاده کردن از اسم container تا حد خیلی زیادی خوانایی رو بالا میبره.
خب حالا بیاییم با یه مثال این DNS رو امتحان کنیم، تو مثال قبلی container3 رو روی شبکه my_network ران کردیم، برای تست این ویژگی میخوام container2 رو هم که قبلا رو شبکه default بود رو هم به این شبکه اضافه کنیم. برای این کار از دستور زیر استفاده میکنیم.
docker network disconnect bridge container2
۲. حالا وصلش میکنیم به شبکه my_network:
docker network connect my_network container2
۳. خب حالا اگه inspect بگیریم میبینیم که به شبکه جدید وصل شده:
docker inspect container2
۴. حالا وقت اینه که از اسم container به عنوان DNS name برای ارتباط استفاده کنیم:
از اونجایی که الان container2 و container3 هر دو تو یه شبکه هستن میتونن با هم ارتباط داشته باشن
docker exec -it container2 ash
ping container3
با استفاده از دستور بالا میتونیم ببنیم که تونستیم بجای استفاده از IP با اسم container با container3 ارتباط بگیریم.
داکر انواع مختلفی از شبکه رو در اختیار ما قرار میده که یکی از مهمترین قابلیتهای داکر محسوب میشه، هر کدوم از این نوعهای مختلف مشخص میکنن که یه کانتینر چه دسترسیهایی در شبکه داره و چطوری میتونه با کانتینرهای دیگه و یا دنیای بیرون ارتباط برقرار کنه، اینجا قراره با هرکدوم از شبکهها آشنا بشیم و راجع به این صحبت کنیم که هر کدوم از این شبکهها چه کاربردی دارند. انواع شبکههایی که داکر در اختیارمون میزاره به شرح زیر است:
این شبکه که پیشتر باهاش آشنا شدیم یکی از سادترین و در عینحال پرکاربردترین شبکه در داکر محسوب میشه که میتونیم با کمترین میزان تنظیمات و یا آشنایی با جزئیات شبکه، اینجاد و ازش استفاده کنیم. با استفاده از شبکه Bridge میتونیم یه شبکه مجازی خصوصی روی ماشین host (ماشینی که داکر روش نصبه) ایجاد کنیم که هر کانتینری که بهش وصل میشه به شکل اتوماتیک یه IP بهش اختصاص داده میشه و کانتینرهایی که تو این شبکه هستن میتونن با همدیگه ارتباط برقرار کنند. موارد استفادهش رو میشه اینطوری گفت:
اگه یادتون باشه گفتیم تو شبکه از نوع Bridge، داکر روی سخت افزار شبکه ماشین Host (ماشینی که داکر روش نصب شده) یه شبکهی مجازی ایجاد میکنه و کانتینرها از این شبکه مجازی استفاده میکننن، ولی تو شبکه از نوع هاست اینطوری نیس، برای شبکه Host داکر مسقیما از سخت افزار شبکه ماشین هاست استفاده میکنه، یعنی منابع نرمافزاری و سخت افزاری شبکه ماشین هاست با کانتینر ها به اشتراک گذاشته میشه.
حالا چه سودی داره این نوع از شبکه؟
از اونطرف مشکلاتی که ممکنه بوجود بیاد:
خببب شبکه Overlay، تا الان صحبت از این بود که کانتینرها دارن روی یک ماشین اجرا میشن و از منابع همون ماشین به صورت اشتراکی استفاده میکنن ولی اگه قرار باشه هر کدوم از این کانتینرها روی ماشین خودشون اجرا بشن چی؟ توی این حالت دیگه نمیشه از دو شبکه قبلی استفاده کرد، پس اگه قرار باشه کانتینرها که روی ماشین های مختلف اجرا میشن با هم ارتباط برقرار کنن باید از شبکه Overlay استفاده کنیم. این نوع از شبکه مخصوصا برای سیستمهای توضیع شده خیلی مهم هست.
موارد استفاده ش چیه؟
فک کنم تا همینجاش هم خیلی طولانی شد :) هدفم ایجاد کنجکاوی بود که برید و بیشتر راجع شبکه در داکر بخونین. یادتون باشه برای متخصص شدن جزییات مهم هستن، این جزییات هستن که شما رو از بقیه متمایز میکنه پس چیزی رو که ازش استفاده میکنین خوب راجع بهش یاد بگیرین تا بتونین به بهترین شکل ازش استفاده کنین و راه حلهای درست رو پیدا کنین. نه اینکه صرفا چیزی درست کنیم که فقط کار میکنه :))
در پایان مثل همیشه اینکه اگه نوشته رو دوست داشتید با دوستان به اشتراک بزارید که هم بهشون کمک کنه و هم انرژی بشه برای من که ادامه بدم :)
اگه پیشنهادی هم برای موضوع نوشته بعدی دارین بگین.
و اینکه میتونید منو با آیدی mehdi_zarepour تو توییتر پیدا کنید، نوشتههای جدید رو اونجا توییت میکنم. اگه اینجا اکانت ندارین اونجا بهم پیام بدین یا منشن بزارین.