تو قسمت هفتم از مسیر بلاگ پستهای کوبرنتیز، میریم سراغ مفاهیم نتورک توی کوبرنتیز و با هم بررسی میکنیم که چطوری ریکوئستها توی کلاستر به مقصد خودشون میرسن.
خب یه مروری کنیم پستهای قبلی رو:
- دواپس چیه و چرا لازمه؟ اینجا در مورد دواپس و ضرورت استفاده از آن صحبت کردم.
- مسیر شغلی دواپس اینجا در مورد مسیر شغلی دواپس و موارد پیرامون آن صحبت کردم.
- چطور اپلیکیشن مناسب کلاد آماده کنیم؟ و اینجا توضیح دادم که چطور میتونیم یه اپلیکیشن مناسب کلاد توسعه بدیم.
- چه عمقی از لینوکس برای دواپس لازمه؟ و اینجا توضیح دادم که کدوم موارد لینوکس برای دواپس الزامی هست که اول سراغ اون موارد بریم.
- خودکارش کن، مشکلاتت حل میشه 🙂 در اینجا در مورد اتومیشن و اینکه انسیبل چیه و چه کمکی به ما میکنه صحبت کردم.
- در مسیر دواپس اینبار اجزای اصلی انسیبل تو این پست اجزای انسیبل رو معرفی کردم و آنها را شرح دادم.
- در مسیر دواپس به داکر رسیدم. (قسمت اول) تو این پست داکر رو شروع کردیم و اونو معرفی کردیم.
- در مسیر دواپس اینبار: پشت داکر چه خبره؟ (قسمت دوم) توی این پست در مورد تکنولوژی هایی که داکر ازشون استفاده میکنه توضیح دادیم.
- در مسیر دواپس اینبار: والیوم و نتورک داکر (قسمت سوم) توی این پست در مورد شبکه توی داکر و اینکه چطوری دیتای کانتینر رو میتونیم نگه داریم توضیح دادیم.
- در مسیر دواپس اینبار: داکر فایل ( قسمت چهارم ) توی این پست در مورد اینکه چطور با استفاده از داکر اپلیکیشن مون رو بیلد کنیم و ایمیج بسازیم توضیح دادیم.
- در مسیر دواپس اینبار: کامپوز فایل و داکر کامپوز (قسمت پنجم) توی این پست در مورد اینکه چطور روند دیپلوی کردن سرویسهامون و کانفیگ اونها رو به صورت کد داشته باشیم توضیح دادیم.
- در مسیر دواپس: اینبار داکر سوآرم (قسمت ششم) توی این پست در مورد داکر سوآرم و اینکه چطوری به کمک داکر چنتا سرور رو کلاستر کنیم، توضیح دادیم.
- در مسیر دواپس اینبار: دور و بری های داکر (قسمت هفتم) توی این پست در مورد ابزارهای جانبی که بهمون توی کار با داکر کمک میکنن توضیح دادیم.
- در مسیر دواپس: جمع بندی داکر (قسمت هشتم) توی این پست در مورد امنیت داکر توضیح دادیم و در آخر هم یه سری از بست پرکتیسها و تجربیات خودم رو گفتم.
- تست نوشتن و شروع مسیر CI/CD (قسمت اول) توی این پست انواع تست رو بررسی کردیم و با ابزارهای CI/CD آشنا شدیم و یه مقایسه بین گیتلب و جنکینز داشتیم.
- در مسیر CI/CD گیت رو بررسی میکنیم (قسمت دوم) توی این پست قبل ورود به گیتلب نیاز بود که گیت و ورژن کنترل سیستم ها رو یه بررسی کنیم.
- در مسیر CI/CD شناخت گیتلب (قسمت سوم) توی این پست اجزای گیتلب رو بررسی کردیم و با کامپوننتهای مختلفی که داره بیشتر آشنا شدیم.
- در مسیر CI/CD پایپلاین و رانر گیتلب (قسمت چهارم) توی این پست پایپلاین و رانر گیتلب رو بررسی کردیم.
- در مسیر CI/CD وریبل، گیتآپس و جمعبندی (قسمت پنجم) توی این پست وریبلهای گیتلب رو بررسی کردیم و یه معرفی کوتاه از گیتآپس و آتودواپس کردیم و در انتها یه مقدار تجربههای خودم رو در گیتلب باهاتون به اشتراک گذاشتم.
- مسیر Observability (قسمت اول) توی این پست معرفی observability رو داشتیم و مقایسه اش با مانیتورینگ و یه توضیح مختصر هم در مورد اپنتلهمتری دادیم.
- در مسیر Observability، الک (قسمت دوم) توی این پست استک قدرتمند ELK رو بررسی کردیم.
- در مسیر Observability، جمع بندی استک الک (قسمت سوم) توی این پست بقیه کامپوننتهای استک الک رو بررسی کردیم و fluentd و fluentbit رو مقایسه کردیم و نهایتا یه معرفی هم روی opensearch داشتیم.
- در مسیر Observability، استک پرومتئوس (قسمت چهارم) توی این پست یه معرفی اولیه داشتیم روی استک پرومتئوس.
- در مسیر Observability، استک پرومتئوس (قسمت پنجم) توی این پست یه مقدار کامپوننت های استک پرومتئوس رو بیشتر بررسی کردیم.
- در مسیر Observability، استک ویکتوریا (قسمت ششم) توی این پست استک ویکتوریا رو معرفی کردیم و سعی کردیم با پرومتئوس مقایسهاش کنیم.
- در مسیر Observability، میمیر (قسمت هفتم) توی این پست در مورد ابزار میمیر از ابزارهای گرافانا توضیح دادیم و کاربردش رو بررسی کردیم.
- در مسیر Observability، لوکی (قسمت هشتم) توی این پست در مورد ابزار گرافانا برای مدیریت لاگ یعنی لوکی توضیح دادیم و آخرشم یه معرفی کوتاه رو graylog داشتیم.
- در مسیر Observability، تمپو (قسمت نهم) توی این پست در مورد تریسینگ توضیح دادیم و گرافانا تمپو رو بررسی کردیم و یه معرفی کوتاه روی Jaeger داشتیم
- در مسیر Observability، گرافانا (قسمت دهم) توی این پست در مورد گرافانا و HA کردنش و همچنین یه سری از ابزارهاش مثل alloy , incident, on-call توضیح دادیم.
- آغاز مسیر کوبر (قسمت اول) تو این قدم به معرفی ابزارهای ارکستریشن پرداختیم و مدارک کوبرنتیز رو بررسی کردیم.
- کوبر سینگل ( قسمت دوم ) توی این قدم در مورد kubectl , kubeconfig توضیح دادیم و تعدادی ابزار رو معرفی کردیم که به کمک اونها میتونیم یک کوبرنتیز دمهدستی واسه تستهامون داشته باشیم.
- کامپوننتهای کوبر ( قسمت سوم ) توی این پست کامپوننتهای مختلف کوبرنتیز رو بررسی کردیم و اجزای نودهای مستر و ورکر رو دونه دونه بررسی کردیم و توضیح دادیم.
- پادها و مدیریت اونها در کوبرنتیز (قسمت چهارم) توی این پست در مورد پاد توی کوبرنتیز توضیح دادیم و موارد مربوط به اون رو بررسی کردیم.
- ورکلودهای کوبر و مدیریت منابع کوبر (قسمت پنجم) توی این پست در مورد namespaceها توی کوبر توضیح دادیم و انواع ورکلود کوبر رو بررسی کردیم.
- اگه لازم شد کوبر خودش گنده میشه! ( قسمت ششم ) توی این پست در مورد سه نوع ورکلود مرتبط با scaling به صورت خودکار در کوبرنتیز توضیح دادیم.
توصیه میکنم که حتما این پستها رو هم مطالعه کنید. بریم که ادامه بدیم.
مفاهیم مختلف توی نتورک کوبرنتیز رو دونه دونه در ادامه توضیح میدیم، کمکم که بیشتر در مورد آبجکتهای نتورکی کوبر بخونید مدلش دستتون میاد و متوجه میشید که چه اتفاقی داره میافته.
Service:
توی کوبرنتیز، سرویس یک مفهوم انتزاعی هست که یک دسته از پادها رو مشخص میکنه و پالیسیهای دسترسی به اونها رو داره. به این الگو میکروسرویس هم گفته میشه و معمولا میکروسرویسی که توسط سرویس تارگت میشه با سلکتور مشخص میشه. بنابراین شما دیگه کاری به پادهای فرانتاند به عنوان مثال نداری، با سرویسش حرف میزنی، کاری به پادهای بکند نداری درخواستهات رو به سرویسش میفرستی و اون وظیفه داره که درخواست شما رو به پاد مناسبش برسونه. و وقتی چندین تا پاد هم داشته باشه بین آنها لودبالانس میکنه و کمک می کنه که درخواستها به خوبی توزیع بشن.
بنابراین ما درخواستهامون رو میفرستیم سمت سرویس و اون به نوعی لودبالانس رو انجام میده و بین پادهایی که مربوط بهش هستن پخش میکنه درخواست هارو که معمولا این پادها با لیبل و سلکتور اتصالشون به سرویس برقرار میشه.
حالا چرا معمولا؟ مگه بدون لیبل و سلکتور هم داریم؟ بله!
فرض کنید شما میخواید با دیتابیسی بیرون از کلاستر کوبرنتیز صحبت کنید برای پروداکشنتون ولی مثلا توی محیط دولوپ دیتابیستون هم روی کلاستر هست. یا مثلا میخواید به سرویسی در یک نیماسپیس دیگه یا یک کلاستر دیگه اشاره کنید. یا مثلا در حال مهاجرت به کوبرنتیز هستید ولی همچنان بخشی از سرویس بکند شما بیرون کلاستر هست … در این موارد نیاز داریم که از سرویس بدون سلکتور استفاده کنیم. قبلتر گفتیم که هر نود کلاستر کوبرنتیز روی خودش kubelet و kubeproxy داره. کیوبپروکسی موظف هست که به نوعی یک virtual ip برای انواع سرویس ( به جز headless که در ادامه توضیح میدیم ) پیاده سازی کنه تا بتونیم با سرویس توی نودها مختلف ارتباط برقرار کنیم.
حالا اگه لود بالانس نیاز نداشتیم چی؟ مثلا گاهی نیاز میشه که یک سرویس ip واحد نخواهیم و نیاز نداشته باشیم که کیوبپروکسی برامون سرویس رو هندل کنه و لودبالانس انجام بده. مثلا کجا؟
مثلا یه کلاستر دیتابیس داشته باشیم با ورکلود statefulset، در این موارد از مفهومی به اسم Headless Service استفاده میکنیم.
چهار type مختلف سرویس در کوبرنتیز داریم، به ترتیب هر کدوم ویژگیهای قبلی رو داره و یه سری نکات بیشتر هم داره که در ادامه اونها رو بررسی میکنیم:
ClusterIP:
نوعی از سرویس که روی ip داخلی کلاستر اسکپوز میکنه سرویس رو کلاسترآیپی هست. بنابراین اگه از کلاستر آیپی استفاده کنیم سرویس ما فقط درون کلاستر در دسترس هست ازین طریق و type دیفالت سرویس هم همین کلاسترآیپی هست.
برای درک بهتر اهمیت مفهوم سرویس، توی مثال کلاسترآیپی بالا تصور کنید که مفهوم سرویس وجود نداشت و هر کدوم از پادهای فرانتاند به پاد بکاند متناظرش در سطر پایینتر متصل بود و به همین شکل بین بکاند و ردیس. حالا اگه یه صورت قطری سه تا پاد از بین بروند هر سه مسیر سرویسدهی ما مختل میشود در حالیکه با استفاده از سرویس به صورت بالا اگه از سه تا پاد بکاند مثلا دوتاش هم بیافته باز سرویس همچنان بالا میمونه.
NodePort:
تایپ بعدی سرویس توی کوبرنتیز NodePort هست که سرویس رو روی یک پورت ثابت روی همه نودهای کلاستر اکسپوز میکنه، در این حالت میتونیم از بیرون کلاستر هم به سرویس دسترسی داشته باشیم و کافیه که به آیپی یکی از نودهای کلاستر و NodePort مورد نظر درخواست بدیم.
مطلبی که مهم هست اینجا تفاوت بین port و nodeport و targetport هست.
همونطور که بالاتر گفتیم پورتی که روی تمام نودهای کلاستر اکسپوز شده NodePort هست، پورتی که واقعا روی اون پاد داره اکسپوز میشه TargetPort هست و نهایتا پورتی که سرویس ما روی اون داره گوش میده رو Port میگیم. دقت کنید که نود پورت تمام فانکشن clusterip رو دارا هست.
LoadBalancer:
این تایپ سرویس باید امکانش توسط کلاد پروایدر برامون فراهم بشه. با استفاده از این تایپ سرویس میتونیم از طریق لودبالانسر کلاد پروایدر سرویسمون رو اکسپوز کنیم به بیرون. به نوعی ویژگی دوتای قبلی یعنی کلاسترآیپی و نودپورت رو داره اما Routing رو لودبالانسر کلاد پروایدر برامون انجام میده. یعنی بهمون پابلیک آی پی می ده که از بیرون کلاستر هم قابل دسترس باشه.
ExternalName:
اگه همون حالت قبلی LoadBalancer رو با یه رکورد CNAME توی dns داشته باشیم، تایپ چهارم سرویس یعنی ExternalName رو داریم.
قبل از اینکه ادامه بدیم یه مقدار در مورد سرویس عمیقتر شیم، گفتیم سرویس یه مفهوم انتزاعیه و توسط کیوبپروکسی پیاده سازی میشه، یعنی مثلا مثل api-server یه کامپوننت کلاستر نیست که بخوایم جداش کنیم و بگیم این سرویس هست. خب کیوبپروکسی چجوری پیاده سازی میکنه سرویس رو مثلا؟
توی تصویر بالا سه تا پاد رو میبینیم که پشت یه سرویس هستن، کیوبپروکسی هم توی این کلاستر با iptables کار میکنه چون می اونه با ipvs هم باشه. همونطور که مشخصه رولهای iptables رو به شکلی میزنه کیوب پروکسی که از ترافیکی که سمت سرویس میاد اول یکسومش بره سمت پاد اول، بعدش از باقیمانده ترافیک نصفشم بره سمت پاد دوم و نصف دیگه سمت پاد سوم. به این صورت با استفاده از iptables لودبالانس بین پادهای یک سرویس انجام میشه.
خب پس تا اینجا سرویس و انواع اون رو توضیح دادیم، بریم سراغ بقیش 🙂
EndPoint:
توی کوبرنتیز API، اندپوینت ریسورسی هست که یه لیست از endpointهای نتورکی رو مشخص میکنه که معمولا یه سرویس برای مشخص شدن پادهایی که باید ترافیک رو سمتشون بفرسته ازش استفاده میکنه.
و مفهوم جدیدتری که اومده و پیشنهاد میشه به جای endpoint، مفهوم EndpointSlice هست که یه مسیر ساده تر که قابلیت scale پذیری راحتتری هم داره رو برای track کردن اندپوینتهای نتورکی استفاده میکنه.
قبل از اینکه بریم سراغ توضیح Ingress دوتا مفهوم دیگه هم هست که صرفا معرفیشون میکنیم که بدونیم نباید ازشون استفاده کنیم! چون بست پرکتیس نیست.
مفهوم Host Network رو هم توی کوبر داریم که یه جورایی شبیه نتورک هاست داکر هست، یعنی پادی که با Host Network میاد بالا به نوعی به همهی اینترفیسهای شبکه اون ماشینی که روش اومده بالا دسترسی داره و ایزوله سازی ای در مورد شبکهاش اتفاق نیافتاده.
به همین شکل چیزی مشابه مفهوم پابلیش کردن پورت توی داکر داریم که توی کوبر بهش میگیم Host Port که پورت یه پاد رو مپ میکنه به یکی از پورت های نودی که پاد روش هست، که در این حالت ازون پاد فقط یه دونه باید داشته باشیم چونکه دوتا پروسه نمیتونن با هم bind بشن به یه پورت از طریق Host Port، بنابراین اگه سه تا نود توی کلاسترمون داشته باشیم و بخوایم یه پاد با چهارتا رپلیکا رو به اینصورت دیپلوی کنیم فقط سه تاش اسکجول میشه و چهارمی توی حالت پندینگ میمونه. تفاوتی که با نود پورت داره اینه که تو نود پورت مهم نیست پاد کجا بالا اومده اون پورت روی همه نودها پابلیش می سه ولی تو host port تنها روی همون هاستی که پاد اومده بالا پابلیش می شه.
NetwokPolicy:
قبلتر گفتیم که میتونیم با استفاده از namespace توی یک کلاستر کوبرنتیز چنتا کلاستر به صورت مجازی داشته باشیم و به مشتریهای مختلف سرویس بدیم، اما اگه نخوایم مثلا پادهای توی namespace اول بتونن پادهای توی namespace دوم رو ببینن و بهشون دسترسی نداشته باشن چیکار باید بکنیم؟
یا مثلا فرض کنید نیاز داریم پادهای یه سرویس کاملا به لحاظ نتورکی ایزوله باشند، در این موارد باید از نتورک پالیسیها توی کوبرنتیز استفاده کنیم.
به صورت پیشفرض توی کلاستر تمام ترافیک ورودی (ingress) و تمام ترافیک خروجی (egress) به صورت allowed هست و اگه بخوایم میتونیم با استفاده از نتورک پالیسیها flow ترافیک رو کنترل کنیم هم در لول IP و هم در لول پورت یعنی در لایههای سه و چهار شبکه این امکان رو داریم که نتورک پالیسی در نظر بگیریم برای اپلیکیشنهامون.
نتورک پالیسی بهمون این امکان رو می ده که ایزولیشن نتورکی ایجاد کنیم. البته باید cni که استفاده می کنید این موضوع رو پشتیبانی کنه وگرنه امکانش براتون فراهم نمیشه.
Ingress:
باتوجه به اینکه توی ایران هنوز کلاد پروایدری که بهمون امکان استفاده از تایپهای LoadBalancer و ExternalName نداریم، اگر داریم سرویسی رو روی کلاستر کوبرنتیزمون دیپلوی میکنیم که میخوایم اونو به بیرون اکسپوز کنیم و با دامنه در اختیار مشتری قرارش بدیم، بهترین گزینهای که میتونیم ازش استفاده کنیم اینگرس هست.
اینگرس یه تایپ سرویس نیست، بلکه به نوعی یه روتر هوشمند برای کلاسترمون هست که بهمون این امکان رو میده که ترافیک ورودی رو route کنیم به سمت ریسورسی که میخوایم و همچنین بتونیم چندین سرویس رو پشت یه ip واحد داشته باشیم. یه جورایی مفاهیم ریورسپروکسیها رو توی کوبرنتیز میتونیم با استفاده از اینگرس داشته باشیم.
با اینگرس میتونیم توی لایه هفتم شبکه ترافیک رو تفکیک کنیم و از روی path و header و موارد این چنینی در خواستهارو جدا کنیم و به سمت پادهایی که میخوایم بفرستیم.
اینگرس کنترلر های متفاوت و بزرگی داریم که هر کدوم امکانات متفاوت و متعددی رو در اختیار ما قرار می دن از nginx و traefik بگیر تا کلی چیز دیگه. خوبه در مورد اینگرس بیشتر بخونید چون دنیای بزرگی داره و کلی امکان در اختیار ما قرار می ده.
و نهایتا خوبه که PortForwarding رو هم بشناسیم، گاهی پیش میاد که در زمان کار با کلاستر میخوایم برای دیباگ یا بررسی چند لحظهای پورت یکی از پادها رو بیاریم روی لپتاپ خودمون bind کنیم به یه پورت و ببینیمش، اینجا پورت فورواردینگ توی کوبرنتیز بهمون کمک میکنه.
kubectl -n <namespace> port-forward <resource_name> <host_port>:<pod_port>
با دستور بالا میتونیم این کار رو انجام بدیم و وضعیت اون پورت از پادی که مدنظرمون هست رو بررسی کنیم.
دقت کنید که پورت فورواردینگ قط برای تیشوت مناسبه و کاربرد داره و برای سرویس دهی اصلا روش مناسبی نیست. ولی برای تیشوت راهکار خیلی خوب و دم دستی هست.
در ادامه مسیر میریم سراغ ادامه مطالب کوبرنتیز و موارد مربوط به استورج رو بررسی میکنیم.
مراقب خودتون باشید. 🌹🐳🌹