المفاهيم الأساسية لـ Envoy Gateway: شرح Gateway و Listener و Proxy وعائلة Route

7 min read

الانطباع الأول لدى كثير من الناس عن Gateway API يكون شيئًا مثل: "عدد المصطلحات ليس ضخمًا، لكن عقلي يشعر وكأنه يشاهد قائمة شخصيات أسماؤها متشابهة ولا أستطيع تمييز البطل من الشخصيات الجانبية." هذه المقالة موجودة لتقطع هذا الالتباس، وتغطي أيضًا أنواع الـ route الشائعة في الطريق.

البنية العامة

تقسّم مفاهيم Envoy Gateway الرسمية النظام إلى ثلاث طبقات:

  • User Configuration: موارد Gateway API و CRDs التوسعية الخاصة بـ Envoy Gateway التي تكتبها
  • Envoy Gateway Controller: يقرأ الموارد ويتحقق منها ويترجم الإعدادات
  • Envoy Proxy: مستوى البيانات الذي يتعامل فعليًا مع المرور

هذا يعني أن ما تقوم بتعديله عادة ليس Envoy Proxy نفسه، بل إنك "تصرّح بما تريده". ويقوم Envoy Gateway بترجمة هذه التصريحات إلى إعدادات يستطيع Envoy Proxy تنفيذها. وهذا هو السبب الذي يجعله ألطف من كتابة إعدادات البروكسي يدويًا.

الأدوار الأساسية

يكفي أن تتذكر هذه الآن:

  • GatewayClass: يعرّف "أي implementation من Gateway يُستخدم في هذا الـ cluster"
  • Gateway: يعرّف "أين يوجد ingress وما البروتوكول الذي يتحدث به"
  • Listener: يعرّف فتحة ingress محددة بحسب port/protocol/hostname
  • Route: يعرّف "أي الطلبات تذهب إلى أي Service"
  • Envoy Proxy: الـ Gateway Proxy الفعلي الذي يستقبل المرور ويوجهه

بلغة بسيطة:

  • GatewayClass هو ورقة المواصفات
  • Gateway هو المدخل الأمامي للمبنى
  • Listener هو مكتب الاستقبال
  • Route هو اللوحات الإرشادية داخل المبنى
  • Envoy Proxy هو نظام الحماية الذي يطبّق التحكم ويرافق المرور

من دون أي واحد من هذه العناصر، لن يصل المرور إلى المكان الذي تريده.

YAML مصغّر يوضح الصورة كاملة

إليك أصغر مثال مفهوم:

apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: eg
spec:
  controllerName: gateway.envoyproxy.io/gatewayclass-controller
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: eg
spec:
  gatewayClassName: eg
  listeners:
    - name: http
      protocol: HTTP
      port: 80
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: backend
spec:
  parentRefs:
    - name: eg
  hostnames:
    - "www.example.com"
  rules:
    - backendRefs:
        - name: backend
          port: 3000

وعند ربطها معًا تصبح المنطقية كالتالي:

  1. GatewayClass يقول إن Envoy Gateway controller هو المسؤول
  2. Gateway يصرّح بمدخل HTTP واحد على المنفذ 80
  3. HTTPRoute يقول إن الطلبات الخاصة بـ www.example.com يجب أن تذهب إلى backend:3000
  4. يقوم Envoy Gateway بترجمة كل ذلك إلى ما يفهمه Envoy Proxy

فهم كل حقل

GatewayClass

هذا تعريف على مستوى الـ cluster لنوع ingress. وأكثر حقل حاسم فيه غالبًا هو:

spec:
  controllerName: gateway.envoyproxy.io/gatewayclass-controller

ومعناه ببساطة: "هذا الـ GatewayClass تتم إدارته بواسطة Envoy Gateway controller."

إذا لم يتطابق controllerName، فالأمر يشبه إرسال طلب توصيل إلى الشركة الخطأ، ولن يلتقطه أحد.

Gateway

هذا يعرّف "كيف يبدو ingress." وأكثر حقل يتم الرجوع إليه هو listeners:

listeners:
  - name: http
    protocol: HTTP
    port: 80

وهذا يعني:

  • افتح listener اسمه http
  • اقبل مرور HTTP
  • استمع خارجيًا على المنفذ 80

وبالنسبة إلى HTTPS، ستضيف عادة listener آخر مع protocol: HTTPS وتربط به إعدادات TLS.

ما يديره Gateway عادة:

  • المنفذ والبروتوكول الخارجيان
  • hostname لكل listener
  • موضع TLS termination
  • أي namespaces يمكن أن ترتبط routes الخاصة بها

Gateway هو في العادة مسؤولية طبقة المنصة، لذلك تكون ملكيته غالبًا لدى فريق المنصة.

Listener

هذا الدور هو الأكثر تجاهلًا من المبتدئين، لكنه في الحقيقة حاسم جدًا.

الـ listener هو فتحة ingress مواجهة للخارج على الـ Gateway. وهو يعرّف:

  • name
  • port
  • protocol
  • hostname
  • tls
  • allowedRoutes

مثال:

listeners:
  - name: https
    protocol: HTTPS
    port: 443
    hostname: api.example.com

وهذا يعني:

  • اسم هذه الفتحة هو https
  • تقبل HTTPS
  • تستمع على المنفذ 443
  • مخصصة لـ api.example.com

إذا كان لديك عدة listeners مثل:

  • http للمنفذ 80
  • https للمنفذ 443
  • grpc للمنفذ 50051

فأنت تفتح عدة فتحات ingress على نفس الـ Gateway، ويمكن لكل واحدة منها أن ترتبط بها routes مختلفة.

Envoy Proxy

كثير من الناس يركزون فقط على YAML وينسون أن Envoy Proxy هو الذي يتعامل فعليًا مع المرور الحي.

ودوره هو:

  • استقبال طلبات العميل
  • مطابقة الإعدادات التي دفعها Envoy Gateway
  • توجيه المرور إلى backend المناسب
  • التعامل مع TLS و headers و timeouts و retries وسلوكيات مستوى البيانات الأخرى

لذلك اعتبر Envoy Gateway هو "مستوى التحكم"، و Envoy Proxy هو "مستوى البيانات / Gateway Proxy."

عائلة Route

Route ليس مجرد HTTPRoute. فالعائلة كلها عنصر أساسي في تصميم Gateway API.

HTTPRoute

هذا هو النوع الذي ستكتبه وتعدله غالبًا. وهناك ثلاثة حقول أساسية:

spec:
  parentRefs:
    - name: eg
  hostnames:
    - "www.example.com"
  rules:
    - backendRefs:
        - name: backend
          port: 3000
  • parentRefs: إلى أي Gateway يجب أن يرتبط
  • hostnames: أي Host header يفعّل هذه القاعدة
  • backendRefs: إلى أين تُرسل الطلبات المطابقة

أكثر نقطة يختلط فهمها على الناس: Gateway ليس المكان الذي تكتب فيه التوجيه الدقيق، بل HTTPRoute هو الذي يقرر فعليًا "كيف يُقسّم المرور."

GRPCRoute

إذا كنت تتعامل مع gRPC، فـ GRPCRoute أكثر طبيعية من حشره داخل HTTPRoute.

يمكنه المطابقة على:

  • gRPC hostname
  • gRPC service
  • gRPC method
  • headers

مثال:

matches:
  - method:
      service: com.example.User
      method: Login

هذه الدلالات تنسجم طبيعيًا مع gRPC، فأنت لا تطابق فقط URL paths، بل تطابق مباشرة نموذج gRPC service/method.

وتشير الوثائق الرسمية أيضًا إلى أنه إذا كان GRPCRoute و HTTPRoute يشتركان في نفس الـ listener ولديهما hostnames متعارضة، فيجب على الـ implementations رفض أحدهما. وباختصار: لا تجعل HTTP و gRPC يتقاتلان على نفس الـ hostname.

TCPRoute

TCPRoute يتعامل مع مرور TCP الخام. وعلى عكس HTTPRoute، فهو لا يفهم path أو header على مستوى L7، بل هو أقرب إلى forwarding على مستوى L4.

السيناريوهات المناسبة:

  • خدمات ذات بروتوكولات غير HTTP
  • خدمات TCP صِرفة
  • توجيه الاتصالات إلى backends مختلفة بالاعتماد فقط على منفذ الـ listener

قواعد البيانات ذات البروتوكولات المخصصة أو بروتوكولات TCP الخاصة أمثلة نموذجية لاستخدام TCPRoute.

TLSRoute

TLSRoute يتعامل مع مرور TLS، وهو شائع جدًا في سيناريوهات TLS passthrough.

الفكرة الأساسية:

  • الـ Gateway لا يقوم بالضرورة بإنهاء TLS
  • قد يوجّه المرور فقط بناءً على SNI hostname داخل مصافحة TLS
  • يبقى المرور المشفّر محفوظًا حتى الـ backend

وهذا مهم في السيناريوهات التي تتطلب تشفيرًا من الطرف إلى الطرف، أو عندما لا تريد إنهاء TLS عند Gateway.

كيف تختار نوع Route

المتطلب استخدم هذا
مواقع الويب و REST APIs والمرور العام للويب HTTPRoute
توجيه gRPC حسب service/method GRPCRoute
مرور TCP الخام TCPRoute
TLS passthrough / التوجيه المبني على SNI TLSRoute

هذا الجدول مهم لأن كثيرًا من الناس يكتبون HTTPRoute تلقائيًا لكل شيء. لكن إذا كنت تتعامل فعليًا مع gRPC أو TCP، فإن إجبار ذلك على الدخول في HTTPRoute سيجعل الـ YAML أكثر awkward مع الوقت.

لماذا التفكير في Routes أسهل من Ingress

كانت إعدادات Ingress القديمة غالبًا تضغط الكثير من المسؤوليات داخل مورد واحد، مما سبّب بعض نقاط الألم المستمرة:

  • خلط إعدادات المنصة مع توجيه التطبيق
  • التعبير عن الميزات المتقدمة عبر annotations ضعيفة القراءة
  • قدرة تعبيرية محدودة للبروتوكولات غير HTTP

ومقاربة Gateway API هي فصل المسؤوليات:

  • فرق المنصة تدير GatewayClass و Gateway
  • فرق التطبيقات تدير HTTPRoute الخاص بها

وهذا الفصل ممتاز للعمل التعاوني بين عدة أشخاص. فلا تحتاج إلى لمس طبقة ingress كاملة لمجرد تغيير path واحد، ومعدل تداخل الفرق على بعضها ينخفض بشكل واضح.

ابدأ بالانتباه إلى status

بعيدًا عن spec، ابنِ تدريجيًا عادة التحقق من status. وخصوصًا في HTTPRoute و Gateway:

kubectl get gateway eg -o yaml
kubectl get httproute backend -o yaml

ابدأ بالتحقق من:

  • هل تم Accepted للـ route
  • هل الـ gateway listener في حالة Ready
  • هل تم تعيين عنوان بنجاح

الأمر أشبه بالتحقق من نتيجة الامتحان. لا تكتفِ بأنك قدّمت الورقة، بل تحقّق أنها صُحّحت وتم النجاح.

الخلاصة في سطر واحد

تعامل مع GatewayClass و Gateway و Listener و Route و Envoy Proxy على أنها: "من يدير؟ كيف يُفتح ingress؟ كيف ترتبط كل فتحة؟ كيف ينقسم المرور؟ ومن ينفّذ؟" وستكون قد فهمت بالفعل 80% من المفاهيم الأساسية.

💡 كثير من المبتدئين يندفعون مباشرة إلى تفاصيل CRD. لا تستعجل، رتّب هذه الأدوار في ذهنك أولًا، وسيتوقف YAML عن الشعور وكأنك تقابل غرباء في كل مرة.

الخطوة التالية

الآن وبعد أن ترسخت المفاهيم، تتعمق المقالة التالية في أكثر سيناريوهات توجيه HTTP شيوعًا، مثل host و path و header وتقسيم المرور: 👉 التوجيه العملي لـ HTTP