مقارنة صحيحة بين تطبيق Kubernetes واستبداله وتصحيحه

لدى Kubernetes عدة خيارات لتحديث الموارد: التطبيق والتحرير والتصحيح والاستبدال. هناك ارتباك حول ما يفعله كل واحد ومتى يستخدمه. دعونا معرفة ذلك.

مقارنة صحيحة بين تطبيق Kubernetes واستبداله وتصحيحه

إذا بحث في جوجل توجد عبارة "تطبيق kubernetes مقابل استبدال". الرد على StackOverflow، وهو غير صحيح. عند البحث "تطبيق 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، إذا كنت تعمل مع مجموعات عبر مكتبة العميل لـ Kubernetes API باستخدام بعض لغات البرمجة. تتعامل المكتبة مع هذه الطرق عبر طلبات HTTP باستخدام الطرق 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 طريقتين أخريين للتحديث: تصحيح دمج JSON и تصحيح JSON. يأخذ نهج تصحيح دمج JSON مواصفات Kubernetes جزئية كمدخلات ويدعم دمج الكائنات المشابهة لنهج تصحيح الدمج الاستراتيجي. الفرق بين الاثنين هو أنه يدعم فقط استبدال المصفوفة، بما في ذلك مصفوفة الحاوية في مواصفات الجراب. وهذا يعني أنه عند استخدام تصحيح دمج 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 على الحالة الحالية للمورد من واجهة برمجة التطبيقات
  • يقوم كل واحد بتحديث المواصفات محليًا عن طريق زيادة العداد بمقدار واحد وأيضًا إضافة "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". على الأقل حتى تحل هذه المقالة محل الإجابة الحالية.

مقارنة صحيحة بين تطبيق Kubernetes واستبداله وتصحيحه

المصدر: www.habr.com

إضافة تعليق