مثل أي حل آخر ، فإن Helm - مدير الحزم في Kubernetes - لديه إيجابيات وسلبيات ونطاق ، لذلك عند استخدامه ، يجب عليك تقييم توقعاتك بشكل صحيح ...
نستخدم هيلم في ترسانتنا من أدوات المتداول المستمر. في وقت كتابة هذا التقرير ، كان هناك
أكثر من ألف تطبيق في مجموعاتنا وحوالي 4000 تثبيت لهذه التطبيقات في أشكال مختلفة. نواجه مشكلات بشكل دوري ، لكن بشكل عام نحن راضون عن الحل ، ولا يوجد لدينا وقت تعطل وفقدان للبيانات.
الدافع الرئيسي لكتابة هذه المقالة هو تزويد المستخدم
بتقييم موضوعي للمشاكل الرئيسية في Helm 2 دون استنتاجات نهائية ، وكذلك الرغبة في تبادل الخبرات وحلولنا.
[BUG] بعد النشر ، لا تتوافق حالة موارد الإصدار في الكتلة مع مخطط Helm الموضح
Helm لا يأخذ في الاعتبار حالة موارد الإصدار في كتلة أثناء العملية. عند إعادة التثبيت ، يتم تحديد النتيجة فقط من خلال التكوينات الحالية والمحفوظة. وبالتالي ، فإن حالة المورد في الكتلة وسجل هيلم مختلفة ، ولا يأخذ هيلم هذا في الاعتبار.
النظر في كيفية هذه المشكلة تتجلى:
- يتوافق قالب المورد على المخطط مع الحالة X.
- يقوم المستخدم بتثبيت المخطط (يحفظ Tiller حالة المورد X).
- بعد ذلك ، يقوم المستخدم بتغيير المورد في الكتلة يدويًا (تتغير الحالة من X إلى Y).
- دون إجراء أي تغييرات ، فإنه ينفذ
helm upgrade
... والمورد لا يزال في الحالة ص ، على الرغم من أن المستخدم يتوقع X.
وهذا ليس كل شيء. في مرحلة ما ، يقوم المستخدم بتغيير قالب المورد على المخطط (حالة جديدة W) - ثم لدينا سيناريوهين بعد
helm upgrade
:
- تطبيق التصحيح XW آخذ في الانخفاض.
- بعد تطبيق التصحيح ، ينتقل المورد إلى الحالة Z ، والتي لا تتوافق مع الحالة المطلوبة.
لتجنب مثل هذه المشكلة ، يُقترح تنظيم العمل باستخدام الإصدارات كما يلي:
لا ينبغي لأحد أن يغير الموارد يدويًا ، فإن Helm هو الأداة الوحيدة للعمل مع موارد الإصدار. من الناحية المثالية ، يتم إصدار تغييرات المخطط في إصدار Git وتطبق
حصريًا داخل القرص المضغوط.
إذا كان هذا الخيار غير مناسب ، فيمكنك
مراقبة تزامن حالات موارد الإصدار. قد يبدو التزامن اليدوي كما يلي:
- نكتشف حالة موارد الإصدار من خلال
helm get
. - معرفة حالة الموارد في Kubernetes عبر
kubectl get
. - إذا كانت الموارد مختلفة ، فسنقوم بمزامنة Helm مع Kubernetes:
- إنشاء فرع منفصل.
- تحديث المخططات البيانية. يجب أن تطابق القوالب حالات الموارد في Kubernetes.
- نحن ننفذ النشر. نحن مزامنة الدولة في سجل هيلم والكتلة.
- بعد ذلك ، يمكن حذف الفرع ومواصلة العمل العادي.
عند تطبيق تصحيحات باستخدام
kubectl apply
، يتم تنفيذ ما يسمى
kubectl apply
، أي تؤخذ الحالة الحقيقية للمورد المحدث في الاعتبار. يمكنك رؤية رمز الخوارزمية
هنا ، وقراءته
هنا .
في وقت كتابة هذا التقرير ، يبحث مطورو Helm عن طرق لتطبيق 3-way-merge في Helm 3. مع Helm 2 ، الأمور ليست وردية للغاية: لم يتم التخطيط ل 3-way-merge ، ولكن هناك PR لإصلاح طريقة إنشاء الموارد - يمكنك معرفة التفاصيل أو حتى المشاركة كجزء من
القضية ذات الصلة .
[BUG] خطأ: لا توجد موارد تحمل الاسم NAME
تتجلى المشكلة إذا تم
إنشاء موارد جديدة بنجاح عند تكرار التمهيد ، وفشل التشغيل في النهاية.
الموارد الجديدة تعني تلك التي لم تكن في التثبيت الأخير للمخطط.
في حالة فشل بدء التشغيل ، يتم حفظ الإصدار في السجل المميز
FAILED ، ويعتمد Helm أثناء التثبيت على حالة أحدث إصدار
DEPLOYED ، وهو في هذه الحالة لا يعرف أي شيء عن الموارد الجديدة. نتيجة لذلك ، يحاول Helm إعادة إنشاء هذه الموارد وفشل بسبب الخطأ "لا توجد موارد بالاسم الذي تم العثور عليه في NAME" (الخطأ يقول العكس ، ولكن هذه هي المشكلة). جزء من المشكلة هو أن Helm لا يأخذ في الاعتبار حالة موارد الإصدار في الكتلة عند إنشاء التصحيح ، كما هو موضح في القسم السابق.
في الوقت الحالي ، الحل الوحيد هو إزالة الموارد الجديدة يدويًا.
لتجنب مثل هذه الحالة ، يمكن حذف الموارد الجديدة التي تم إنشاؤها تلقائيًا في الترقية / الاستعادة الحالية في حالة فشل الأمر في نهاية المطاف. بعد مناقشة طويلة مع المطورين في Helm ، لأوامر الترقية / الاستعادة ، تمت إضافة خيار
--cleanup-on-fail
، الذي ينشط التنظيف التلقائي عند فشل بدء التشغيل. لدينا
العلاقات العامة قيد المناقشة ، والبحث عن أفضل الحلول.
بدءًا من الإصدار 2.13 من Helm ، يظهر الخيار -
--atomic
في
--atomic
helm install/upgrade
، التي تنشط التنظيف والتراجع أثناء تثبيت غير ناجح (لمزيد من التفاصيل ، انظر
PR ).
[خطأ]: شاهد الساعة مغلقة قبل انتهاء المهلة
يمكن أن تحدث المشكلة عند تنفيذ ربط Helm لفترة طويلة جدًا (على سبيل المثال ، أثناء عمليات الترحيل) - على الرغم من عدم تجاوز المهلات المحددة
helm install/upgrade
spec.activeDeadlineSeconds
و
spec.activeDeadlineSeconds
المقابلة.
يتم إنشاء هذا الخطأ بواسطة خادم API Kubernetes أثناء انتظار مهمة ربط لإكمال. لا يتعامل Helm مع هذا الخطأ ويتعطل فورًا - بدلاً من إعادة محاولة طلب الانتظار.
كحل ، يمكنك زيادة المهلة في api-server:
--min-request-timeout=xxx
في الملف
/etc/kubernetes/manifests/kube-apiserver.yaml
.
[BUG] خطأ: فشل الترقية: "foo" لا تحتوي على إصدارات منشورة
إذا فشل الإصدار الأول من خلال
helm install
، فسوف تُرجع
helm upgrade
اللاحقة خطأً مماثلاً.
يبدو أن الحل بسيط للغاية: تحتاج إلى تنفيذ
helm delete --purge
يدويًا -
helm delete --purge
بعد فشل التثبيت الأول ، ولكن هذا الإجراء اليدوي يكسر أتمتة CI / CD. من أجل عدم مقاطعة تنفيذ الأوامر اليدوية ، يمكنك استخدام ميزات
werf للتشغيل . عند استخدام werf ، سيتم إعادة إنشاء الإصدار الإشكالي تلقائيًا عند إعادة التثبيت.
بالإضافة إلى ذلك ، بدءًا من Helm 2.13 ، في
helm upgrade --install
helm install
helm upgrade --install
فقط بتحديد الخيار
--atomic
وبعد فشل التثبيت ، سيتم حذف الإصدار تلقائيًا (انظر
العلاقات العامة للحصول على التفاصيل).
رد تلقائي
يفتقر Helm إلى خيار -
--autorollback
، الذي ، عند
--autorollback
، سيتذكر المراجعة الحالية الناجحة (سينخفض إذا لم تنجح المراجعة الأخيرة) ، وبعد محاولة نشر غير ناجحة ، سيتراجع إلى المراجعة المحفوظة.
نظرًا لأنه من الأهمية بمكان أن يعمل المنتج دون انقطاع ، فمن الضروري البحث عن حلول ، ويجب أن يكون بدء التشغيل متوقعًا. لتقليل احتمالية تعطل المنتج ، يتم استخدام
نهج مع عدة دوائر (على سبيل المثال ، التدريج ، qa والإنتاج) ، والذي يتكون في التدوير المتسلسل على الدوائر. من خلال هذا النهج ، يتم إصلاح معظم المشكلات قبل طرحها على المستوى الإنتاجي ، كما يتيح لك بالتزامن مع autorolback تحقيق نتائج جيدة.
لتنظيم الاسترداد التلقائي ، يمكنك استخدام المكون الإضافي
لشاشة helm ، والذي يسمح لك بربط الاستعادة بمقاييس من Prometheus. مقالة جيدة تصف هذا النهج متاحة
هنا .
بالنسبة لبعض مشاريعنا ، يتم استخدام نهج بسيط إلى حد ما:
- قبل النشر ، نتذكر المراجعة الحالية (نعتقد أنه في حالة طبيعية ، إذا كان الإصدار موجودًا ، فسيكون بالضرورة في حالة DEPLOYED):
export _RELEASE_NAME=myrelease export _LAST_DEPLOYED_RELEASE=$(helm list -adr | \ grep $_RELEASE_NAME | grep DEPLOYED | head -n2 | awk '{print $2}')
- قم بتشغيل التثبيت أو الترقية:
helm install/upgrade ... || export _DEPLOY_FAILED=1
- نتحقق من حالة النشر ونقوم بالتراجع إلى الحالة المحفوظة:
if [ "$_DEPLOY_FAILED" == "1" ] && [ "x$_LAST_DEPLOYED_RELEASE" != "x" ] ; then helm rollback $_RELEASE_NAME $_LAST_DEPLOYED_RELEASE fi
- ننهي خط الأنابيب بخطأ إذا كان النشر غير ناجح:
if [ "$_DEPLOY_FAILED" == "1" ] ; then exit 1 ; fi
مرة أخرى ، بدءًا من الإصدار 2.13 من Helm ، عند الاتصال
helm upgrade
يكفي تحديد الخيار -
--atomic
وبعد أن يتم إعادة تثبيت التثبيت الفاشل تلقائيًا (انظر
PR للاطلاع
على التفاصيل).
في انتظار توافر موارد الإصدار والتعليقات في وقت بدء التشغيل
كما هو مخطط ، يجب على هيلم مراقبة تنفيذ اختبارات الثبات والاستعداد المقابلة عند استخدام خيار
--wait
:
--wait if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment are in a ready state before marking the release as successful. It will wait for as long as --timeout
لا تعمل هذه الوظيفة بشكل صحيح الآن: لا يتم دعم جميع الموارد وليس جميع إصدارات واجهة برمجة التطبيقات. وعملية الانتظار المعلنة نفسها لا تلبي احتياجاتنا.
كما هو الحال مع
kubectl wait
، لا توجد ردود فعل سريعة وليس هناك طريقة لتنظيم هذا السلوك. إذا فشلت النسخة التجريبية ، فلن نعرف عنها
إلا بعد انتهاء المهلة . في حالة وجود مشكلة في التثبيت ، من الضروري إكمال عملية بدء التشغيل في أقرب وقت ممكن ، وقلب خط أنابيب CI / CD ، واستعادة الإصدار إلى إصدار العمل ومتابعة تصحيح الأخطاء.
إذا تم التراجع عن إصدار المشكلة ، ولم يقم Helm بإرجاع أي معلومات أثناء عملية التشغيل ، فما الذي يتم تصحيحه ؟! في حالة
kubectl wait
يمكنك تنظيم عملية منفصلة لعرض السجلات ، والتي ستتطلب أسماء موارد الإصدار. كيفية تنظيم حل بسيط وعملي ليست واضحة على الفور. وإلى جانب سجلات pod ، يمكن تضمين معلومات مفيدة في عملية النشر ، وأحداث الموارد ...
يمكن للأداة المساعدة
werf CI / CD الخاصة بنا نشر مخطط Helm ومراقبة توفر الموارد ، بالإضافة إلى معلومات العرض المتعلقة بالتداول. يتم دمج جميع البيانات في دفق واحد وتصدر للسجل.
يرصد هذا المنطق في حل
kubedog منفصل. باستخدام الأداة المساعدة ، يمكنك الاشتراك في مورد وتلقي الأحداث والسجلات ، وكذلك التعرف على النشرات الفاشلة في الوقت المناسب. أي كحل ، بعد استدعاء
helm install/upgrade
بدون خيار
--wait
،
--wait
استدعاء kubedog لكل مورد إصدار.
نحن نهدف إلى جعل أداة من شأنها أن توفر جميع المعلومات اللازمة لتصحيح الأخطاء في إخراج خط أنابيب CI / CD. اقرأ المزيد عن الأداة المساعدة في
مقالتنا الأخيرة .
ربما في Helm 3 في يوم ما ، سيظهر حل مماثل ، لكن مشكلتنا حتى الآن في حالة تعليق.
الأمان عند استخدام helm init افتراضيًا
افتراضيًا ، عند تنفيذ الأمر
helm init
، يتم تثبيت مكون الخادم في الكتلة بامتيازات مشابهة للمستعمل الخارق ، مما قد يؤدي إلى عواقب غير مرغوب فيها عند الوصول إليها بواسطة جهات خارجية.
لضمان أمان المجموعة ، من الضروري الحد من إمكانات Tiller ، فضلاً عن الاهتمام بالاتصال - أمان الشبكة التي يتم من خلالها الاتصال بين مكونات Helm.
يمكن تحقيق الأول من خلال استخدام آلية Kubernetes RBAC القياسية ، والتي ستحد من تصرفات الحارث ، والثانية - عن طريق إعداد SSL. اقرأ المزيد في وثائق Helm:
تأمين تثبيت Helm .
يُعتقد أن وجود مكون الخادم - Tiller - هو خطأ معماري خطير ، حرفيًا مورد أجنبي له حقوق المستخدم الخارق في نظام Kubernetes البيئي. نوافق جزئياً على أن التنفيذ غير كامل ، لكن دعونا نلقي نظرة على هذا من الجانب الآخر . إذا قاطعت عملية النشر وقتلت عميل Helm ، فلن يظل النظام في حالة غير محددة ، أي سوف تيلر جعل حالة الإصدار صالحة. من الضروري أيضًا فهم أنه على الرغم من التخلي عن Tiller في Helm 3 ، فإن هذه الوظائف ستتم بطريقة أو بأخرى بواسطة وحدة تحكم CRD.المريخ الذهاب قوالب
تشتمل قوالب التشغيل على حد دخول كبير ، لكن التكنولوجيا لا يوجد بها قيود على القدرات والمشاكل في DRY. تمت مناقشة المبادئ الأساسية وبناء الجملة والوظائف والمشغلين في مقالتنا
السابقة في سلسلة Helm.
عدم وجود أسرار من خارج منطقة الجزاء
من الملائم تخزين وصيانة رمز التطبيق والبنية التحتية وقوالب النشر عند وجودها في مكان واحد. والأسرار ليست استثناء.
لا يدعم Helm الأسرار الخارجة عن الصندوق ، ومع ذلك ، يتوفر المكون الإضافي
helm-secrets ، والذي يعد أساسًا طبقة بين
sops ومدير أسرار Mozilla و Helm.
عند العمل مع الأسرار ، نستخدم الحل الخاص بنا الذي يتم تنفيذه في
werf (
وثائق عن الأسرار ). من الميزات:
- سهولة التنفيذ.
- حفظ سر في ملف ، وليس فقط في YAML. مريحة عند تخزين الشهادات والمفاتيح.
- تجديد الأسرار مع مفتاح جديد.
- بدء دون مفتاح سري (عند استخدام werf). قد يكون مفيدًا لتلك الحالات عندما لا يكون لدى المطور هذا المفتاح السري ، ولكن هناك حاجة إلى بدء نشر على اختبار أو دائرة محلية.
الخاتمة
يتم وضع Helm 2 كمنتج مستقر ، ولكن هناك العديد من الأخطاء التي تعلق في طي النسيان (بعضها يدوم لعدة سنوات!). بدلاً من الحلول ، أو على الأقل التصحيحات ، يتم تكريس كل الجهود لتطوير Helm 3.
على الرغم من حقيقة أن MR و المشكلة يمكن تعليقها لعدة أشهر (فيما يلي
مثال على كيفية إضافة سياسة ما
before-hook-creation policy
للخطافات لعدة أشهر) ، لا يزال بإمكانك المشاركة في تطوير المشروع. كل يوم خميس ، يتم تنظيم اجتماع لمدة نصف ساعة لمطوري Helm ، حيث يمكنك التعرف على الأولويات والاتجاهات الحالية للفريق ، وطرح الأسئلة وفرض أفضل الممارسات الخاصة بك. حول ميتي وقنوات الاتصال الأخرى مكتوبة بالتفصيل
هنا .
سواء كنت تستخدم هيلم أم لا ، فهذا أمر طبيعي لك. نلتزم اليوم بموقف من هذا القبيل ، على الرغم من أوجه القصور ، هيلم هو حل مقبول للنشر والمشاركة في تطويره مفيد للمجتمع بأسره.
PS
اقرأ أيضًا في مدونتنا: