شبکه در Docker و انواع آن

یکی از قسمت‌های مهم داکر Networking هست، قسمتی که تعیین میکنه که Container ها چطوری باهم و با دنیای بیرون ارتباط برقرار می‌کنن. فهمیدن Docker Networking (نمی دونم چه معادل فارسی براش می تونم به کار ببرم!) برای Deploy کردن امن و scalable خیلی مهمه، برای همین تصمیم گرفتم توی این نوشته تا حدی که سرنخ های خوبی بهتون بده برای درک بهتر و عمیق شدن صحبت می‌کنیم.داکر Networking چیست؟خیلی ساده بخواییم بگیم، 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 پینگ داریمایجاد و استفاده از شبکه Customخب تا اینجا دیدیم که همه کانتینرهایی که به صورت پیشفرض ایجاد میشن، به شبکه دیفالت که اسمش 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 وصل شده و دیگه به شبکه دیفالت وصل نیست.داکر DNSویژگی کاربردی دیگه‌ای که وقتی از custom network استفاده می کنیم و داکر در اختیارمون می‌زاره یه Embed DNS هست که با کمکش دیگه نیاز نیس برای دسترسی به کانتینرهای تو یه شبکه از IP شون استفاده کنیم و میتونیم صرفا از نام container بجای IP استفاده کنیم و اصلا استفاده از IP خودش مشکل جدیدی رو برایمون ایجاد میکنه، تو حالت‌هایی که زیر بهشون اشاره می‌کنم ممکنه IP تغییر کنه و اگه از اون IP توی کد یا config ها استفاده کرده باشین به مشکل می خورین:وقتی که به هر دلیلی تصمیم بگیریم که کانتینر رو حذف کنیم و یه کانتینر جدید از روی image مون ایجاد کنیم.تغییرات تو شبکه: اگه container رو از شبکه حذف کنیم و دوباره وصلش کنیم IP جدید بهش داده میشه.اگه Docker daemon یا سیستمی که داکر روش نصبه ری‌استارت بشننکته: البته جدا از تغییر IP استفاده کردن از اسم container تا حد خیلی زیادی خوانایی رو بالا میبره.خب حالا بیاییم با یه مثال این DNS رو امتحان کنیم، تو مثال قبلی container3 رو روی شبکه my_network ران کردیم، برای تست این ویژگی میخوام container2 رو هم که قبلا رو شبکه default بود رو هم به این شبکه اضافه کنیم. برای این کار از دستور زیر استفاده میکنیم.اول بیاییم این container رو از شبکه دیفالت disconnect کنیم: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 ashping container3با استفاده از دستور بالا می‌تونیم ببنیم که تونستیم بجای استفاده از IP با اسم container با container3 ارتباط بگیریم.انواع شبکه در داکرداکر انواع مختلفی از شبکه رو در اختیار ما قرار میده که یکی از مهمترین قابلیت‌های داکر محسوب میشه، هر کدوم از این نوع‌های مختلف مشخص میکنن که یه کانتینر چه دسترسی‌هایی در شبکه داره و چطوری میتونه با کانتینرهای دیگه و یا دنیای بیرون ارتباط برقرار کنه، اینجا قراره با هرکدوم از شبکه‌ها آشنا بشیم و راجع به این صحبت کنیم که هر کدوم از این شبکه‌ها چه کاربردی دارند. انواع شبکه‌هایی که داکر در اختیارمون میزاره به شرح زیر است:BridgeHostOverlayMacvlanNone Networkشبکه Bridgeاین شبکه که پیشتر باهاش آشنا شدیم یکی از سادترین و در عین‌حال پرکاربردترین شبکه در داکر محسوب میشه که میتونیم با کمترین می‌زان تنظیمات و یا آشنایی با جزئیات شبکه، اینجاد و ازش استفاده کنیم. با استفاده از شبکه Bridge می‌تونیم یه شبکه مجازی خصوصی روی ماشین host (ماشینی که داکر روش نصبه) ایجاد کنیم که هر کانتینری که بهش وصل میشه به شکل اتوماتیک یه IP بهش اختصاص داده میشه و کانتینرهایی که تو این شبکه هستن میتونن با هم‌دیگه ارتباط برقرار کنند. موارد استفاده‌ش رو میشه اینطوری گفت:وقتی scale اپلیکیشن که پیاده میکنیم کوچیکه و داشته یه شبکه ساده نیازمون رو برطرف میکنهوقتی که میخواییم شبکه خصوصی داشته باشیموقتی که نیاز داشته باشیم کانتینر ها بتونن باهم ارتباط برقرار کننزمانی که کانتینر نیاز داشته باشه با استفاده از port mapping با دنیای بیرون (شبکه خارج از ماشین هاست مثل اینترنت) ارتبط داشته باشهشبکه Hostاگه یادتون باشه گفتیم تو شبکه از نوع Bridge، داکر روی سخت افزار شبکه ماشین Host (ماشینی که داکر روش نصب شده) یه شبکه‌ی مجازی ایجاد می‌کنه و کانتینرها از این شبکه مجازی استفاده می‌کننن، ولی تو شبکه از نوع هاست اینطوری نیس، برای شبکه Host داکر مسقیما از سخت افزار شبکه ماشین هاست استفاده میکنه، یعنی منابع نرم‌افزاری و سخت‌ افزاری شبکه ماشین هاست با کانتینر ها به اشتراک گذاشته میشه.حالا چه سودی داره این نوع از شبکه؟سرعت بالاتر: از اونجایی که دیگه خبری از یه شبکه مجازی نیس پس سرعت انتقال داده تو این شبکه بیشترهنیازی به Port Mapping نیست: تو این نوع شبکه دیگه نیاز نیست کانتینرها رو به یه Port از ماشین هاست Map کنیم. عملا میشه گفت دیگه از این لحاظ این نوع از شبکه ساده تره.دسترسی راحت تر: تو این نوع از شبکه، هر کدوم از کانتینرها مثل یه سرویس هستن که روی هاست ران شدن، پس ماشین های دیگه برای دسترسی به کانتینرها می تونن به راحتی از IP ماشین هاست و Portی که سرویس (کانتینر روش ران شده) استفاده کنناز اونطرف مشکلاتی که ممکنه بوجود بیاد:مشکل امنیتی: اگه یکی از کانتینرها مشکل امنیتی داشته باشه، از اونجایی که مستقیم روی شبکه ماشین هاست هست، میتونه ریسکی برای کانتینرهای دیگه یا ماشین هاست باشه.تداخل Portها: از اونجایی که دیگه Port Mapping نداریم، اگه دو یا چندتا از کانتینرها روی Port های مشابه اجرا بشن مشکل ایجاد می‌شه.شبکه Overlayخببب شبکه Overlay، تا الان صحبت از این بود که کانتینرها دارن روی یک ماشین اجرا میشن و از منابع همون ماشین به صورت اشتراکی استفاده می‌کنن ولی اگه قرار باشه هر کدوم از این کانتینرها روی ماشین خودشون اجرا بشن چی؟ توی این حالت دیگه نمیشه از دو شبکه قبلی استفاده کرد، پس اگه قرار باشه کانتینرها که روی ماشین های مختلف اجرا میشن با هم ارتباط برقرار کنن باید از شبکه Overlay استفاده کنیم. این نوع از شبکه مخصوصا برای سیستم‌های توضیع شده خیلی مهم هست.موارد استفاده ش چیه؟در Docker Swarm: شبکه Overlay جزو جدانشدنی و بنیادین سولوشن Docker Swarm هست.معماری Microservice: اگه قرار باشه چند میکروسرویس داشته باشیم که هر کدوم روی ماشین‌های مختلف اجرا میشن میتونیم از این نوع از شبکه برای ارتباط استفاده کنیم.و کلا همه مواردی که کانتینرها بصورت فیزیکی از هم جدا هستن و روی ماشین های مختلف اجرا میشنفک کنم تا همینجاش هم خیلی طولانی شد :) هدفم ایجاد کنجکاوی بود که برید و بیشتر راجع شبکه در داکر بخونین. یادتون باشه برای متخصص شدن جزییات مهم هستن، این جزییات هستن که شما رو از بقیه متمایز میکنه پس چیزی رو که ازش استفاده میکنین خوب راجع بهش یاد بگیرین تا بتونین به بهترین شکل ازش استفاده کنین و راه حل‌های درست رو پیدا کنین. نه اینکه صرفا چیزی درست کنیم که فقط کار میکنه :))در پایان مثل همیشه اینکه اگه نوشته رو دوست داشتید با دوستان به اشتراک بزارید که هم بهشون کمک کنه و هم انرژی بشه برای من که ادامه بدم :)اگه پیشنهادی هم برای موضوع نوشته بعدی دارین بگین.و اینکه میتونید منو با آی‌دی mehdi_zarepour تو توییتر پیدا کنید، نوشته‌های جدید رو اونجا توییت میکنم. اگه اینجا اکانت ندارین اونجا بهم پیام بدین یا منشن بزارین.