لدى Kubernetes عدة خيارات لتحديث الموارد: التطبيق والتحرير والتصحيح والاستبدال. هناك ارتباك حول ما يفعله كل واحد ومتى يستخدمه. دعونا معرفة ذلك.
إذا kubectl patch
والتي لا تتضمن المقارنة apply
и patch
. ستنظر هذه المقالة في الخيارات المختلفة، بالإضافة إلى الاستخدام السليم لكل منها.
خلال دورة حياة مورد Kubernetes (الخدمة، النشر، الدخول، وما إلى ذلك)، تحتاج أحيانًا إلى تغيير بعض خصائص هذا المورد أو إضافتها أو إزالتها. على سبيل المثال، قم بإضافة ملاحظة أو زيادة أو تقليل عدد النسخ المتماثلة.
Kubernetes CLI
إذا كنت تعمل بالفعل مع مجموعات Kubernetes عبر واجهة سطر الأوامر (CLI)، فأنت على دراية بذلك بالفعل apply
и edit
. فريق apply
يقرأ مواصفات المورد من الملف ويقوم بإجراء "إبلاغ" إلى مجموعة Kubernetes، أي. يقوم بإنشاء المورد إذا لم يكن موجودًا ويقوم بتحديثه إذا كان موجودًا. فريق edit
يقرأ المورد عبر واجهة برمجة التطبيقات (API)، ثم يكتب مواصفات المورد إلى ملف محلي، والذي يتم فتحه بعد ذلك في محرر نصوص. بعد أن تقوم بتحرير الملف وحفظه، kubectl
سيتم إرسال التغييرات التي تم إجراؤها مرة أخرى من خلال واجهة برمجة التطبيقات (API)، والتي ستطبق هذه التغييرات بعناية على المورد.
ليس الجميع يعرف الأوامر patch
и replace
. فريق patch
يسمح لك بتغيير جزء من مواصفات المورد، مع توفير الجزء الذي تم تغييره فقط في سطر الأوامر. فريق replace
يعمل نفس edit
، ولكن يجب القيام بكل شيء يدويًا: تحتاج إلى تنزيل الإصدار الحالي من مواصفات المورد، على سبيل المثال، باستخدام kubectl get -o yaml
، قم بتحريره، ثم استخدمه replace
لتحديث مورد وفقًا لمواصفات تم تغييرها. فريق replace
لن يعمل في حالة حدوث أي تغييرات بين القراءة واستبدال المورد.
واجهة برمجة تطبيقات Kubernetes
ربما تكون على دراية بالطرق CoreV1().Pods().Update()
, replaceNamespacedService
أو patch_namespaced_deployment
، إذا كنت تعمل مع مجموعات عبر PUT
и PATCH
... حيث update
и replace
استخدام PUT
و patch
، مهما كانت تافهة، استخدامات PATCH
.
تجدر الإشارة إلى أن kubectl
يعمل أيضًا مع المجموعات عبر واجهة برمجة التطبيقات (API). بعبارة أخرى، kubectl
عبارة عن غلاف أعلى مكتبة العميل للغة Go، والذي يوفر إلى حد كبير القدرة على توفير الأوامر الفرعية في شكل أكثر إحكاما وقابلية للقراءة بالإضافة إلى إمكانيات واجهة برمجة التطبيقات القياسية. على سبيل المثال، كما لاحظت بالفعل، الطريقة apply
ولم يذكر أعلاه في الفقرة السابقة. حاليًا (مايو 2020، تقريبا. مترجم) كل المنطق kubectl apply
، أي. يعمل إنشاء موارد غير موجودة وتحديث الموارد الموجودة بالكامل على جانب التعليمات البرمجية kubectl
. تبذل الجهود apply
إلى جانب API، لكنه لا يزال في مرحلة تجريبية. سأكتب بمزيد من التفاصيل أدناه.
التصحيح بشكل افتراضي
أفضل استخداما patch
، إذا كنت تريد تحديث المورد. هذه هي الطريقة التي تعمل بها مكتبات العميل أعلى واجهة برمجة تطبيقات Kubernetes و kubectl
(ليس من المستغرب، لأنه عبارة عن غلاف لمكتبة العميل، تقريبا. مترجم).
العمل بشكل استراتيجي
كل الفرق kubectl
apply
, edit
и patch
استخدم الطريقة PATCH
في طلبات HTTP لتحديث مورد موجود. إذا قمت بالخوض في تنفيذ الأوامر بمزيد من التفصيل، فكلهم يستخدمون هذا النهج patch
قد يستخدم أساليب أخرى (المزيد حول هذا أدناه). يحاول أسلوب تصحيح الدمج الاستراتيجي "تصحيح الأمر" عن طريق دمج المواصفات المتوفرة مع المواصفات الحالية. وبشكل أكثر تحديدًا، فهو يحاول الجمع بين كل من الكائنات والمصفوفات، مما يعني أن التغييرات تميل إلى أن تكون إضافية. على سبيل المثال، تشغيل الأمر patch
مع متغير بيئة جديد في مواصفات حاوية pod، يؤدي إلى إضافة متغير البيئة هذا إلى متغيرات البيئة الموجودة بدلاً من الكتابة فوقها. للإزالة باستخدام هذا الأسلوب، يجب عليك إجبار قيمة المعلمة على أن تكون خالية في المواصفات المتوفرة. أي من الفرق kubectl
هل من الأفضل استخدامه للتحديث؟
إذا قمت بإنشاء وإدارة الموارد الخاصة بك باستخدام kubectl apply
، عند التحديث فمن الأفضل استخدامه دائمًا kubectl apply
إلى kubectl
يمكنه إدارة التكوين وتتبع التغييرات المطلوبة بشكل صحيح من تطبيق إلى آخر. الاستفادة دائما apply
هو أنه يتتبع المواصفات المطبقة مسبقًا، مما يسمح له بمعرفة متى تتم إزالة خصائص المواصفات وعناصر المصفوفة بشكل صريح. هذا يسمح لك باستخدام apply
لإزالة الخصائص وعناصر المصفوفة، بينما لن ينجح الدمج الاستراتيجي العادي. فرق edit
и patch
لا تقم بتحديث الملاحظات التي kubectl apply
يستخدم لتتبع تغييراته، لذلك يتم تتبع أي تغييرات وإجراؤها من خلال واجهة برمجة تطبيقات Kubernetes، ولكن يتم إجراؤها من خلال الأوامر edit
и patch
، غير مرئي للأوامر اللاحقة apply
وهذا هو، apply
لا يقوم بإزالتها حتى لو لم تظهر في مواصفات الإدخال الخاصة بـ apply
(الوثائق تقول ذلك edit
и patch
إجراء تحديثات على الملاحظات المستخدمة apply
ولكن في الممارسة العملية - لا).
إذا كنت لا تستخدم الأمر apply
، يمكن استخدامه ك edit
و patch
، واختيار الأمر الذي يناسب التغيير الذي يتم إجراؤه. عند إضافة خصائص قائمة مكونات الصنف وتغييرها، يكون كلا الأسلوبين متماثلين تقريبًا. عند حذف خصائص المواصفات أو عناصر المصفوفة edit
يتصرف مثل الإطلاق لمرة واحدة apply
، بما في ذلك تتبع شكل المواصفات قبل وبعد تحريرها، حتى تتمكن من إزالة الخصائص وعناصر المصفوفة من المورد بشكل صريح. تحتاج إلى تعيين قيمة الخاصية بشكل صريح على أنها فارغة في المواصفات الخاصة بـ patch
لإزالته من المورد. تعد إزالة عنصر صفيف باستخدام تصحيح الدمج الاستراتيجي أكثر تعقيدًا لأنها تتطلب استخدام توجيهات الدمج. راجع أساليب الترقية الأخرى أدناه للحصول على بدائل أكثر قابلية للتطبيق.
لتنفيذ أساليب التحديث في مكتبة العميل التي تتصرف بشكل مشابه للأوامر المذكورة أعلاه kubectl
، يجب أن يتم تعيينها في الطلبات content-type
в application/strategic-merge-patch+json
. إذا كنت ترغب في إزالة الخصائص في إحدى المواصفات، فأنت بحاجة إلى تعيين قيمها بشكل صريح على أنها فارغة بطريقة مماثلة 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 على الحالة الحالية للمورد من واجهة برمجة التطبيقات
- يقوم كل واحد بتحديث المواصفات محليًا عن طريق زيادة العداد بمقدار واحد وأيضًا إضافة "A" أو "B" على التوالي إلى الملاحظة "تم التحديث بواسطة"
- ويقوم بتحديث المورد بشكل أسرع قليلاً
- B يقوم بتحديث المورد
ونتيجة لذلك، يتم فقدان التحديث أ. العملية الأخيرة patch
يفوز، ويتم زيادة العداد بمقدار واحد بدلاً من اثنين، وتنتهي قيمة الملاحظة "تم التحديث بواسطة" بالحرف "B" ولا تحتوي على "A". دعونا نقارن ما ورد أعلاه بما يحدث عند إجراء التحديثات باستخدام هذا النهج replace
:
- يحصل A وB على الحالة الحالية للمورد من واجهة برمجة التطبيقات
- يقوم كل واحد بتحديث المواصفات محليًا عن طريق زيادة العداد بمقدار واحد وأيضًا إضافة "A" أو "B" على التوالي إلى الملاحظة "تم التحديث بواسطة"
- ويقوم بتحديث المورد بشكل أسرع قليلاً
- يحاول B تحديث المورد، ولكن تم رفض التحديث بواسطة واجهة برمجة التطبيقات لأن إصدار المورد موجود في المواصفات
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
فلا يجب الاعتماد عليها عند استخدام مكتبات العملاء التي تعمل مع واجهة برمجة التطبيقات. في هذه الحالة، سيتعين عليك قراءة مواصفات المورد الحالية وتحديثها ثم تنفيذها PUT
طلب.
لا يمكنك إجراء التصحيح – فنحن نقوم بالاستبدال
تحتاج في بعض الأحيان إلى إجراء بعض التغييرات التي لا يمكن لواجهة برمجة التطبيقات معالجتها. في هذه الحالات، يمكنك فرض استبدال المورد عن طريق حذفه وإعادة إنشائه. يتم ذلك باستخدام kubectl replace --force
. يؤدي تشغيل الأمر إلى إزالة الموارد فورًا ثم إعادة إنشائها من المواصفات المتوفرة. لا يوجد معالج "فرض الاستبدال" في واجهة برمجة التطبيقات، وللقيام بذلك من خلال واجهة برمجة التطبيقات، يتعين عليك تنفيذ عمليتين. تحتاج أولاً إلى حذف المورد عن طريق الإعداد له gracePeriodSeconds
إلى الصفر (0) و propagationPolicy
في "الخلفية" ثم أعد إنشاء هذا المورد بالمواصفات المطلوبة.
تحذير: قد يكون هذا الأسلوب خطيرًا وقد يؤدي إلى حالة غير محددة.
تنطبق على جانب الخادم
كما ذكرنا أعلاه، يعمل مطورو Kubernetes على تنفيذ المنطق apply
من kubectl
في واجهة برمجة تطبيقات Kubernetes. المنطق 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، بالإضافة إلى البرامج النصية المكتوبة ذاتيًا باستخدام مكتبات العملاء.
نتائج
آمل أن تكون هذه النظرة العامة القصيرة حول الطرق المختلفة لتحديث الموارد في المجموعات مفيدة لك. من الجيد أن تعرف أن الأمر لا يقتصر على التطبيق مقابل الاستبدال، بل من الممكن تحديث المورد باستخدام التطبيق أو التحرير أو التصحيح أو الاستبدال. بعد كل شيء، من حيث المبدأ، كل نهج له مجال التطبيق الخاص به. بالنسبة للتغييرات الذرية، يفضل الاستبدال؛ وإلا، يجب عليك استخدام تصحيح الدمج الاستراتيجي عبر التطبيق. على أقل تقدير، أتوقع منك أن تفهم أنه لا يمكنك الوثوق في Google أو StackOerflow عند البحث عن "kubernetes Apply vs Replace". على الأقل حتى تحل هذه المقالة محل الإجابة الحالية.
المصدر: www.habr.com