تو قسمت نهم از مسیر بلاگ پستهای کوبرنتیز، میریم سراغ مفاهیم پراب و مدیریت منابع و ریکوئست و لیمیت رو بررسی میکنیم.
خب یه مروری کنیم پستهای قبلی رو:
- دواپس چیه و چرا لازمه؟ اینجا در مورد دواپس و ضرورت استفاده از آن صحبت کردم.
- مسیر شغلی دواپس اینجا در مورد مسیر شغلی دواپس و موارد پیرامون آن صحبت کردم.
- چطور اپلیکیشن مناسب کلاد آماده کنیم؟ و اینجا توضیح دادم که چطور میتونیم یه اپلیکیشن مناسب کلاد توسعه بدیم.
- چه عمقی از لینوکس برای دواپس لازمه؟ و اینجا توضیح دادم که کدوم موارد لینوکس برای دواپس الزامی هست که اول سراغ اون موارد بریم.
- خودکارش کن، مشکلاتت حل میشه 🙂 در اینجا در مورد اتومیشن و اینکه انسیبل چیه و چه کمکی به ما میکنه صحبت کردم.
- در مسیر دواپس اینبار اجزای اصلی انسیبل تو این پست اجزای انسیبل رو معرفی کردم و آنها را شرح دادم.
- در مسیر دواپس به داکر رسیدم. (قسمت اول) تو این پست داکر رو شروع کردیم و اونو معرفی کردیم.
- در مسیر دواپس اینبار: پشت داکر چه خبره؟ (قسمت دوم) توی این پست در مورد تکنولوژی هایی که داکر ازشون استفاده میکنه توضیح دادیم.
- در مسیر دواپس اینبار: والیوم و نتورک داکر (قسمت سوم) توی این پست در مورد شبکه توی داکر و اینکه چطوری دیتای کانتینر رو میتونیم نگه داریم توضیح دادیم.
- در مسیر دواپس اینبار: داکر فایل ( قسمت چهارم ) توی این پست در مورد اینکه چطور با استفاده از داکر اپلیکیشن مون رو بیلد کنیم و ایمیج بسازیم توضیح دادیم.
- در مسیر دواپس اینبار: کامپوز فایل و داکر کامپوز (قسمت پنجم) توی این پست در مورد اینکه چطور روند دیپلوی کردن سرویسهامون و کانفیگ اونها رو به صورت کد داشته باشیم توضیح دادیم.
- در مسیر دواپس: اینبار داکر سوآرم (قسمت ششم) توی این پست در مورد داکر سوآرم و اینکه چطوری به کمک داکر چنتا سرور رو کلاستر کنیم، توضیح دادیم.
- در مسیر دواپس اینبار: دور و بری های داکر (قسمت هفتم) توی این پست در مورد ابزارهای جانبی که بهمون توی کار با داکر کمک میکنن توضیح دادیم.
- در مسیر دواپس: جمع بندی داکر (قسمت هشتم) توی این پست در مورد امنیت داکر توضیح دادیم و در آخر هم یه سری از بست پرکتیسها و تجربیات خودم رو گفتم.
- تست نوشتن و شروع مسیر 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 به صورت خودکار در کوبرنتیز توضیح دادیم.
- نتورک کوبر (قسمت هفتم) توی این قسمت انواع سرویس توی کوبرنتیز رو بررسی کردیم و در مورد مفاهیم اینگرس و نتورک پالیسی توضیح دادیم.
- استورج کوبرنتیز (قسمت هشتم) توی این قسمت در مورد انواع استورج توی کوبرنتیز توضیح دادیم و مفاهیم PV و PVC و Storage Class رو بررسی کردیم.
توصیه میکنم که حتما این پستها رو هم مطالعه کنید. بریم که ادامه بدیم.
در Kubernetes، پراب (Probe) مکانیزمی است که به kubelet کمک میکند تا وضعیت سلامت یک کانتینر را بررسی کند. به بیان ساده، پرابها تستهایی هستند که به صورت دورهای اجرا میشوند تا تشخیص دهند که آیا یک کانتینر:
- سالم است (Healthy): یعنی به درستی کار میکند.
- آماده است (Ready): یعنی میتواند درخواستهای جدید را پردازش کند.
- مشکلی دارد (Unhealthy): یعنی به درستی پاسخ نمیدهد.
این مکانیزم از طریق صدا زدن یک Handler که توسط کانتیر ایجاد شده، اتفاق میافتد.
سه نوع هندلر وجود دارند که به اختصار اونها رو توضیح میدیم.
ExecAction:
یک کامند رو درون کانتینر اجرا میکنه و اگه با status code صفر از کامند خارج بشه اون رو موفقیت آمیز در نظر میگیره و وضعیت کانتینر رو سالم گزارش میکنه.
TCPSocketAction:
به یک پورت خاص پاد از طریق ip پاد متصل میشه و یک TCP Check رو انجام میده و درصورتیکه پورت باز باشه این تست رو موفق در نظر میگیره.
HTTPGetAction:
یک درخواست HTTP GET به ip پاد میزنه در پورت و path مشخص و در صورتیکه response کد بزرگتر مساوی ۲۰۰ و کمتر از ۴۰۰ باشد اون رو موفق در نظر میگیره.
انواع پرابها:
۱. Liveness Probe:
برای بررسی اینکه آیا کانتینر سالم است یا نه. اگر کانتینر سالم نباشد، kubelet میتواند آن را ریاستارت کند.
۲. Readiness Probe:
برای بررسی اینکه آیا کانتینر آماده ارائه خدمات است یا نه. اگر آماده نباشد، از لیست پادهای قابل دسترس (Endpoints) حذف میشود.
۳. Startup Probe:
برای بررسی اینکه آیا کانتینر توانسته به درستی شروع به کار کند یا نه. این پراب معمولاً برای کانتینرهایی که زمان زیادی برای شروع نیاز دارند استفاده میشود.
با استفاده از این پرابها و وضعیتی که از پادها برامون مشخص میکنند تصمیم میگیرم که در زمان لودبالانس ترافیک رو سمت کدوم پادها بفرستیم و کدوم پادها در دسترس هستند و میتونند به درستی سرویس بدهند.
پرابها نقش مهمی در مدیریت خودکار کانتینرها و اطمینان از پایداری سیستم دارند.
میتونیم تنظیمات مختلفی رو برای پرابها در نظر بگیریم و پرابها رو کانفیگ کنم که در ادامه چند مورد از اونها رو توضیح میدیم.
- initialDelaySeconds:
تعداد ثانیههایی که پس از شروع کانتینر صبر میشود تا پرابهای startup، liveness یا readiness آغاز شوند. مقدار پیشفرض ۰ ثانیه است. حداقل مقدار مجاز ۰ است.
- periodSeconds:
فاصله زمانی (بر حسب ثانیه) برای اجرای پراب رو با این متغیر نشان میدهیم یعنی هر چند ثانیه یکبار پراب مجدد اجرا شود و وضعیت چک شود. مقدار پیشفرض ۱۰ ثانیه است. حداقل مقدار مجاز ۱ است.
- timeoutSeconds:
تعداد ثانیههایی که پس از آن پراب تایماوت میشود. یعنی اگه تا اون زمان پاسخ نگرفت دیگه منتظر پاسخ نمیمونه و دریافت نشده در نظر میگیره. مقدار پیشفرض ۱ ثانیه است. حداقل مقدار مجاز ۱ است.
- successThreshold:
حداقل تعداد موفقیتهای متوالی برای اینکه پراب پس از یک بار شکست، موفق در نظر گرفته شود. مقدار پیشفرض ۱ است. برای پرابهای liveness و startup باید مقدار ۱ داشته باشد. حداقل مقدار مجاز ۱ است.
- failureThreshold:
زمانی که یک پراب شکست بخورد، Kubernetes تعداد failureThreshold بار تلاش میکند پیش از اینکه تسلیم شود. تسلیم شدن در مورد liveness probe به معنای ریاستارت کردن پاد است. در مورد readiness probe، پاد به عنوان آمادهنبودن (Unready) علامتگذاری میشود. مقدار پیشفرض ۳ است. حداقل مقدار مجاز ۱ است.
کوبرنتیز با استفاده از Probها میتونه از وضعیت پادها و سرویسهای ما مطلع بشه و در جریان وضعیت آنها قرار میگیره که این خیلی خوبه. اگر برای پادهامون Prob قرار ندیم کوبرنتیز نمیدونه که اون پادها در چه وضعیتی قرار دارند و این اصلا چیز خوبی نیست. با استفاده از این موارد ما داریم به کوبرنتیز خودمون شعور بیشتر اضافه میکنیم که درک کنه پادمون حالش چطوره و زمانی که حالش میزون بود سمتش ترافیک بفرسته.
Kubernetes Resource Management:
زمانی که Resource Request را برای کانتینرهای یک پاد مشخص میکنید، Scheduler از این اطلاعات برای تصمیمگیری در مورد اینکه پاد روی کدام نود قرار بگیرد استفاده میکند. زمانی که محدودیت منابع Resource Limit را برای یک کانتینر مشخص میکنید، kubelet این محدودیتها را اعمال میکند تا کانتینر در حال اجرا اجازه نداشته باشد بیش از حدی که تعیین کردهاید از منابع استفاده کند. همچنین kubelet حداقل مقدار درخواستشده از آن منبع سیستم را به صورت اختصاصی برای استفاده آن کانتینر رزرو میکند.
در فایل مانیفست پاد، CPU و Memory هر کدام به عنوان یک Resource Type تعریف شدهاند که میتوان محدودیتهایی در سطح کانتینر برای آنها تعیین کرد. هر نوع منبع دارای یک واحد پایه است. CPU بر حسب هستههای پردازشی (cores) مشخص میشود و Memory بر حسب بایت (bytes) تعیین میگردد. برای هر نوع منبع دو نوع محدودیت قابل تنظیم است: Requests و Limits.
- Request
مقدار منابعی است که سیستم برای پاد تضمین میکند و Kubernetes از این مقدار برای تصمیمگیری در مورد اینکه پاد روی کدام نود قرار گیرد استفاده میکند. به عبارتی مقدار منابعی است که کوبرنتیز و kubelet تضمین میکند که در اختیار pod قرار میدهد. مقدار منابعی است که گارانتی میکند.
- Limit
حداکثر مقدار منابعی است که Kubernetes به پاد اجازه میدهد استفاده کند. دقت کنید اجازه میده که استفاده کنی ولی گارانتی نمیکنه که حتما برای شما تامین کند. اگر داشت در اختیار Pod قرار میده. اصلا گارانتی براش نیست. اگر وجود داشت تامین میشود. سقف مصرف منابع pod هست و بیشتر از اون نمیتونه pod منابع در اختیار بگیره.
در واقع توی request به کوبرنتیز میگیم تضمین کن که این میزان رو حتما بهش بدی ولی توی limit میگیم اگه داشتی تا این حد بهش بده!
پس دیدیم که در کوبرنتیز Requests و Limits مکانیزمهایی هستند که برای کنترل منابعی مانند CPU و Memory استفاده میشوند. فقط باید به خاطر داشت که مقدار Limit هرگز نمیتواند کمتر از مقدار Request باشد. اگر این کار را امتحان کنید، Kubernetes خطا میدهد و اجازه اجرای pod را نمیدهد.
یه نکتهی مهم اینکه این حد و حدود منابع برای pod تنظیم میشود. اینکه اون پاد چند تا کانتینر داشته باشه فرقی نمیکنه و این منابع برای مجموع اون کانتینرها میباشد. اگر ۴ تا کانتینر داشته باشه و میزان لیمنت منابع روی ۲ گیگ رم باشه مجموع اون ۴ تا کانتیر میتونن ۲ گیگ رم مصرف کنند. به این نکته توجه کنید که کوچکترین یونیت قابل مدیریت داخل کوبرنتیز Pod است.
برای دیدن اینکه هر نود توی کلاستر داره چه میزان از منابع رو مصرف میکنه میتونید از کامند زیر استفاده کنید.
kubectl get nodes –no-headers | awk ‘{print $1}’ | xargs -I {} sh -c ‘echo {}; kubectl describe node {} | grep Allocated -A 5 | grep -ve Event -ve Allocated -ve percent -ve — ; echo’
این کامند به صورت مرحلهای اجرا میشود تا اطلاعات مصرف منابع را برای تمامی نودهای کلاستر Kubernetes نمایش دهد. اجازه دهید مرحله به مرحله آن را توضیح دهیم:
kubectl get nodes –no-headers
این بخش لیستی از تمامی نودهای موجود در کلاستر را بدون نمایش هدر (ستونهای عنوان) دریافت میکند. خروجی این بخش شامل نام نودها است، مثلا:
node – 1
node – 2
node – 3
awk ‘{print $1}’
این دستور ستون اول خروجی (نام نودها) را استخراج میکند. در نتیجه، تنها نام نودها به مراحل بعدی منتقل میشود.
xargs -I {} sh -c ‘…’
این دستور به ازای هر نام نود ({})، یک شل اسکریپت اجرا میکند. داخل این اسکریپت مراحل زیر انجام میشود:
الف) echo {}
نام نود فعلی را چاپ میکند تا در خروجی مشخص باشد کدام نود بررسی میشود.
ب) kubectl describe node {}
برای نود فعلی ({})، دستور kubectl describe node
اجرا میشود. این دستور اطلاعات مفصلی درباره نود ارائه میدهد، از جمله منابع تخصیصیافته و وضعیت پادهای در حال اجرا.
ج) grep Allocated -A 5
در خروجی دستور بالا، خطوطی که شامل عبارت Allocated هستند و ۵ خط بعد از آن فیلتر میشوند. این خطوط اطلاعات مصرف منابع CPU و Memory را نشان میدهند.
د) grep -ve Event -ve Allocated -ve percent -ve —
این بخش، خطوطی که شامل عبارتهای اضافی مانند Event، Allocated، یا percent باشند را فیلتر میکند تا خروجی تمیزتر شود و فقط اعداد و اطلاعات مهم نمایش داده شوند.
ه) echo
یک خط خالی بین اطلاعات هر نود چاپ میکند تا خوانایی خروجی بهتر شود.
نمونه خروجی:
فرض کنید کلاستر شما ۳ نود دارد. خروجی این کامند ممکن است به صورت زیر باشد:
node-1
CPU Requests: 100m (10%)
CPU Limits: 200m (20%)
Memory Requests: 512Mi (25%)
Memory Limits: 1Gi (50%)
node-2
CPU Requests: 150m (15%)
CPU Limits: 300m (30%)
Memory Requests: 256Mi (10%)
Memory Limits: 512Mi (20%)
node-3
CPU Requests: 200m (20%)
CPU Limits: 400m (40%)
Memory Requests: 1Gi (50%)
Memory Limits: 2Gi (100%)
این کامند به شما امکان میدهد به صورت سریع و تمیز مصرف منابع Allocated در هر نود را مشاهده کنید.
مناسب برای بررسی مشکلات مربوط به تخصیص منابع یا شناسایی نودهایی که ممکن است دچار کمبود منابع شوند.
این کامند وابسته به خروجی دقیق دستور kubectl describe node
است و ممکن است در نسخههای مختلف Kubernetes تغییرات جزئی داشته باشد.
QoS on Kubernetes:
برای کوبرنتیز مهمه که میزان ریکوئست و لیمیت رو چقدر تنظیم کردید و فاصلهی آنها با هم چقدر است. از اون میتونه تشخیص بده که پاد چقدر برای شما مهمه. خیلی مکانیزم جالبی داره.
زمانی که Kubernetes یک پاد ایجاد میکند، یکی از کلاسهای QoS (Quality of Service) زیر را به آن اختصاص میدهد:
Guaranteed:
یک پاد زمانی این کلاس را دریافت میکند که شرایط زیر را داشته باشد:
- مقدار request برای مموری با limit برابر باشد.
- مقدار request برای cpu با limit برابر باشد.
یعنی میزان ریکوئست و لیمیت اندازهی هم ست شده باشه. این طوری داری میگی به کوبرنتیز که دوست من این پاد برام خیلی مهمه و سقف منابعی که لازم داره رو براش گارانتی کن. این طوری کوبرنتیز باید بگرده جایی رو پیدا کنه که بتونه این پاد رو اونجا با این میزان منابع دلیور کنه.
Burstable:
پاد وقتی این کلاس را دریافت میکند که برای Memory یا Cpu دارای request و limit باشد. یعنی وقتی که تنظیمات منابع رو داشته باشه تو این کلاس قرار میگیره. اگر یادتون باشه ما با limite range که تو namespace ایجاد می کردیم برای همه منابع ست میکردیم.
BestEffort:
این کلاس به پادی اختصاص مییابد که request و limit مشخصی برای مموری و cpu نداشته باشند.