کوبرنتیز: 01-معرفی

در این مجموعه پست‌ها قصد دارم درباره‌ی کوبرنتیز یکسری آموزش بذارم. البته باید این هم اضافه کنم که در این زمینه خودم هم تازه کار محسوب میشم بنابراین خیلی روی درست و جامع بودن این آموزش حساب باز نکنید. با این حال، سنگ مفت گنجیشک مفت، بزن بریم.

یکی از تکنولوژی‌های خفنی که در چند سال گذشته تاثیر مثبت و خیلی زیادی روی بحث توسعه نرم‌افزار و چرخه کد زنی داشته، کانتینرها بودن. دیگه کمتر برنامه‌نویسی میاد و برای توسعه و تست یه کد با ماشین مجازی محیط توسعه و بقیه ابزارهاش را اجرا می‌کنه. بجاش به نوشتن چند تا فایل داکر و یکی دو تا داکر کامپوز، میتونه چند صد تا کانتینر را ایجاد و پیکربندی کنه و به راحتی از کانتینرهای موجود برای ابزارهای مختلف استفاده کنه.

اما طبق اصل ناپایستگی مشکلات، مشکلات نه کم می‌شوند و نه از بین می‌روند، بلکه زیاد و کلفت‌تر شده و همواره تغییر شکل می‌دهند :)

درسته که داکر خیلی چیز خفنیه ولی وقتی تعداد کانتینرها زیاد میشه، دیگه نمیشه جمعشون کرد. کافیه یه کانتینر (مثلا دیتابیس یا rabbitmq) از کار بیوفته تا کل سیستم بیاد پایین. اختصاص IP و مدیریت پیکربندی کانتینرها هم جای خود. در اینجاست که گوگل کوبرنتیز را معرفی می‌کنه.

کوبرنتیز یک فریم‌ورک متن بازه (فعلا) که برای هماهنگ‌سازی و مقیاسیدن :) برنامه‌های مبتنی بر کانتینر معرفی شده و ضمن اشتغال آفرینی به ما در حل چالش‌های زیر کمک می‌کنه:

  • مدیریت پیچیدگی: مدیریت دستی کانتینرها (یه دویست سی‌صد تا) کاریست بس سخت و دردناک. اصلا امکان نداره یه جایی را دست بذاری و بعدش مجبور نشی آبشاری کلی فایل دیگه را عوض کنی تا دوباره برنامت کار کنه.
  • دسترسی: اگه چند تا سرور داشته باشی، کوبرنتیز میاد و کانتینرهاتو بین اونها تقسیم میکنه (مگه اینکه بهش بگی نکنه) تا اگه یکی از سرورها به فنا رفت، برنامت به جاییش نباشه.
  • مقیاس‌پذیری: با کوبرنتیز مثل گلابی میتونی تعداد کانتینرهاتو زیاد و کم کنی تا اگه سرعت اینترنت به کاربرا اجازه داد زیادی به برنامت وصل بشن، سرعت سرویست نیاد پایین.
  • بازیابی: وقتی یه کانتینر از کار میوفته، کوبرنتیز خودش دوباره راهش میندازه تا برنامت از کار نیوفته. خیلی هم عالی.

معماری کوبرنتیز

کوبرنتیز ،مثل سایر محصولات گوگل، معماری نسبتا ضخیم و بی‌تربیتی داره. اما در کل با یه معماری ارباب-کارگر طرفیم که دو نوع گره داره:

  • گره ارباب (master node): این گره (یا گره‌ها) مدیریت خوشه (کلاستر) را بر عهده دارند. ترافیک ورودی به خوشه توسط این گره بین سایر گره‌های تقسیم میشه. همینطور زمانبندی و اینکه چه کانتینری کجا باشه را هم این گره تعیین میکنه. ادمین میتونه به این گره وصل بشه و از API برای مدیریت خوشه استفاده کنه. همینطور دیتابیس etcd هم که وضعیت گره‌های خوشه را نگه میداره روی این گره است.
  • گره کارگر (worker node): این نوع گره، از گره ارباب دستور میگیره که تعدادی کانتینر را اجرا کنه. روی این گره حداقل یه container runtime هست (مثل داکر، یا containerd یا cri-o) که کانتینر را اجرا میکنه. همینطور kubelet هم هست که به عنوان یه واسط بین سرور و container runtime عمل میکنه و تضمین میکنه که کانتینرها دارند درست اجرا میشن. برای شبکه هم یه kube-proxy روی این نوع گره هست که میتونه مسیریابی بسته‌های را با کیفیت مورد انتظار گوگل انجام بده.

اجزای کلیدی کوبرنتیز

برای کار با کوبرنتیز یه تعدادی جزء (منفردالبه اجزا) هستند که هر کدوم یه کاری میکنند و در کنار هم میتونند برای توسعه محصولات بومی بدون معادل خارجی مورد استفاده قرار بگیرند. موارد زیر فعلا تعریفن، در پست‌های بعدی که دست به کیبورد بشیم (بله نصب کوبرنتیز هم شامل میشه) بهتر میشه درک کرد. بنابراین اگه یکم گنگ و بی‌مفهوم و غیر بدیهی و ضد و نقیض و In contrast بنظ میرسه خیلی سخت نگیرید.

  • پاد (Pod): یک گروه از کانتینرها (معمولا هم یک کانتینر) که از دید برنامه‌نویس یا دواپس‌کار یک بلوک را تشکیل میدن. این بلوک‌ها را کنار هم میذاریم تا برنامه اصلی را بسازیم. پاد ممکنه در هر لحظه به فنا بره و IPش عوض بشه، ولی تضمین میشه که کوبرنتیز دوباره میسازدش.
  • سرویس (Service): یکی از بدترین نام‌گذاری‌های طول تاریخ بشر. سرویس به ما اجازه میده که چند تا پاد را بهشون یه اسم (مثل آدرس وب‌سایت) اختصاص بدیم و وقتی یه بسته بهش میرسه، به یکی از این پادها میده (load balancing). با توجه به اینکه پاد در هر لحظه ممکنه به فنا بره، سرویس به کمک ما میاد تا بدون توجه به فجایع مربوط به پاد و اینکه در هر لحظه چند تا پاد داریم، باهاشون کار کنیم.
  • اینگرس (Ingress): فارسیش میشه اجازه ورود. اینگرس کمک میکنه که اجازه دسترسی به سرویس از بیرون را بدیم و روش HTTPS و مسیریابی یا URL تعریف کنیم.
  • کانفیگ مپ (ConfigMap): فارسیش میشه نقشه پیکربندی. کانفیگ مپ کمک میکنه که پیکربندی برنامه را از تعریف شبکه و کانتینر و ... جدا کنیم. قسمت خفن اینجاست که با کانفیگ مپ میشه به صورت پویا (در زمان اجرا) کانفیگ برنامه را عوض کنیم، بدون اینکه به بیلد کردن دوباره برنامه نیاز باشه! معمولا برای تعریف متغیرهای محیطی و URLها مورد استفاده قرار میگیره (و نه رمزها).
  • راز (Secret): مثل کانفیگ مپه ولی برای نگداری از کلمات عبور و رمز و کلید API و اینجور چیزا بکار میاد. مطابق انتظار با فرمت base64 داده باید داخلش ثبت کنید (صرفا جهت اطلاع، base64 امنیتی برای شما فراهم نمیکنه و صرفا یه شیوه نمایشه که تضمین میکنه کاراکتر دردسرساز نداریم).
  • حجم (Volume): تقریبا معادل همون دیسک میشه (برای دوستانی که تا حالا با داکر کار نکردند) و به ما کمک میکنه که دسترسی به داده‌های مشترک را برای پادها فراهم کنیم و همینطور یجایی بهشون بدیم که داده‌هاشون را ثبت کنند. اینطوری اگه پاد به فنا رفت، داده به فنا نمیره و پاد بعدی میتونه ازش استفاده کنه.

پیاده‌سازی (Deployment) و مجموعه حالت‌دار (Stateful Set)

موقع کار با کوبرنتیز یه راز سیاه هست که همیشه باید بهش دقت کنید، اونم اینکه پاد در هر لحظه ممکنه به فنا بره، حتی اگه دیتابیس باشه. و اگه یه چیز درمورد دیتابیس مهم باشه اینه که عمرا نباید جایی بره. کلا کوبرنتیز برای برنامه‌هایی خوبه که حالت (داده) در خودشون نگه نمیدارند یا حداقل داده خیلی مهمی ندارند. مثلا یه برنامه تحت وب را میشه تقسیم کرد به کش، دیتابیس و خود برنامه (که فرضا با جنگو نوشتیم). کش اگه به فنا رفت، سرویس کند میشه ولی بعد یکی دو ساعت دوباره همه‌چیز مثل روز اوله. کد جنگو هم اگه کرش کرد، دوباره که پادش بیاد بالا هیچ مشکلی نداریم. ولی دیتابیس اگه به فنا رفت خودمون هم به فنا رفتیم. اینجاست که دو تا مفهموم پیاده‌سازی و مجموعه حالت‌دار برامون دست تکون میدن:

  • پیاده‌سازی: وقتی بکار میاد که برنامه حالت نداره و میخوایم راحت تعداد پادها را زیاد و کم کنیم.
  • مجموعه حالت‌دار: وقتی که داده‌های مهم داریم و نمیشه خیلی به برنامه دست زد (مثل دیتابیس) میتونیم از مجموعه حالت‌دار استفاده کنیم.

این نکته هم اضافه کنم که معمولا کوبرنتیز اصلا گزینه خوبی برای دیتابیس نیست (دردسرش بشتر از سودشه) و با توجه به حساسیت کار، دیتابیس را همیشه بیرون از کوبرنتیز نگه میداریم. خوشبختانه خود دیتابیس‌ها راهکارهای مناسب برای مقیاس پذیری و دسترسی پذیری و بازیابی از خطا و موارد مهم دیگه را پشتیبانی می‌کنند و ما هم سری که درد نمیکنه را دستمال نمیبندیم.

در پایان، کوبرنتیز سخته ولی با توجه به مسیر توسعه تکنولوژی و برنامه نویسی، یادگرفتنش خیلی ارزشمنده. در پست بعدی (که احتمالا دو روز دیگه مینویسم) میریم و کوبرنتیز را هم روی سیستم خودمون و هم روی یک سرور نصب میکنیم. فعلا!