بنينا تطبيقًا يعمل عبر الـ Deployment، لكن كيف نصل إليه؟ الإجابة هي الخدمة (Service). هذا درس متوسّط المستوى.
لماذا نحتاج الخدمات؟
تذكّر أنّ الـ pods مؤقّتة: تُنشأ وتُحذف باستمرار، ولكلّ pod جديد عنوان IP جديد. فكيف يعتمد عليها ترافيك ثابت وعناوينها متغيّرة؟
الخدمة تحلّ هذا: توفّر نقطة وصول ثابتة (اسم وعنوان لا يتغيّران) أمام مجموعة pods، وتوزّع الطلبات عليها. تستخدم التسميات (Labels) لتعرف أي pods تخدم، تمامًا كما رأينا مع الـ ReplicaSet.
apiVersion: v1
kind: Service
metadata:
name: web-svc
spec:
type: ClusterIP
selector:
app: web
ports:
- port: 80
targetPort: 80
الأنواع الثلاثة
يحدّد حقل type كيف تُكشَف الخدمة:
- ClusterIP (الافتراضي): تمنح عنوانًا داخليًا لا يُوصَل إليه إلّا من داخل العنقود. مثالية للتخاطب بين الخدمات الداخلية (مثلًا: خدمة تصل إلى قاعدة بيانات).
- NodePort: تفتح منفذًا على كل عقدة في العنقود، فيمكن الوصول من خارجه عبر
<عنوان-العقدة>:<المنفذ>. مفيدة للتجارب، لكنّها بدائية للإنتاج. - LoadBalancer: تطلب موزّع أحمال من مزوّد السحابة يوجّه الترافيك الخارجي إلى خدمتك. الخيار المعتاد لكشف الخدمات للإنترنت في السحابة.
كيف تختار؟
| احتاجك | النوع |
|---|---|
| تخاطب داخلي بين الخدمات | ClusterIP |
| وصول خارجي سريع للتجربة | NodePort |
| كشف للإنترنت في السحابة | LoadBalancer |
القاعدة: ابدأ بـ ClusterIP لكل شيء داخلي، واستخدم LoadBalancer عند الحاجة لكشف خدمة للعالم الخارجي.
الخطوات التالية
الخدمات تكشف تطبيقك، لكن كشف كل خدمة عبر LoadBalancer مكلف؛ لتوجيه HTTP الذكي عبر مدخل واحد نستخدم الـ Ingress. ولتنظيم مواردك، تعرّف على الـ Namespaces.