القوالب المسمّاة والمساعدات
القوالب المسمّاة والمساعدات
في الدرس الرابع تعلّمتَ أن قوالب Helm هي ملفات Go text/template مرتبطة بشجرة .Values. لكن chart تطبيق إنتاجي حقيقي يحتوي على عشرة قوالب أو أكثر: Deployment وService وIngress وHPA وPDB وServiceAccount وRBAC وConfigMap وNetworkPolicy وغيرها. يحتاج كل واحد منها إلى نفس مجموعة التسميات (labels) في Kubernetes، ونفس تسميات المحدّد (selector labels)، ونفس مساعد الاسم الذي يضبط الطول عند 63 حرفاً، ونفس تعليقات إصداري الـ chart والتطبيق. من دون موقع مشترك لهذا المنطق ستنسخ نفس الاثني عشر سطراً في كل ملف، وحين يتغيّر معيار التسمية ستجد نفسك أمام عشرة ملفات للتحديث — وستفوتك واحدة حتماً.
الحل هو _helpers.tpl: ملف يحتوي على قوالب مسمّاة (تُعرف أيضاً بالـ partials) تمركّز المنطق القابل لإعادة الاستخدام. يتناول هذا الدرس الميكانيكيات بعمق، إذ الإتقان في هذه الطبقة هو الفارق بين مكتبة chart قابلة للصيانة وفوضى من YAML المكرّر.
آلية عمل القوالب المسمّاة: define وinclude
يوفّر محرّك قوالب Go في Helm توجيهَين لمشاركة المنطق عبر الملفات:
{{ define "name" }}…{{ end }}— يُعلن عن كتلة قالب مسمّاة. يمكن لأي ملف فيtemplates/تعريفها، لكن الاتفاقية تقضي بوضعها جميعاً فيtemplates/_helpers.tpl. الملفات التي تبدأ بشرطة سفلية لا تُصيَّر كـ manifests أبداً — وجودها فقط لتضمين التعريفات في الفضاء المشترك.{{ include "name" . }}— يُصيّر قالباً مسمّى في النطاق الحالي (النقطة.) ويُعيد الناتج كسلسلة نصية. هذه هي الأداة الصحيحة لحقن ناتج جزئي في مستند أب.{{ template "name" . }}— مطابق دلالياً لكنه لا يُعيد السلسلة المُصيَّرة؛ بل يكتب مباشرةً في تدفق الإخراج. هذا يجعله غير قابل للتمرير عبرnindentأوtrim، لذا في الممارسة العملية استخدمincludeدائماً.
template مقابل include: خطأ شائع في الـ charts هو استخدام {{ template "myapp.labels" . }} مباشرةً في كتلة metadata: بدلاً من {{ include "myapp.labels" . | nindent 4 }}. لا يمكن تمرير التوجيه template عبر الأنابيب، لذا تُشفَّر المسافة البادئة داخل الـ partial نفسه وتنكسر فور استخدامه على عمق تداخل مختلف. استخدم include دائماً.
تشريح _helpers.tpl
كل chart تُنشئها بـ helm create تأتي مع _helpers.tpl جاهز. فهم كل قالب مسمّى فيه شرط مسبق لكتابة قوالبك الخاصة. إليك النسخة الإنتاجية المعيارية لـ chart باسم myapp:
لاحظ عدة أنماط حرجة مضمّنة في هذا القالب:
- حذف المسافات البيضاء بـ
{{- … -}}يُبقي الـ YAML المُصيَّر نظيفاً. trunc 63 | trimSuffix "-"يمنع أخطاء التحقّق من صحة تسميات DNS في Kubernetes حين تكون أسماء الإصدارات طويلة (مثلاً في ArgoCD يتضمّن اسم الإصدار غالباً البيئة وفرع Git).selectorLabelsمجموعة فرعية صارمة منlabels. يستخدمselector:في Service وكذلكmatchLabels:في Deployment تسمياتselectorLabels؛ أماmetadata.labelsفيستخدم قالبlabelsالكامل. هذا الفصل جوهري.
استخدام المساعدات في القوالب
إليك كيفية استهلاك قالب Deployment للمساعدات مع قواعد المسافة البادئة الدقيقة:
تُضيف دالة nindent N سطراً جديداً ثم تُبادر بمسافة N بادئة لكامل السلسلة متعددة الأسطر. هذا هو سبب إلزامية include: دالة nindent هي دالة تمرير سلسلة نصية — لا تقبل الإخراج الفارغ لتوجيه template.
checksum/config: إضافة checksum/config: {{ include … | sha256sum }} إلى قالب الـ pod يجعل Helm يُدوّر الـ Deployment تلقائياً كلما تغيّر الـ ConfigMap المُشار إليه. بدون هذا، يُنتج helm upgrade الذي يعدّل ConfigMap فقط صفراً من عمليات إعادة تشغيل الـ pods — يستمر تطبيقك في العمل بإعدادات قديمة. هذا التعليق معيار إنتاجي في كل كبرى شركات التقنية.
كتابة مساعدات مخصّصة
إلى جانب مساعدات التسمية القياسية، ستكتب كثيراً من الـ partials المتخصّصة. أمثلة شائعة من charts الإنتاج:
معيار تسمية Kubernetes
التسميات التي تُنتجها قوالب المساعدات تتبع مواصفة التسميات الموصى بها في Kubernetes (app.kubernetes.io/*). ليست هذه اصطلاحاً اختيارياً — فالأدوات في النظام البيئي (Prometheus ServiceMonitors، اكتشاف Datadog التلقائي، ArgoCD، Lens) تستعلم الموارد بهذه التسميات تحديداً. إتقانها يفتح لك المراقبة (observability) مجاناً.
المجموعة الكاملة من التسميات الموصى بها لكل مورد:
app.kubernetes.io/name— اسم التطبيق (لا اسم الإصدار). تستخدمه Prometheus للاكتشاف التلقائي لـ ServiceMonitors.app.kubernetes.io/instance— اسم الإصدار (فريد لكل تثبيت). يتيح تشغيل نسخ متعددة من التطبيق ذاته في namespace واحد.app.kubernetes.io/version— إصدار التطبيق (عادةً.Chart.AppVersion). يغذّي تتبّع الإصدارات في Datadog.app.kubernetes.io/managed-by— دائماًHelm. تستخدمهhelm listلاكتشاف الإصدارات.helm.sh/chart— اسم الـ chart + الإصدار. يستخدمه ArgoCD للكشف عن انحراف الـ chart.
team: platform، cost-center: infrastructure، env: prod. تُحقن هذه التسميات عبر مساعد myapp.globalLabels يقرأ من .Values.global. كل مورد في كل chart في الشركة يُصدر هذه التسميات، لذا تستطيع أدوات تكلفة السحابة (Kubecost, Infracost) تفصيل الإنفاق حسب الفريق والبيئة تلقائياً — دون وسم يدوي.
التحقّق من صحة الإخراج المُصيَّر
يجب أن تفحص مساعداتك قبل التطبيق على الكلاستر. ثلاثة أوامر يجب أن يعرفها كل مؤلّف charts:
شغّل helm template في بيئة CI لكل pull request. القالب المكسور يُنتج YAML مكسوراً قبل أن يصل إلى الكلاستر، والبيئة تكتشف المشكلة قبل أن ينظر فيها أي مراجع.
_helpers.tpl ليس مجرد اتفاقية — إنه الأساس المعماري لـ Helm chart قابل للصيانة. عرّف معيار تسميتك مرة واحدة، طبّق نمط include … | nindent N في كل مكان، أضف تعليق checksum/config على قوالب الـ pods، وسيصبح chart مواطناً أصيلاً في Kubernetes يتكامل مع المنظومة الكاملة من أدوات المراقبة وGitOps.