شرح Helm Charts: مدير الحزم في Kubernetes بطريقة عملية
ما هو Helm ولماذا يُعد أداة أساسية مع Kubernetes؟
عند تشغيل التطبيقات المعتمدة على الحاويات في بيئات الإنتاج، يبرز Kubernetes كخيار قوي لإدارة التوسّع، التوافر، وتوزيع الأحمال. لكن التعامل المباشر مع ملفات تعريف Kubernetes قد يصبح مرهقاً، خصوصاً عندما تكبر البنية وتزداد البيئات والنسخ ومتطلبات الصيانة.
هنا يأتي دور Helm، الذي يصف نفسه بأنه مدير الحزم الخاص بـ Kubernetes. فكرته الأساسية تقوم على استخدام ما يُعرف باسم Helm Charts، وهي حِزم تحتوي على قوالب وإعدادات جاهزة لوصف موارد Kubernetes بطريقة مرنة وقابلة لإعادة الاستخدام.
الميزة الحقيقية في Helm ليست فقط تسريع النشر، بل أيضاً توحيد طريقة إدارة التطبيقات، بما يشمل التثبيت، الترقية، التراجع إلى إصدار سابق، وإزالة الموارد بسهولة. وهذا يجعله مناسباً جداً للفرق التقنية التي تدير تطبيقات متعددة أو بيئات تشغيل مختلفة.
[IMAGE: https://www.freecodecamp.org/news/content/images/size/w2000/2020/12/helm-blog-logo.jpg]

كيف يعمل Helm عملياً؟
يعتمد Helm الحديث، وخصوصاً منذ إصدار Helm 3، على التواصل المباشر مع عنقود Kubernetes عبر واجهات REST دون الحاجة إلى مكوّن قديم مثل Tiller، والذي تمت إزالته. وعند تثبيت أي Chart، يقوم Helm بنشر الموارد المطلوبة ثم يحتفظ ببيانات الإصدار داخل Kubernetes Secrets، ما يسمح بتتبّع الإصدارات وإجراء عمليات rollback بسرعة.
متى تحتاج إلى Helm Charts؟
تزداد قيمة Helm كلما أصبحت بنية التطبيق أكثر تعقيداً. قد لا يكون ضرورياً لحاوية بسيطة جداً، لكنه مفيد للغاية عند إدارة أنظمة متعددة العقد، خدمات مترابطة، أو تطبيقات تحتاج إلى إعدادات تختلف بين بيئة التطوير والإنتاج.
- عند نشر تطبيقات جاهزة مثل
WordPressأوKafkaأوCassandra. - عند الحاجة إلى إدارة الإصدارات والترقيات والتراجع بأمان.
- عند استخدام إعدادات مختلفة لكل بيئة مثل
devوstagingوprod. - عند بناء قوالب موحدة تسهّل على الفرق نشر التطبيقات بسرعة وبجودة ثابتة.
المتطلبات الأساسية قبل التجربة
لتطبيق الأمثلة الواردة في هذا الدليل، تحتاج إلى عنقود Kubernetes فعّال. من أسهل الطرق للتجربة استخدام Docker Desktop مع تفعيل ميزة Kubernetes. كما ستحتاج إلى تثبيت أداتي kubectl وHelm.
من المهم أيضاً التحلي ببعض الصبر أثناء التنفيذ، لأن بعض الحاويات تحتاج إلى بضع دقائق حتى تصبح جاهزة لاستقبال الطلبات.
نشر تطبيق بسيط باستخدام Helm
لنبدأ بتجربة عملية توضح الفكرة. سنقوم أولاً بالاتصال بسياق العمل الصحيح داخل Kubernetes، ثم نستخدم مستودعاً عاماً لتثبيت خادم Apache.
$ kubectl config use-context docker-desktop
Switched to context "docker-desktop".
$ kubectl get node
NAME STATUS ROLES AGE VERSION
docker-desktop Ready master 20d v1.19.3
الخطوة التالية هي إضافة مستودع الحزم:
$ helm repo add bitnami https://charts.bitnami.com/bitnami
بعد ذلك يمكن تثبيت الحزمة المطلوبة مباشرة:
$ helm install my-apache bitnami/apache --version 8.0.2
بعد اكتمال النشر، يمكنك التحقق من حالة الحاويات باستخدام kubectl:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
my-apache-apache-589b8df6bd-q6m2n 1/1 Running 0 2m27s
كما يتيح لك Helm استعراض الإصدارات المنشورة عبر الأمر التالي:
$ helm list
NAME REVISION STATUS CHART APP VERSION
my-apache 1 deployed apache-8.0.2 2.4.46
ما الذي نستفيده هنا؟
بدلاً من كتابة عدة ملفات يدوية لخدمة بسيطة، يمنحك Helm Chart طريقة مختصرة وموثوقة لنشر التطبيق بسرعة، مع إمكانية تتبع الإصدار الحالي وسجل التغييرات المرتبطة به.
ترقية التطبيق عبر Helm upgrade
عندما تحتاج إلى تحديث التطبيق إلى إصدار أحدث، فإن Helm يجعل العملية مباشرة وواضحة:
$ helm upgrade my-apache bitnami/apache --version 8.0.3
$ helm list
NAME REVISION STATUS CHART APP VERSION
my-apache 2 deployed apache-8.0.3 2.4.46
يشير الحقل REVISION إلى أن هذا هو الإصدار الثاني من عملية النشر. وهذه المعلومة مهمة جداً لأنها تُستخدم لاحقاً في التراجع إلى الإصدارات السابقة.
التراجع إلى إصدار سابق باستخدام Helm rollback
إذا تسبب تحديث جديد في مشكلة، يمكنك العودة بسرعة إلى نسخة مستقرة سابقة:
$ helm rollback my-apache 1
Rollback was a success! Happy Helming!
$ helm list
NAME REVISION STATUS CHART APP VERSION
my-apache 3 deployed apache-8.0.2 2.4.46
هذه القدرة تمنح فرق التشغيل مرونة كبيرة في بيئات الإنتاج، لأنها تقلل زمن الاستجابة عند حدوث خلل بعد التحديث.
أين يحتفظ Helm بمعلومات الإصدارات؟
يقوم Helm بتخزين بيانات الإصدارات داخل كائنات Secrets في Kubernetes:
$ kubectl get secret
NAME TYPE DATA AGE
default-token-nc4hn kubernetes.io/sat 3 20d
sh.helm.release.v1.my-apache.v1 helm.sh/release.v1 1 1m
sh.helm.release.v1.my-apache.v2 helm.sh/release.v1 1 1m
sh.helm.release.v1.my-apache.v3 helm.sh/release.v1 1 1m
حذف التطبيق المنشور وتنظيف البيئة
عندما تنتهي من التجربة أو تحتاج إلى إزالة الإصدار الحالي، يكفي تنفيذ:
$ helm delete my-apache
release "my-apache" uninstalled
وهكذا تحصل على دورة حياة متكاملة للتطبيق تشمل النشر، التحديث، التراجع، والحذف من خلال أوامر موحدة وسهلة.
الوصول إلى Helm Charts جاهزة للإنتاج
أحد أبرز أسباب انتشار Helm هو وجود مستودعات عامة ضخمة تضم حِزماً جاهزة لتطبيقات شائعة. هذه الحزم لا تحتوي فقط على ملفات ثابتة، بل تشمل منطقاً قابلاً للتخصيص ومرناً للتعامل مع مراحل التثبيت والترقية وعمليات ما قبل وبعد التنفيذ.
بعض الحِزم المتقدمة يمكنها تشغيل مهام إضافية أثناء دورة حياة التطبيق، مثل تحديث قاعدة البيانات قبل ترقية الخدمة الرئيسية، أو تفعيل مراقبة المؤشرات الصحية، أو إعداد النسخ المتماثلة تلقائياً.
نشر WordPress وMariaDB باستخدام Helm
لفهم القوة الحقيقية لـ Helm، من المفيد تجربة تطبيق أكثر واقعية مثل WordPress. في هذا المثال، الحزمة لا تنشر موقع WordPress فقط، بل تتضمن كذلك قاعدة بيانات MariaDB، مع إمكانية إضافة حاويات مراقبة لاستخراج المقاييس الصحية.
يمكن العثور على هذه الحزم عبر منصات مثل artifacthub.io. بعد اختيار الحزمة المناسبة، تكون أوامر التثبيت واضحة ومباشرة:
$ helm repo add bitnami https://charts.bitnami.com/bitnami
$ helm install my-wordpress bitnami/wordpress --version 10.1.4
بعد التثبيت، يمكن استخراج كلمة مرور المدير من Secret داخل Kubernetes. على أنظمة Mac OS مثلاً:
$ echo Username: user
$ echo Password: $(kubectl get secret --namespace default my-wordpress-3 -o jsonpath="{.data.wordpress-password}" | base64 --decode)
Username: user
Password: sZCa14VNXe
وفي PowerShell على Windows:
$pw = kubectl get secret --namespace default my-wordpress -o jsonpath="{.data.wordpress-password}"
[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($pw))
يمكن بعد ذلك الوصول إلى الموقع محلياً عبر http://localhost، ولوحة الإدارة عبر https://localhost/admin.
لماذا هذا المثال مهم؟
لأن نشر تطبيق مثل WordPress يدوياً في بيئة إنتاج يتطلب وقتاً وجهداً كبيرين، خاصة عند إضافة قاعدة بيانات، التوسّع، والمراقبة. أما مع Helm فالكثير من هذا العمل يصبح جاهزاً ضمن Chart واحد قابل للتخصيص.
تشغيل إعداد إنتاجي متعدد النسخ
إذا كنت تستهدف بيئة إنتاجية، فقد تحتاج إلى أكثر من نسخة من WordPress مع تفعيل مراقبة المقاييس. مثال الإعدادات التالية يوضح أهم التعديلات:
### Start 3 WordPress instances that will all receive
### requests from our visitors. A load-balancer will distribute calls
### to all containers evenly.
replicaCount: 3
### start a sidecar container that will expose metrics for your wordpress container
metrics:
enabled: true
image:
registry: docker.io
repository: bitnami/apache-exporter
tag: 0.8.0-debian-10-r243
قبل تطبيق هذا الإعداد، يمكن حذف النشر السابق:
$ helm delete my-wordpress
release "my-wordpress" uninstalled
ثم تنفيذ النشر الإنتاجي:
$ helm install my-wordpress-prod bitnami/wordpress --version 10.1.4 -f values-production.yaml
بعدها ستلاحظ تشغيل عدة Pods:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
my-wordpress-prod-5c9776c976-4bs6f 2/2 Running 0 103s
my-wordpress-prod-5c9776c976-9ssmr 2/2 Running 0 103s
my-wordpress-prod-5c9776c976-sfq84 2/2 Running 0 103s
my-wordpress-prod-mariadb-0 1/1 Running 0 103s
يظهر هنا أن هناك ثلاث نُسخ من WordPress ونسخة واحدة من MariaDB. وكل Pod من تطبيق WordPress يحتوي على حاويتين: الأولى للتطبيق نفسه، والثانية لمُصدّر Prometheus الذي يوفّر المقاييس.
فحص المقاييس الصحية عبر Prometheus exporter
لمراقبة صحة التطبيق، يمكنك توجيه منفذ محلي إلى أحد Pods العاملة:
kubectl port-forward my-wordpress-prod-5c9776c976-sfq84 9117:9117
احرص على استبدال معرف Pod بما يتوافق مع بيئتك. بعد ذلك افتح http://localhost:9117 لمشاهدة المقاييس بصيغة Prometheus.
مثال على المخرجات:
apache_cpuload 1.2766
process_resident_memory_bytes 1.6441344e+07
قد تبدو هذه القيم غير مألوفة في البداية، لكنها مفيدة جداً عند مراقبة استهلاك المعالج والذاكرة وسلوك التطبيق تحت الضغط. ومع الوقت ستتمكن من تحديد المقاييس الأكثر أهمية لتطبيقك وربطها بمنظومة تنبيه أو لوحات مراقبة.
وعند الانتهاء من التجربة، يمكنك تنظيف الموارد:
$ helm delete my-wordpress-prod
release "my-wordpress-prod" uninstalled
كيف يساعد Helm في بناء تطبيقات مخصصة؟
ملفات النشر التقليدية في Kubernetes ثابتة بطبيعتها. وهذا يعني أن تغيير عدد النسخ أو متغيرات البيئة أو حدود الموارد يتطلب إما تكرار ملفات متعددة أو استخدام قوالب خارجية وحلول مخصّصة. ومع توسّع المشاريع، يتحول هذا النهج إلى عبء صيانة حقيقي.
أما Helm فيقدّم محرك قوالب قوي يتيح لك تعريف ملف واحد مرن، ثم تغذيته بقيم مختلفة بحسب البيئة أو مركز البيانات أو نوع النشر.
تشغيل مدونة Ghost أولاً باستخدام Docker
قبل تحويل التطبيق إلى Helm Chart مخصص، يمكن تشغيل نسخة سريعة عبر Docker:
docker run --rm -p 2368:2368 --name my-ghost ghost
ستصبح المدونة متاحة عبر http://localhost:2368. وبعد الانتهاء، أوقفها حتى تعيد تشغيلها من خلال Kubernetes:
$ docker rm -f my-ghost
my-ghost
نشر Ghost بملفات Kubernetes تقليدية
يمكنك بناء ملف نشر بسيط لتشغيل نسختين من التطبيق:
# file 'application/deployment.yaml'
apiVersion: apps/v1
kind: Deployment
metadata:
name: ghost-app
spec:
selector:
matchLabels:
app: ghost-app
replicas: 2
template:
metadata:
labels:
app: ghost-app
spec:
containers:
- name: ghost-app
image: ghost
ports:
- containerPort: 2368
ثم خدمة من نوع LoadBalancer لتوزيع الطلبات:
# file 'application/service.yaml'
apiVersion: v1
kind: Service
metadata:
name: my-service-for-ghost-app
spec:
type: LoadBalancer
selector:
app: ghost-app
ports:
- protocol: TCP
port: 80
targetPort: 2368
ويمكن تطبيق الموردين مباشرة:
$ kubectl apply -f ./application/deployment.yaml -f ./application/service.yaml
deployment.apps/ghost-app created
service/my-service-for-ghost-app created
وعند الرغبة في الحذف:
$ kubectl delete -f ./application/deployment.yaml -f ./application/service.yaml
deployment.apps/ghost-app deleted
service/my-service-for-ghost-app deleted
هذا الأسلوب يعمل، لكنه لا يتوسع جيداً عندما تتعدد البيئات والإعدادات.
إنشاء Helm Chart مخصص لتطبيق Ghost
لإنشاء قالب جديد، استخدم الأمر:
$ helm create my-ghost-app
Creating my-ghost-app
سينشئ Helm مجموعة ملفات افتراضية. في هذا المثال سنركز على الملفات الأساسية فقط.
ملف المشروع Chart.yaml
# Chart.yaml
apiVersion: v2
name: my-ghost-app
description: A Helm chart for Kubernetes
type: application
version: 0.1.0
appVersion: 1.16.0
قالب النشر templates/deployment.yaml
# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: ghost-app
spec:
selector:
matchLabels:
app: ghost-app
replicas: {{ .Values.replicaCount }}
template:
metadata:
labels:
app: ghost-app
spec:
containers:
- name: ghost-app
image: ghost
ports:
- containerPort: 2368
env:
- name: url
{{- if .Values.prodUrlSchema }}
value: http://{{ .Values.baseUrl }}
{{- else }}
value: http://{{ .Values.datacenter }}.non-prod.{{ .Values.baseUrl }}
{{- end }}
هذا القالب يشبه ملف Kubernetes التقليدي، لكنه أصبح ديناميكياً بفضل القيم والمتغيرات الشرطية. وهنا تظهر قوة Helm في استبدال القيم وفق البيئة المستهدفة.
قالب الخدمة templates/service.yaml
# templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-service-for-my-webapp
spec:
type: LoadBalancer
selector:
app: ghost-app
ports:
- protocol: TCP
port: 80
targetPort: 2368
الملف الافتراضي للقيم values.yaml
# values.yaml
replicaCount: 1
prodUrlSchema: false
datacenter: us-east
baseUrl: myapp.org
يفترض أن يكون أي Chart قابلاً للتشغيل باستخدام القيم الافتراضية فقط. كما يُستحسن إزالة بعض الملفات غير الضرورية في هذا المثال المبسط مثل:
my-ghost-app/templates/tests/test-connection.yamlmy-ghost-app/templates/serviceaccount.yamlmy-ghost-app/templates/ingress.yamlmy-ghost-app/templates/hpa.yamlmy-ghost-app/templates/NOTES.txt
معاينة المخرجات قبل النشر باستخدام dry-run
من أفضل مزايا Helm أنك تستطيع عرض النتيجة النهائية التي ستُرسل إلى Kubernetes قبل تنفيذها فعلياً:
$ helm template --debug my-ghost-app
install.go:159: [debug] Original chart version: ""
install.go:176: [debug] CHART PATH: /helm/my-ghost-app
---
# Source: my-ghost-app/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-service-for-my-webapp
spec:
type: LoadBalancer
selector:
app: my-example-app
ports:
- protocol: TCP
port: 80
targetPort: 2368
---
# Source: my-ghost-app/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: ghost-app
spec:
selector:
matchLabels:
app: ghost-app
replicas: 1
template:
metadata:
labels:
app: ghost-app
spec:
containers:
- name: ghost-app
image: ghost
ports:
- containerPort: 2368
env:
- name: url
value: us-east.non-prod.myapp.org
في هذا المثال، قام Helm بتوليد قيمة المتغير url استناداً إلى القيم الموجودة في values.yaml، لأن prodUrlSchema مضبوط على false.
استخدام ملفات قيم متعددة لبيئات مختلفة
المرونة الحقيقية تظهر عند إنشاء ملفات قيم منفصلة لكل مركز بيانات أو مرحلة تشغيل. مثلاً:
# values.us-east.yaml
datacenter: us-east
# values.us-west.yaml
datacenter: us-west
# values.nonprod.yaml
replicaCount: 1
prodUrlSchema: false
# values.prod.yaml
replicaCount: 3
prodUrlSchema: true
ثم يمكنك دمجها أثناء المعاينة أو النشر:
$ helm template --debug my-ghost-app -f my-ghost-app/values.nonprod.yaml -f my-ghost-app/values.us-east.yaml
install.go:159: [debug] Original chart version: ""
install.go:176: [debug] CHART PATH: /helm/my-ghost-app
---
# Source: my-ghost-app/templates/service.yaml
# templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-service-for-my-webapp
spec:
type: LoadBalancer
selector:
app: my-example-app
ports:
- protocol: TCP
port: 80
targetPort: 2368
---
# Source: my-ghost-app/templates/deployment.yaml
# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: ghost-app
spec:
selector:
matchLabels:
app: ghost-app
replicas: 1
template:
metadata:
labels:
app: ghost-app
spec:
containers:
- name: ghost-app
image: ghost
ports:
- containerPort: 2368
env:
- name: url
value: http://us-east.non-prod.myapp.org
هذا النهج يقلل التكرار بشكل كبير، ويجعل عملية النشر عبر خطوط CI/CD أكثر تنظيماً وقابلية للتوسع.
النشر الفعلي للتطبيق المخصص
يمكنك الآن تنفيذ النشر النهائي لبيئة الإنتاج:
$ helm install -f my-ghost-app/values.prod.yaml my-ghost-prod ./my-ghost-app/
NAME: my-ghost-prod
LAST DEPLOYED: Mon Dec 21 00:09:17 2020
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
وبعد التحقق من عمل التطبيق عبر http://localhost، يمكن حذف الإصدار ثم إعادة نشره بإعدادات مختلفة:
$ helm delete my-ghost-prod
release "my-ghost-prod" uninstalled
$ helm install -f my-ghost-app/values.nonprod.yaml -f my-ghost-app/values.us-east.yaml my-ghost-nonprod ./my-ghost-app
وأخيراً يمكن تنظيف البيئة:
$ helm delete my-ghost-nonprod
أهم فوائد Helm للمشاريع التقنية
- توحيد إعدادات النشر بدلاً من تكرار ملفات
YAMLيدوياً. - تسهيل الترقية والتراجع مع الاحتفاظ بسجل الإصدارات.
- تسريع إطلاق التطبيقات المعقدة عبر
Chartsجاهزة. - تحسين قابلية الصيانة عند تعدد البيئات ومراكز البيانات.
- دعم الأتمتة داخل خطوط النشر المستمر
CI/CD.
أفضل الممارسات عند استخدام Helm Charts
- ابدأ بمعاينة القوالب عبر
helm templateقبل النشر الفعلي. - افصل القيم الافتراضية عن قيم البيئات المختلفة في ملفات مستقلة.
- استخدم أسماء إصدارات واضحة تسهّل الإدارة والمتابعة.
- راقب الحاويات والمقاييس بعد كل ترقية، خاصة في الإنتاج.
- اعتمد على
Chartsموثوقة ومحدّثة من مصادر معروفة.
الخلاصة التقنية
إذا كنت تدير تطبيقات على Kubernetes بصورة متكررة أو على نطاق متنامٍ، فإن Helm ليس مجرد أداة إضافية، بل طبقة تنظيمية مهمة فوق البنية نفسها. قوته الحقيقية تظهر عندما تجمع بين القوالب المرنة، وسهولة إدارة الإصدارات، والقدرة على بناء مسارات نشر قابلة للتكرار. من الناحية العملية، كلما زاد تعقيد التطبيق أو عدد البيئات، أصبحت الاستفادة من Helm Charts أكبر وأكثر وضوحاً.