توزیع بار با Load Balancer سرویس کوبرنتیز ستون
در کوبرنتیز، مفهوم سرویس برای توزیع بار بین پادها به کار میرود. از مهمترین انواع سرویسها میتوان به ClusterIP، NodePort و LoadBalancer اشاره کرد. برای آشنایی بیشتر با این سرویسها، میتوانید به مستند سرویس کوبرنتیز مراجعه کنید. در ادامه کارکرد این سرویسها را مرور میکنیم و سپس سرویس LoadBalancer کوبرنتیز ستون را شرح میدهیم.
این سرویس، نوع پیشفرض سرویس در کوبرنتیز است و یک نقطهی دسترسی فقط برای ارتباطات داخلی کلاستر فراهم میکند. کوبرنتیز به طور خودکار یک IP داخلی (Cluster IP) در رنج داخلی کلاستر و یک نام DNS به این سرویس اختصاص میدهد که سرویسهای دیگر داخل کلاستر میتوانند با استفاده از این IP یا نام DNS، با اپلیکیشن شما ارتباط برقرار کنند. کنترلر سرویس در کوبرنتیز بهطور خودکار ترافیک ورودی را به پادهای مناسبی که با selector سرویس مطابقت دارند، هدایت میکند. این نوع سرویس، خارج از کلاستر قابل دسترسی نیست.
این نوع سرویس، علاوه بر ایجاد یک ClusterIP داخلی، یک پورت ثابت (در بازه پیشفرض ۳۰۰۰۰ تا ۳۲۷۶۷) را روی IP همهی ماشینهای Worker باز میکند. دسترسی به سرویس از طریق آدرس [NodePort]:[IP-نود] امکانپذیر است. اما این روش برای دسترسی از اینترنت عمومی یک شرط اساسی دارد: نودهای Worker باید IP خارجی (External IP) داشته باشند. در پلتفرم کوبرنتیز ستون، با هدف افزایش امنیت، به نودها IP خارجی اختصاص داده نمیشود. در نتیجه، سرویس NodePort به تنهایی برای ارائه سرویس در اینترنت عمومی کاربرد ندارد. همچنین این سرویس محدودیتهای ذاتی دیگری نیز دارد؛ مانند پایدار نبودن IP نودها و الزام به استفاده از شماره پورت در آدرس.
برای رفع تمام این محدودیتها، سرویس LoadBalancer ارائه شده است که پلتفرم کوبرنتیز ستون به طور کامل از آن پشتیبانی میکند.
این سرویس، استانداردترین و مطمئنترین روش برای در دسترس قرار دادن سرویسها در خارج از کلاستر است. با تعریف این نوع سرویس، کوبرنتیز بهصورت خودکار یک لود بالانسر با IP ثابت در subnet کلاستر ایجاد میکند. همچنین، با افزودن annotationهای مربوطه، میتوان یک IP خارجی به این Load Balancer اختصاص داد تا از بیرون کلاستر نیز قابل دسترسی باشد. همهی این عملیات، به شکل خودکار، توسط کوبرنتیز ستون، انجام میشود.

فرض کنید یک اپلیکیشن دارید که در قسمت metadata.labels با یک لیبل مشخص، مثلا app: hello-world مشخص شده است. یکی از پادهای این اپلیکیشن به شرح زیر است:
برای ایجاد یک لودبالانسر که ترافیک ورودی یک IP خاص را به پادهای این اپلیکیشن هدایت کند، باید یک سرویس از نوع LoadBalancer تعریف کنید.
فایل YAML زیر نمونهای از یک سرویس LoadBalancer است:
با ساخت لود بالانسر، یک IP داخلی در سابنت و یک External IP به سرویس شما اختصاص پیدا میکند. پس از اختصاص این IP خارجی، میتوانید مستقیما از آن استفاده کنید یا با استفاده از Ingress یا راهکار دیگری، یک دامنه به آن اختصاص دهید و از آن دامنه در سمت کلاینت خود استفاده کنید.
به طور پیشفرض LoadBalancer ساخته شده، تنها یک IP خصوصی (Private IP) دارد که از داخل سابنتی که کلاستر خود را در آن ساختهاید قابل دسترسی است. در صورتی که میخواهید این لودبالانسر از بیرون سابنت کلاستر کوبرنیتز نیز در دسترس باشد، باید به آن یک External IP اختصاص یابد. میتوانید این کار را با افزودن annotation زیر به سرویسی که داخل کوبرنتیز خود با تایپ LoadBalancer داشتید انجام دهید.
توصیه میشود هیچگاه LoadBalancer را بدون در نظر گرفتن اقدامات امنیتی در برابر حملاتی مانند DDoS در اینترنت عمومی نکنید. برای اطلاع بیشتر به مستند امنسازی کوبرنتیز در برابر حملات DDoS مراجعه نمایید.
اگر نمیخواهید هیچ IP خارجی به Load Balancer شما متصل شود، کافی است annotation مربوطه را حذف کرده یا مقدار آن را به internal تغییر دهید.
با حذف سرویس لودبالانسر، IP خارجی متصل به آن نیز، به طور خودکار، حذف میشود. در صورتی که میخواهید این IP رزرو شده، باقی بماند وبتوانید مجددا از آن استفاده کنید، باید مانند نمونه زیر، از انوتیشن رزرو IP استفاده نمایید.
در قسمت spec.ports میتوانید برای هر جفت پورت و targetPort تعریف شده، یکی از دو پروتکل UDP یا TCP را تعریف کنید. در صورت مشخص نکردن پروتکل، TCP به عنوان پروتکل پیشفرض در نظر گرفته میشود. دقت کنید که همه پورتهای تعریف شده در یک لودبالانسر باید از یک پروتکل (UDP یا TCP) استفاده کنند. استفاده همزمان از هر دو پروتکل در یک لودبالانسر مجاز نیست. تعریف بیش از ده پورت در یک لود بالانسر مجاز نیست.
نمونه لودبالانسر hello-world-udp با دو پورت:
در سرویس لودبالانسر کوبرنتیز، دو حالت برای مدیریت ترافیک وجود دارد که در قسمت externalTrafficPolicy تعیین میشود. با قرار دادن فیلد externalTrafficPolicy: Cluster، ترافیک ورودی به این سرویس را NAT میکند، به این معنی که IP واقعی کلاینتی که درخواست را داده است، در مقصد دیده نمیشود. حالت پیشفرض لودبالانسر کوبرنتیز، همین حالت است، چرا که به نقل از مستند لودبالانسر کوبرنتیز، این حالت در تعادل بار مطمئنتر عمل میکند. اما اگر میخواهید IP واقعی کلاینت را در مقصد داشته باشید، میتوانید از فیلد externalTrafficPolicy: Local در تعریف لودبالانسر خود استفاده نمایید. به عنوان مثال، سرویس hello-world-preserving-local-ip را ببینید.
توجه! در حالت externalTrafficPolicy: Local لودبالانسر فقط پروتکل TCP را پشتیبانی میکند. به عبارت دیگر، در قسمت ports فقط میتوانید از protocol: TCP استفاده کنید و کوبرنتیز در این حالت از پروتکل UDP پشتیبانی نمیکند.
توجه! در حالت Local، تنها ماشینهایی Worker که پادهای مقصد روی آنها حضور دارند، ترافیک را از LoadBalancer دریافت میکنند و ماشینهای دیگر در انتقال این ترافیک مشارکت نمیکنند. این موضوع برای کنترل ترافیک بین ماشینها در حالتی که نمیخواهیم همهی Worker ها در انتقال ترافیک مربوطه مشارکت کنند، مفید است اما در حالت کلی حالت Cluster با مشارکت همهی ماشینها در انتقال ترافیک، برای اتکاپذیری بیشتر توصیه میشود.
توجه: در صورتی که میخواهید IP به شکل رزرو شده باقی بماند، ثبت انوتیشن رزرو IP روی سرویس جدید الزامی است. در غیر این صورت، IP مورد نظر، این بار از حالت رزرو خارج شده و با حذف لودبالانسر، حذف خواهد شد.
اگر لود بالانسر خود را حذف کردهاید اما IP خارجی آن رزرو شده است، میتوانید با رعایت مراحل زیر هنگام ایجاد مجدد لود بالانسر، همان external IP را دوباره استفاده کنید (توجه: IP داخلی تغییر خواهد کرد):
- از طریق پنل، IP خارجی موردنظر را پیدا کنید و مطمئن شوید به هیچ منبعی متصل نیست و آزاد است.
- نام آن را یادداشت کنید.
- هنگام ساخت سرویس جدید، مقدار annotation زیر را برابر با نام IP قرار دهید:
به صورت کلی سرویس جدید شما باید انوتیشن های زیر را داشته باشد:
برای اطمینان از عملکرد صحیح لودبالانسر، میتوان از تنظیمات بررسی سلامت (Health Check) استفاده کرد. این تنظیمات از طریق Annotationهای زیر قابل پیکربندی هستند:
- lb-health-check-period-seconds: این مقدار مشخص میکند که هر چند ثانیه یکبار بررسی سلامت انجام شود. مقدار پیشفرض 30 ثانیه است و میتواند بین 30 تا 600 ثانیه تنظیم شود.
- lb-health-check-timeout-seconds: این مقدار مشخص میکند که حداکثر زمان انتظار برای پاسخ در بررسی سلامت چقدر باشد. مقدار پیشفرض 10 ثانیه است و میتواند بین 1 تا 180 ثانیه تنظیم شود.
- lb-health-check-success-threshold: تعداد پاسخهای موفق متوالی که قبل از تغییر وضعیت سرویس به سالم (Healthy) مورد نیاز است. مقدار پیشفرض 2 بوده و بین 1 تا 10 قابل تنظیم است.
- lb-health-check-failure-threshold: تعداد شکستهای متوالی که قبل از تغییر وضعیت سرویس به ناسالم (Unhealthy) مورد نیاز است. مقدار پیشفرض 3 بوده و بین 1 تا 10 قابل تنظیم است.
مونه تنظیمات بررسی سلامت در لودبالانسر:
معمولا برای مدیریت سرویسهایی که نیاز داریم از بیرون کلاستر، در سطح اینترنت در دسترس باشند، از اپراتورهای اینگرس (Ingress) استفاده میشود که پراستفادهترین آنها Ingress Nginx است. میتوانید در هنگام نصب این اپراتور، آن را با اضافه کردن انوتیشنهای لازم با لودبالانسر کوبرنتیز ستون یکپارچهسازی کنید تا از اتکاپذیری و مقیاسپذیری آن بهرمند شوید. روشهای مختلفی برای نصب این اپراتور وجود دارد که یکی از آنها استفاده از helm است. در مثال زیر انوتیشنهای لازم را در فایل values.yaml قرار میدهیم تا کنترلر Ingress Nginx از ابتدا با یک لودبالانسر ابری بالا بیاید.
حال با لیست کردن سرویسها میبینید که ingress-nginx با یک لودبالانسر بالا آمده است که IP خارجی آن به طور خودکار توسط لودبالانسر کوبرنتیز ستون، به آن افزوده شده است.
ستون برای پیادهسازی سرویس لودبالانسر کوبرنتیز در لایهی پایینتر، از External IP و لودبالانسر سرویس کامپیوت ستون استفاده میکند که به شکل مستقل میتوانید برای ماشینهای کامپیوت خود از آنها در پنل استفاده نمایید. این موارد وقتی از طریق سرویس کوبرنتیز ستون ساخته میشود، به شکل خودکار توسط این سرویس مدیریت میشود و تغییر آنها به شکل دستی در پنل امکانپذیر نیست.
لودبالانسری که برای پیادهسازی لودبالانسر کوبرنتیز شما در سرویس کامپیوت ستون به شکل خودکار ساخته میشود، همنام لودبالانسر شما در داخل کلاستر نیست. مدیریت آن بهطور کامل توسط سرویس کوبرنتیز ستون انجام میشود؛ بنابراین هر تغییری که در لود بالانسر کلاستر خود اعمال کنید، بهصورت خودکار در لایهی لود بالانسر کامپیوت اعمال خواهد شد. لطفاً از اعمال تغییرات مستقیم از طریق پنل خودداری کنید.