این داستان در مورد نحوه استفاده ما از کانتینرها در یک محیط تولید، به ویژه Kubernetes است. این مقاله به جمع آوری معیارها و سیاهههای مربوط از کانتینرها و همچنین ساخت تصاویر اختصاص دارد.
ما از شرکت فین تک Exness هستیم که خدمات تجارت آنلاین و محصولات فین تک را برای B2B و B2C توسعه می دهد. تحقیق و توسعه ما تیم های مختلفی دارد، بخش توسعه بیش از 100 کارمند دارد.
ما نماینده تیمی هستیم که مسئول پلتفرم برنامهنویسان برای جمعآوری و اجرای کد است. بهویژه، ما مسئول جمعآوری، ذخیره و گزارش معیارها، گزارشها و رویدادها از برنامهها هستیم. ما در حال حاضر تقریباً سه هزار کانتینر Docker را در یک محیط تولیدی کار میکنیم، ذخیرهسازی کلان داده 50 ترابایتی خود را حفظ میکنیم، و راهحلهای معماری را ارائه میکنیم که حول زیرساختهای ما ساخته شدهاند: Kubernetes، Rancher، و ارائهدهندگان مختلف ابر عمومی.
انگیزه ما
چه چیزی می سوزد؟ کسی نمیتونه جواب بده کوره کجاست؟ درک آن سخت است. کی آتش گرفت؟ می توانید بفهمید، اما نه فورا.
چرا برخی ظروف ایستاده اند در حالی که برخی دیگر افتاده اند؟ مقصر کدام ظرف بود؟ به هر حال، بیرون کانتینرها یکسان است، اما داخل هر کدام نئو مخصوص به خود را دارد.
توسعه دهندگان ما افراد شایسته ای هستند. آنها خدمات خوبی ارائه می دهند که برای شرکت سود می آورد. اما هنگامی که ظروف با برنامههای کاربردی به بیراهه میروند، خرابیهایی وجود دارد. یک ظرف CPU بیش از حد مصرف می کند، دیگری شبکه را مصرف می کند، سومی عملیات I/O را مصرف می کند و چهارمی کاملاً مشخص نیست که با سوکت ها چه می کند. همه چیز سقوط می کند و کشتی غرق می شود.
نمایندگان
برای درک آنچه در داخل اتفاق می افتد، تصمیم گرفتیم که عوامل را مستقیماً در ظروف قرار دهیم.
این عوامل برنامه های بازدارنده ای هستند که ظروف را در حالتی نگه می دارند که یکدیگر را نشکنند. نمایندگی ها استاندارد شده اند و این امکان یک رویکرد استاندارد برای سرویس دهی ظروف را فراهم می کند.
در مورد ما، نمایندگان باید گزارشها را در قالب استاندارد، برچسبگذاری شده و درنگ ارائه کنند. آنها همچنین باید معیارهای استاندارد شده ای را ارائه دهند که از منظر برنامه کاربردی تجاری قابل توسعه باشد.
Agent همچنین به معنای ابزارهایی برای بهره برداری و نگهداری است که می توانند در سیستم های ارکستراسیون مختلف که تصاویر مختلف را پشتیبانی می کنند (Debian، Alpine، Centos و غیره) کار کنند.
در نهایت، نمایندگان باید از CI/CD ساده که شامل فایلهای Docker است پشتیبانی کنند. در غیر این صورت، کشتی از هم می پاشد، زیرا کانتینرها در امتداد ریل های "کج" تحویل داده می شوند.
فرآیند ساخت و دستگاه تصویر را هدف قرار دهید
برای اینکه همه چیز استاندارد و قابل مدیریت باشد، نوعی فرآیند ساخت استاندارد باید دنبال شود. بنابراین، ما تصمیم گرفتیم ظروف را توسط ظروف جمع آوری کنیم - این بازگشت است.
در اینجا ظروف با خطوط یکپارچه نشان داده می شوند. در همان زمان، آنها تصمیم گرفتند کیت های توزیع را در آنها قرار دهند تا "زندگی مانند تمشک به نظر نرسد." چرا این کار انجام شد، در ادامه توضیح خواهیم داد.
نتیجه یک ابزار ساخت است - یک ظرف مخصوص نسخه که به نسخه های توزیع خاص و نسخه های اسکریپت خاص ارجاع می دهد.
چگونه می توانیم ازآن استفاده کنیم؟ ما یک داکر هاب داریم که حاوی یک ظرف است. ما آن را در داخل سیستم خود منعکس می کنیم تا از وابستگی های خارجی خلاص شویم. نتیجه یک ظرف است که با رنگ زرد مشخص شده است. ما یک قالب ایجاد می کنیم تا تمام توزیع ها و اسکریپت های مورد نیاز را در کانتینر نصب کنیم. پس از آن، ما یک تصویر آماده برای استفاده جمع آوری می کنیم: توسعه دهندگان کد و برخی از وابستگی های خاص خود را در آن قرار می دهند.
چه چیزی در مورد این رویکرد خوب است؟
- اول، کنترل نسخه کامل ابزارهای ساخت - ساخت ظرف، اسکریپت و نسخه های توزیع.
- ثانیاً، ما به استانداردسازی دست یافتهایم: ما الگوها، تصویر متوسط و آماده برای استفاده را به همان روش ایجاد میکنیم.
- سوم اینکه کانتینرها قابلیت حمل را به ما می دهند. امروز از Gitlab استفاده می کنیم و فردا به TeamCity یا Jenkins سوئیچ می کنیم و می توانیم کانتینرهای خود را به همین ترتیب اجرا کنیم.
- چهارم، به حداقل رساندن وابستگی ها. تصادفی نبود که کیت های توزیع را در ظرف قرار دادیم، زیرا این به ما امکان می دهد هر بار آنها را از اینترنت دانلود نکنیم.
- پنجم، سرعت ساخت افزایش یافته است - وجود نسخه های محلی تصاویر به شما امکان می دهد از اتلاف وقت در بارگیری جلوگیری کنید، زیرا یک تصویر محلی وجود دارد.
به عبارت دیگر، ما به یک فرآیند مونتاژ کنترل شده و انعطاف پذیر دست یافته ایم. ما از همان ابزارها برای ساختن هر کانتینر کاملاً نسخه شده استفاده می کنیم.
روش ساخت ما چگونه کار می کند
مونتاژ با یک فرمان راه اندازی می شود، فرآیند در تصویر اجرا می شود (با رنگ قرمز برجسته شده است). توسعه دهنده یک فایل Docker دارد (که با رنگ زرد مشخص شده است)، ما آن را رندر می کنیم و متغیرها را با مقادیر جایگزین می کنیم. و در طول راه ما سرصفحه ها و پاورقی ها را اضافه می کنیم - اینها عوامل ما هستند.
هدر توزیع هایی را از تصاویر مربوطه اضافه می کند. و پاورقی سرویس های ما را در داخل نصب می کند، راه اندازی حجم کار، ورود به سیستم و سایر عوامل را پیکربندی می کند، نقطه ورودی را جایگزین می کند و غیره.
ما مدت ها فکر می کردیم که آیا سوپروایزر نصب کنیم. در نهایت تصمیم گرفتیم که به او نیاز داریم. ما S6 را انتخاب کردیم. سرپرست مدیریت کانتینر را فراهم می کند: به شما امکان می دهد در صورت خرابی فرآیند اصلی به آن متصل شوید و مدیریت دستی کانتینر را بدون ایجاد مجدد آن فراهم می کند. گزارشها و متریکها فرآیندهایی هستند که در داخل ظرف اجرا میشوند. آنها هم باید به نحوی کنترل شوند و ما با کمک سرپرست این کار را انجام می دهیم. در نهایت، S6 از خانه داری، پردازش سیگنال و سایر وظایف مراقبت می کند.
از آنجایی که ما از سیستم های ارکستراسیون مختلفی استفاده می کنیم، پس از ساخت و اجرا، کانتینر باید بفهمد در چه محیطی قرار دارد و با توجه به موقعیت عمل کند. مثلا:
این به ما امکان می دهد یک تصویر بسازیم و آن را در سیستم های مختلف ارکستراسیون اجرا کنیم و با در نظر گرفتن ویژگی های این سیستم ارکستراسیون راه اندازی می شود.
برای یک کانتینر، درختهای فرآیند متفاوتی را در Docker و Kubernetes دریافت میکنیم:
محموله تحت نظارت S6 اجرا می شود. به جمعآورنده و رویدادها توجه کنید - اینها عوامل ما مسئول گزارشها و معیارها هستند. Kubernetes آنها را ندارد، اما Docker دارد. چرا؟
اگر به مشخصات "pod" (از این پس - Kubernetes pod) نگاه کنیم، خواهیم دید که محفظه رویدادها در یک pod اجرا می شود که دارای یک محفظه جمع کننده جداگانه است که عملکرد جمع آوری متریک ها و گزارش ها را انجام می دهد. ما میتوانیم از قابلیتهای Kubernetes استفاده کنیم: اجرای کانتینرها در یک پاد، در یک فرآیند و/یا فضای شبکه. در واقع عوامل خود را معرفی کنید و برخی وظایف را انجام دهید. و اگر همان کانتینر در داکر راهاندازی شود، تمام قابلیتهای مشابه خروجی را دریافت میکند، یعنی میتواند گزارشها و معیارها را تحویل دهد، زیرا عوامل به صورت داخلی راهاندازی میشوند.
متریک ها و لاگ ها
ارائه معیارها و گزارش ها یک کار پیچیده است. تصمیم او چندین جنبه دارد.
زیرساخت برای اجرای محموله ایجاد شده است و نه برای تحویل انبوه سیاههها. یعنی این فرآیند باید با حداقل نیاز به منابع کانتینر انجام شود. ما در تلاش هستیم تا به توسعه دهندگان خود کمک کنیم: "یک ظرف Docker Hub را دریافت کنید، آن را اجرا کنید و ما می توانیم گزارش ها را تحویل دهیم."
جنبه دوم محدود کردن حجم لاگ ها است. اگر افزایشی در حجم گزارشها در چندین کانتینر رخ دهد (برنامه یک stack-trace را در یک حلقه خروجی میدهد)، بار روی CPU، کانالهای ارتباطی و سیستم پردازش گزارش افزایش مییابد و این بر عملکرد میزبان به عنوان یک کل و سایر ظروف بر روی میزبان، سپس گاهی اوقات این منجر به "سقوط" میزبان می شود.
جنبه سوم این است که لازم است تا حد امکان از روش های جمع آوری معیارهای خارج از جعبه پشتیبانی شود. از خواندن فایل ها و نظرسنجی Prometheus-endpoint گرفته تا استفاده از پروتکل های خاص برنامه.
و آخرین جنبه کاهش مصرف منابع است.
ما یک راه حل متن باز Go به نام Telegraf را انتخاب کردیم. این یک کانکتور جهانی است که از بیش از 140 نوع کانال ورودی (پلاگین های ورودی) و 30 نوع کانال خروجی (پلاگین های خروجی) پشتیبانی می کند. ما آن را نهایی کرده ایم و اکنون به شما خواهیم گفت که چگونه با استفاده از Kubernetes به عنوان مثال از آن استفاده می کنیم.
فرض کنید یک توسعهدهنده یک بار کاری را مستقر میکند و Kubernetes درخواستی برای ایجاد یک pod دریافت میکند. در این مرحله، یک ظرف به نام Collector به طور خودکار برای هر pod ایجاد می شود (ما از mutation webhook استفاده می کنیم). کلکسیونر نماینده ماست. در ابتدا، این کانتینر خود را برای کار با Prometheus و سیستم جمع آوری سیاهه ها پیکربندی می کند.
- برای انجام این کار، از حاشیه نویسی pod استفاده می کند و بسته به محتوای آن، مثلاً یک نقطه پایانی Prometheus ایجاد می کند.
- بر اساس مشخصات غلاف و تنظیمات کانتینر خاص، تصمیم می گیرد که چگونه سیاههها را تحویل دهد.
ما گزارشها را از طریق Docker API جمعآوری میکنیم: توسعهدهندگان فقط باید آنها را در stdout یا stderr قرار دهند، و Collector آن را مرتب میکند. لاگ ها به صورت تکه ای با کمی تاخیر جمع آوری می شوند تا از اضافه بار احتمالی میزبان جلوگیری شود.
معیارها در بین نمونه های بار کاری (فرآیندها) در کانتینرها جمع آوری می شوند. همه چیز برچسب گذاری می شود: فضای نام، زیر، و غیره، و سپس به فرمت Prometheus تبدیل می شود - و برای جمع آوری در دسترس قرار می گیرد (به جز برای گزارش). ما همچنین گزارشها، معیارها و رویدادها را به کافکا و موارد دیگر ارسال میکنیم:
- سیاههها در Graylog در دسترس هستند (برای تجزیه و تحلیل بصری).
- گزارشها، معیارها، رویدادها برای ذخیرهسازی طولانیمدت به Clickhouse ارسال میشوند.
همه چیز در AWS دقیقاً یکسان است، فقط ما Graylog را با کافکا با Cloudwatch جایگزین می کنیم. سیاههها را به آنجا ارسال می کنیم و همه چیز بسیار راحت است: بلافاصله مشخص می شود که متعلق به کدام خوشه و ظرف هستند. همین امر در مورد Google Stackdriver نیز صادق است. یعنی طرح ما هم در بستر با کافکا و هم در فضای ابری کار می کند.
اگر Kubernetes با غلاف نداشته باشیم، این طرح کمی پیچیدهتر است، اما بر اساس همان اصول کار میکند.
همان فرآیندها در داخل کانتینر اجرا می شوند، آنها با استفاده از S6 هماهنگ می شوند. همه فرآیندهای مشابه در داخل یک ظرف در حال اجرا هستند.
به عنوان یک نتیجه،
ما یک راه حل کامل برای ساخت و راه اندازی تصاویر، با گزینه هایی برای جمع آوری و ارائه گزارش ها و معیارها ایجاد کرده ایم:
- ما یک رویکرد استاندارد برای مونتاژ تصاویر ایجاد کردیم و بر اساس آن الگوهای CI را توسعه دادیم.
- عوامل جمع آوری داده ها افزونه های Telegraf ما هستند. ما آنها را به خوبی در تولید آزمایش کردیم.
- ما از webhook جهش برای پیاده سازی کانتینرها با عوامل در غلاف استفاده می کنیم.
- ادغام در اکوسیستم Kubernetes/Rancher.
- ما می توانیم همان کانتینرها را در سیستم های ارکستراسیون مختلف اجرا کنیم و به نتیجه ای که انتظار داریم برسیم.
- یک پیکربندی مدیریت کانتینر کاملاً پویا ایجاد کرد.
نویسنده همکار: ایلیا پرودنیکوف
منبع: www.habr.com