توی این قسمت میخوایم ورکلودهای کوبرنتیز رو باهم بررسی کنیم اما قبلش با هم namespace و resource quota رو میبینم و در مورد مدیریت منابع کلاستر توضیح میدیم.
خب یه مروری کنیم پستهای قبلی رو:
- دواپس چیه و چرا لازمه؟ اینجا در مورد دواپس و ضرورت استفاده از آن صحبت کردم.
- مسیر شغلی دواپس اینجا در مورد مسیر شغلی دواپس و موارد پیرامون آن صحبت کردم.
- چطور اپلیکیشن مناسب کلاد آماده کنیم؟ و اینجا توضیح دادم که چطور میتونیم یه اپلیکیشن مناسب کلاد توسعه بدیم.
- چه عمقی از لینوکس برای دواپس لازمه؟ و اینجا توضیح دادم که کدوم موارد لینوکس برای دواپس الزامی هست که اول سراغ اون موارد بریم.
- خودکارش کن، مشکلاتت حل میشه 🙂 در اینجا در مورد اتومیشن و اینکه انسیبل چیه و چه کمکی به ما میکنه صحبت کردم.
- در مسیر دواپس اینبار اجزای اصلی انسیبل تو این پست اجزای انسیبل رو معرفی کردم و آنها را شرح دادم.
- در مسیر دواپس به داکر رسیدم. (قسمت اول) تو این پست داکر رو شروع کردیم و اونو معرفی کردیم.
- در مسیر دواپس اینبار: پشت داکر چه خبره؟ (قسمت دوم) توی این پست در مورد تکنولوژی هایی که داکر ازشون استفاده میکنه توضیح دادیم.
- در مسیر دواپس اینبار: والیوم و نتورک داکر (قسمت سوم) توی این پست در مورد شبکه توی داکر و اینکه چطوری دیتای کانتینر رو میتونیم نگه داریم توضیح دادیم.
- در مسیر دواپس اینبار: داکر فایل ( قسمت چهارم ) توی این پست در مورد اینکه چطور با استفاده از داکر اپلیکیشن مون رو بیلد کنیم و ایمیج بسازیم توضیح دادیم.
- در مسیر دواپس اینبار: کامپوز فایل و داکر کامپوز (قسمت پنجم) توی این پست در مورد اینکه چطور روند دیپلوی کردن سرویسهامون و کانفیگ اونها رو به صورت کد داشته باشیم توضیح دادیم.
- در مسیر دواپس: اینبار داکر سوآرم (قسمت ششم) توی این پست در مورد داکر سوآرم و اینکه چطوری به کمک داکر چنتا سرور رو کلاستر کنیم، توضیح دادیم.
- در مسیر دواپس اینبار: دور و بری های داکر (قسمت هفتم) توی این پست در مورد ابزارهای جانبی که بهمون توی کار با داکر کمک میکنن توضیح دادیم.
- در مسیر دواپس: جمع بندی داکر (قسمت هشتم) توی این پست در مورد امنیت داکر توضیح دادیم و در آخر هم یه سری از بست پرکتیسها و تجربیات خودم رو گفتم.
- تست نوشتن و شروع مسیر 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 توضیح دادیم و تعدادی ابزار رو معرفی کردیم که به کمک اونها میتونیم یک کوبرنتیز دمهدستی واسه تستهامون داشته باشیم.
- کامپوننتهای کوبر ( قسمت سوم ) توی این پست کامپوننتهای مختلف کوبرنتیز رو بررسی کردیم و اجزای نودهای مستر و ورکر رو دونه دونه بررسی کردیم و توضیح دادیم.
- پادها و مدیریت اونها در کوبرنتیز (قسمت چهارم) توی این پست در مورد پاد توی کوبرنتیز توضیح دادیم و موارد مربوط به اون رو بررسی کردیم.
توصیه میکنم که حتما این پستها رو هم مطالعه کنید. بریم که ادامه بدیم.
در محیطهای Kubernetes، مدیریت منابع و جداسازی پروژهها و تیمها از اهمیت ویژهای برخوردار است. استفاده از Namespaces، Resource Quotas و LimitRange ابزارهایی قدرتمند برای دستیابی به این اهداف بهمون میده.
کوبرنتیز Namespace:
کوبرنتیز میتواند از قابلیت ارائه چندین کلاستر به صورت مجازی پشتیبانی کند در حالیکه به صورت فیزیکی پشت اونها یک کلاستر مشابه باشد. به هر کدوم ازین کلاسترهای مجازی میگن یه namespace.
بنابراین با استفاده از نیماسپیس میتونیم منابع کلاستر رو بین چندین یوزر تقسیم کنیم. نیماسپیسهایی که اول اسمشون با -kube شروع میشه مربوط به سیستم کوبرنتیز هستن و ما نباید اسم نیماسپیسهایی که میسازیم رو ازاین فرمت انتخاب کنیم. نه اینکه نتونیم بلکه بهتره که این کار رو نکنیم.
موقعی که کلاستر رو ستاپ میکنیم چهارتا نیماسپیس اولیه داره که در ادامه اونارو به اختصار بررسی میکنیم:
default:
یکی از نیماسپیسهایی هست که به صورت پیشفرض هست و هیچی داخلش نیست و ما میتونیم سرویسهای خودمون رو اونجا داشته باشیم. تنها یه سرویس داخلش ساخته شده. نیماسپیس پیشفرض کوبرنتیز نیز میباشد.
kube-system:
این نیماسپیس برای آبجکتهایی که توسط سیستم کوبرنتیز ایجاد شدن استفاده میشه.
kube-public:
این نیماسپیس به صورت خودکار ایجاد میشه و برای تمام یوزرها حتی اونایی که authenticate نشدن توسط کلاستر قابلیت خواندن داره. دقت کنید که این نیماسپیس به صورت قراردادی با این نام ایجاد شده و وجودش اجباری نیست.
kube-node-lease:
این نیماسپیس Lease آبجکتهارو توی هرنود نگهداری میکنه. نود لیزها به kubelet امکان اینو میدن که heartbeats بفرستن تا control plane بتونه failure های نود رو تشخیص بده.
بنابراین Namespace در Kubernetes به عنوان یک مکانیزم برای تقسیمبندی منابع در یک کلاستر عمل میکند. هر Namespace میتواند به عنوان یک محیط مجزا برای یک تیم یا پروژه خاص در نظر گرفته شود که امکان مدیریت مستقل منابع را فراهم میکند.
بررسی Resource Quota:
توی کوبرنتیز Resource Quotas امکانی برای محدود کردن مصرف منابع در یک Namespace خاص هستند. این قابلیت به مدیران سیستم اجازه میدهد تا از استفاده بیش از حد منابع توسط تیمها یا پروژهها جلوگیری کنند و منابع را هر طور که تمایل داشتن بین آنها تقسیم کنند.
کنترل مصرف منابع مثل محدود کردن میزان CPU، حافظه، فضای دیسک و دیگر منابع ، جلوگیری از این که یک تیم یا پروژه بتواند منابع کل کلاستر را مصرف کند و اختلال در ح-هکلاستر ایجاد کند، از مزایای ریسورسکوتا هستن.
بررسی Limit Range:
توی کوبرنتیز LimitRange ابزاری برای تعیین محدودیتهای پیشفرض و حداکثر/حداقل منابع برای پادها و کانتینرها در یک Namespace است. این قابلیت تضمین میکند که هر پاد یا کانتینر حداقل و حداکثر منابع مشخصی مصرف کند. بنابراین با استفاده از LimitRange میتونیم مصرف منابع یک پاد رو کنترل کنیم که زیاد نشه.
پس با ریسورس کوتا منابع نیماسپیس و با لیمیترنج منابع پادهای داخل نیماسپیس رو میتونیم کنترل کنیم و براشون سقف و کف بذاریم. این موضوع خیلی مهمه و همیشه سعی میکنیم در کنار ایجاد namespace این دو تا ریسورس مهم رو هم ایجاد کنیم. با این کار کمک میکنه که مدیریت بهتری روی منابع کلاستر خودمون داشته باشیم.
توی قدم بعدی میریم سراغ ورکلودهای کوبرنتیز …
ورکلودهای کوبرنتیز:
گفتیم پاد واسه کوبرنتیز میشه، مجموعه یک یا چند کانتینر که داره روی کلاستر ران میشه. حالا ورکلود یه اپلیکیشن هست که داره روی کلاستر ران میشه که ممکنه یک کامپوننت باشه یا چنتا کامپوننت که با هم کار میکنن در قالب یه مجموعهای از پادها.
هر پادی توی کلاستر یه lifecycle داره، مثلا موقعی که یه پاد داره روی کلاستر ران میشه و به یه مشکل مثل fault توی نودی که این پاد روش اومده بالا میخوره، معنیش اینه که تمام پادهای رو اون نود fail میکنند و نهایتا رفتاری که باید کوبرنتیز نشون بده این هست که به جای پادهایی که خراب شدن، پاد جدید ایجاد کنه روی کلاستر حتی اگه بعدا اون نود که به fault خورده برگرده به حالت healthy. حالا برای اینکه کارمون رو راحتتر کنیم نیازی نیست بریم مستقیم با پادها کار کنیم.
میتونیم از ورکلودها به جاش استفاده کنیم. از طریق اونها میتونیم کنترلرهایی رو کانفیگ کنیم که همیشه حواسشون باشه که تعداد مطلوبی از پادها بالا باشه. دقت کنید نه تنها میتونیم بلکه باید از ورکلودها استفاده کنیم. برای اینکه بتونیم از controller manager و قابلیتهای آن استفاده کنیم نیاز داریم که حتما از ورکلودها استفاده کنیم. توی کوبرنتیز به صورت built-in تعدادی ورکلود داریم که در ادامه تعدادی از اونها رو با هم بررسی میکنیم.
- ReplicaSet
توی رپلیکا ست هدف اینه که یه تعداد مشخصی از پادهای سرویسمون همیشه بالا باشه و یه کنترلر میسازه که حواسش به تعداد این پاد باشه، بنابراین از ReplicaSet بیشتر جاهایی که میخوایم در دسترس بودن تعداد مشخصی از یک پاد گارانتی کنیم، استفاده میکنیم. این ورکلود سادهترین و دم دستی ترین ورکلود کوبرنتیز هست و تنها کاری که میکنه اینه که حواسش به تعداد رپلیکا هست و اون رو کنترل و مدیریت میکنه.
- Deployment
دیپلویمنت همون رپلیکاست هست ولی با دوتا فرق مهم، هم حافظه داره و هم میشه باهاش حرف زد!!! البته برای اینکه راحتتر درکش کنیم اینطوری میگیم.
حافظه داره یعنی اینکه versioning داره و بهمون قابلیت rollout و rollback میده، مثلا وقتی یه نسخهی جدید از اپلیکیشنمون میدیم و ایمیج اون دیپلویمنت رو آپدیت میکنیم اگر خواسته باشیم میتونیم برگردیم به استیت قبلی و ایمیج قبلی خودمون و بریم روی نسخهی قبلی. یه نکتهی مهم اینکه دیپلویمنت برای اینکه بتونه این history رو داشته باشه خودش داره از ReplicaSet استفاده میکنه و با استفاده از آن این کار رو انجام میده.
میشه باهاش حرف زد یعنی اینکه deployment strategy بهمون میده، مثلا میتونیم بهش بگیم اگه من تغییری توی این سرویس دادم و ازش ده تا پاد بالا هست شما اول دوتاشو بیار پایین و دوتا جدید رو جایگزینش کن و بعد دوتای بعدی و … یا اینکه بگیم اول همه ده تا رو بزن نابود کن و بعدش ده تا از جدیده بیار بالا و … این استراتژیها خیلی کمک میکنه که بتونیم بهترین عملکرد رو در تغییرات داشته باشیم.
در ادامه مسیر انواع استراتژیهارو توضیح میدیم.
دقت کنید که وقتی میگیم مثلا دیپلویمنت گارانتی میکنه یه تعداد مشخصی از پادهای سرویستون رو، منظور این نیست که دیگه شما یه دیپلویمنت بزنی دیگه بعدش میتونی دست رو قرآن بذاری که داون نمیشه هیچوقت!!! دیپلویمنت کاری که میکنه اضافه کردن یه کنترلر هست که اون تعداد رو چک کنه ولی اگه فرآیند بالا اومدن پادهای دیپلویمنت fail بشه که اصلا بعید نیست دیگه دیپلویمنت کاریش نمیتونه بکنه که دلایل مختلفی هم میتونه داشته باشه این مساله، مثلا ممکنه resource quota و limit range جلومون رو بگیره یا توی pull کردن ایمیج به ارور بخوریم که اتفاقا بسیار متداول هست برای ماهایی که این سمت آبهای نیلگون هستیم یا مثلا دیپلویمنت permission های کافی رو نداشته باشه یا readiness probe ها fail کنن یا کانفیگ اشتباه منجر به درست کار نکردن اپلیکیشن در runtime بشه و …
دیپلویمنت تنهای موقعی rollout میکنه و میره ورژن بعدی که تغییری توی پاد تمپلت اونو تریگر کنه مثلا لیبلها آپدیت بشن یا ایمیج کانتینرهاش تغییر کنن، آپدیت های دیگه مثل scale کردن دیپلویمنت منجربه تریگر کردن rollout نمیشه.
- DaemonSet
فرض کنید که میخوایم از یه پادی روی همه نودهای کلاستر داشته باشیم، مثلا اگه یه نود به کلاستر اضافه شد یه دونه ازون پاد هم بره روش، مثلا برای یه سرویسی مثل ایجنت مانیتورینگ همچین نیازی داریم یا برای دیمن استورج یا سیستم لاگینگ. دیمنست کارش همینه، که مطمئن شه روی همه نودهای کلاستر یه نسخه از پادی که بهش گفتیم بالا هست و اگه نود پاک شه و از مدار خارج بشه یکی از رپلیکای آن هم کم میشه. یعنی به زبان ساده تعداد رپلیکای ما به تعداد نودهای ما وابسته هست.
ممکنه یه سوال اینجا پیش بیاد که فرقش با static pod چیه؟ پاسخ این هست که درسته که هم استاتیک پاد و هم دیمنست اسکجولر کوبرنتیز را ignore میکنند و روی همه نودهایی که باشن بالا میان ولی تفاوت اینجاست که استاتیک پاد رو kubelet بالا میاره و اصلا به کنترل پلین نیازی نداره و بیشتر برای دیپلوری کردن کامپوننتهای control plane ازش استفاده میکنیم ولی دیمنست رو Api-Server بعد از درخواست کنترلر دیمنست میسازه و روند ساختش مثل پادهای عادی هست و همون مسیر رو طی میکنه و ازش بیشتر برای ایجنتهای مانیتورینگ و لاگ و … استفاده میکنیم.
- StatefulSet
این ورکلود همونطوری که از اسمش مشخصه اومده تا برای دیپلوی کردن اپلیکیشنهای stateful بهمون کمک کنه. به نوعی شبیه دیپلویمنت برامون یه دسته از پاد رو گارانتی میکنه که بالا باشه اما مشخصهای که داره ordering و uniqueness پادهاش هست و به ترتیب میاد بالا یا اگه پاک کنیم به ترتیب شماره از آخر شروع میکنه به پاک کردن، که این مساله بهمون کمک میکنه تا بتونیم با استفاده از statefulset اپلیکیشنهای stateful رو روی کلاسترمون دیپلوی کنیم.
چنتا نکته که درمورد statefulset خوبه حواسمون بهش باشه:
اگه یه statefulset رو پاک کنیم یا scale down کنیم، والیومهایی که بهش داده شده بود پاک نمیشن که به نظرم این چیز بدی نیست ولی اگر ندونیم بد چون ممکنه مجدد اسکیلش رو زیاد کنیم و بیاد از همون والیوم قبلی استفاده کنه. پس بهش دقت کنیم.
برای ارتباط با پادهای statefulset از headless service باید استفاده کنیم که در بخش نتورک در ادامه مسیر بیشتر توضیح خواهم داد در موردش. به زبان ساده سرویسی هست که لودبالانس نمیکنه و همهی درخواستهای ما رو به یکی از پادها میرسونه.
هیچ گارانتی وجود نداره که اگه statefulset رو پاک کنیم پادهای اون هم terminate میکنن و از بین میرن.
پادهایی که بالا میان hostname شون از یه الگو پیروی میکنه که شامل نام stateful و شماره ترتیب پاد هست، به این صورت هر پاد نام یونیکی داره.
- Job & CronJob
یک جاب توی کوبر میاد یک یا چند پاد رو میسازه و انقدر این کار رو تکرار میکنه تا یه تعداد مشخصی از اونها به صورت موفق terminate کنند و اجراشون تموم بشه. زمانیکه پادهای با موفقیت کامل بشن جاب هم کامل شده.
حالا همون جاب رو اگه بخوایم سر یه تایمهای مشخصی اجراش تکرار بشه از cronjob استفاده میکنیم، یوزکیسش میشه مثلا بکاپ گرفتن از یه دیتایی به صورت هفتگی.
در ادامه مسیرمون میریم سراغ استراتژیهای مختلف دیپلویمنت و ورکلودهای مربوط به auto scaling در کوبرنتیز رو بررسی میکنیم. 🌹
مراقب خودتون باشید. 🌹🐳🌹