ما هو Helm Chart؟ دليل عملي للمبتدئين في Kubernetes
مقدمة: لماذا نحتاج إلى Helm مع Kubernetes؟
يُعد Kubernetes من أهم الأدوات المستخدمة لإدارة التطبيقات السحابية الحديثة، إذ يوفّر آليات قوية لتشغيل الحاويات، وتوسيع الخدمات، وتنظيم البنية التشغيلية. لكن على الرغم من هذه القوة، فهو لا يحل كل التحديات بمفرده، خاصة عند التعامل مع ملفات الضبط الطويلة، وتكرار القيم، وإدارة الإصدارات، وتبسيط النشر بين البيئات المختلفة.
هنا يظهر دور Helm، وهو مشروع مفتوح المصدر صُمّم لتسهيل إدارة موارد Kubernetes عبر أسلوب أكثر مرونة وتنظيماً. وبدلاً من التعامل اليدوي مع عدد كبير من ملفات YAML، يمكن استخدام Helm لتجميع هذه الملفات داخل حِزم قابلة لإعادة الاستخدام والنشر بسهولة.

ما هو Helm؟
يُعرف Helm غالباً بأنه مدير الحزم الخاص بـ Kubernetes، لكن هذا الوصف لا يعكس كامل إمكاناته. فدوره لا يقتصر على تثبيت الحزم، بل يشمل أيضاً تنظيم القوالب، وإدارة التبعيات، وتتبع الإصدارات، وتسهيل التراجع إلى إصدارات سابقة عند حدوث مشكلات.
بدأ Helm كمشروع مفتوح المصدر من تطوير DeisLabs، ثم انتقل إلى مؤسسة CNCF التي تتولى صيانته حالياً. وكان الهدف الأساسي منه هو توفير طريقة أفضل للتعامل مع ملفات Kubernetes YAML التي تتزايد بسرعة في المشاريع الفعلية.
ما هو Helm Chart؟
Helm Chart هو حزمة تحتوي على ملف واحد أو أكثر من ملفات توصيف موارد Kubernetes. ويمكن أن يتضمن أيضاً تبعيات إلى Charts أخرى، سواء كانت فرعية أو مرتبطة به بشكل مباشر. عند تثبيت Chart رئيسي، يستطيع Helm تثبيت شجرة التبعيات كاملة بأمر واحد فقط.
هذا يعني أنك لست بحاجة إلى تمرير قائمة طويلة من الملفات إلى kubectl في كل مرة. بدلاً من ذلك، يمكنك إدارة التطبيق بالكامل من خلال حزمة موحدة وقابلة للتتبع.
لماذا يُعد Helm مهماً في المشاريع العملية؟
تكمن قوة Helm في المساحات التي لا يغطيها Kubernetes بشكل مباشر، وأهمها القوالب Templating. فـ Kubernetes يركّز على تشغيل الحاويات وإدارة الموارد، وليس على بناء قوالب ديناميكية قابلة لإعادة الاستخدام عبر فرق متعددة وبيئات مختلفة.
عند إدارة مشروع حقيقي، غالباً ما تحتاج إلى تغيير قيم مثل:
- اسم البيئة مثل
developmentأوproduction. - وسم الصورة
image tag. - عدد النسخ
replicas. - المتغيرات الحساسة مثل المفاتيح السرية وعناوين البريد.
إذا تعاملت مع هذه القيم يدوياً داخل ملفات ثابتة، فستصبح الصيانة أصعب، وسيرتفع خطر الخطأ، كما ستتكرر الملفات بلا داعٍ. أما باستخدام Helm، فيمكنك تحويل هذه القيم إلى متغيرات ديناميكية داخل القوالب.
مثال تقليدي على ملف نشر في Kubernetes
لنفترض أن لدينا ملف Deployment لتطبيق بسيط. قد يبدو بالشكل التالي:
apiVersion: apps/v1
kind: Deployment
metadata:
name: zaqar
namespace: default
labels:
app: zaqar
version: v1.0.0
env: production
spec:
replicas: 1
selector:
matchLabels:
app: zaqar
env: production
template:
metadata:
labels:
app: zaqar
version: v1.0.0
env: production
spec:
containers:
- name: zaqar
image: "khaosdoctor/zaqar:v1.0.0"
imagePullPolicy: IfNotPresent
env:
- name: SENDGRID_APIKEY
value: "MY_SECRET_KEY"
- name: DEFAULT_FROM_ADDRESS
value: "my@email.com"
- name: DEFAULT_FROM_NAME
value: "Lucas Santos"
ports:
- name: http
containerPort: 3000
protocol: TCP
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 250m
memory: 256Mi
هذا الأسلوب يعمل، لكنه يصبح مرهقاً عند الحاجة إلى تشغيل نفس التطبيق في أكثر من بيئة، أو عند استخدامه داخل خط نشر آلي CI pipeline.
المشكلة مع القيم الثابتة والبدائل اليدوية
في المشاريع التقليدية، قد يلجأ بعض المطورين إلى استبدال القيم الثابتة بعلامات مؤقتة placeholders، مثل:
apiVersion: apps/v1
kind: Deployment
metadata:
name: zaqar
namespace: default
labels:
app: zaqar
version: #!VERSION!#
env: #!ENV!#
spec:
replicas: 1
selector:
matchLabels:
app: zaqar
env: #!ENV!#
template:
metadata:
labels:
app: zaqar
version: #!VERSION!#
env: #!ENV!#
spec:
containers:
- name: zaqar
image: "khaosdoctor/zaqar:#!VERSION!#"
imagePullPolicy: IfNotPresent
env:
- name: SENDGRID_APIKEY
value: "#!SENDGRID_KEY!#"
- name: DEFAULT_FROM_ADDRESS
value: "#!FROM_ADDR!#"
- name: DEFAULT_FROM_NAME
value: "#!FROM_NAME!#"
ports:
- name: http
containerPort: 3000
protocol: TCP
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 250m
memory: 256Mi
بعد ذلك، يتم استخدام أدوات مثل sed لاستبدال هذه القيم قبل النشر. مثال على ذلك:
cat deploy.yaml | \
sed 's/#!ENV!#/production/g' | \
sed 's/#!VERSION!#/v1.0.0/g' | \
sed 's/#!SENDGRID_KEY!#/MyKey/g' | \
sed 's/#!FROM_ADDR!#/my@email.com/g' | \
sed 's/#!FROM_NAME!#/Lucas Santos/g'
ثم يمكن تمرير الناتج إلى kubectl. ورغم أن هذه الطريقة قابلة للتنفيذ، فإنها تصبح معقدة وسريعة الانهيار كلما ازداد عدد الملفات والمتغيرات. وهنا يأتي Helm بوصفه حلاً أكثر نضجاً ووضوحاً.
كيف يحل Helm هذه المشكلة؟
يعتمد Helm على قوالب Go templates داخل ملفات الموارد. وبدلاً من الاعتماد على بدائل نصية بدائية، يمكنك استخدام متغيرات منظمة، ودوال مدمجة، وقيم افتراضية، والتحقق من الحقول الإلزامية.
مثال على ملف Deployment بصيغة قالب Helm:
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Values.name }}
namespace: {{ default .Release.Namespace .Values.namespace }}
labels:
app: {{ .Values.name }}
version: {{ .Values.image.tag }}
env: {{ .Values.env }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ .Values.name }}
env: {{ .Values.env }}
template:
metadata:
labels:
app: {{ .Values.name }}
version: {{ .Values.image.tag }}
env: {{ .Values.env }}
spec:
containers:
- name: {{ .Chart.Name }}
image: "khaosdoctor/zaqar: {{ .Values.image.tag }} "
imagePullPolicy: {{ .Values.image.pullPolicy }}
env:
- name: SENDGRID_APIKEY
value: {{ required "You must set a valid Sendgrid API key" .Values.environment.SENDGRID_APIKEY | quote }}
- name: DEFAULT_FROM_ADDRESS
value: {{ required "You must set a default from address" .Values.environment.DEFAULT_FROM_ADDRESS | quote }}
- name: DEFAULT_FROM_NAME
value: {{ required "You must set a default from name" .Values.environment.DEFAULT_FROM_NAME | quote }}
ports:
- name: http
containerPort: 3000
protocol: TCP
resources:
{{ - toYaml .Values.resources | nindent 12 }}
في هذا المثال، يتم سحب القيم من ملف values.yaml أو تمريرها مباشرة من سطر الأوامر باستخدام الخيار --set.
مثال على تثبيت Chart
helm upgrade --install --create-namespace myChart ./path/to/my/chart \
--set image.tag=v1.0.0 \
--set env=production \
--set environment.SENDGRID_APIKEY=myKey \
--set environment.DEFAULT_FROM_ADDRESS="my@email.com" \
--set environment.DEFAULT_FROM_NAME="Lucas Santos"
ما فوائد القوالب والدوال في Helm؟
يوفر Helm مجموعة من الدوال المفيدة داخل القوالب، ما يمنحك مرونة كبيرة في بناء ملفات نشر ذكية وقابلة لإعادة الاستخدام.
- الدالة
default: تستخدم قيمة افتراضية إذا لم يتم تمرير قيمة صريحة. - الدالة
required: تمنع تثبيتChartإذا لم يتم تمرير قيمة إلزامية. - الدالة
quote: تساعد على تنسيق القيم النصية بشكل آمن. - الدالتان
toYamlوnindent: مفيدتان لتنسيق المقاطع المعقدة داخلYAML.
هذه الإمكانات تجعل نشر التطبيقات أكثر أماناً ومرونة، خاصة في البيئات متعددة الفرق أو متعددة المراحل التشغيلية.
إدارة الإصدارات وسجل الإطلاقات في Helm
من المزايا المهمة في Helm أنه لا يكتفي بالنشر فقط، بل يحتفظ أيضاً بسجل للإطلاقات releases. وهذا يفيدك في الحالات التالية:
- الرجوع إلى إصدار سابق عند حدوث خطأ بعد التحديث.
- تتبع التغييرات التي طالت التطبيق بمرور الوقت.
- ضبط البنية التحتية بوصفها شيفرة قابلة للتكرار والمراجعة.
كما يسمح لك Helm بتحديد إصدار معين من Chart، وهي ميزة مهمة للحفاظ على التوافق بين الكود والبنية التشغيلية.
كيف تنشئ Helm Chart جديداً؟
إنشاء Chart جديد عملية بسيطة. بعد تثبيت Helm، يمكنك تنفيذ الأمر التالي:
helm create <chart-name>
سيقوم هذا الأمر بإنشاء هيكل مجلدات وملفات جاهز للعمل. هذا الهيكل ليس عشوائياً، بل يتّبعه Helm لفهم مكونات الحزمة وطريقة تثبيتها.
أهم ملفات ومجلدات Chart
Chart.yaml: يحتوي على اسم الحزمة، ووصفها، وإصدارها، ويمكن أيضاً تعريف التبعيات من خلال المفتاحdependencies.values.yaml: الملف الافتراضي الذي يضم القيم المستخدمة في القوالب.templates/: المجلد الذي توضع داخله ملفات مواردKubernetesبصيغة قوالب.charts/: يستخدم لتضمين الحزم التابعة إذا كانChartيعتمد على حزم أخرى.
عند وجود تبعيات، يقوم Helm بتثبيتها من الأسفل إلى الأعلى. فإذا كان Chart A يعتمد على Chart B، وChart B يعتمد على Chart C، فسيكون ترتيب التثبيت: C → B → A.
كيف تستضيف Helm Chart بعد إنشائه؟
بعد إنشاء Chart، لا يحتاج المستخدمون إلى تنزيل المستودع الكامل من أجل تثبيته. يتيح Helm مفهوم مستودعات الحزم chart repositories، وهي مشابهة في فكرتها لمستودعات الحزم الشهيرة مثل NPM أو مستودعات صور Docker.
يعتمد مستودع Helm عادة على ملف index.yaml يتم تقديمه عبر خادم ويب ثابت. يحتوي هذا الملف على معلومات مهمة مثل:
- الإصدارات المتاحة من الحزمة.
- بصمات التحقق
SHA256. - مسار ملف الحزمة المضغوط بصيغة
.tgz.
بذلك يستطيع Helm معرفة مكان الحزمة المناسبة وتنزيلها مباشرة. ويمكنك استضافة هذا المستودع في عدة أماكن، مثل:
GitHub Pages.- خدمات الحاويات والسجلات السحابية مثل
Azure CR. - حلول مخصصة مثل
Chart Museumالتي توفّر إدارة أفضل وواجهة استخدام مناسبة.
ملاحظات مهمة حول Helm 3
إذا كنت ستبدأ باستخدام Helm اليوم، فمن الأفضل الاعتماد على الإصدار Helm 3. الإصدار Helm 2 ما زال معروفاً لدى بعض الفرق، لكنه كان يتطلب مكوّناً جانبياً في الخادم يسمى Tiller، وهو ما كان يزيد التعقيد ويربط التثبيت بعنقود واحد.
أما Helm 3 فقد أزال هذه الحاجة، وجعل التجربة أبسط وأكثر أماناً، مع تحسينات مناسبة لسير العمل الحديث في Kubernetes.
متى يكون استخدام Helm خياراً مثالياً؟
يصبح Helm خياراً مثالياً في الحالات التالية:
- عند إدارة عدد كبير من ملفات
YAML. - عند الحاجة إلى إعادة استخدام نفس القوالب في بيئات متعددة.
- عند الرغبة في ضبط الإصدارات والتراجع السريع عند الخطأ.
- عند نشر تطبيقات تحتوي على تبعيات متعددة.
- عند بناء مشاريع مفتوحة المصدر أو داخلية قابلة للتوزيع بسهولة.
أما إذا كان مشروعك صغيراً جداً ويعتمد على ملف أو ملفين فقط دون أي تعقيد، فقد لا تشعر بقيمة Helm في البداية. لكن بمجرد توسع المشروع، سيظهر الفارق بوضوح.
الخلاصة التقنية
Helm ليس مجرد أداة لتثبيت الحزم، بل هو طبقة تنظيمية مهمة فوق Kubernetes تساعدك على تحويل ملفات النشر من نصوص جامدة إلى قوالب ذكية قابلة للتوسعة والإدارة. من الناحية التقنية، تكمن قيمته الحقيقية في توحيد النشر، وتقليل الأخطاء البشرية، وتحسين إدارة التبعيات والإصدارات. إذا كنت تعمل على مشاريع قابلة للنمو، فإن تعلم Helm Charts خطوة عملية ستوفّر عليك كثيراً من الوقت والتعقيد مستقبلاً.