Kubernetes چندین گزینه برای به روز رسانی منابع دارد: اعمال، ویرایش، وصله و جایگزینی. در مورد اینکه هر کدام چه کاری انجام می دهند و چه زمانی باید از آنها استفاده کرد سردرگمی وجود دارد. بیایید آن را بفهمیم.
اگر 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
، اگر با خوشه ها کار می کنید از طریق 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 از دو روش به روز رسانی دیگر پشتیبانی می کند: 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 اعتماد کنید. حداقل تا زمانی که این مقاله جایگزین پاسخ فعلی شود.
منبع: www.habr.com