يربط هذا الدرس الختامي كل ما تعلمته في التيوتوريال معاً: Ingress مع إنهاء TLS، وعزل الشبكة عبر NetworkPolicy، وتخزين دائم باستخدام PersistentVolumeClaim — وكل ذلك على مجموعة تطبيقات واقعية. المثال هو Guestbook API (واجهة خلفية بـ Node.js لا تحتفظ بحالة، مقرونة بنسخة Redis تحتفظ بالبيانات)، غير أن كل تقنية تُطبَّق مباشرةً على خدمات Java في الإنتاج، أو خطوط بيانات Python، أو أي حمل عمل يحتاج إلى حالة.
ما ستبنيه: نشران (api + redis)، وخدمتان، وIngress واحد بشهادة TLS من Let's Encrypt، وNetworkPolicy تقصر الاتصال على المسار api → redis فقط، وPersistentVolumeClaim يبقى سليماً بعد إعادة تشغيل البود وفشل العقدة.
الخطوة 1 — Namespace وعزل الموارد
أعطِ دائماً لكل تطبيق حقيقي Namespace خاصاً به. يمنحك ذلك حدود RBAC واضحة، ويجعل مخرجات kubectl مقروءة، ويسمح لمحددات NetworkPolicy بالتأثير فقط على البودات التي تعنيك.
Redis هو مخزن في الذاكرة، لكن خاصية الاستمرارية (RDB/AOF) تكتب على القرص. بدون PVC، يُفقد كل البيانات عند إعادة تشغيل البود. يطلب الـ PVC أدناه حجم 10Gi من StorageClass الافتراضي في الكلستر — على AWS هو gp3، وعلى GKE هو standard-rwo. وضع الوصول ReadWriteOnce صحيح: Redis عملية كتابة واحدة ولا يجوز مشاركة الحجم مع نسخة أخرى.
لماذا Headless لـ Redis؟ الخدمة الـ Headless (clusterIP: None) تجعل DNS يُعيد IP البود مباشرةً بدلاً من VIP. يتيح ذلك لعملاء Redis استخدام منطق consistent-hashing أو تجميع الاتصالات دون نقرة إضافية عبر kube-proxy.
الخطوة 3 — نشر API بلا حالة وخدمته
الـ API قابل للتوسع أفقياً: ثلاث نسخ، بدون حالة محلية. يقرأ متغير البيئة REDIS_HOST لتحديد موقع Redis. نوع الخدمة هو ClusterIP — يجب أن لا تكون LoadBalancer لأن Ingress controller سيوجه حركة المرور إليها داخلياً.
هنا يدخل الحركة الخارجية إلى الكلستر. يفترض المانيفست أدناه أنك تستخدم ingress-nginx controller وcert-manager مع ClusterIssuer باسم letsencrypt-prod. الحاشية cert-manager.io/cluster-issuer هي كل ما تحتاج إضافته — cert-manager يراقبها، ويستصدر شهادة TLS عبر ACME HTTP-01، ويخزنها في Secret باسم guestbook-tls. يقرأ Ingress controller هذا السيكريت ثم يُنهي TLS قبل إعادة توجيه HTTP العادي إلى الخدمة الخلفية.
يجب أن يحل DNS قبل أن يتمكن cert-manager من إصدار الشهادة. أنشئ سجل DNS من نوع A يشير guestbook.example.com إلى الـ IP الخارجي لـ Ingress controller قبل تطبيق هذا المانيفست. سيفشل cert-manager في التحقق عبر ACME HTTP-01 — ويتراجع بشكل متصاعد — إذا لم يُحل النطاق. استخدم kubectl describe certificate guestbook-tls -n guestbook لمتابعة حالة الإصدار.
بشكل افتراضي، يسمح Kubernetes بكل حركة المرور بين البودات داخل الكلستر. في الإنتاج، يعني ذلك أن بود API مخترقاً يمكنه الاتصال مباشرةً بأي قاعدة بيانات أو مخزن أسرار أو نقطة تحكم داخلية. تفرض NetworkPolicies وضعية أمان الشبكة بمبدأ أقل الصلاحيات. السياستان أدناه تُطبقان قائمة سماح صارمة:
Redis يقبل TCP/6379 فقط من البودات المُعلَّمة بـ tier: api في نفس الـ namespace.
الـ API يقبل المنفذ 8080 من namespace الـ Ingress controller فقط، ولا شيء آخر.
مسار الطلب من البداية إلى النهاية: تُنهى HTTPS عند Ingress controller، ثم تُوجَّه إلى بودات الـ API (محمية بـ NetworkPolicy)، التي تكتب البيانات الدائمة في Redis المدعوم بـ PVC.
الخطوة 6 — التطبيق والتحقق
طبِّق كل شيء بترتيب التبعيات، ثم تأكد من صحة كل طبقة قبل الانتقال إلى التالية.
# تطبيق جميع المانيفستات
kubectl apply -f redis-pvc.yaml
kubectl apply -f redis-deployment.yaml
kubectl apply -f api-deployment.yaml
kubectl apply -f ingress.yaml
kubectl apply -f network-policy.yaml
# التحقق من أن PVC في حالة Bound (الـ StorageClass وفّر الحجم)
kubectl get pvc -n guestbook
# التحقق من أن البودات في حالة Running وجاهزة
kubectl get pods -n guestbook -w
# التحقق من أن Ingress يمتلك عنواناً (الـ IP الخارجي لـ LB)
kubectl get ingress -n guestbook
# مراقبة إصدار شهادة TLS من cert-manager (~60 ثانية على كلستر سليم)
kubectl describe certificate guestbook-tls -n guestbook
# اختبار سريع للنقطة النهائية المباشرة
curl -v https://guestbook.example.com/healthz
# اختبار تطبيق NetworkPolicy: يجب أن ينتهي بمهلة (لا مسار من default إلى redis)
kubectl run test-pod --rm -it --image=busybox --namespace=default \
-- sh -c "nc -zv redis.guestbook.svc.cluster.local 6379"
# يجب أن ينجح (بود من طبقة api → redis)
kubectl exec -n guestbook deploy/guestbook-api \
-- sh -c "nc -zv redis.guestbook.svc.cluster.local 6379"
أنماط الفشل في الإنتاج والتحصين
لكل خطوة في هذا المشروع نمط فشل مقابل يظهر في الكلسترات الحقيقية:
PVC عالق في Pending — الـ StorageClass غير موجود أو CSI driver غير مُثبَّت. شغِّل kubectl describe pvc redis-data -n guestbook؛ ابحث في قسم Events عن خطأ الـ provisioner.
الشهادة عالقة في Pending — لم ينتشر DNS بعد، أو تحدي ACME HTTP-01 محجوب بسبب NetworkPolicy. يُنشئ cert-manager Ingress مؤقتاً وبود تحدٍّ HTTP في namespace الخاص به. تأكد من أن NetworkPolicy في namespace الـ API لا تمنع المنفذ 80 الوارد من cert-manager.
502 Bad Gateway من Ingress — فحص الجاهزية (readiness probe) يفشل، لذا لا أعضاء في Endpoints. صِف البود وافحص سجلات الفحص: kubectl describe pod -n guestbook -l app=guestbook-api.
فقدان البيانات بعد إعادة تشغيل بود Redis — نسيت تركيب PVC، أو أُحذف PVC. دائماً عيِّن reclaimPolicy: Retain على StorageClasses في الإنتاج للحماية من الحذف العرضي للـ PVC.
أدِر مجموعة المانيفستات هذه بـ GitOps. أودِع جميع ملفات YAML في مستودع وأدِرها بـ Argo CD أو Flux. بذلك، يصبح kubectl delete namespace guestbook (عرضياً أو خبيثاً) حدثاً ذاتي الإصلاح — يُعيد مراقب GitOps إنشاء الـ namespace ويُعيد مزامنة كل مورد في غضون ثوانٍ.
نستخدم ملفات تعريف الارتباط لتشغيل هذا الموقع وتحليل الزيارات وعرض إعلانات مخصّصة. يمكنك قبول كل ملفات تعريف الارتباط أو رفض غير الأساسية منها.
سياسة الخصوصية