تطوير الويب

Pods وDeployments وJobs وأنماط متعددة الحاويات CKAD 2026

6 دقائق للقراءة

السلسلة: هذا الدرس جزء من سلسلة شهادة CKAD. للحصول على نظرة شاملة، اقرأ المقال الرئيسي أولاً.

مقدمة

المجالان 1 و2 من منهج CKAD يزنان وحدهما 40% من الامتحان. يغطّيان ما يفعله المطوّر يومياً على Kubernetes: إنشاء Pod، نشره بعدة نسخ عبر Deployment، إطلاق مهمة واحدة بـ Job، جدولة مهام دورية بـ CronJob، ودمج عدة حاويات في Pod واحدة عبر أنماط sidecar وinit container. هذا الدرس يطبّق كل نمط على عنقود kind 1.35، مع توليد manifests بـ dry-run، تعديل مباشر، وتشخيص منهجي.

المتطلبات

  • عنقود kind 1.35 شغّال من الدرس السابق
  • aliases k=kubectl و$do=--dry-run=client -o yaml مضبوطة
  • 40 دقيقة

الخطوة 1 — إنشاء Pod بسيطة بـ dry-run

قاعدة ذهبية في امتحان CKAD: لا تكتب manifest YAML باليد أبداً. ابدأ دائماً من dry-run، احفظ في ملف، ثم عدّل عند الحاجة. هذا الانضباط ينقذ 30-40 ثانية في كل مهمة، أي 10 دقائق محتملة على الامتحان كاملاً.

k run nginx-pod --image=nginx:1.27 $do > pod.yaml
cat pod.yaml
k apply -f pod.yaml
k get pod nginx-pod
k describe pod nginx-pod | grep -E "Image|Status|Node"

مخرَج k describe يجب أن يُظهر Status: Running، Image: nginx:1.27، وNode مُسنَداً. هذا التسلسل — generate، apply، verify — هو قلب workflow CKAD. اعتمده حتى تنفّذه دون تفكير.

الخطوة 2 — إنشاء Deployment بـ 3 نسخ

Deployment هو الـ workload الأكثر استخداماً عملياً. يحفظ عدد النسخ المرغوب عبر ReplicaSet تحته، ويُدير rolling updates تلقائياً.

k create deployment web --image=nginx:1.27 --replicas=3 $do > deploy.yaml
k apply -f deploy.yaml
k get deploy,rs,pods -l app=web
k rollout status deployment/web

يجب أن ترى 1 Deployment، 1 ReplicaSet، و3 Pods، كلها موسومة app=web. الأمر kubectl rollout status ينتظر جهوزية كل Pods — مفيد لسكربتات CI/CD.

الخطوة 3 — تدريب rolling update وrollback

الامتحان يطرح بانتظام أسئلة عن استراتيجية النشر والـ rollback. التدريب جوهري لعدم التردّد تحت الضغط.

k set image deployment/web nginx=nginx:1.28
k rollout status deployment/web
k rollout history deployment/web
k rollout undo deployment/web --to-revision=1
k describe deployment web | grep Image:

يجب أن ترى الصورة تعود إلى nginx:1.27 بعد rollback. --to-revision=N ثمين: بدونه، rollout undo يرجع إلى السابقة فقط.

الخطوة 4 — Pod متعددة الحاويات بـ sidecar

نمط sidecar مركزي في CKAD: حاوية رئيسة وحاوية ثانوية تثريها (logging، proxy، تحديث ملفات). الاثنتان تتقاسمان volume.

cat > sidecar-pod.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
  name: web-with-logger
spec:
  volumes:
    - name: shared-logs
      emptyDir: {}
  containers:
    - name: web
      image: nginx:1.27
      volumeMounts:
        - name: shared-logs
          mountPath: /var/log/nginx
    - name: log-shipper
      image: busybox:1.37
      command: ["sh","-c","tail -F /logs/access.log"]
      volumeMounts:
        - name: shared-logs
          mountPath: /logs
EOF

k apply -f sidecar-pod.yaml
k get pod web-with-logger
k logs web-with-logger -c log-shipper

حاوية log-shipper تشتغل موازية لـ nginx وتقرأ ملف الوصول عبر volume المشترك shared-logs. هذا تماماً ما تفعله Fluent Bit أو Vector في الإنتاج. في الامتحان، ستُختبَر على الأرجح بقراءة multi-conteneurs بـ -c <container>.

الخطوة 5 — Init container للتحضير

Init container ينفَّذ قبل الحاويات الرئيسة ويجب أن ينتهي بـ exit 0 لتُطلَق الأخرى. نمط كلاسيكي: انتظار تبعية خارجية أو تنزيل بيانات.

cat > init-pod.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
  name: app-with-init
spec:
  initContainers:
    - name: wait-for-db
      image: busybox:1.37
      command: ["sh","-c","until nslookup my-db; do echo waiting; sleep 2; done"]
  containers:
    - name: app
      image: nginx:1.27
EOF

k apply -f init-pod.yaml
k get pod app-with-init -w

الـ Pod ستبقى في حالة Init:0/1 طالما لم تكن الخدمة my-db موجودة — متعمَّد لإظهار الآلية. اقتل الأمر بـ Ctrl+C ونظّف بـ k delete pod app-with-init $now.

الخطوة 6 — Job لتنفيذ مرة واحدة

Job ينفّذ Pod حتى الانتهاء بنجاح. يُستخدم لمهام batches: ترحيل قاعدة بيانات، استيراد بيانات أولية، حساب ظرفي.

k create job pi-calc --image=perl:5.40 -- perl -Mbignum=bpi -wle "print bpi(200)" $do > job.yaml
k apply -f job.yaml
k get jobs
k logs job/pi-calc

المخرَج يعرض 200 خانة عشرية من باي. الـ Job يبقى Completed ولا يُحذف تلقائياً — مفيد لاسترداد السجلات. للتنظيف: k delete job pi-calc. لـ auto-cleanup، أضف spec.ttlSecondsAfterFinished: 60 في manifest.

الخطوة 7 — CronJob للجدولة الدورية

CronJob ينشئ Jobs حسب تعبير cron Linux. لا غنى عنه للنسخ الاحتياطي الليلي، التقارير اليومية، التنظيف الدوري.

k create cronjob daily-report --image=busybox:1.37 --schedule="*/2 * * * *" -- echo "Daily report $(date)" $do > cron.yaml
k apply -f cron.yaml
k get cronjobs
sleep 130
k get jobs
k logs job/daily-report-XXXXX

كل دقيقتين، Job جديدة تُنشأ. schedule يتبع بنية cron الكلاسيكية: دقائق، ساعات، يوم الشهر، شهر، يوم الأسبوع. المعامل successfulJobsHistoryLimit (افتراضياً 3) يتحكم بعدد Jobs الناجحة المحفوظة.

الخطوة 8 — تشخيص Pod في خطأ

التشخيص مُختبَر في المجال 5 لكنه ردّ فعل ينبغي امتلاكه منذ المجال 1. الأوامر الجوهرية هي describe، logs، events، exec.

k run broken --image=nginx:nonexistent-tag
sleep 10
k get pod broken
k describe pod broken | tail -20
k get events --sort-by=.lastTimestamp | tail -10
k delete pod broken $now

سترى Status: ImagePullBackOff في describe وحدث «Failed to pull image» في events. هذه الإجراء التشخيصي المنهجي — describe أولاً، events ثانياً — ما يربح أسئلة التشخيص في الامتحان.

الخطوة 9 — DaemonSet لـ Pod لكل عقدة

DaemonSet ينشر Pod تلقائياً على كل عقدة من العنقود. حالات استخدام: وكلاء logging (Fluent Bit)، رصد (node-exporter)، أو شبكة (CNI plugins).

cat > daemonset.yaml <<'EOF'
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: log-agent
spec:
  selector:
    matchLabels:
      app: log-agent
  template:
    metadata:
      labels:
        app: log-agent
    spec:
      containers:
        - name: agent
          image: busybox:1.37
          command: ["sh","-c","while true; do echo collecting on $HOSTNAME; sleep 30; done"]
EOF

k apply -f daemonset.yaml
k get ds,pods -l app=log-agent -o wide

على عنقود kind بـ 3 عقد، يجب أن ترى 3 Pods (1 لكل عقدة) — إلا إن حجبت NoSchedule على control-plane. أضف tolerations الملائمة إن أردت Pod أيضاً على control-plane.

فهم الفرق ReplicaSet مقابل Deployment مقابل StatefulSet

سؤال متكرر في الامتحان وفخ كلاسيكي. ReplicaSet هو الأوّلية ذات المستوى المنخفض التي تحفظ N نسخ — لا تستخدمه مباشرة، Deployment يديره. Deployment يضيف استراتيجية تحديث rolling/recreate وتاريخ rollback. يُستخدم لـ 95% من التطبيقات stateless. StatefulSet يضيف هويات ثابتة (pod-0، pod-1، pod-2) وPersistentVolumeClaims مخصّصة لكل نسخة — لا غنى عنه لقواعد البيانات، message queues، الخدمات التي تتطلب quorum.

الفخ: استخدام Deployment لـ MongoDB أو Postgres. «يشتغل» عند التشغيل، لكن في أول rolling update، تفقد هوية كل نسخة وينكسر quorum. القاعدة البسيطة: إن وجب على Pods معرفة ترتيبها والاحتفاظ بـ volume بين إعادات التشغيل، فهو StatefulSet.

أخطاء شائعة

الخطأ السبب الحل
Pod في CrashLoopBackOff صورة تنهار فوراً kubectl logs --previous لرؤية انهيار النسخة السابقة
Init container يحجب التطبيق Init container لا ينتهي kubectl logs POD -c INIT_CONTAINER ثم صحّح الأمر
CronJob لا يطلق أبداً Schedule سيئ الصياغة أو مُعلَّق تحقّق kubectl get cronjob -o wide، انظر ACTIVE/LAST SCHEDULE
Rolling update عالق Pods في خطأ، MaxSurge مُستهلَك kubectl rollout undo ثم صحّح في dev
DaemonSet لا ينشر على control-plane Taint NoSchedule افتراضي أضف tolerations في PodSpec عند الحاجة

دروس مرافقة

أسئلة شائعة

ما المهلة بين Job وPod؟
لا مهلة. Job ينشئ فوراً Pod واحدة أو أكثر حسب spec.parallelism. يبقى Job قائماً ما لم تكتمل كل Pods بنجاح.

هل يمكن تغيير عدد نسخ Job؟
نعم عبر spec.completions (العدد الكلي) وspec.parallelism (العدد المتزامن). للأعمال parallelisables بلا تنسيق، فعّال جداً.

مقالات ذات صلة

Sponsoriser ce contenu

Cet emplacement est à vous

Position premium en fin d'article — c'est l'instant où les lecteurs sont le plus engagés. Réservez cet espace pour votre marque, votre formation ou votre offre.

Recevoir nos tarifs
Publicité