كيف تصبح مطور تطبيقات معتمدًا في Kubernetes: دليل عملي لاجتياز شهادة CKAD
مقدمة إلى شهادة CKAD ولماذا تستحق الاهتمام
إذا كنت تعمل على بناء التطبيقات السحابية الحديثة، فإن إتقان Kubernetes لم يعد ميزة إضافية، بل أصبح مهارة أساسية في كثير من الفرق التقنية. وشهادة Certified Kubernetes Application Developer أو CKAD تعد من أبرز الشهادات التي تثبت قدرتك على تطوير التطبيقات وتشغيلها وإدارتها داخل بيئة Kubernetes بكفاءة.
هذا الدليل العربي صُمم ليكون مرجعًا عمليًا ومكثفًا لكل من يريد فهم المفاهيم الأساسية والمتقدمة المرتبطة بالشهادة، وحتى لمن لا يخطط لخوض الاختبار حاليًا. ستجد هنا شرحًا مركزًا، وأمثلة تطبيقية، وأوامر مهمة، ونصائح عملية تساعدك في العمل اليومي أيضًا.

عند كتابة المقال الأصلي، كان توزيع محاور شهادة CKAD تقريبًا كما يلي:
13%المفاهيم الأساسية18%الإعداد والتهيئة10%الحاويات المتعددة داخلPod18%المراقبة والرصد20%تصميمPod13%الخدمات والشبكات8%استمرارية البيانات
يفترض هذا الدليل أنك تعرف أساسيات الحاويات وPods مسبقًا، وتبحث الآن عن مستوى أكثر احترافية.
مدخل عملي إلى Kubernetes
Kubernetes هو نظام لإدارة التطبيقات المعتمدة على الحاويات عبر عدة عقد Nodes. وهو يسهّل نشر التطبيقات، وجدولتها، ومراقبتها، وتوسيعها، والحفاظ على استقرارها بشكل آلي.
من أبرز مميزاته:
- نشر التطبيقات وإدارتها بصورة تصريحية
Declarative - المراقبة واستعادة الخدمة تلقائيًا
- التوسع التلقائي
- التخزين الدائم
- الجدولة الذكية للأحمال
يعتمد Kubernetes على مبدأ تحديد الحالة المرغوبة للنظام، ثم يتولى هو العمل للوصول إليها والمحافظة عليها. ويتم التفاعل مع خادم الواجهة البرمجية API Server عبر:
- استدعاءات
REST - أداة سطر الأوامر
kubectl
إذا لم يكن لديك عنقود جاهز، يمكنك استخدام minikube محليًا للتجربة. وبعد تثبيته، جرّب إنشاء أول Pod عبر الأمر التالي:
kubectl run --image=busybox --restart=Never --rm -it -- echo "Welcome to Kubernetes!!"
سيتم حذف هذا الـ Pod تلقائيًا بعد طباعة الرسالة.
إدارة الموارد داخل العنقود
مساحات الأسماء Namespaces
تسمح Namespaces بتقسيم العنقود الواحد إلى مساحات منطقية مستقلة. يفيد هذا في:
- فصل البيئات مثل التطوير والاختبار والإنتاج
- تقسيم الأنظمة الكبيرة إلى مكونات أصغر
- منع تعارض الأسماء بين الموارد
يمكنك إنشاء مساحة أسماء جديدة كالتالي:
kubectl create ns my-namespace
حصص الموارد Resource Quotas
عند الحاجة إلى تقييد عدد الموارد داخل مساحة أسماء معينة، يمكن استخدام ResourceQuota. على سبيل المثال، لتحديد عدد الكائنات من نوع Secret بحد أقصى يساوي 2:
apiVersion: v1
kind: ResourceQuota
metadata:
name: my-quota
spec:
hard:
secrets: "2"
يمكن حفظه في ملف مثل my-quota.yaml ثم تطبيقه:
kubectl apply -f my-quota.yaml
أو مباشرة عبر سطر الأوامر:
kubectl create quota my-quota --hard="secrets=2"
الوسوم Labels
الوسوم هي أزواج key=value تُستخدم لتنظيم الموارد وتصفيتها وربطها ببعضها. وهي عنصر محوري في تشغيل Deployments وServices.
مثال: إذا أضفت الوسم tier=backend إلى مجموعة من الـ Pods، يمكنك استرجاعها بالأمر:
kubectl get pods -l tier=backend
أوامر مفيدة مرتبطة بالوسوم:
# إضافة وسم إلى Pod
kubectl label pods pod-name key=value
# إزالة وسم
kubectl label pods pod-name label_key-
# عرض الوسوم
kubectl get pods --show-labels
# التصفية بواسطة الوسوم
kubectl get pods -l 'tier in (frontend,backend)'
kubectl get pods -l tier=frontend,deployer=coolest-team
التعليقات الوصفية Annotations
تشبه Annotations الوسوم من حيث البنية، لكنها لا تُستخدم للاختيار أو التصفية. الغرض منها تزويد أدوات خارجية بمعلومات إضافية.
مثال شائع: توجيه Prometheus لجمع المقاييس من خدمة محددة:
metadata:
labels:
name: fluentd-elasticsearch
annotations:
prometheus.io/scrape: 'true'
prometheus.io/port: '9102'
ما بعد Pods وDeployments
يُعد Pod أصغر وحدة تشغيلية في Kubernetes. لكن لأن الـ Pods مؤقتة بطبيعتها، نحتاج إلى آليات تحافظ على استمرار التطبيق، مثل Deployment الذي يضمن بقاء عدد محدد من النسخ Replicas قيد التشغيل.
كما يتيح Deployment إمكانات مهمة مثل:
- تحديثات تدريجية
Rolling Updates - الرجوع إلى إصدار سابق
- التحكم بعدد النسخ
الـ Pods متعددة الحاويات
يمكن أن يحتوي الـ Pod الواحد على أكثر من حاوية، وتتشارك هذه الحاويات الشبكة نفسها ويمكنها أيضًا مشاركة البيانات عبر Volumes.
نمط Sidecar
في هذا النمط، تعمل الحاوية الأساسية بجوار حاوية مساعدة تؤدي وظائف داعمة، مثل:
- جمع السجلات
- المراقبة
- تحديث ملفات مشتركة
- إنهاء
TLS
نمط Adapter
تُستخدم حاوية إضافية لتحويل أو تبسيط مخرجات الحاوية الأساسية قبل إرسالها إلى نظام خارجي، مثل تبسيط السجلات المعقدة.
نمط Ambassador
تعمل الحاوية الثانوية كوسيط أو وكيل Proxy بين التطبيق والعالم الخارجي، مثل اختيار قاعدة البيانات المناسبة حسب البيئة.
الخدمات والشبكات في Kubernetes
الخدمات Services
نظرًا لأن عناوين IP الخاصة بالـ Pods قد تتغير، توفر Service عنوانًا ثابتًا للوصول إلى مجموعة من الـ Pods.
أنواع الخدمات الأساسية:
ClusterIP: للوصول الداخلي داخل العنقودNodePort: لفتح منفذ على كل عقدةLoadBalancer: للتعريض الخارجي عبر موزّع أحمال سحابي
تعريض تطبيق داخل العنقود
لإنشاء Deployment لتطبيق باسم my-app على المنفذ 80:
kubectl create deploy my-app --image=my-app --port=80
ثم إنشاء خدمة داخلية:
kubectl expose deploy my-app --port=80
تعريض تطبيق خارج العنقود
يمكنك استخدام خدمة من نوع NodePort كما يلي:
kind: Service
apiVersion: v1
metadata:
name: my-svc
spec:
type: NodePort
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
كائن Ingress
يوفر Ingress نقطة دخول ذكية إلى خدمات العنقود، وعادة يحتاج إلى Ingress Controller مثل Nginx. ورغم أنه خارج جوهر الشهادة في بعض الإصدارات، فإن فهمه مهم عمليًا.
المهام الدورية والمؤقتة
المهام Jobs
تُستخدم Job لتنفيذ أعمال تنتهي مرة واحدة بنجاح، مثل النسخ الاحتياطي أو تصدير البيانات أو تنفيذ معالجة دفعية.
مثال لإنشاء مهمة بسيطة:
kubectl create job my-job --image=busybox -- echo "Hello World"
المهام المجدولة CronJobs
إذا كنت تحتاج إلى تشغيل مهمة بشكل دوري، فاستخدم CronJob.
kubectl create cronjob my-job --image=busybox --schedule="*/1 * * * *" -- echo "Hello World"
من المهم الانتباه إلى ثلاث نقاط:
- قد لا يبدأ التنفيذ في اللحظة الدقيقة المطلوبة دائمًا
- قد يتم تشغيل أكثر من مهمة في الوقت نفسه، لذا يجب أن تكون العملية
Idempotent - قد لا تُنشأ أي مهمة في بعض الظروف، لذلك ينبغي أن تكون المهمة قادرة على تعويض العمل الفائت
DaemonSet وStatefulSet وStatic Pods
رغم أنها ليست محورًا أساسيًا في الشهادة دائمًا، فمن المهم معرفة وظائفها بإيجاز:
DaemonSet: يضمن تشغيل نسخة منPodعلى كل عقدةStatefulSet: مناسب للتطبيقات ذات الحالةStatefulStatic Pods: تُدار مباشرة بواسطةkubeletبدلًا من واجهةAPI
تهيئة Pods والحاويات باحترافية
حاويات التهيئة Init Containers
تُستخدم Init Containers لتحضير البيئة قبل تشغيل الحاويات الأساسية، مثل تنزيل ملفات أو انتظار خدمة أخرى.
spec:
initContainers:
- name: init-myservice
image: busybox:1.28
command:
- 'sh'
- '-c'
- "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"
خرائط الإعداد ConfigMaps
تفصل ConfigMaps إعدادات التطبيق غير السرية عن الشيفرة المصدرية. ويمكن استخدامها كمتغيرات بيئة أو ملفات أو معاملات تشغيل.
# من قيم مباشرة
kubectl create configmap my-map --from-literal=db_url=my-url --from-literal=username=username
# من ملف
kubectl create configmap another-map --from-file=my-file
مثال لاستخدام ConfigMap داخل Pod:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
restartPolicy: Never
containers:
- name: busybox
image: busybox
args:
- /bin/sh
- -c
- "echo $MY_VARIABLE"
env:
- name: MY_VARIABLE
valueFrom:
configMapKeyRef:
name: another-map
key: my-key
envFrom:
- configMapRef:
name: another-map
volumeMounts:
- name: config
mountPath: "/config"
readOnly: true
volumes:
- name: config
configMap:
name: my-map
الأسرار Secrets
تعمل Secrets بطريقة مشابهة لـ ConfigMaps، لكنها مخصصة للبيانات الحساسة مثل كلمات المرور والمفاتيح.
kubectl create secret generic secret-name --from-literal=password=password
kubectl create secret generic secret-name --from-file=path-to-file
مثال على استخدام Secret:
apiVersion: v1
kind: Pod
metadata:
name: another-pod
spec:
restartPolicy: Never
containers:
- name: busybox
image: busybox
args:
- /bin/sh
- -c
- "echo $MY_VARIABLE"
env:
- name: MY_VARIABLE
valueFrom:
secretKeyRef:
name: my-secret2
key: username
envFrom:
- secretRef:
name: yet-another-secret
volumeMounts:
- name: secret-volume
mountPath: "/secrets"
readOnly: true
volumes:
- name: secret-volume
secret:
secretName: my-secret
فحوصات الصحة والجاهزية
فحص الحياة Liveness Probe
يحدد ما إذا كانت الحاوية ما تزال سليمة وتحتاج إلى الاستمرار أو إعادة التشغيل.
فحص الجاهزية Readiness Probe
يحدد ما إذا كان التطبيق جاهزًا لاستقبال الطلبات. إذا فشل هذا الفحص، فلن يوجّه Kubernetes المرور إلى الحاوية.
فحص بدء التشغيل Startup Probe
مفيد للتطبيقات التي تستغرق وقتًا طويلًا أثناء الإقلاع.
مثال كامل:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- args:
- /bin/sh
- -c
- "sleep 20; touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600"
image: busybox
name: tmp
livenessProbe:
exec:
command:
- echo
- "I'm healthy"
initialDelaySeconds: 5
periodSeconds: 5
readinessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 10
dnsPolicy: ClusterFirst
restartPolicy: Never
status: {}
لمراقبة تغير الحالة:
kubectl get pods --watch
ولمشاهدة الأحداث التفصيلية:
kubectl describe pods my-pod
إدارة الموارد للحاويات
يمكنك تحديد موارد الحاوية عبر:
requests: الحد الأدنى المطلوب للجدولةlimits: الحد الأقصى المسموح للاستهلاك
مثال:
apiVersion: v1
kind: Pod
metadata:
name: resource-limited-pod
spec:
restartPolicy: Never
containers:
- name: busybox
image: busybox
args:
- /bin/sh
- -c
- "echo Hello Kubernetes; sleep 3600"
resources:
requests:
memory: "300Mi"
cpu: 0.2
limits:
memory: "1Gi"
cpu: 0.5
إذا تجاوزت الحاوية حد CPU فسيتم خنقها throttled، وإذا تجاوزت الذاكرة فغالبًا ستُعاد تشغيلها.
جدولة الـ Pods على العقد
Taints وTolerations
تسمح Taints بمنع تشغيل Pods على عقدة معينة ما لم تكن هذه الـ Pods تتحمل هذا القيد عبر Tolerations.
kubectl describe node master
قد ترى مثلًا:
Taints: node-role.kubernetes.io/master:NoSchedule
الارتباط بالعقد Node Affinity
يتيح Node Affinity فرض تشغيل أحمال عمل معينة على عقد تملك خصائص محددة، مثل عتاد خاص أو نوع تخزين معين.
التخزين واستمرارية البيانات
الأحجام Volumes
من دون Volumes ستفقد البيانات عند إعادة تشغيل الحاوية. ويمكن استخدام الأحجام لمشاركة البيانات بين الحاويات داخل الـ Pod.
أنواع شائعة:
emptyDir: مساحة مؤقتة مشتركة داخل الـPodhostPath: ربط مسار من نظام ملفات العقدة- أحجام سحابية خاصة بمزود الخدمة
مثال:
apiVersion: v1
kind: Pod
metadata:
name: with-mounted-volume
spec:
volumes:
- name: my-volume
hostPath:
path: /var/my-k8s-volume
containers:
- args:
- /bin/sh
- -c
- "sleep 3600"
image: busybox
name: bb
volumeMounts:
- name: my-volume
mountPath: /tmp/my-volume-path
restartPolicy: Never
مشاركة البيانات بين حاويتين
apiVersion: v1
kind: Pod
metadata:
name: communicating-containers
spec:
volumes:
- name: vol
emptyDir: {}
containers:
- args:
- sh
- -c
- "while true;do echo 'Hello World' >> /etc/shared/log; sleep 1; done"
image: busybox
name: container-1
volumeMounts:
- name: vol
mountPath: /etc/shared/
- args:
- sh
- -c
- "sleep 3600"
image: busybox
name: container-2
volumeMounts:
- name: vol
mountPath: /etc/a-different-location
restartPolicy: Never
تطبيق المثال:
kubectl apply -f communicating-containers.yaml
kubectl exec -it communicating-containers -c container-2 -- tail -f /etc/a-different-location/log
الأحجام الدائمة Persistent Volumes وطلبات الأحجام PVC
يفصل PersistentVolume وPersistentVolumeClaim بين التطبيق وتقنية التخزين الفعلية.
مثال على PV:
apiVersion: v1
kind: PersistentVolume
metadata:
name: myvolume
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
- ReadWriteMany
storageClassName: normal
hostPath:
path: /etc/foo
ومثال على PVC:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mypvc
spec:
storageClassName: normal
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 4Gi
إنشاؤهما:
kubectl apply -f pv.yaml
kubectl apply -f pvc.yaml
الأمان والشبكات
سياسات الشبكة Network Policies
افتراضيًا، يكون التواصل مسموحًا بين معظم الـ Pods. باستخدام NetworkPolicy يمكنك ضبط المرور الداخل والخارج بدقة.
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: access-db-policy
spec:
podSelector:
matchLabels:
app: db
ingress:
- from:
- podSelector:
matchLabels:
access: allowed
سياق الأمان Security Context
يستخدم Security Context لفرض إعدادات أمنية مثل تشغيل الحاوية بغير المستخدم الجذر root.
spec:
securityContext:
runAsUser: 1000
containers:
- name: my-container
image: alpine
securityContext:
runAsUser: 1001
حسابات الخدمة Service Accounts
تتيح التطبيقات المصادقة مع API Server عند الحاجة للتفاعل مع موارد العنقود.
kubectl create serviceaccount my-sa
ثم ربطها بالـ Pod:
spec:
serviceAccountName: my-sa
containers:
- name: web-server
التحكم بالوصول المعتمد على الأدوار RBAC
يعتمد RBAC على تعريف الأدوار Role أو ClusterRole، ثم ربطها بالحسابات عبر RoleBinding أو ClusterRoleBinding.
المراقبة والاستكشاف وإصلاح الأعطال
معرفة حالة الـ Pods
kubectl get pods
يعرض هذا الأمر الحالة STATUS والعمر AGE وعدد مرات إعادة التشغيل RESTARTS والجاهزية READY.
ولمعلومات أعمق:
kubectl describe pods my-pod
سجلات الحاويات Logs
kubectl logs pod-name [-c container-name] [-n namespace]
وللمتابعة المباشرة:
kubectl logs -f pod-name [-c container-name] [-n namespace]
الدخول إلى الحاوية
kubectl exec -it my-pod -c container -n namespace -- sh
يفيد ذلك في الفحص السريع، لكن لا يُنصح باعتباره حلًا دائمًا لأن التعديلات داخل الـ Pod مؤقتة.
مراقبة استهلاك الموارد
kubectl top pod pod-name
نصائح مهمة لاجتياز اختبار CKAD
استخدام الاختصارات Aliases
alias k='kubectl'
alias kg='k get'
alias kgpo='k get pods'
alias kdpo='k describe pod'
alias kd='k describe'
alias kap='k apply -f'
alias kgpoa='kgpo --all-namespaces'
alias kgpol='kgpo --show-labels'
alias kgpow='kgpo -o wide'
alias kgd='kg deploy'
alias kgs='kg svc'
alias kdd='kd deploy'
alias kds='kd svc'
البحث السريع في سجل الأوامر
استخدم Ctrl + r للبحث التفاعلي داخل سجل الأوامر بدلًا من التمرير اليدوي.
استفد من التوثيق و--help
أثناء الاختبار، لا تضيع وقتك في حفظ كل شيء. استخدم kubectl --help بسرعة قبل الرجوع إلى التوثيق.
kubectl create quota -h
إنشاء ملف YAML أساسي بسرعة
kubectl run nginx --image=nginx --restart=Never --dry-run=client -o yaml > pod.yaml
kubectl run nginx --image=nginx --restart=Never --port=80 --labels=key=val --dry-run=client -o yaml > pod.yaml
خيارات مفيدة:
--rm
-it
مثال على Pod مؤقت لاختبار الخدمات:
kubectl run tmp --image=busybox --restart=Never --rm -it -- /bin/sh
استخدم grep لتصفية المخرجات
kubectl describe pods my-pod | grep -i -C 2 labels
kubectl describe pods my-pod | grep -i -C 2 ip
راقب التغيرات مباشرة
kubectl get pods --watch
احذف الموارد بسرعة عند الخطأ
k delete pods my-pod --force --grace-period=0
تشغيل أوامر مخصصة داخل Pod
kubectl run loop --image=busybox -o yaml --dry-run=client --restart=Never \
-- /bin/sh -c 'for i in {1..10}; do echo "Counting: $i"; done' \
> pod.yaml
ويمكنك أيضًا تشغيل أمر مباشر:
kubectl run busybox --image=busybox -it --restart=Never -- echo 'hello world'
kubectl run busybox --image=busybox -it --restart=Never -- /bin/sh -c 'echo hello world'
متابعة حالة النشر Rollout
kubectl rollout -h
التدريب العملي هو العامل الحاسم
مهما قرأت، سيبقى التطبيق العملي هو الطريق الأسرع لترسيخ المفاهيم. درّب نفسك على إنشاء الموارد، فحص السجلات، اختبار الخدمات من داخل Pod مؤقت، والتعامل مع الأخطاء كما لو كنت داخل الاختبار الحقيقي.
حاول دائمًا العمل تحت وقت محدود، مع الاعتماد فقط على التوثيق الرسمي، لأن هذا يحاكي بيئة الاختبار ويزيد من سرعتك وثقتك.
الخلاصة التقنية
شهادة CKAD ليست مجرد سطر مميز في السيرة الذاتية، بل هي إطار عملي يساعدك على فهم كيفية تصميم التطبيقات السحابية وتشغيلها بطريقة صحيحة داخل Kubernetes. إذا ركزت على المفاهيم الأساسية مثل Pods وDeployments وServices وConfigMaps وSecrets والفحوصات والموارد والتخزين، ثم دعمت ذلك بتدريب عملي منتظم، فستكون مستعدًا جيدًا للاختبار ولسوق العمل معًا.