شبكات Kubernetes والتخزين

Gateway API في Kubernetes

18 دقيقة الدرس 4 من 31

Gateway API في Kubernetes

صُمِّم Kubernetes Ingress عام 2015 لحالة استخدام ضيقة: توجيه حركة HTTP/HTTPS إلى الخدمات الخلفية. مع الوقت، تراكمت عليه تعليقات توضيحية (annotations) خاصة بكل بائع — NGINX وAWS ALB وTraefik وIstio — حتى أصبح manifest الـIngress الواحد نادرًا ما يعمل على كلاسترات مختلفة. Kubernetes Gateway API (وصل إلى GA في الإصدار 1.28 يونيو 2023) هو الجواب المعياري: واجهة برمجية تراعي الأدوار الوظيفية، وتتسم بالتعبيرية والقابلية للتوسع، لإدارة حركة المرور على كل طبقة.

Gateway API مقابل Ingress: Ingress مورد واحد تتحكم فيه فريق واحد. Gateway API يفصل المسؤوليات عبر ثلاثة موارد تعكس الأدوار: GatewayClass وGateway وHTTPRoute (إضافةً إلى TLSRoute وTCPRoute وGRPCRoute). هذا الفصل يطابق مباشرةً كيفية توزيع المسؤوليات بين فرق المنصة والشبكة والتطبيقات في شركات التكنولوجيا الكبرى.

نموذج الأدوار الثلاثية

يُرسّخ Gateway API نموذجًا تنظيميًا يعكس ملكية البنية التحتية الفعلية:

  • GatewayClass — يمتلكه مزود البنية التحتية (فريق السحابة أو مدير الكلاستر). يُعلن عن المتحكم الذي ينفّذ الـGateway (مثل Envoy Gateway أو Cilium أو AWS Load Balancer Controller). فكّر فيه كالمشغّل (driver).
  • Gateway — يمتلكه فريق المنصة/الشبكة. يرتبط بـGatewayClass ويُعرّف المستمعين (المنافذ والبروتوكولات وشهادات TLS). يمكن لـGateway واحد خدمة تطبيقات متعددة.
  • HTTPRoute / GRPCRoute / TLSRoute — يمتلكها فريق التطبيق. ترتبط بـGateway وتُعرّف قواعد التوجيه الدقيقة (مطابقة المسار والترويسة والاستعلام والطريقة؛ توزيع الحركة؛ تعديل الطلبات).
Gateway API three-layer role model Infra Provider Platform Team App Team GatewayClass controller: envoy-gateway implements Gateway listener: HTTPS :443 tls: my-cert-secret attaches attaches HTTPRoute (api-team) path: /api/* backend: api-svc:8080 HTTPRoute (web-team) path: /* host: app.io backend: web-svc:3000 Internet Client HTTPS Request
يُفصل Gateway API مسؤوليات مزود البنية التحتية وفريق المنصة وفريق التطبيق في ثلاثة أنواع موارد مستقلة.

تثبيت متحكم Gateway (Envoy Gateway)

لا تُثبَّت CRDs الخاصة بـGateway API افتراضيًا — تُثبّت الـCRDs مرة واحدة، ثم تُثبّت المتحكم (التطبيق) بشكل منفصل. Envoy Gateway هو التطبيق المرجعي المدعوم من CNCF والمبني على Envoy Proxy.

# تثبيت Gateway API CRDs (القناة القياسية — تشمل HTTPRoute و GRPCRoute و TLSRoute) kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.1.0/standard-install.yaml # تثبيت متحكم Envoy Gateway (الإصدار v1.1) helm install eg oci://docker.io/envoyproxy/gateway-helm \ --version v1.1.0 \ --namespace envoy-gateway-system \ --create-namespace # التحقق من توفر CRDs kubectl get crd gateways.gateway.networking.k8s.io \ httproutes.gateway.networking.k8s.io \ gatewayclasses.gateway.networking.k8s.io # التحقق من تشغيل pod المتحكم kubectl get pods -n envoy-gateway-system

تعريف GatewayClass و Gateway

ينشئ فريق المنصة GatewayClass وGateway مرة واحدة. هذه موارد تشمل الكلاستر كله أو مقيّدة بـnamespace معين، ترتبط بها مسارات فرق التطبيقات دون أن تلمس هي manifest الـGateway.

# --- GatewayClass (نطاق الكلاستر، ينشئه فريق البنية التحتية) --- apiVersion: gateway.networking.k8s.io/v1 kind: GatewayClass metadata: name: envoy spec: controllerName: gateway.envoyproxy.io/gatewayclass-controller --- # --- Gateway (namespace: infra، ينشئه فريق المنصة) --- apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: prod-gateway namespace: infra spec: gatewayClassName: envoy listeners: - name: https port: 443 protocol: HTTPS tls: mode: Terminate certificateRefs: - kind: Secret name: prod-tls-cert namespace: infra allowedRoutes: namespaces: from: Selector selector: matchLabels: gateway-access: "true" # الـnamespaces ذات هذا الليبل فقط يمكنها الارتباط

كتابة HTTPRoute (فريق التطبيق)

يعيش HTTPRoute في namespace فريق التطبيق ويرتبط بالـGateway المشترك. يدعم مطابقة المسارات (exact وprefix وregex)، ومطابقة الترويسات والاستعلامات، وتوزيع الحركة للنشر التدريجي (canary)، وتعديل الطلبات والردود — كل ذلك بدون annotations.

# --- HTTPRoute لخدمة api-service (namespace: api-team) --- apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: api-route namespace: api-team spec: parentRefs: - name: prod-gateway namespace: infra # مرجع عابر للـnamespace؛ يجب أن يسمح Gateway بهذا الـNS sectionName: https # يرتبط بمستمع محدد بالاسم hostnames: - "api.example.com" rules: - matches: - path: type: PathPrefix value: /v2 headers: - name: X-Version value: "2" backendRefs: - name: api-svc-v2 port: 8080 weight: 90 # 90% من الحركة المطابقة إلى v2 - name: api-svc-v1 port: 8080 weight: 10 # 10% كـcanary إلى v1 - matches: - path: type: PathPrefix value: /v1 filters: - type: RequestHeaderModifier requestHeaderModifier: add: - name: X-Deprecated value: "true" backendRefs: - name: api-svc-v1 port: 8080

توزيع الحركة والنشر التدريجي بدون Annotations

يحل حقل weight في backendRefs محل فوضى annotations مثل nginx.ingress.kubernetes.io/canary-weight بمُنشأ أول من نوعه، مستقل عن المتحكم. تقود خطوط تسليم الإنتاج في شركات التكنولوجيا الكبرى (Flagger وArgo Rollouts) هذا الحقل برمجيًا لتحويل الحركة 5% في كل مرة بناءً على بوابات مقاييس، ثم ترقية الإصدار أو التراجع عنه تلقائيًا.

نصيحة الإنتاج: استخدم ReferenceGrant عندما يكون HTTPRoute في namespace مختلف عن Gateway. بدونه يفشل الارتباط بصمت ويبقى المسار غير مرتبط — تحقق من kubectl get httproute -n api-team -o yaml وابحث في .status.parents[].conditions عن Accepted: False بسبب NotAllowedByParent.

GRPCRoute و TLSRoute

Gateway API يُدرك البروتوكولات. لخدمات gRPC المتناظرة، استخدم GRPCRoute الذي يمكنه المطابقة على اسم الخدمة واسم الطريقة — أمر بالغ الأهمية لتوجيه طبقة gRPC دون الحيل المبنية على مسار HTTP. لـTLS الخام (قواعد البيانات وسماسرة MQTT)، يُوجّه TLSRoute بواسطة SNI دون إنهاء جلسة TLS.

أنماط الفشل في الإنتاج

  • المسار لم يرتبط: المشكلة الأكثر شيوعًا. تحقق من kubectl get gateway prod-gateway -n infra -o yaml — عداد .status.listeners[].attachedRoutes يخبرك كم مسارًا مرتبطًا. الصفر عادةً يعني عدم تطابق محدد namespace أو غياب ReferenceGrant.
  • شهادة TLS غير موجودة: إذا كان السر المشار إليه في certificateRefs في namespace مختلف، يحتاج Envoy Gateway إلى ReferenceGrant في ذلك الـnamespace أيضًا — نفس نموذج الثقة العابر للـnamespace كالمسارات.
  • المتحكم لا يُطابق: تراقب متحكمات Gateway API الـGatewayClass.spec.controllerName المحددة. إذا ثبّتت متحكمَين (مثل Nginx وEnvoy)، فقط المطابق للاسم يُطابق الـGateway. الآخر يتجاهله.
  • تفاوت إصدارات CRD: تشغيل متحكم v1.1 مع CRDs v1.0 (أو العكس) يتسبب في فشل مُطابقة صامت. طابق دائمًا إصدارات المتحكم والـCRD في CI قبل الترقية للإنتاج.
لا تخلط بين Ingress وHTTPRoute لنفس اسم المضيف. قد يُثبّت كل من متحكمات Ingress ومتحكمات Gateway API موازنات حمل منفصلة. تشغيل كليهما لـapp.example.com ينشئ عنوانَي IP خارجيَّين يتنافسان على نفس سجل DNS، مما يؤدي إلى أخطاء 502 متقطعة وتوجيه لا يمكن التنبؤ به — صعب جدًا تشخيصه في الساعة الثالثة صباحًا.

المراقبة: قراءة حالة المسار

كل مورد من موارد Gateway API يكشف conditions مُهيكلة في .status. أتمتة فحوصات الصحة في خط CD الخاص بك بقراءة هذه الحالات — المسار الذي يُنشر بدون خطأ لكنه لا يرتبط أبدًا هو فشل صامت لم يكن Ingress ليكشفه أبدًا.

# فحص حالة مستمع Gateway وعدد المسارات المرتبطة kubectl get gateway prod-gateway -n infra -o jsonpath='{.status.listeners[*]}' | jq . # فحص شروط ارتباط HTTPRoute kubectl get httproute api-route -n api-team \ -o jsonpath='{.status.parents[*].conditions}' | jq . # المخرج الصحي المتوقع لمسار مرتبط بشكل صحيح: # [ # { "type": "Accepted", "status": "True", "reason": "Accepted" }, # { "type": "ResolvedRefs", "status": "True", "reason": "ResolvedRefs" } # ] # إذا كان Accepted=False، تحقق من reason: NotAllowedByParent يعني سياسة namespace # إذا كان ResolvedRefs=False، لا يمكن حل خدمة Backend أو سر TLS

Gateway API هو مستقبل توجيه الدخول في Kubernetes — لن يتلقى Ingress ميزات جديدة. إذا كنت تبني كلاستر جديدًا اليوم، ابدأ بـGateway API. إذا كنت تنتقل، فمعظم المتحكمات (NGINX وTraefik وIstio) تدعم الآن Gateway API إلى جانب Ingress؛ يمكنك تشغيل كليهما أثناء الانتقال وتحويل DNS عند الاستقرار.