برچسب‌گذاری مبتنی بر محتوا در سازنده werf: چرا و چگونه کار می‌کند؟

برچسب‌گذاری مبتنی بر محتوا در سازنده werf: چرا و چگونه کار می‌کند؟

ورف ابزار منبع باز GitOps CLI ما برای ساخت و ارائه برنامه ها به Kubernetes است. که در انتشار نسخه 1.1 یک ویژگی جدید در جمع آوری تصاویر معرفی شد: برچسب گذاری تصاویر بر اساس محتوا یا برچسب گذاری مبتنی بر محتوا. تا به حال، طرح برچسب‌گذاری معمولی در werf شامل برچسب‌گذاری تصاویر Docker توسط تگ Git، شاخه Git یا Git commit بود. اما همه این طرح ها دارای معایبی هستند که با استراتژی جدید برچسب گذاری کاملاً برطرف می شوند. جزئیات در مورد آن و اینکه چرا آنقدر خوب است در زیر برش است.

ارائه مجموعه ای از میکروسرویس ها از یک مخزن Git

هنگامی که یک برنامه کاربردی به بسیاری از سرویس های کم و بیش مستقل تقسیم می شود، اغلب موقعیتی رخ می دهد. انتشار این سرویس ها می تواند به طور مستقل رخ دهد: یک یا چند سرویس می توانند در یک زمان منتشر شوند، در حالی که بقیه باید بدون هیچ تغییری به کار خود ادامه دهند. اما از نظر ذخیره کد و مدیریت پروژه، نگهداری چنین سرویس های کاربردی در یک مخزن راحت تر است.

شرایطی وجود دارد که خدمات واقعاً مستقل هستند و با یک برنامه منفرد مرتبط نیستند. در این صورت آنها در پروژه های جداگانه قرار می گیرند و انتشار آنها از طریق فرآیندهای جداگانه CI/CD در هر یک از پروژه ها انجام می شود.

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

برچسب گذاری توسط شاخه Git و تگ Git

بیایید بگوییم که رایج ترین استراتژی برچسب گذاری استفاده می شود - برچسب یا شاخه. برای شاخه های Git، تصاویر با نام شعبه برچسب گذاری می شوند، برای یک شاخه در هر زمان تنها یک تصویر منتشر شده با نام آن شاخه وجود دارد. برای تگ های Git، تصاویر با توجه به نام تگ برچسب گذاری می شوند.

هنگامی که یک تگ Git جدید ایجاد می شود - به عنوان مثال، هنگامی که یک نسخه جدید منتشر می شود - یک تگ Docker جدید برای همه تصاویر پروژه در رجیستری Docker ایجاد می شود:

  • myregistry.org/myproject/frontend:v1.1.10
  • myregistry.org/myproject/myservice1:v1.1.10
  • myregistry.org/myproject/myservice2:v1.1.10
  • myregistry.org/myproject/myservice3:v1.1.10
  • myregistry.org/myproject/myservice4:v1.1.10
  • myregistry.org/myproject/myservice5:v1.1.10
  • myregistry.org/myproject/database:v1.1.10

این نام‌های جدید تصاویر از طریق الگوهای Helm به پیکربندی Kubernetes منتقل می‌شوند. هنگام شروع استقرار با دستور werf deploy فیلد در حال به روز رسانی است image در منبع Kubernetes به دلیل تغییر نام تصویر، منابع مربوطه را آشکار می کند و دوباره راه اندازی می کند.

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

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

برچسب گذاری توسط Git commit

werf همچنین دارای یک استراتژی برچسب گذاری مرتبط با commit های Git است.

Git-commit یک شناسه برای محتویات یک مخزن Git است و به تاریخچه ویرایش فایل ها در مخزن Git بستگی دارد، بنابراین منطقی به نظر می رسد که از آن برای برچسب گذاری تصاویر در Docker Registry استفاده کنید.

با این حال، برچسب‌گذاری توسط Git commit همان مضرات برچسب‌گذاری توسط شاخه‌های Git یا تگ‌های Git را دارد:

  • یک commit خالی می تواند ایجاد شود که هیچ فایلی را تغییر نمی دهد، اما تگ Docker تصویر تغییر می کند.
  • می‌توان یک commit ادغام ایجاد کرد که فایل‌ها را تغییر ندهد، اما تگ Docker تصویر تغییر خواهد کرد.
  • می‌توان یک commit ایجاد کرد که فایل‌هایی را در Git که به تصویر وارد نشده‌اند تغییر دهد و تگ Docker تصویر دوباره تغییر کند.

برچسب زدن نام شاخه Git نسخه تصویر را منعکس نمی کند

مشکل دیگری در رابطه با استراتژی برچسب گذاری برای شاخه های Git وجود دارد.

برچسب گذاری بر اساس نام شعبه تا زمانی کار می کند که تعهدات آن شاخه به ترتیب به ترتیب زمانی جمع آوری شوند.

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

علاوه بر این، با فشارهای پی در پی به یک شاخه با فاصله زمانی کوتاه بین آنها، commit قدیمی ممکن است دیرتر از جدیدتر کامپایل شود: نسخه قدیمی تصویر با استفاده از تگ شاخه Git، نسخه جدید را بازنویسی می کند. چنین مشکلاتی را می توان با یک سیستم CI/CD حل کرد (به عنوان مثال، در GitLab CI خط لوله دومی برای یک سری commit راه اندازی می شود). با این حال، همه سیستم ها از این پشتیبانی نمی کنند و باید راه مطمئن تری برای جلوگیری از چنین مشکل اساسی وجود داشته باشد.

تگ گذاری مبتنی بر محتوا چیست؟

بنابراین، برچسب‌گذاری مبتنی بر محتوا چیست - برچسب‌گذاری تصاویر بر اساس محتوا.

برای ایجاد تگ های Docker، از Git اولیه (شاخه Git، تگ Git...) استفاده نمی شود، بلکه یک چک جمع مرتبط با:

  • محتویات تصویر. تگ ID تصویر محتوای آن را منعکس می کند. هنگام ساخت یک نسخه جدید، اگر فایل های موجود در تصویر تغییر نکرده باشند، این شناسه تغییر نخواهد کرد.
  • تاریخچه ایجاد این تصویر در Git. تصاویر مرتبط با شاخه های مختلف Git و تاریخچه ساخت متفاوت از طریق werf دارای برچسب های ID متفاوتی خواهند بود.

چنین برچسب شناسه ای به اصطلاح است امضای مرحله تصویر.

هر تصویر شامل مجموعه ای از مراحل است: from, before-install, git-archive, install, imports-after-install, before-setup، ... git-latest-patch و غیره. هر مرحله دارای یک شناسه است که محتوای آن را منعکس می کند امضای صحنه (امضای صحنه).

تصویر نهایی متشکل از این مراحل با به اصطلاح امضای مجموعه این مراحل تگ شده است - امضای مراحل، - که برای تمام مراحل تصویر تعمیم می یابد.

برای هر تصویر از پیکربندی werf.yaml در حالت کلی، امضای خود و بر این اساس، یک تگ Docker وجود خواهد داشت.

امضای مرحله تمام این مشکلات را حل می کند:

  • مقاوم در برابر تعهدات خالی Git.
  • Resistant to Git فایل‌هایی را تغییر می‌دهد که مرتبط با تصویر نیستند.
  • هنگام راه‌اندازی مجدد بیلدها برای commit‌های Git قدیمی یک شاخه، به مشکل بازنگری نسخه فعلی تصویر منجر نمی‌شود.

اکنون این استراتژی برچسب‌گذاری توصیه شده است و پیش‌فرض در werf برای همه سیستم‌های CI است.

نحوه فعال کردن و استفاده در werf

دستور اکنون یک گزینه مربوطه دارد werf publish: --tag-by-stages-signature=true|false

در یک سیستم CI، استراتژی برچسب گذاری با دستور مشخص می شود werf ci-env. قبلاً پارامتر برای آن تعریف شده بود werf ci-env --tagging-strategy=tag-or-branch. حالا اگر مشخص کنید werf ci-env --tagging-strategy=stages-signature یا این گزینه را مشخص نکنید، werf به طور پیش فرض از استراتژی برچسب گذاری استفاده می کند stages-signature. تیم werf ci-env به طور خودکار پرچم های لازم را برای دستور تنظیم می کند werf build-and-publish (یا werf publish، بنابراین نیازی به تعیین گزینه های اضافی برای این دستورات نیست.

برای مثال دستور:

werf publish --stages-storage :local --images-repo registry.hello.com/web/core/system --tag-by-stages-signature

... می تواند تصاویر زیر را ایجاد کند:

  • registry.hello.com/web/core/system/backend:4ef339f84ca22247f01fb335bb19f46c4434014d8daa3d5d6f0e386d
  • registry.hello.com/web/core/system/frontend:f44206457e0a4c8a54655543f749799d10a9fe945896dab1c16996c6

اینجا 4ef339f84ca22247f01fb335bb19f46c4434014d8daa3d5d6f0e386d امضای مراحل تصویر است backendو f44206457e0a4c8a54655543f749799d10a9fe945896dab1c16996c6 - امضای مراحل تصویر frontend.

هنگام استفاده از توابع خاص werf_container_image и werf_container_env نیازی به تغییر چیزی در الگوهای Helm وجود ندارد: این توابع به طور خودکار نام تصاویر صحیح را تولید می کنند.

پیکربندی مثال در یک سیستم CI:

type multiwerf && source <(multiwerf use 1.1 beta)
type werf && source <(werf ci-env gitlab)
werf build-and-publish|deploy

اطلاعات بیشتر در مورد پیکربندی در اسناد موجود است:

در کل

  • گزینه جدید werf publish --tag-by-stages-signature=true|false.
  • مقدار گزینه جدید werf ci-env --tagging-strategy=stages-signature|tag-or-branch (اگر مشخص نشده باشد، پیش فرض خواهد بود stages-signature).
  • اگر قبلاً از گزینه های برچسب گذاری برای Git commits استفاده کرده اید (WERF_TAG_GIT_COMMIT یا گزینه werf publish --tag-git-commit COMMIT، سپس مطمئن شوید که به استراتژی برچسب گذاری بروید مراحل - امضا.
  • بهتر است بلافاصله پروژه های جدید را به طرح برچسب گذاری جدید تغییر دهید.
  • هنگام انتقال به werf 1.1، توصیه می شود پروژه های قدیمی را به طرح برچسب گذاری جدید تغییر دهید، اما قدیمی برچسب یا شاخه هنوز پشتیبانی می شود.

برچسب‌گذاری مبتنی بر محتوا تمام مشکلاتی را که در مقاله مطرح شده است حل می‌کند:

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

استفاده کن! و فراموش نکنید که به ما سر بزنید GitHubبرای ایجاد یک مشکل یا پیدا کردن یک مورد موجود، اضافه کردن یک نکته مثبت، ایجاد روابط عمومی یا به سادگی توسعه پروژه را تماشا کنید.

PS

در وبلاگ ما نیز بخوانید:

منبع: www.habr.com

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