شرح Helm Charts: مدير الحزم في Kubernetes بطريقة عملية

دقائق القراءة: 10

ما هو 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 Charts لإدارة ونشر التطبيقات على Kubernetes

كيف يعمل 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.yaml
  • my-ghost-app/templates/serviceaccount.yaml
  • my-ghost-app/templates/ingress.yaml
  • my-ghost-app/templates/hpa.yaml
  • my-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

  1. ابدأ بمعاينة القوالب عبر helm template قبل النشر الفعلي.
  2. افصل القيم الافتراضية عن قيم البيئات المختلفة في ملفات مستقلة.
  3. استخدم أسماء إصدارات واضحة تسهّل الإدارة والمتابعة.
  4. راقب الحاويات والمقاييس بعد كل ترقية، خاصة في الإنتاج.
  5. اعتمد على Charts موثوقة ومحدّثة من مصادر معروفة.

الخلاصة التقنية

إذا كنت تدير تطبيقات على Kubernetes بصورة متكررة أو على نطاق متنامٍ، فإن Helm ليس مجرد أداة إضافية، بل طبقة تنظيمية مهمة فوق البنية نفسها. قوته الحقيقية تظهر عندما تجمع بين القوالب المرنة، وسهولة إدارة الإصدارات، والقدرة على بناء مسارات نشر قابلة للتكرار. من الناحية العملية، كلما زاد تعقيد التطبيق أو عدد البيئات، أصبحت الاستفادة من Helm Charts أكبر وأكثر وضوحاً.

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *