در ادامهی پستهای قبلی تو این پست داریم میریم ابزار Grafana Mimir رو یکم بررسی کنیم و ببینیم چه کمکی به ما میکنه.
استک Grafana mimir
- چیه و چه کمکی به ما میکنه
همونطور که قبلتر هم اشاره کردیم پرومتئوس برای long term storage دیزاین نشده، یکی دیگه از ابزارهایی که میتونه به عنوان یک استورج long term و high available برای پرومتئوس نقش ایفا کنه، میمیر هست که ابزاری distributed هست و میتونه اسکیل هم بشه. میمیر به ما این امکان رو میده که متریک هامون رو تا یک بیلیون سری اکتیو بالا ببریم در کنارش بهمون HA میده. توسعه میمیر توی Grafana Labs شروع شد و سال ۲۰۲۲ معرفی شد و هدف این پروژه این هست که تبدیل بشه به یک دیتابیس تایمسریز که بیشترین قابلیت اسکیل و پرفورمنس رو داره.
- چرا لازم داریم که از mimir استفاده کنیم
ویژگیهایی مثل سازگاری صددرصد با پرومتئوس، قابلیت ریموت رایت، پشتیبانی از PromQL و آلرتینگ در کنار سازگاری با long-term storage هایی مثل S3 و GCS و Azure blob storage و OpenStack Swift باعث میشه تا به این فکر کنیم که ما هم لازم داریم از میمیر استفاده کنیم؟
یادم میاد وقتی که داشتم اسلایدهای Observability رو برای جلسات توضیح کانسپت دورههام آماده میکردم، اعلام کرده بودن که میمیر در آینده با ابزارهایی مثل Influx و OpenTelemetry و Graphite و Datadog هم کامپتیبل خواهد شد و چند وقت پیش سر کلاس یکی از دورهها به اون اسلاید که رسیدیم بچه ها نگاه کردن و دیدن که بله این اتفاق افتاده و با اکثرشون سازگار شده. حقیقتا دمشون گرم اینقدر که خوبن
حالا چه شکلی این اتفاق میافته ؟
به صورت native میمیر از Prometheus metrics استفاده میکنه ولی از اونجا که ویژنشون most scalable Prometheus backend هست و میخوان یه دیتابیس تایمسریز قدرتمند بدون در نظر گرفتن فورمت متریک بشن، باید از بقیه انواع متریک هم پشتیبانی کنند تا یوزرها مجبور نباشن برای استفاده از میمیر کد هاشون رو تغییر بدن.
میمیر سه تا پراکسی رو اپن سورس کرده که با استفاده از اونها میشه متریک های Graphite و Datadog و InfluxDB رو هم توی میمیر ذخیره کرد. این پراکسیها که با لیبل experimental توی پروژه هستن امکان گرفتن متریکها از هر سیستمی رو برای میمیر به وجود میارن.
با اضافه کردن این پراکسیها به عنوان یک additional endpoint به ایجنتها، هر کدوم از متریک های اونها به Prometheus time series ترجمه میشه و میتونه به فرمت پرومتئوس ریموت رایت توی میمیر ذخیره بشه. پراکسیها رو توی گیت هاب میتونید پیدا کنید و به صورت آزمایشی هستن فعلا.
در ادامه چنتا دیگه از ویژگیهای میمیر رو براتون میارم:
- High availability through replication
- Blazing fast queries through a horizontally scalable, sharded query engine
- Unlimited cardinality with the horizontally scalable compacto, tested to 1 billion active series
- Advanced multi-tenancy and isolation
- Horizontally scalable, clustered architecture
- چطور کار میکنه
توی سه مرحله زیر براتون توضیحش میدم:
- Store Prometheus metrics
تو مرحله اول باید دیتا وارد میمیر بشه، با استفاده از پرومتئوس متریکهای اپلیکیشن هارو جمع میکنیم و اونها رو توی میمیر مینویسیم یا اینکه با استفاده از Grafana Agent یا یک ابزاری که Prometheus remote write compatible باشه، دیتا رو مستقیما به میمیر میفرستیم.
- Run it easily, without sacrificing scalability or reliability
میمیر به صورت خودکار کلاستر میشه نه نیاز به شارد هست نه رپلیکا نه ری بالانس کردن به صورت دستی. اگه میخواین کپسیتی رو افرایش بدین فقط یه نود جدید به کلاستر اضافه کنید بقیشو میمیر انجام میده
- Visualize in Grafana
میمیر به یوزر این قابلیت رو میده که کوئری بزنه و دیتای جدید رو از طریق recording rules بسازه و برای آلرت رول بذاره از طریق تننتهای مختلف.
- دیزاین
ساختار میمیر بر پایه میکروسرویسها هست. این سیستم تعدادی میکروسرویس داره که میتونن به صورت horizontal اسکیل بشن و به صورت موازی و جداگانه از هم ران بشن که به هر کدوم از این میکروسرویسها کامپوننت میگه و دیزان به شکلی هست که کد برای همه کامپوننتها کامپایل میشه و یک دونه فایل باینری داریم و پارامتر target – کنترل میکند که اون باینری رفتار کدوم کامپوننت یا میکروسرویس رو نشون بده. در ادامه در مورد mode های مختلف دیپلوی کردن میمیر و کامپوننتهاش بیشتر توضیح میدم.
- دیپلوی
گرافانا میمیر رو میتونیم به یکی از دو روش زیر دیپلوی کنیم و مود دیپلوی رو هم با پارامتر target – مشخص میکنند که یا به عنوان فلگ توی CLI اون رو مینویسم یا توی فایل yaml کانفیگ مینویسیم.
- Monolithic mode
مود دیفالت همین هست و توی این مود تمام کامپوننتهای مورد نیاز میمیر در قالب یک پروسه ران میشن که میشه اون رو به صورت target=all – مشخص کرد. مونولتیک ساده ترین راه دیپلوی میمیر هست و برای استفاده آزمایشی یا محیط توسعه مناسب هست.
با ران کردن چندین باینری میمیر با همین مقدار پارامتر target میتونیم اون رو اسکیل کنیم و بدون پیچیدگی کانفیگ این کار انجام میشه و HA خواهیم داشت.
- Microservices mode
توی این مود کامپوننتهای توی پروسههای مجزا ران میشن و برای اسکیل کردن باید هر کامپوننت را که میخوایم جداگانه اسکیل کنیم، مثلا باینری رو با پارامتر به شکل target=ingester – و target=distributor – و … اجرا میکنیم. دیپلوی با این مود بهمون انعطاف پذیری بیشتری میده و توصیه میشه که از مود میکروسرویس توی پروداکشن استفاده کنید ولی پیچیدگی خودش رو هم داره به نسبت روش قبل.
اگه میخواید میمیر رو توی این مود دیپلوی کنید استفاده از mimir-distributed Helm chart روی کوبرنتیز روشی هست که توصیه میشه.
- Read-write mode (experimental)
این روش که فعلا به صورت آزمایشی هست در واقع سعی میکنه تا جایگزینی باشه برای هر دو روش قبل! توی read-write mode کامپوننتها برای راحت تر کردن سربار عملیاتی در کنار حفط کردن امکان اسکیل و انعطاف، به سه تا گروه تقسیم میشن و این سرویس ها رو بالا میاریم که هر سرویس و کامپوننت هایی که شامل میشه به صورت زیر هست:
- read
- query-frontend
- querier
- backend
- store-gateway
- compactor
- ruler
- alertmanager
- query-scheduler
- overrides-exporter
- write
- distributor
- ingester
مثل روشهای قبل اینجا باینتری رو با پارامتر target=read – و target=write – و target=backend – مقداردهی میکنیم.
دیپلوی به روش read-write mode فعلا فقط با استفاده از روش Jsonnet and Tanka در دسترس هست.
به صورت کلی این مدل دیزاین تو استک های گرافانا جاری هست و این سه مدل دیپلویمنت رو تو tempo و loki هم داریم. کلا یه مدل دیزاین شدند.
- کامپوننت ها
میمیر از کامپوننت های زیر تشکیل شده که با هم کار میکنن. در ادامه یه توضیح مختصر در مورد هرکدوم میدم:
کامپکتور کامپوننتی stateless هست و به بهتر شدن پرفورمنس و کم کردن استفاده از استورج کمک میکنه و وظیفه اش فشرده کردن یا همون کامپکت کردن چندین بلاک هست که توسط یک tenant به یک بلاک بزرگتر داده شده. کامپکتور این کار رو با کم کردن سایز ایندکسها و از بین بردن چانکهای duplicate شده دیتا انجام میده که در نتیجه این کار هزینه استورج کم میشه و کوئری زدن رو تعداد کمتری از بلاک سریعتر هم میشه پس سرعت رو هم بیشتر میکنه.
وظیفه دیگهی کامپکتور اینه که بلاکهایی که دیگه توی هیچ ریتنشن کانفیگ شدهای نیستن رو حذف کنه و باکتهای هر تننت رو آپدیت نگه داره که میتونید در موردش بیشتر بخونید.
دیستریبیوتر کامپوننت stateless بعدی هست که دیتای تایمسریز رو از پرومتئوس یا ایجنت گرافانا دریافت میکنه و صحت و درستی دیتا رو بررسی میکنه و مطمئن میشه که لیمیتهای کانفیگ اون تننت رو رعایت کرده. بعد از معرفی کامپوننتها در مورد اینکه tenant چی هست هم توضیح میدم. در ادامه دیستریبیوتر دیتا رو به batchهای مختلف تقسیم میکنه و اونها رو به چندین ingester به صورت موازی میفرسته و seriesهارو بین ingesterها شارد میکنه اصطلاحا و هر سریز به صورت پیش فرض دارای رپلیکا ۳ هست یعنی دوتا کپی دیگه هم ازش ذخیره میکنه.
اینجستر کامپوننت stateful ی هست که دیتای ورودی رو توی استورج از طریق write path مینویسه و سمپل های کوئریها رو از طریق read path برمیگردونه.
کوئرییر کامپوننت stateless بعدی هست که دستورات PromQL رو بررسی میکنه و دیتای تایم سریز رو میگیره و لیبل میرنه برای read path. این کامپوننت برای کوئری زدن به long-term storage از کامپوننت store-gateway استفاده میکنه و برای کوئری زدن به دیتایی که اخیرا نوشته شده و هنوز منتقل نشده به دیسک از کامپوننت ingster استفاده میکنه.
کوئرییر فرانت کامپوننت stateless بعدی هست که همون API کامپوننت کوئرییر رو ارائه میده و میتونیم ازش استفاده کنیم برای شتاب دادن به read path. استفاده از این کامپوننت برای بالا اومدن کلاستر مورد نیاز نیست اما توصیه میشه که اون رو داشته باشیم تا کوئری هامون بهتر انجام بشن.
دومین کامپوننت stateful هم استور گیتوی هست که از طریق اون میشه به long-term storage کوئری زد و همونطور که بالاتر اشاره کردم querier از این کامپوننت برای گرفتن دیتای استورج استفاده میکنه و علاوه بر اون ruler هم ازش برای هندل کردن کوئری ها استفاده میکنه.
چهارتا کامپوننت اختیاری دیگه هم هست که در ادامه مختصرا توضیحشون میدم:
کامپوننتی هست که multi-tenancy و قابلیت اسکیل رو به Prometheus Alertmanager اضافه میکنه.
این کامپوننت لیمیت هارو به صورت متریک های پرومتئوس اکسپوز میکنه تا اپراتور ها بدونن که هر تننت چقدر به لیمیت هاش نزدیک شده.
کامپوننت اختیاری و stateless هست که صفی از صف ها رو نگه میداره! و لود رو بین querier های در دسترس پخش میکنه.
رولر کامپوننت stateless بعدی هست که عبارت های PromQL رو به شکلی که در رول های آلرت مشخص شده بررسی میکنه و هر تننت یه دسته از این رول هارو داره و میتونه توی namespace های مختلف اونها رو به صورت گروه داشته باشه.
- Multi-tenancy
کلا مفهوم تننت یه جورایی یه مفهوم لاجیکی هست برای ایزوله کردن یا به نوعی پارتیشن کردن ریسورس ها برای گروه های مختلف مثلا توی یک اینستنس گرافانا تننت بهمون کمک میکنه تا دیتا ها و داشبوردها و یوزر های مختلف رو جدا کنیم و بتونیم اونها رو منیج کنیم توی یک گرافانا ی سینگل که دیپلوی کردیم. معمولا از تننت ها توی محیط هایی که تیم های مختلف یا گروه های مختلف دارن از یک ریسورس مشترک رو به اشتراک میذارن استفاده میکنیم که بهشون محیط های multi-tenant میگیم. توی میمیر مثلا هر کامپوننتی که مالتی تننسی داشته باشیم برای از یک tenant ID توی هدر درخواست هاش استفاده میکنه و برای هر تننت میشه کانفیگ ها و لیمیت های مختص به اون رو قرار داد.
کلا موضوع مالتی تننت به ما کمک می کنه چندین تا مشتری و سرویس گیرنده رو روی یه استک داشته باشیم.
شاید به نوعی بشه گفت مثلا هر کدوم از مشتری های میمیر که دارن دیتا رو توی اون میریزن میتونن تننت خودشون رو داشته باشن مثلا هر اینستنس پرومتئوس یا هر ایجنت گرافانا یک تننت برای خودش داره و …
توی پستهای بعدی بیشتر ابزارهای مانیتورینگ و Observability رو بررسی میکنیم و کنار هم یاد میگیرم.
مراقب خودتون باشید.
- دواپس چیه و چرا لازمه؟ اینجا در مورد دواپس و ضرورت استفاده از آن صحبت کردم.
- چطور اپلیکیشن مناسب کلاد آماده کنیم؟ و اینجا توضیح دادم که چطور میتونیم یه اپلیکیشن مناسب کلاد توسعه بدیم.
- چه عمقی از لینوکس برای دواپس لازمه؟ و اینجا توضیح دادم که کدوم موارد لینوکس برای دواپس الزامی هست که اول سراغ اون موارد بریم.
- خودکارش کن,مشکلاتت حل میشه در اینجا در مورد اتومیشن و اینکه انسیبل چیه و چه کمکی به ما میکنه صحبت کردم.
- در مسیر دواپس اینبار اجزای اصلی انسیبل تو این پست اجزای انسیبل رو معرفی کردم و آنها را شرح دادم.
- در مسیر دواپس به داکر رسیدیم (قسمت اول) تو این پست داکر رو شروع کردیم و اونو معرفی کردیم.
- در مسیر دواپس اینبار: پشت داکر چه خبره؟ (قسمت دوم) توی این پست در مورد تکنولوژی هایی که داکر ازشون استفاده میکنه توضیح دادیم.
- تست نوشتن و شروع مسیر CI/CD (قسمت اول) توی این پست انواع تست رو بررسی کردیم و با ابزارهای CI/CD آشنا شدیم و یه مقایسه بین گیتلب و جنکینز داشتیم.
- در مسیر CI/CD گیت رو بررسی میکنیم (قسمت دوم) توی این پست قبل ورود به گیتلب نیاز بود که گیت و ورژن کنترل سیستم ها رو یه بررسی کنیم.
- در مسیر CI/CD شناخت گیتلب (قسمت سوم) توی این پست اجزای گیتلب رو بررسی کردیم و با کامپوننتهای مختلفی که داره بیشتر آشنا شدیم.
- در مسیر CI/CD پایپلاین و رانر گیتلب (قسمت چهارم) توی این پست پایپلاین و رانر گیتلب رو بررسی کردیم.
- در مسیر CI/CD وریبل، گیتآپس و جمعبندی (قسمت پنجم) توی این پست وریبلهای گیتلب رو بررسی کردیم و یه معرفی کوتاه از گیتآپس و آتودواپس کردیم و در انتها یه مقدار تجربههای خودم رو در گیتلب باهاتون به اشتراک گذاشتم.
- در مسیر 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 رو بررسی کردیم.
- پراب، ریکوئست و لیمیت (قسمت نهم) توی این قسمت موارد مربوط به محدود کردن منابع کانتینر توی کوبرنتیز رو بررسی کردیم و در مورد انواع probe ها توی کوبرنتیز توضیح دادیم.
- پاد تو نود (قسمت دهم) توی این قسمت درمورد فرآیند انتقال پاد به نود مناسب مفاهیم پیشرفتهتری مثل affinity و anti-affinity و taint و toleration رو بررسی کردیم.
- اولویت پاد و امنیت (قسمت یازدهم) توی این قسمت در مورد تعیین اولویت برای پادها و جنبههای مختلف امنیت در کوبرنتیز توضیح دادیم.
- کنترل دسترسی به کوبر (قسمت دوازدهم) توی این قسمت در مورد مراحل دسترسی به api کوبرنتیز صحبت کردیم و بعدش مفاهیمی مثل سرویس اکانت رو توضیح دادیم.
- دیزاین کلاستر (قسمت سیزدهم) توی این قسمت در مورد طراحی و دیزاین یک کلاستر و روشهای مختلفی که داره توضیح دادیم و همچنین تفاوت روشهای مختلف تقسیم منابع در کلاسترها را بررسی کردیم.
- مالتی تننسی در کوبر (قسمت چهاردهم) توی این قسمت چالشهای مربوط به داشتن چند مستاجر بر روی کلاستر کوبرنتیز توضیح دادیم.
- هلم (قسمت پانزدهم) توی این قسمت پکیج منیجر معروف کوبرنتیز یعنی Helm رو بررسی کردیم و در موردش ویژگیها و کاربردهاش توضیح دادیم.
- سی آر دی و اُپراتور (قسمت شانزدهم) توی این قسمت در مورد اینکه چطوری یه ریسورس کاستوم شده به کلاستر اضافه کنیم توضیح دادیم و مفهوم اُپراتور رو توی کوبر بررسی کردیم.
- نصب کلاستر با kubeadm (قسمت هفدهم) توی این قسمت قدم به قدم نحوه نصب یک کلاستر کوبرنتیز رو با استفاده از ابزار kubeadm توضیح دادیم.
- نصب کلاستر با kubespray (قسمت هجدهم) توی این قسمت نحوه نصب کلاستر با یه پروژه خیلی خوب به نام کیوب اسپری که یه انسیبل خفن برای ستاپ کلاستر رائه میده رو توضیح دادیم.
- نصب کلاستر با rancher (قسمت نوزدهم) توی این قسمت توضیح دادیم که چطور با استفاده از ابزار RKE یک کلاستر کوبرنتیز راهاندازی کنیم.