مقایسه صحیح اعمال، جایگزینی و وصله Kubernetes

Kubernetes چندین گزینه برای به روز رسانی منابع دارد: اعمال، ویرایش، وصله و جایگزینی. در مورد اینکه هر کدام چه کاری انجام می دهند و چه زمانی باید از آنها استفاده کرد سردرگمی وجود دارد. بیایید آن را بفهمیم.

مقایسه صحیح اعمال، جایگزینی و وصله Kubernetes

اگر در گوگل جستجو کنید عبارت "kubernetes اعمال در مقابل جایگزین" قرار دارد به StackOverflow پاسخ دهید، که صحیح نیست. هنگام جستجو "kubernetes application vs patch" اولین لینک مستندات آن است kubectl patch، که شامل مقایسه نمی شود apply и patch. در این مقاله به گزینه های مختلف و همچنین استفاده مناسب از هر یک می پردازیم.

در طول چرخه حیات یک منبع Kubernetes (سرویس، استقرار، ورود و غیره)، گاهی اوقات لازم است برخی از ویژگی های این منبع را تغییر دهید، اضافه یا حذف کنید. به عنوان مثال، یک یادداشت اضافه کنید، تعداد کپی ها را کم یا زیاد کنید.

Kubernetes CLI

اگر قبلاً از طریق CLI با خوشه های Kubernetes کار می کنید، قبلاً با آن آشنا هستید apply и edit. تیم apply مشخصات منبع را از فایل می خواند و یک "upsert" در خوشه Kubernetes ایجاد می کند. منبع را در صورت نبودن ایجاد می کند و در صورت وجود آن را به روز می کند. تیم edit یک منبع را از طریق API می خواند، سپس مشخصات منبع را در یک فایل محلی می نویسد، که سپس در یک ویرایشگر متن باز می شود. پس از ویرایش و ذخیره فایل، kubectl تغییرات ایجاد شده را از طریق API ارسال می کند، که با دقت این تغییرات را در منبع اعمال می کند.

همه دستورات را نمی دانند patch и replace. تیم patch به شما این امکان را می دهد که بخشی از مشخصات منبع را تغییر دهید و فقط قسمت تغییر یافته را در خط فرمان ارائه دهید. تیم replace مانند کار می کند edit، اما همه چیز باید به صورت دستی انجام شود: شما باید نسخه فعلی مشخصات منبع را دانلود کنید، به عنوان مثال، با استفاده از kubectl get -o yaml، آن را ویرایش کنید، سپس استفاده کنید replace برای به روز رسانی یک منبع با توجه به مشخصات تغییر یافته. تیم replace اگر بین خواندن و جایگزینی منبع تغییری رخ دهد، کار نخواهد کرد.

Kubernetes API

احتمالا با روش ها آشنایی دارید CoreV1().Pods().Update(), replaceNamespacedService یا patch_namespaced_deployment، اگر با خوشه ها کار می کنید از طریق کتابخانه مشتری برای Kubernetes API با استفاده از برخی از زبان های برنامه نویسی کتابخانه این روش ها را از طریق درخواست های HTTP با استفاده از روش ها مدیریت می کند PUT и PATCH... که در آن update и replace استفاده کنید PUTو patch، هر چقدر هم که پیش پا افتاده باشد، استفاده می کند PATCH.

شایان ذکر است که است kubectl همچنین با خوشه ها از طریق API کار می کند. به عبارت دیگر، kubectlیک بسته بندی در بالای کتابخانه مشتری برای زبان Go است که تا حد زیادی علاوه بر قابلیت های استاندارد API، امکان ارائه دستورات فرعی را به شکل فشرده تر و خواناتر فراهم می کند. به عنوان مثال، همانطور که قبلاً متوجه شده اید، روش apply در بالا در پاراگراف قبلی ذکر نشده است. در حال حاضر (مه 2020، تقریبا مترجم) همه منطق kubectl apply، یعنی ایجاد منابع ناموجود و به روز رسانی منابع موجود، کاملاً در سمت کد کار می کند kubectl. تلاش هایی در حال انجام است در انتقال منطق apply به سمت API، اما هنوز در نسخه بتا است. در زیر با جزئیات بیشتری خواهم نوشت.

پچ به صورت پیش فرض

بهترین استفاده patch، اگر می خواهید منبع را به روز کنید. اینگونه است که هر دو کتابخانه کلاینت در بالای Kubernetes API و kubectl (تعجب آور نیست، زیرا یک بسته بندی برای کتابخانه مشتری است، تقریبا مترجم).

استراتژیک کار کنید

همه تیم ها kubectl apply, edit и patch از روش استفاده کنید PATCH در HTTP برای به روز رسانی یک منبع موجود درخواست می کند. اگر با جزئیات بیشتری به اجرای دستورات بپردازید، همه آنها از این رویکرد استفاده می کنند وصله ادغام استراتژیک برای به روز رسانی منابع، اگرچه دستور patch ممکن است از روش‌های دیگری استفاده کند (در زیر در این مورد بیشتر توضیح می‌دهیم). رویکرد وصله ادغام استراتژیک تلاش می کند تا با ادغام مشخصات ارائه شده با مشخصات موجود، "آن را به درستی انجام دهد". به طور خاص، سعی می‌کند هم اشیا و هم آرایه‌ها را ترکیب کند، به این معنی که تغییرات تمایل به افزایش دارند. برای مثال اجرای دستور patch با یک متغیر محیطی جدید در مشخصات کانتینر پاد، باعث می شود که آن متغیر محیطی به جای بازنویسی، به متغیرهای محیط موجود اضافه شود. برای حذف با استفاده از این روش، باید مقدار پارامتر را در مشخصات ارائه شده تهی کنید. کدام یک از تیم ها kubectl آیا استفاده از آن برای به روز رسانی بهتر است؟

اگر منابع خود را با استفاده از آن ایجاد و مدیریت کنید kubectl apply، هنگام به روز رسانی بهتر است همیشه استفاده کنید kubectl applyبه kubectl می تواند پیکربندی را مدیریت کند و تغییرات درخواستی را از برنامه ای به برنامه دیگر به درستی ردیابی کند. مزیت همیشه استفاده کنید apply این است که مشخصات قبلاً اعمال شده را ردیابی می کند و به آن اجازه می دهد بداند که چه زمانی خصوصیات مشخصات و عناصر آرایه به صراحت حذف شده اند. این به شما امکان می دهد استفاده کنید apply برای حذف خواص و عناصر آرایه، در حالی که یک ادغام استراتژیک معمولی کار نخواهد کرد. تیم ها edit и patch یادداشت ها را به روز نکنید kubectl apply برای ردیابی تغییرات خود استفاده می کند، بنابراین هر تغییری که از طریق Kubernetes API ردیابی و ایجاد می شود، اما از طریق دستورات ایجاد می شود. edit и patch، برای دستورات بعدی نامرئی است applyاین است که، apply آنها را حذف نمی کند حتی اگر در مشخصات ورودی برای ظاهر نشده باشند apply (اسناد این را می گوید edit и patch یادداشت های استفاده شده را به روز کنید apply، اما در عمل - نه).

اگر از دستور استفاده نمی کنید apply، می تواند به عنوان استفاده شود editو patch، دستوری را انتخاب کنید که به بهترین وجه با تغییر ایجاد شده مطابقت دارد. هنگام افزودن و تغییر خواص BOM، هر دو رویکرد تقریباً یکسان هستند. هنگام حذف ویژگی های مشخصات یا عناصر آرایه edit مانند پرتاب یکباره رفتار می کند apply، از جمله پیگیری اینکه مشخصات قبل و بعد از ویرایش چگونه بوده است، بنابراین می توانید به صراحت ویژگی ها و عناصر آرایه را از یک منبع حذف کنید. شما باید به صراحت مقدار خاصیت را در مشخصات برای null تنظیم کنید patchبرای حذف آن از منبع حذف یک عنصر آرایه با استفاده از وصله ادغام استراتژیک پیچیده تر است زیرا به استفاده از دستورالعمل های ادغام نیاز دارد. سایر رویکردهای ارتقاء را در زیر برای جایگزین های بادوام تر ببینید.

برای پیاده سازی روش های به روز رسانی در کتابخانه مشتری که رفتاری مشابه دستورات بالا دارند kubectl، باید در درخواست ها تنظیم شود content-type в application/strategic-merge-patch+json. اگر می‌خواهید ویژگی‌ها را در یک مشخصات حذف کنید، باید به صراحت مقادیر آن‌ها را به روشی مشابه null کنید. kubectl patch. اگر نیاز به حذف عناصر آرایه دارید، باید دستورالعمل های ادغام را در مشخصات به روز رسانی بگنجانید یا از روشی متفاوت برای به روز رسانی استفاده کنید.

روش های دیگر برای به روز رسانی

Kubernetes از دو روش به روز رسانی دیگر پشتیبانی می کند: وصله ادغام JSON и پچ JSON. رویکرد وصله ادغام JSON یک مشخصات جزئی Kubernetes را به عنوان ورودی دریافت می کند و از ادغام اشیاء مشابه رویکرد وصله ادغام استراتژیک پشتیبانی می کند. تفاوت بین این دو این است که فقط از جایگزینی آرایه پشتیبانی می کند، از جمله آرایه کانتینر در مشخصات pod. این بدان معناست که هنگام استفاده از یک پچ ادغام JSON، باید مشخصات کاملی را برای همه کانتینرها ارائه کنید تا در صورت تغییر خاصیت هر کانتینری. بنابراین این رویکرد برای حذف عناصر از یک آرایه در یک BOM مفید است. در خط فرمان می توانید وصله ادغام JSON را با استفاده از آن انتخاب کنید kubectl patch --type=merge. هنگام کار با Kubernetes API، باید از روش درخواست استفاده کنید PATCH و نصب content-type в application/merge-patch+json.

رویکرد وصله JSON، به جای ارائه مشخصات جزئی یک منبع، از ارائه تغییراتی که می‌خواهید در منبع ایجاد کنید به‌عنوان یک آرایه استفاده می‌کند، که در آن هر عنصر آرایه توضیحی از تغییر ایجاد شده در منبع را نشان می‌دهد. این رویکرد روشی انعطاف‌پذیرتر و قدرتمندتر برای بیان تغییرات ایجاد شده است، اما به قیمت فهرست کردن تغییرات ایجاد شده در قالب جداگانه و غیر Kubernetes به جای ارسال مشخصات جزئی منبع است. که در kubectl می توانید با استفاده از پچ JSON را انتخاب کنید kubectl patch --type=json. هنگام استفاده از Kubernetes API، این رویکرد با استفاده از روش درخواست کار می کند PATCH و نصب content-type в application/json-patch+json.

ما نیاز به اعتماد داریم - استفاده از جایگزین

در برخی موارد، باید مطمئن باشید که هیچ تغییری در منبعی بین زمان خواندن منبع و زمان به‌روزرسانی آن ایجاد نمی‌شود. به عبارت دیگر، باید مطمئن شوید که همه تغییرات انجام خواهند شد اتمی. در این صورت برای به روز رسانی منابع باید از آن استفاده کنید replace. به عنوان مثال، اگر یک ConfigMap با شمارنده ای دارید که توسط چندین منبع به روز می شود، باید مطمئن شوید که دو منبع همزمان شمارنده را به روز نمی کنند و باعث از بین رفتن به روز رسانی می شود. برای نشان دادن، دنباله ای از رویدادها را با استفاده از این رویکرد تصور کنید patch:

  • A و B وضعیت فعلی منبع را از API دریافت می کنند
  • هر کدام به صورت محلی مشخصات را با افزایش شمارنده یک عدد و همچنین اضافه کردن "A" یا "B" به ترتیب به یادداشت "updated-by" به روز می کنند.
  • و منبع را کمی سریعتر به روز می کند
  • B منبع را به روز می کند

در نتیجه آپدیت A از بین می رود. آخرین عملیات patch برنده می شود، شمارنده به جای دو، یک افزایش می یابد، و مقدار یادداشت "به روز رسانی شده" با "B" پایان می یابد و حاوی "A" نیست. بیایید موارد بالا را با اتفاقاتی که هنگام به‌روزرسانی با استفاده از این رویکرد انجام می‌شود، مقایسه کنیم replace:

  • A و B وضعیت فعلی منبع را از API دریافت می کنند
  • هر کدام به صورت محلی مشخصات را با افزایش شمارنده یک عدد و همچنین اضافه کردن "A" یا "B" به ترتیب به یادداشت "updated-by" به روز می کنند.
  • و منبع را کمی سریعتر به روز می کند
  • B سعی می کند منبع را به روز کند، اما به روزرسانی توسط API رد می شود زیرا نسخه منبع در مشخصات موجود است. replace با نسخه فعلی منبع در Kubernetes مطابقت ندارد زیرا نسخه منبع با عملیات جایگزینی A افزایش یافته است.

در حالت فوق، B باید منبع را دوباره واکشی کند، تغییراتی را در حالت جدید ایجاد کند و دوباره امتحان کند replace. این باعث می شود که شمارنده دو برابر شود و نت "به روز رسانی شده" در پایان "AB" را شامل شود.

مثال بالا نشان می دهد که هنگام اجرا replace کل منبع به طور کامل جایگزین شده است. مشخصات استفاده شده برای replace، نباید جزئی باشد یا به صورت جزئی باشد apply، اما کامل، از جمله اضافه شده است resourceVersion به فراداده مشخصات اگر فعال نکرده اید resourceVersion یا نسخه ای که ارائه می کنید فعلی نیست، جایگزینی رد می شود. بنابراین بهترین روش برای استفاده این است replace - منبع را بخوانید، آن را به روز کنید و بلافاصله جایگزین کنید. استفاده كردن kubectl، ممکن است شبیه به این باشد:

$ kubectl get deployment my-deployment -o json 
    | jq '.spec.template.spec.containers[0].env[1].value = "new value"' 
    | kubectl replace -f -

شایان ذکر است که دو دستور زیر که به صورت متوالی اجرا می شوند، با موفقیت اجرا می شوند، زیرا deployment.yaml دارای خاصیت نیست .metadata.resourceVersion

$ kubectl create -f deployment.yaml
$ kubectl replace -f deployment.yaml

به نظر می رسد که این با آنچه در بالا گفته شد، تناقض دارد. "اضافه كردن resourceVersion در فراداده مشخصات." آیا این اشتباه است؟ نه، اینطور نیست، زیرا اگر kubectl اطلاعیه هایی که شما مشخص نکردید resourceVersion، آن را از منبع می خواند و به مشخصاتی که شما مشخص کرده اید اضافه می کند و تنها سپس آن را اجرا می کند. replace. از آنجایی که اگر به اتمی بودن تکیه کنید، این به طور بالقوه خطرناک است، جادو کاملاً روی طرف کار می کند kubectl، هنگام استفاده از کتابخانه های سرویس گیرنده ای که با API کار می کنند، نباید به آن تکیه کنید. در این صورت شما باید مشخصات منبع فعلی را بخوانید، آن را به روز کنید و سپس اجرا کنید PUT درخواست.

شما نمی توانید یک پچ انجام دهید - ما یک جایگزین انجام می دهیم

گاهی اوقات شما نیاز به ایجاد برخی تغییرات دارید که توسط API قابل مدیریت نیست. در این موارد، می توانید با حذف و ایجاد مجدد منبع، جایگزین آن را مجبور کنید. این کار با استفاده از kubectl replace --force. اجرای دستور بلافاصله منابع را حذف می کند و سپس آنها را از مشخصات ارائه شده دوباره ایجاد می کند. در API کنترل کننده "force replace" وجود ندارد و برای انجام این کار از طریق API، باید دو عملیات را انجام دهید. ابتدا باید منبع را با تنظیم آن حذف کنید gracePeriodSeconds به صفر (0) و propagationPolicy در "پس زمینه" و سپس دوباره این منبع را با مشخصات مورد نظر ایجاد کنید.

هشدار: این رویکرد به طور بالقوه خطرناک است و ممکن است منجر به وضعیت نامشخص شود.

در سمت سرور اعمال کنید

همانطور که در بالا ذکر شد، توسعه دهندگان Kubernetes در حال کار بر روی پیاده سازی منطق هستند apply از kubectl در Kubernetes API. منطق ها apply در Kubernetes 1.18 از طریق kubectl apply --server-side یا از طریق API با استفاده از روش PATCH с content-type application/apply-patch+YAML.

توجه: JSON همچنین YAML معتبر است، بنابراین می توانید مشخصات را به عنوان JSON ارسال کنید حتی اگر content-type اراده application/apply-patch+yaml.

در کنار این منطق kubectl از طریق API در دسترس همه قرار می گیرد، apply در سمت سرور، مسئولیت فیلدهای موجود در مشخصات را دنبال می کند، بنابراین امکان دسترسی چندگانه ایمن را برای ویرایش بدون درگیری آن فراهم می کند. به عبارت دیگر، اگر apply در سمت سرور گسترده تر می شود، یک رابط مدیریت منابع امن جهانی برای مشتریان مختلف ظاهر می شود، به عنوان مثال، kubectl، Pulumi یا Terraform، GitOps، و همچنین اسکریپت های خودنویس با استفاده از کتابخانه های مشتری.

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

امیدوارم این مرور کوتاه از روش های مختلف به روز رسانی منابع در خوشه ها برای شما مفید بوده باشد. خوب است بدانید که این فقط اعمال در مقابل جایگزینی نیست، می‌توان یک منبع را با استفاده از اعمال، ویرایش، وصله یا جایگزینی به‌روزرسانی کرد. از این گذشته ، در اصل ، هر رویکرد حوزه کاربرد خاص خود را دارد. برای تغییرات اتمی، جایگزینی ترجیح داده می شود، در غیر این صورت، باید از پچ استراتژی ادغام از طریق App استفاده کنید. حداقل، من انتظار دارم که درک کنید که هنگام جستجوی "kubernetes application vs جایگزین" نمی توانید به Google یا StackOerflow اعتماد کنید. حداقل تا زمانی که این مقاله جایگزین پاسخ فعلی شود.

مقایسه صحیح اعمال، جایگزینی و وصله Kubernetes

منبع: www.habr.com

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