werf - ابزار ما برای CI / CD در Kubernetes (نمایش کلی و گزارش تصویری)

27 می در سالن اصلی کنفرانس DevOpsConf 2019 که به عنوان بخشی از جشنواره برگزار شد RIT++ 2019، به عنوان بخشی از بخش "تحویل مداوم"، گزارشی ارائه شد "werf - ابزار ما برای CI/CD در Kubernetes". در مورد آنها صحبت می کند مشکلات و چالش هایی که همه در هنگام استقرار در Kubernetes با آن مواجه هستند، و همچنین در مورد تفاوت های ظریف که ممکن است بلافاصله قابل توجه نباشد. با تجزیه و تحلیل راه حل های ممکن، نشان می دهیم که چگونه این کار در یک ابزار منبع باز پیاده سازی می شود ورف.

از زمان ارائه، ابزار ما (که قبلا به عنوان dapp شناخته می شد) به یک نقطه عطف تاریخی رسیده است. 1000 ستاره در GitHub — ما امیدواریم که جامعه رو به رشد کاربران آن زندگی را برای بسیاری از مهندسان DevOps آسان‌تر کند.

werf - ابزار ما برای CI / CD در Kubernetes (نمایش کلی و گزارش تصویری)

پس بیایید معرفی کنیم ویدئوی گزارش (~47 دقیقه، بسیار آموزنده تر از مقاله) و عصاره اصلی آن به صورت متنی. برو!

تحویل کد به Kubernetes

بحث دیگر در مورد werf نیست، بلکه در مورد CI/CD در Kubernetes خواهد بود، به این معنی که نرم افزار ما در ظروف Docker بسته بندی شده است. (من در این مورد صحبت کردم گزارش 2016)و از K8s برای اجرای آن در تولید استفاده خواهد شد (بیشتر در مورد این در سال 2017).

تحویل در Kubernetes چگونه است؟

  • یک مخزن Git با کد و دستورالعمل های ساخت آن وجود دارد. این برنامه در یک تصویر داکر ساخته شده و در رجیستری داکر منتشر شده است.
  • همان مخزن همچنین حاوی دستورالعمل هایی در مورد نحوه استقرار و اجرای برنامه است. در مرحله استقرار، این دستورالعمل ها به Kubernetes ارسال می شود که تصویر مورد نظر را از رجیستری دریافت کرده و راه اندازی می کند.
  • به علاوه، معمولاً آزمایشاتی وجود دارد. برخی از این موارد را می توان هنگام انتشار یک تصویر انجام داد. همچنین می‌توانید (با پیروی از همان دستورالعمل‌ها) یک نسخه از برنامه (در یک فضای نام جداگانه K8s یا یک خوشه جداگانه) را مستقر کنید و آزمایش‌ها را در آنجا اجرا کنید.
  • در نهایت، شما به یک سیستم CI نیاز دارید که رویدادها را از Git (یا کلیک دکمه ها) دریافت کند و تمام مراحل تعیین شده را فراخوانی کند: ساخت، انتشار، استقرار، آزمایش.

werf - ابزار ما برای CI / CD در Kubernetes (نمایش کلی و گزارش تصویری)

در اینجا چند نکته مهم وجود دارد:

  1. زیرا ما زیرساخت تغییرناپذیری داریم (زیرساخت تغییرناپذیر)، تصویر برنامه ای که در تمام مراحل ( صحنه سازی، تولید و ...) استفاده می شود. باید یکی وجود داشته باشد. من در این مورد با جزئیات بیشتر و با مثال صحبت کردم. اینجا.
  2. زیرا ما زیرساخت را به عنوان رویکرد کد دنبال می کنیم (IaC)، کد برنامه، دستورالعمل مونتاژ و راه اندازی آن باید باشد دقیقا در یک مخزن. برای اطلاعات بیشتر در این مورد رجوع کنید به همان گزارش.
  3. زنجیره تحویل (تحویل) ما معمولاً آن را اینگونه می بینیم: برنامه مونتاژ شد، آزمایش شد، منتشر شد (مرحله انتشار) و تمام - تحویل انجام شده است. اما در واقعیت، کاربر آنچه را که شما عرضه کرده‌اید، دریافت می‌کند، هیچ سپس زمانی که شما آن را به تولید تحویل دادید، و زمانی که او توانست به آنجا برود و این تولید کار کرد. بنابراین من معتقدم که زنجیره تحویل به پایان می رسد فقط در مرحله عملیاتی (اجرا کن)، یا به طور دقیق تر، حتی در لحظه ای که کد از تولید حذف شد (جایگزین آن با یک کد جدید).

بیایید به طرح تحویل فوق در Kubernetes برگردیم: نه تنها توسط ما، بلکه به معنای واقعی کلمه توسط همه کسانی که با این مشکل سروکار داشتند اختراع شد. در واقع این الگو اکنون GitOps نامیده می شود (می توانید در مورد این اصطلاح و ایده های پشت آن بیشتر بخوانید اینجا). بیایید به مراحل طرح نگاه کنیم.

مرحله ساخت

به نظر می رسد می توانید در مورد ساخت تصاویر Docker در سال 2019 صحبت کنید، زمانی که همه می دانند چگونه Dockerfiles بنویسند و اجرا کنند. docker build?.. در اینجا نکات ظریفی وجود دارد که می خواهم به آنها توجه کنم:

  1. وزن تصویر مهم است، پس استفاده کنید چند مرحلهتنها برنامه‌ای را که واقعاً برای عملیات ضروری است در تصویر باقی بگذارید.
  2. تعداد لایه ها باید با ترکیب زنجیره ای از RUN- دستورات بر اساس معنی
  3. با این حال، این مشکلات را اضافه می کند اشکال زدایی، زیرا وقتی اسمبلی خراب می شود، باید دستور مناسب را از زنجیره ای که مشکل ایجاد کرده است پیدا کنید.
  4. سرعت مونتاژ مهم است زیرا می خواهیم به سرعت تغییرات را ارائه کنیم و نتایج را ببینیم. به عنوان مثال، شما نمی خواهید هر بار که یک برنامه را می سازید، وابستگی ها را در کتابخانه های زبان بازسازی کنید.
  5. اغلب از یک مخزن Git که نیاز دارید بسیاری از تصاویر، که می تواند توسط مجموعه ای از Dockerfiles (یا مراحل نامگذاری شده در یک فایل) و یک اسکریپت Bash با مونتاژ متوالی آنها حل شود.

این فقط نوک کوه یخی بود که همه با آن روبرو هستند. اما مشکلات دیگری نیز وجود دارد، به ویژه:

  1. اغلب در مرحله مونتاژ به چیزی نیاز داریم کوه (به عنوان مثال، نتیجه دستوری مانند apt را در یک دایرکتوری شخص ثالث کش کنید).
  2. ما میخواهیم غیر ممکن به جای نوشتن در پوسته
  3. ما میخواهیم ساخت بدون داکر (چرا به یک ماشین مجازی اضافی نیاز داریم که در آن باید همه چیز را برای این کار پیکربندی کنیم، در حالی که ما قبلاً یک خوشه Kubernetes داریم که می‌توانیم کانتینرها را در آن اجرا کنیم؟).
  4. مونتاژ موازی، که به روش های مختلف قابل درک است: دستورات مختلف از Dockerfile (در صورت استفاده از چند مرحله)، چندین commit از یک مخزن، چندین Dockerfiles.
  5. مونتاژ توزیع شده: می‌خواهیم چیزهایی را در غلاف‌هایی جمع‌آوری کنیم که «گذرا» هستند زیرا حافظه پنهان آنها ناپدید می شود، به این معنی که باید در جایی جداگانه ذخیره شود.
  6. بالاخره قله آرزوها را نام بردم خودکار: ایده آل است که به مخزن بروید، دستوری را تایپ کنید و یک تصویر آماده دریافت کنید، با درک درستی از نحوه و کارهایی که باید انجام دهید. با این حال، من شخصاً مطمئن نیستم که همه تفاوت های ظریف را می توان از این طریق پیش بینی کرد.

و این هم پروژه ها:

  • moby/buildkit - سازنده ای از Docker Inc (که قبلاً در نسخه های فعلی Docker ادغام شده است) که سعی در حل همه این مشکلات دارد.
  • کانیکو - سازنده ای از Google که به شما امکان می دهد بدون Docker بسازید.
  • Buildpacks.io - تلاش CNCF برای ایجاد جادوی خودکار و به ویژه یک راه حل جالب با rebase برای لایه ها.
  • و یک سری ابزارهای دیگر مانند ساختن, Genuinetools/IMG...

... و ببینید چند ستاره در GitHub دارند. یعنی از یک طرف docker build وجود دارد و می تواند کاری انجام دهد، اما در واقعیت موضوع به طور کامل حل نشده است - گواه این امر توسعه موازی کلکتورهای جایگزین است که هر کدام بخشی از مشکلات را حل می کند.

مونتاژ در ورف

پس رسیدیم ورف (قبلاً معروف مانند dapp) - یک ابزار منبع باز از شرکت Flant که ما سال هاست آن را ساخته ایم. همه چیز 5 سال پیش با اسکریپت های Bash شروع شد که مونتاژ Dockerfiles را بهینه کرد و در 3 سال گذشته توسعه کامل در چارچوب یک پروژه با مخزن Git خودش انجام شده است. (اول در روبی و سپس بازنویسی کرد به Go، و در همان زمان تغییر نام داد). چه مسائل مونتاژی در ورف حل می شود؟

werf - ابزار ما برای CI / CD در Kubernetes (نمایش کلی و گزارش تصویری)

مشکلاتی که با رنگ آبی رنگ آمیزی شده اند قبلاً اجرا شده اند، ساخت موازی در همان میزبان انجام شده است و مواردی که با رنگ زرد مشخص شده است برنامه ریزی شده است تا پایان تابستان تکمیل شود.

مرحله انتشار در ثبت (انتشار)

شماره گرفتیم docker push... - آپلود یک تصویر در رجیستری چه چیزی می تواند دشوار باشد؟ و سپس این سوال مطرح می شود: "چه برچسبی باید روی تصویر بگذارم؟" به دلیلی بوجود می آید که ما داریم گیت فلو (یا سایر استراتژی های Git) و Kubernetes، و صنعت در تلاش است اطمینان حاصل کند که آنچه در Kubernetes اتفاق می افتد از آنچه در Git اتفاق می افتد پیروی می کند. به هر حال، Git تنها منبع حقیقت ماست.

چه چیزی در این سخت است؟ اطمینان از تکرارپذیری: از یک commit در Git که ماهیت آن تغییر ناپذیر است (تغییر ناپذیر)، به یک تصویر Docker، که باید یکسان نگه داشته شود.

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

استراتژی های برچسب گذاری

اولی ساده است تگ git. ما یک رجیستری داریم که یک تصویر با عنوان برچسب گذاری شده است 1.0. Kubernetes دارای صحنه و تولید است که این تصویر در آن بارگذاری می شود. در Git ما commit می کنیم و در نقطه ای تگ می کنیم 2.0. ما آن را طبق دستورالعمل های مخزن جمع آوری می کنیم و با برچسب در رجیستری قرار می دهیم 2.0. ما آن را روی صحنه می‌آوریم و اگر همه چیز خوب بود، به تولید می‌رسیم.

werf - ابزار ما برای CI / CD در Kubernetes (نمایش کلی و گزارش تصویری)

مشکل این روش این است که ما ابتدا تگ را قرار دادیم، و تنها پس از آن تست کردیم و آن را رول کردیم. چرا؟ اولاً، این به سادگی غیرمنطقی است: ما نسخه‌ای از نرم‌افزار را صادر می‌کنیم که هنوز حتی آن را آزمایش نکرده‌ایم (غیر این‌صورت نمی‌توانیم انجام دهیم، زیرا برای بررسی، باید یک برچسب بگذاریم). ثانیاً این مسیر با Gitflow سازگار نیست.

گزینه دوم - git commit + تگ. شاخه اصلی یک تگ دارد 1.0; برای آن در رجیستری - یک تصویر مستقر برای تولید. علاوه بر این، خوشه Kubernetes دارای خطوط پیش نمایش و مرحله بندی است. در ادامه Gitflow را دنبال می کنیم: در شاخه اصلی برای توسعه (develop) ما ویژگی های جدیدی ایجاد می کنیم و در نتیجه یک commit با شناسه ایجاد می کنیم #c1. ما آن را جمع آوری کرده و با استفاده از این شناسه در رجیستری منتشر می کنیم (#c1). با همان شناسه برای پیش‌نمایش قرار می‌دهیم. ما همین کار را با commit ها انجام می دهیم #c2 и #c3.

وقتی متوجه شدیم که ویژگی های کافی وجود دارد، شروع به تثبیت همه چیز می کنیم. یک شعبه در Git ایجاد کنید release_1.1 (روی پایه #c3 از develop). نیازی به جمع آوری این نسخه نیست، زیرا ... این در مرحله قبل انجام شد. بنابراین، ما به سادگی می توانیم آن را به مرحله بندی برسانیم. ما اشکالات را برطرف می کنیم #c4 و به طور مشابه به مرحله اجرا در می آیند. در عین حال، توسعه در حال انجام است develop، جایی که تغییرات به صورت دوره ای از آن گرفته می شود release_1.1. در برخی موارد، ما یک commit را دریافت می کنیم که کامپایل و در استیجینگ آپلود می شود که از آن راضی هستیم (#c25).

سپس شاخه انتشار را (با فست فوروارد) ادغام می کنیم (release_1.1) در استاد. ما یک تگ با نسخه جدید روی این commit قرار دادیم (1.1). اما این تصویر قبلاً در رجیستری جمع آوری شده است، بنابراین برای اینکه دوباره آن را جمع آوری نکنید، به سادگی یک تگ دوم را به تصویر موجود اضافه می کنیم (اکنون دارای برچسب هایی در رجیستری است. #c25 и 1.1). پس از آن، آن را به تولید می رسانیم.

یک اشکال وجود دارد که فقط یک تصویر در مرحله بارگذاری می شود (#c25، و در تولید به نوعی متفاوت است (1.1)، اما می دانیم که از نظر فیزیکی، اینها همان تصویر از رجیستری هستند.

werf - ابزار ما برای CI / CD در Kubernetes (نمایش کلی و گزارش تصویری)

نقطه ضعف واقعی این است که هیچ پشتیبانی از commit های ادغام وجود ندارد، شما باید سریع به جلو انجام دهید.

ما می توانیم جلوتر برویم و یک ترفند انجام دهیم... بیایید به یک مثال از یک Dockerfile ساده نگاه کنیم:

FROM ruby:2.3 as assets
RUN mkdir -p /app
WORKDIR /app
COPY . ./
RUN gem install bundler && bundle install
RUN bundle exec rake assets:precompile
CMD bundle exec puma -C config/puma.rb

FROM nginx:alpine
COPY --from=assets /app/public /usr/share/nginx/www/public

بیایید طبق اصل زیر یک فایل از آن بسازیم:

  • SHA256 از شناسه های تصاویر استفاده شده (ruby:2.3 и nginx:alpine) که چک جمع محتویات آنها هستند.
  • همه تیم ها (RUN, CMD و غیره.)؛
  • SHA256 از فایل هایی که اضافه شد.

... را از چنین فایلی بگیرید (دوباره SHA256). این امضا هر چیزی که محتوای تصویر داکر را مشخص می کند.

werf - ابزار ما برای CI / CD در Kubernetes (نمایش کلی و گزارش تصویری)

بیایید به نمودار و به جای تعهد، از چنین امضاهایی استفاده خواهیم کرد، یعنی تصاویر را با امضا تگ کنید.

werf - ابزار ما برای CI / CD در Kubernetes (نمایش کلی و گزارش تصویری)

اکنون، زمانی که لازم است، برای مثال، ادغام تغییرات از نسخه به Master، می‌توانیم یک ادغام واقعی انجام دهیم: شناسه متفاوتی خواهد داشت، اما امضای یکسانی خواهد داشت. با همان شناسه تصویر را برای تولید قرار می دهیم.

نقطه ضعف این است که اکنون نمی توان تعیین کرد که چه نوع تعهدی برای تولید تحت فشار قرار گرفته است - چک جمع ها فقط در یک جهت کار می کنند. این مشکل با یک لایه اضافی با ابرداده حل می شود - بعداً بیشتر به شما خواهم گفت.

برچسب زدن در ورف

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

مخزن werf Git دستورالعمل های مخصوص ساخت را ذخیره می کند که مراحل مختلف ساخت را توصیف می کند (قبل از نصب, نصب, قبل از راه اندازی, برپایی). تصویر مرحله اول را با امضایی که به عنوان چک جمع مراحل اول تعریف شده است جمع آوری می کنیم. سپس کد منبع را اضافه می کنیم، برای تصویر مرحله جدید چک جمع آن را محاسبه می کنیم... این عملیات برای تمام مراحل تکرار می شود که در نتیجه مجموعه ای از تصاویر مرحله به دست می آید. سپس تصویر نهایی را می سازیم که حاوی متادیتا در مورد منشاء آن نیز می باشد. و این تصویر را به روش های مختلف تگ می کنیم (جزئیات بعدا).

werf - ابزار ما برای CI / CD در Kubernetes (نمایش کلی و گزارش تصویری)

فرض کنید بعد از این یک commit جدید ظاهر می شود که در آن فقط کد برنامه تغییر کرده است. چه اتفاقی خواهد افتاد؟ برای تغییرات کد، یک پچ ایجاد می شود و یک تصویر مرحله جدید آماده می شود. امضای آن به عنوان چک جمع تصویر مرحله قدیمی و پچ جدید تعیین خواهد شد. یک تصویر نهایی جدید از این تصویر تشکیل خواهد شد. رفتار مشابه با تغییرات در مراحل دیگر رخ خواهد داد.

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

werf - ابزار ما برای CI / CD در Kubernetes (نمایش کلی و گزارش تصویری)

پاک کردن رجیستری

ما در مورد حذف لایه هایی که پس از برچسب های حذف شده باقی مانده اند صحبت نمی کنیم - این یک ویژگی استاندارد خود Docker Registry است. ما در مورد وضعیتی صحبت می کنیم که تگ های Docker زیادی جمع می شوند و می فهمیم که دیگر به برخی از آنها نیاز نداریم، اما آنها فضا را اشغال می کنند (و/یا ما هزینه آن را پرداخت می کنیم).

راهکارهای نظافت چیست؟

  1. شما فقط نمی توانید هیچ کاری انجام دهید تمیز نکن. گاهی اوقات پرداخت اندکی برای فضای اضافی واقعا آسان تر از باز کردن یک درهم تنیده بزرگ از برچسب ها است. اما این فقط تا یک نقطه خاص کار می کند.
  2. ریست کامل. اگر تمام تصاویر را حذف کنید و فقط تصاویر فعلی را در سیستم CI دوباره بسازید، ممکن است مشکلی ایجاد شود. اگر ظرف در مرحله تولید مجدد راه اندازی شود، یک تصویر جدید برای آن بارگذاری می شود - تصویری که هنوز توسط کسی آزمایش نشده است. این ایده زیرساخت های تغییرناپذیر را از بین می برد.
  3. سبز آبی. یک رجیستری شروع به سرریز شدن کرد - ما تصاویر را در دیگری آپلود می کنیم. همان مشکل روش قبلی: در چه مرحله ای می توانید رجیستری را که سرریز شده است پاک کنید؟
  4. به وقت. همه تصاویر قدیمی تر از 1 ماه حذف شوند؟ اما قطعا سرویسی وجود خواهد داشت که یک ماه است به روز نشده است...
  5. دستی تعیین کنید چه چیزی را می توان از قبل حذف کرد.

دو گزینه واقعا قابل اجرا وجود دارد: تمیز نکنید یا ترکیبی از آبی-سبز + به صورت دستی. در مورد دوم، ما در مورد موارد زیر صحبت می کنیم: وقتی متوجه شدید که زمان پاک کردن رجیستری فرا رسیده است، یک رجیستری جدید ایجاد می کنید و تمام تصاویر جدید را در طول یک ماه، به عنوان مثال، به آن اضافه می کنید. و بعد از یک ماه، ببینید کدام پادها در Kubernetes هنوز از رجیستری قدیمی استفاده می کنند و آنها را نیز به رجیستری جدید منتقل کنید.

به چی رسیدیم ورف? ما جمع آوری می کنیم:

  1. Git head: همه تگ‌ها، همه شاخه‌ها - با فرض اینکه به هر چیزی که در Git در تصاویر برچسب گذاری شده است نیاز داریم (و اگر نه، باید آن را در خود Git حذف کنیم).
  2. همه غلاف هایی که در حال حاضر به Kubernetes پمپ می شوند.
  3. ReplicaSets قدیمی (چیزی که اخیراً منتشر شده است)، و همچنین قصد داریم نسخه‌های Helm را اسکن کنیم و آخرین تصاویر را در آنجا انتخاب کنیم.

... و از این مجموعه یک لیست سفید تهیه کنید - لیستی از تصاویری که ما آنها را حذف نمی کنیم. ما همه چیز را پاک می کنیم، پس از آن تصاویر صحنه یتیم را پیدا می کنیم و آنها را نیز حذف می کنیم.

مرحله استقرار

اعلامی بودن قابل اعتماد

اولین نکته ای که می خواهم در استقرار به آن توجه کنم، عرضه پیکربندی منابع به روز شده است که به صورت اعلامی اعلام شده است. سند اصلی YAML که منابع Kubernetes را توصیف می کند، همیشه با نتیجه ای که در خوشه اجرا می شود بسیار متفاوت است. زیرا Kubernetes به پیکربندی اضافه می کند:

  1. شناسه ها؛
  2. اطلاعات خدمات؛
  3. بسیاری از مقادیر پیش فرض؛
  4. بخش با وضعیت فعلی؛
  5. تغییرات ایجاد شده به عنوان بخشی از وب هوک پذیرش؛
  6. نتیجه کار کنترلرهای مختلف (و زمانبندی) است.

بنابراین، هنگامی که یک پیکربندی منبع جدید ظاهر می شود (جدید، ما نمی توانیم پیکربندی فعلی، "live" را فقط با آن بگیریم و بازنویسی کنیم (زنده). برای این کار باید مقایسه کنیم جدید با آخرین پیکربندی اعمال شده (آخرین اعمال شده) و رول کنید زنده پچ دریافت کرد

این رویکرد نامیده می شود ادغام دو طرفه. برای مثال در Helm استفاده می شود.

نیز وجود دارد ادغام دو طرفه، که در این تفاوت دارد:

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

ما بیش از 1000 برنامه را با Helm مستقر می کنیم، بنابراین در واقع با ادغام دو طرفه زندگی می کنیم. با این حال، یک سری مشکلات دارد که ما با پچ های خود حل کرده ایم، که به Helm کمک می کند تا به طور عادی کار کند.

وضعیت عرضه واقعی

پس از اینکه سیستم CI ما یک پیکربندی جدید برای Kubernetes بر اساس رویداد بعدی ایجاد کرد، آن را برای استفاده ارسال می کند. (درخواست دادن) به یک خوشه - با استفاده از Helm یا kubectl apply. سپس، ادغام N-way که قبلاً توضیح داده شد رخ می دهد، که API Kubernetes به سیستم CI و به کاربر آن پاسخ تأیید می دهد.

werf - ابزار ما برای CI / CD در Kubernetes (نمایش کلی و گزارش تصویری)

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

برای انجام درست همه چیز، این طرح به یک پیوند اضافی نیاز دارد - یک ردیاب ویژه که اطلاعات وضعیت را از API Kubernetes دریافت می کند و آن را برای تجزیه و تحلیل بیشتر وضعیت واقعی اشیا منتقل می کند. ما یک کتابخانه منبع باز در Go ایجاد کردیم - سگ مکعبی (به اطلاعیه آن مراجعه کنید اینجا)، که این مشکل را حل می کند و در werf تعبیه شده است.

رفتار این ردیاب در سطح werf با استفاده از حاشیه نویسی که در Deployments یا StatefulSets قرار می گیرد پیکربندی می شود. حاشیه نویسی اصلی - fail-mode - معانی زیر را درک می کند:

  • IgnoreAndContinueDeployProcess - ما مشکلات راه اندازی این جزء را نادیده می گیریم و به استقرار ادامه می دهیم.
  • FailWholeDeployProcessImmediately - یک خطا در این مؤلفه فرآیند استقرار را متوقف می کند.
  • HopeUntilEndOfDeployProcess - ما امیدواریم که این جزء تا پایان استقرار کار کند.

به عنوان مثال، این ترکیب از منابع و مقادیر حاشیه نویسی fail-mode:

werf - ابزار ما برای CI / CD در Kubernetes (نمایش کلی و گزارش تصویری)

وقتی برای اولین بار استقرار می کنیم، ممکن است پایگاه داده (MongoDB) هنوز آماده نباشد - استقرارها با شکست مواجه خواهند شد. اما می توانید منتظر بمانید تا لحظه ای شروع شود و استقرار همچنان انجام خواهد شد.

دو حاشیه نویسی دیگر برای kubedog در werf وجود دارد:

  • failures-allowed-per-replica - تعداد سقوط های مجاز برای هر ماکت؛
  • show-logs-until - لحظه ای را تنظیم می کند که تا زمانی که werf (در stdout) لاگ ها را از همه غلاف های باز شده نشان می دهد. پیش فرض است PodIsReady (برای نادیده گرفتن پیام‌هایی که احتمالاً نمی‌خواهیم وقتی ترافیک به پاد می‌رسد)، اما مقادیر نیز معتبر هستند: ControllerIsReady и EndOfDeploy.

چه چیز دیگری از استقرار می خواهیم؟

علاوه بر دو نکته ای که قبلاً توضیح داده شد، ما می خواهیم:

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

نمایش نتایج: از

برای ما به عنوان یک شرکت، برای پیاده سازی تمام تفاوت های ظریف توصیف شده در مراحل مختلف تحویل (ساخت، انتشار، استقرار)، یک سیستم CI و ابزار کافی است. ورف.

به جای نتیجه گیری:

werf - ابزار ما برای CI / CD در Kubernetes (نمایش کلی و گزارش تصویری)

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

فیلم ها و اسلایدها

ویدئویی از اجرا (47 دقیقه):

ارائه گزارش:

PS

گزارش های دیگر در مورد Kubernetes در وبلاگ ما:

منبع: www.habr.com

اضافه کردن نظر