ProHoster > وبلاگ > اداره > ادغام 3 طرفه به werf: استقرار به Kubernetes با Helm "روی استروئیدها"
ادغام 3 طرفه به werf: استقرار به Kubernetes با Helm "روی استروئیدها"
چیزی که ما (و نه تنها ما) مدتها منتظرش بودیم اتفاق افتاد: ورف، ابزار منبع باز ما برای ساخت برنامه ها و تحویل آنها به Kubernetes، اکنون از اعمال تغییرات با استفاده از وصله های ادغام سه طرفه پشتیبانی می کند! علاوه بر این، میتوان منابع K3s موجود را در نسخههای Helm بدون بازسازی این منابع به کار برد.
اگر خیلی کوتاه است، پس می گذاریم WERF_THREE_WAY_MERGE=enabled - ما استقرار "مانند kubectl apply"، سازگار با نصب های موجود Helm 2 و حتی کمی بیشتر.
اما بیایید با این تئوری شروع کنیم: وصلههای ادغام سهطرفه دقیقاً چه هستند، مردم چگونه رویکرد تولید آنها را پیدا کردند و چرا در فرآیندهای CI/CD با زیرساختهای مبتنی بر Kubernetes مهم هستند؟ و بعد از آن، بیایید ببینیم که 3-way merge در werf چیست، چه حالت هایی به طور پیش فرض استفاده می شود و چگونه آن را مدیریت کنیم.
پچ ادغام سه طرفه چیست؟
بنابراین، بیایید با وظیفه باز کردن منابع توصیف شده در مانیفست YAML در Kubernetes شروع کنیم.
برای کار با منابع، Kubernetes API عملیات اساسی زیر را ارائه می دهد: ایجاد، وصله، جایگزینی و حذف. فرض بر این است که با کمک آنها لازم است یک توزیع مداوم مناسب از منابع به خوشه ایجاد شود. چگونه؟
دستورات ضروری kubectl
اولین رویکرد برای مدیریت اشیاء در Kubernetes استفاده از دستورات ضروری kubectl برای ایجاد، اصلاح و حذف آن اشیا است. به زبان ساده:
تیم kubectl run می توانید Deployment یا Job را اجرا کنید:
kubectl run --generator=deployment/apps.v1 DEPLOYMENT_NAME --image=IMAGE
تیم kubectl scale - تغییر تعداد کپی ها:
kubectl scale --replicas=3 deployment/mysql
غیره
این رویکرد ممکن است در نگاه اول راحت به نظر برسد. با این حال مشکلاتی وجود دارد:
سخت است خودکار کردن.
مانند منعکس کننده پیکربندی در گیت؟ چگونه تغییرات رخ داده در خوشه را بررسی کنیم؟
نحوه ارائه تکرارپذیری تنظیمات در راه اندازی مجدد؟
...
واضح است که این رویکرد با ذخیره سازی برنامه و زیرساخت به عنوان کد (IaC؛ یا حتی) مناسب نیست GitOps به عنوان یک گزینه مدرن تر، که در اکوسیستم Kubernetes محبوبیت پیدا می کند). بنابراین، این دستورات توسعه بیشتری در kubectl دریافت نکردند.
ایجاد، دریافت، جایگزینی و حذف عملیات
با اولیه ایجاد ساده است: مانیفست را به عملیات ارسال کنید create kube api و منبع ایجاد شده است. نمایش YAML مانیفست را می توان در Git ذخیره کرد و با استفاده از دستور ایجاد کرد kubectl create -f manifest.yaml.
С برداشتن هم ساده: همان را جایگزین کنید manifest.yaml از Git به تیم kubectl delete -f manifest.yaml.
عمل replace به شما امکان می دهد بدون ایجاد مجدد منبع، پیکربندی منبع را با یک پیکربندی جدید جایگزین کنید. این بدان معنی است که قبل از ایجاد تغییر در یک منبع، منطقی است که نسخه فعلی را با عملیات پرس و جو کنید get، آن را تغییر دهید و با عملیات آپدیت کنید replace. apiserver kube تعبیه شده است قفل خوش بینانه و اگر بعد از جراحی get شی تغییر کرده است، سپس عملیات replace نمی گذرد
برای ذخیره پیکربندی در Git و به روز رسانی آن با استفاده از جایگزین، باید عملیات را انجام دهید get، پیکربندی Git را با آنچه دریافت کردیم ادغام کرده و اجرا کنید replace. به طور پیش فرض، kubectl فقط به شما اجازه استفاده از دستور را می دهد kubectl replace -f manifest.yamlجایی که manifest.yaml - یک مانیفست کاملاً آماده (در مورد ما ادغام شده) که باید نصب شود. معلوم می شود که کاربر نیاز به پیاده سازی مانیفست های ادغام دارد و این یک موضوع بی اهمیت نیست...
همچنین شایان ذکر است که اگرچه manifest.yaml و در Git ذخیره می شود، نمی توانیم از قبل بدانیم که آیا ایجاد یک شی یا به روز رسانی آن ضروری است - این باید توسط نرم افزار کاربر انجام شود.
مجموع: آیا می توانیم یک عرضه مداوم ایجاد کنیم فقط با استفاده از ایجاد، جایگزینی و حذف، مطمئن شوید که پیکربندی زیرساخت به همراه کد و CI/CD مناسب در Git ذخیره می شود؟
در اصل ما می توانیم ... برای این شما باید عملیات ادغام را پیاده سازی کنید اعلامیه ها و نوعی الزام آور که:
وجود یک شی را در خوشه بررسی می کند،
ایجاد منابع اولیه را انجام می دهد،
آن را به روز می کند یا حذف می کند.
هنگام به روز رسانی، لطفاً به این نکته توجه داشته باشید ممکن است منبع تغییر کرده باشد از دفعه آخر get و به طور خودکار قفل خوش بینانه را مدیریت می کند - تلاش های مکرر به روز رسانی انجام دهید.
با این حال، چرا زمانی که kube-apiserver راه دیگری برای به روز رسانی منابع ارائه می دهد، چرخ را دوباره اختراع کنیم: عملیات patch، که کاربر را از برخی از مشکلات توصیف شده رها می کند؟
وصله
حالا به پچ ها می رسیم.
وصله ها روش اصلی اعمال تغییرات در اشیاء موجود در Kubernetes هستند. عمل patch اینگونه عمل می کند:
کاربر kube-apiserver باید یک پچ به فرم JSON ارسال کند و شی را مشخص کند،
و خود apiserver با وضعیت فعلی شی برخورد می کند و آن را به شکل مورد نیاز می آورد.
قفل خوش بینانه در این مورد مورد نیاز نیست. این عملیات بیشتر از اینکه جایگزین شود، توضیحی است، اگرچه در ابتدا ممکن است برعکس به نظر برسد.
به این ترتیب:
با استفاده از یک عملیات create ما یک شی مطابق با مانیفست از Git ایجاد می کنیم،
با کمک delete - حذف اگر شی دیگر مورد نیاز نیست،
با کمک patch - ما شی را تغییر می دهیم و آن را به شکل توصیف شده در Git می آوریم.
با این حال، برای انجام این کار، باید ایجاد کنید پچ صحیح!
نحوه کار وصله ها در Helm 2: 2-way-merge
هنگامی که برای اولین بار نسخه ای را نصب می کنید، Helm این عملیات را انجام می دهد create برای منابع نمودار
هنگام بهروزرسانی نسخه Helm برای هر منبع:
وصله بین نسخه منبع از نمودار قبلی و نسخه نمودار فعلی را در نظر می گیرد،
این پچ را اعمال می کند.
ما این پچ را می نامیم پچ ادغام دو طرفه، زیرا در ایجاد آن 2 مانیفست دخیل است:
مانیفست منبع از نسخه قبلی،
نمایه منبع از منبع فعلی
هنگام برداشتن عملیات delete در kube apiserver برای منابعی فراخوانی می شود که در نسخه قبلی اعلام شده بودند، اما در نسخه فعلی اعلام نشده بودند.
رویکرد وصله ادغام دو طرفه یک مشکل دارد: منجر به با وضعیت واقعی منبع در خوشه و مانیفست در Git هماهنگ نیست.
تشریح مسئله با مثال
در Git، نمودار یک مانیفست را که در آن فیلد است ذخیره می کند image استقرار مهم است ubuntu:18.04.
کاربر از طریق kubectl edit مقدار این فیلد را به ubuntu:19.04.
هنگام استقرار مجدد نمودار Helm پچ تولید نمی کند، زیرا میدان image در نسخه قبلی نسخه و در نمودار فعلی یکسان هستند.
پس از استقرار مجدد image باقی ubuntu:19.04، اگرچه نمودار می گوید ubuntu:18.04.
ما همگامزدایی شدیم و قابلیت اعلامی را از دست دادیم.
منبع همگام چیست؟
به طور کلی پر از به دست آوردن تطابق بین مانیفست منبع در یک خوشه در حال اجرا و مانیفست از Git غیرممکن است. زیرا در یک مانیفست واقعی ممکن است یادداشتها/برچسبهای سرویس، ظروف اضافی و سایر دادهها وجود داشته باشد که توسط برخی کنترلکنندهها به صورت پویا از منبع اضافه و حذف میشوند. ما نمی توانیم و نمی خواهیم این داده ها را در Git نگه داریم. با این حال، ما میخواهیم فیلدهایی را که به صراحت در Git مشخص کردهایم، پس از عرضه، مقادیر مناسب را دریافت کنند.
خیلی کلی معلوم میشه قانون منابع همگام: هنگام انتشار یک منبع، میتوانید فقط آن قسمتهایی را که به صراحت در مانیفست از Git مشخص شدهاند (یا در نسخه قبلی مشخص شدهاند و اکنون حذف شدهاند) تغییر یا حذف کنید.
پچ ادغام دو طرفه
ایده اصلی پچ ادغام دو طرفه: با در نظر گرفتن نسخه فعلی مانیفست از خوشه در حال اجرا، یک وصله بین آخرین نسخه اعمال شده مانیفست از Git و نسخه هدف مانیفست از Git ایجاد کنید. پچ به دست آمده باید با قانون منابع همگام سازی شده مطابقت داشته باشد:
فیلدهای جدید اضافه شده به نسخه هدف با استفاده از یک پچ اضافه می شوند.
فیلدهای قبلی موجود در آخرین نسخه اعمال شده و موجود در نسخه هدف با استفاده از یک پچ بازنشانی می شوند.
فیلدهای موجود در نسخه فعلی شی که با نسخه هدف مانیفست متفاوت است با استفاده از وصله به روز می شوند.
بر اساس این اصل است که وصله ایجاد می کند kubectl apply:
آخرین نسخه اعمال شده مانیفست در حاشیه نویسی خود شی ذخیره می شود،
هدف - از فایل YAML مشخص شده گرفته شده است،
مورد فعلی از یک خوشه در حال اجرا است.
اکنون که تئوری را مرتب کردیم، زمان آن رسیده است که به شما بگوییم در werf چه کردیم.
اعمال تغییرات در werf
قبلاً، werf مانند Helm 2 از وصله های ادغام دو طرفه استفاده می کرد.
پچ تعمیر
به منظور تغییر به نوع جدیدی از وصله ها - 3-way-merge - اولین مرحله ما به اصطلاح وصله های تعمیر.
هنگام استقرار، از یک وصله ادغام دو طرفه استاندارد استفاده میشود، اما werf علاوه بر این، وصلهای ایجاد میکند که وضعیت واقعی منبع را با آنچه در Git نوشته شده است همگامسازی میکند (چنین وصلهای با استفاده از همان قانون منابع همگامسازی شده که در بالا توضیح داده شد ایجاد میشود) .
اگر همگامزدایی اتفاق بیفتد، در پایان استقرار، کاربر یک هشدار با یک پیام مربوطه و یک وصله دریافت میکند که باید برای آوردن منبع به یک فرم همگامسازی شده اعمال شود. این پچ نیز در حاشیه نویسی ویژه ثبت شده است werf.io/repair-patch. فرض بر این است که دست های کاربر خود این پچ را اعمال خواهد کرد: werf به هیچ وجه آن را اعمال نخواهد کرد.
ایجاد وصلههای تعمیری یک اقدام موقتی است که به شما امکان میدهد واقعاً ایجاد وصلهها را بر اساس اصل ادغام سهطرفه آزمایش کنید، اما این وصلهها را بهطور خودکار اعمال نکنید. در حال حاضر، این حالت عملکرد به طور پیش فرض فعال است.
وصله ادغام سه طرفه فقط برای نسخه های جدید
از اول دسامبر 1، نسخههای بتا و آلفا werf آغاز میشود به طور پیش فرض برای اعمال تغییرات فقط در نسخههای جدید Helm که از طریق werf منتشر شدهاند، از وصلههای ادغام سهطرفه کامل استفاده کنید. نسخههای موجود همچنان از رویکرد ادغام دو طرفه + وصلههای تعمیر استفاده میکنند.
این حالت عملیاتی را می توان به صراحت با تنظیم فعال کرد WERF_THREE_WAY_MERGE_MODE=onlyNewReleases اکنون.
از 15 دسامبر 2019، نسخههای بتا و آلفای werf بهطور پیشفرض از وصلههای ادغام سهطرفه کامل برای اعمال تغییرات در همه نسخهها استفاده میکنند.
این حالت عملیاتی را می توان به صراحت با تنظیم فعال کرد WERF_THREE_WAY_MERGE_MODE=enabled اکنون.
با مقیاس خودکار منابع چه کنیم؟
2 نوع مقیاس خودکار در Kubernetes وجود دارد: HPA (افقی) و VPA (عمودی).
افقی به طور خودکار تعداد کپی ها، عمودی - تعداد منابع را انتخاب می کند. هم تعداد کپی ها و هم منابع مورد نیاز در مانیفست منبع مشخص شده است (به مانیفست منبع مراجعه کنید). spec.replicas یا spec.containers[].resources.limits.cpu, spec.containers[].resources.limits.memory и دیگران).
مشکل: اگر کاربر یک منبع را در نمودار پیکربندی کند تا مقادیر خاصی را برای منابع مشخص کند یا کپیها و مقیاسکنندههای خودکار برای این منبع فعال شوند، با هر استقرار werf این مقادیر را به آنچه در مانیفست نمودار نوشته شده بازنشانی میکند. .
دو راه حل برای مشکل وجود دارد. برای شروع، بهتر است از تعیین صریح مقادیر خودکار در مانیفست نمودار خودداری کنید. اگر این گزینه به دلایلی مناسب نیست (به عنوان مثال، به دلیل اینکه تنظیم محدودیت های منابع اولیه و تعداد تکرارها در نمودار راحت است)، سپس werf حاشیه نویسی های زیر را ارائه می دهد:
werf.io/set-replicas-only-on-creation=true
werf.io/set-resources-only-on-creation=true
اگر چنین حاشیهنویسی وجود داشته باشد، werf مقادیر مربوطه را در هر استقرار بازنشانی نمیکند، بلکه آنها را تنها زمانی تنظیم میکند که منبع در ابتدا ایجاد شود.
برای جزئیات بیشتر، به مستندات پروژه مراجعه کنید HPA и VPA.
استفاده از وصله ادغام سه طرفه را ممنوع کنید
کاربر در حال حاضر می تواند استفاده از وصله های جدید در werf را با استفاده از یک متغیر محیطی ممنوع کند WERF_THREE_WAY_MERGE_MODE=disabled. با این حال، شروع از 1 مارس 2020، این ممنوعیت دیگر اعمال نخواهد شد. و فقط استفاده از وصله های ادغام 3 طرفه امکان پذیر خواهد بود.
پذیرش منابع در ورف
تسلط بر روش اعمال تغییرات با وصلههای ادغام سهطرفه به ما این امکان را میدهد که فوراً ویژگیهایی مانند استفاده از منابع موجود در خوشه را در نسخه Helm پیادهسازی کنیم.
Helm 2 یک مشکل دارد: شما نمی توانید منبعی را به مانیفست های نمودار اضافه کنید که از قبل در خوشه وجود دارد بدون اینکه این منبع را از ابتدا ایجاد کنید (نگاه کنید به. #6031, #3275). ما به werf آموزش دادیم که منابع موجود را برای انتشار بپذیرد. برای انجام این کار، باید یک حاشیه نویسی را روی نسخه فعلی منبع از خوشه در حال اجرا نصب کنید (به عنوان مثال، با استفاده از kubectl edit):
"werf.io/allow-adoption-by-release": RELEASE_NAME
اکنون منبع باید در نمودار توضیح داده شود و دفعه بعد که werf نسخه ای با نام مناسب را اجرا می کند، منبع موجود در این نسخه پذیرفته می شود و تحت کنترل آن باقی می ماند. علاوه بر این، در فرآیند پذیرش یک منبع برای انتشار، werf با استفاده از همان وصلههای ادغام سهطرفه و قانون منابع همگامسازی شده، وضعیت فعلی منبع را از خوشه در حال اجرا به وضعیتی که در نمودار توضیح داده شده است، میآورد.
یادداشت: تنظیمات WERF_THREE_WAY_MERGE_MODE بر پذیرش منابع تأثیر نمی گذارد - در مورد پذیرش، همیشه از یک وصله ادغام سه طرفه استفاده می شود.
امیدوارم بعد از این مقاله مشخص شده باشد که وصله های ادغام 3 طرفه چیست و چرا به آنها آمده است. از نقطه نظر عملی توسعه پروژه werf، اجرای آنها گام دیگری در جهت بهبود استقرار هلم مانند بود. اکنون میتوانید مشکلات مربوط به همگامسازی پیکربندی را فراموش کنید، که اغلب هنگام استفاده از Helm 2 به وجود میآمدند. در همان زمان، یک ویژگی مفید جدید استفاده از منابع Kubernetes قبلاً دانلود شده به نسخه Helm اضافه شد.
هنوز برخی از مسائل و چالشها در مورد استقرار Helm مانند، مانند استفاده از قالبهای Go وجود دارد که به آنها ادامه خواهیم داد.
اطلاعات مربوط به روش های به روز رسانی منابع و پذیرش را نیز می توانید در اینجا پیدا کنید این صفحه مستندات.
هلم 3
قابل توجه ویژه منتشر شد همین روزها نسخه اصلی جدید Helm - v3 - که همچنین از وصله های ادغام سه طرفه استفاده می کند و Tiller را از بین می برد. نسخه جدید Helm نیاز دارد مهاجرت نصب های موجود برای تبدیل آنها به فرمت ذخیره سازی نسخه جدید.
Werf، به نوبه خود، در حال حاضر از استفاده از Tiller خلاص شده است، به 3-way-merge تغییر داده و اضافه شده است. خیلی بیشتر، در حالی که با نصب های موجود Helm 2 سازگار است (هیچ اسکریپت انتقال نیازی به اجرا ندارد). بنابراین، تا زمانی که werf به Helm 3 تغییر نکند، کاربران werf مزایای اصلی Helm 3 را نسبت به Helm 2 از دست نمی دهند (werf آنها را نیز دارد).
با این حال، سوئیچ werf به پایگاه کد Helm 3 اجتناب ناپذیر است و در آینده نزدیک اتفاق خواهد افتاد. احتمالاً این werf 1.1 یا werf 1.2 خواهد بود (در حال حاضر، نسخه اصلی werf 1.0 است؛ برای اطلاعات بیشتر در مورد دستگاه ویرایشگر werf، رجوع کنید به اینجا). در این مدت، Helm 3 زمانی برای تثبیت خواهد داشت.
PS
در وبلاگ ما نیز بخوانید:
مجموعه ای از یادداشت ها در مورد نوآوری ها در werf: