نظرة سريعة على Kubernetes Gateway API

Nicolas Fränkel

Nicolas Fränkel

September 7, 2022

Ecosystem

في إحدى مشاركاتي الأخيرة على المدونة، وصفت عدة طرق للوصول إلى الـ Pods في Kubernetes. يمكن الوصول إلى الـ Pod من خلال عنوان IP الخاص به، ولكن الـ Pods بطبيعتها عابرة. الطريقة المثلى هي تكوين Service: حيث يكون عنوان IP الخاص به ثابتًا، ومهمة Kubernetes هي الحفاظ على التحديث بين الـ Service والـ Pods التي يعتمد عليها. تتوفر أنواع مختلفة من الخدمات: داخلية فقط، NodePort للسماح بالوصول من خارج الكتلة، وLoadBalancer التي تعتمد على مكون طرف ثالث - بشكل عام، مزود سحابي. أخيرًا، ذكرت كائن Ingress، الذي يسمح أيضًا بالتوجيه.

لقد تركت عمدًا الحديث عن الوافد الجديد، وهو Gateway API. وهذا هو موضوع هذه المشاركة.

من Ingress إلى Gateway API

مر الوصول الخارجي إلى الـ Pods في Kubernetes بعدة خطوات تطورية، على سبيل المثال، Ingress هو الحل لمشكلة عدم وجود توجيه في LoadBalancer. أكبر مشكلة في Ingress هي اعتماده على كائنات "خاصة". كتذكير، إليك مقتطف لإنشاء التوجيه باستخدام Apache APISIX:

apiVersion: apisix.apache.org/v2beta3 #1
kind: ApisixRoute #1
metadata:
  name: apisix-route
spec:
  http:
    - name: left
      match:
        paths:
          - "/left"
      backends:
        - serviceName: left
          servicePort: 80
    - name: right
      match:
        paths:
          - "/right"
      backends:
        - serviceName: right
          servicePort: 80
  1. كائنات خاصة

الكائنات الخاصة تشكل مشكلة عند الترحيل. بينما قد يكون الترحيل من مزود إلى آخر غير شائع، إلا أنه يجب أن يكون سلسًا قدر الإمكان. عند استخدام الكائنات الخاصة، تحتاج أولاً إلى تعيين الكائنات القديمة إلى الجديدة. من المحتمل أن هذا التعيين ليس واحدًا لواحد. ثم تحتاج إلى ترجمة المواصفات إلى النموذج الجديد: من المحتمل أن يكون هذا مشروعًا كاملًا.

الفكرة وراء Gateway API هي الفصل النظيف بين الكائنات القياسية والتنفيذ الخاص.

Gateway API

Gateway API هو مشروع مفتوح المصدر تديره مجتمع SIG-NETWORK. وهو مجموعة من الموارد التي تصف شبكة الخدمات في Kubernetes. هذه الموارد - GatewayClass، Gateway، HTTPRoute، TCPRoute، Service، إلخ - تهدف إلى تطوير شبكة الخدمات في Kubernetes من خلال واجهات تعبيرية وقابلة للتوسيع وموجهة نحو الأدوار التي يتم تنفيذها من قبل العديد من البائعين ولديها دعم واسع من الصناعة.

-- https://gateway-api.sigs.k8s.io

التعريف أعلاه يذكر أيضًا اهتمامًا تنظيميًا: يجب أن تدير الأدوار المختلفة مجموعة مختلفة من الكائنات.

نموذج Gateway API

الصورة من gateway-api.sigs.k8s.io

في الواقع، اهتمامات مشغل الكتلة والمطور مختلفة تمامًا. هذا يشبه إلى حد كبير خوادم تطبيقات Java EE القديمة، التي قدمت مواصفات منظمة حول الأدوار: المطورين، الموزعين، والمشغلين. في رأيي، الفرق الأكبر هو أن المواصفات كانت تركز بشكل رئيسي على تجربة المطور؛ أما الباقي فكان متروكًا للمنفذين. يبدو أن Gateway API تهتم بجميع الشخصيات.

تكوين الوصول إلى الـ Pods عبر Gateway API

لنستبدل Ingress الذي قمنا بتكوينه مسبقًا بـ Gateway API. هناك عدة خطوات ضرورية.

تثبيت CRDs الجديدة لـ Gateway

k apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v0.5.0/standard-install.yaml

تثبيت تنفيذ

سأستخدم Apache APISIX. بدلاً من ذلك، يحتفظ موقع SIG بـ قائمة بالتنفيذات.

helm install apisix apisix/apisix \
  --namespace ingress-apisix \
  --create-namespace \
  --devel \                                                                #1
  --set gateway.type=NodePort \                                            #2
  --set gateway.http.nodePort=30800 \                                      #2
  --set ingress-controller.enabled=true \                                  #2
  --set ingress-controller.config.kubernetes.enableApiGateway=true \       #3
  --set ingressPublishService="ingress-apisix/apisix-gateway"              #4
  1. بدون الخيار --devel، يقوم Helm بتثبيت الإصدار الأحدث، الذي لا يعمل مع Gateway API
  2. يجب أن يكون Gateway قابلًا للوصول من خارج الكتلة على أي حال
  3. السحر يحدث هنا!
  4. سأعود إلى هذا لاحقًا

لنتحقق من أن كل شيء يعمل:

k get all -n ingress-apisix
NAME                                             READY   STATUS    RESTARTS   AGE
pod/apisix-5fc9b45c69-cf42m                      1/1     Running   0          14m    #1
pod/apisix-etcd-0                                1/1     Running   0          14m    #2
pod/apisix-etcd-1                                1/1     Running   0          14m    #2
pod/apisix-etcd-2                                1/1     Running   0          14m    #2
pod/apisix-ingress-controller-6f8bd94d9d-wkzfn   1/1     Running   0          14m    #3

NAME                                TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)
service/apisix-admin                ClusterIP   10.96.69.19     <none>        9180/TCP
service/apisix-etcd                 ClusterIP   10.96.226.79    <none>        2379/TCP,2380/TCP
service/apisix-etcd-headless        ClusterIP   None            <none>        2379/TCP,2380/TCP
service/apisix-gateway              NodePort    10.96.101.224   <none>        80:30800/TCP #4
service/apisix-ingress-controller   ClusterIP   10.96.141.230   <none>        80/TCP
  1. Apache APISIX نفسه
  2. Apache APISIX يخزن تكوينه في etcd. يقوم المخطط بجدولة ثلاث Pods افتراضيًا، وهي ممارسة جيدة للتعامل مع الأعطال في الأنظمة الموزعة
  3. Apache APISIX controller: وحدة تحكم Kubernetes هي حلقة تحكم تحرك الحالة الحالية نحو الحالة المطلوبة
  4. خدمة Apache APISIX Gateway: إنها خدمة NodePort التي قمنا بتثبيتها عبر مخطط Helm. وهو أيضًا الاسم الذي أشرنا إليه أثناء تثبيت مخطط Helm - ingressPublishService

في هذه المرحلة، البنية التحتية جاهزة.

الإعلان عن تنفيذ Gateway

كما ذكرت أعلاه، تقوم API بفصل نظيف بين المواصفات والتنفيذ. ومع ذلك، نحتاج إلى ربطها بطريقة ما. هذه مسؤولية كائن GatewayClass:

apiVersion: gateway.networking.k8s.io/v1alpha2 #1
kind: GatewayClass #2
metadata:
  name: apisix-gateway-class #3
spec:
  controllerName: apisix.apache.org/gateway-controller #4
  1. نحن لا نستخدم الإصدار الأحدث عن قصد، حيث يستخدم Apache APISIX هذا الإصدار. كن على علم بأنه سيتطور في المستقبل (القريب)
  2. كائن GatewayClass
  3. قم بتسميته كما تريد؛ ومع ذلك، سنستخدمه لاحقًا للإشارة إلى فئة البوابة
  4. اسم المتحكم يعتمد على التنفيذ. هنا، نستخدم Apache APISIX.

لاحظ أن GatewayClass له نطاق على مستوى الكتلة. يسمح هذا النموذج بالإعلان عن تنفيذات مختلفة لـ Gateway API واستخدامها بالتوازي داخل نفس الكتلة.

إنشاء Gateway

مع Apache APISIX، الأمر بسيط للغاية:

apiVersion: gateway.networking.k8s.io/v1alpha2 #1
kind: Gateway #2
metadata:
  name: apisix-gateway
spec:
  gatewayClassName: apisix-gateway-class #3
  listeners: #4
    - name: http
      protocol: HTTP
      port: 80
  1. نفس النطاق كما أعلاه
  2. كائن Gateway
  3. الإشارة إلى فئة البوابة التي تم الإعلان عنها مسبقًا
  4. السماح ببعض القيود على هذا المستوى حتى يتمكن مشغل الكتلة من تجنب الاستخدام غير المرغوب فيه

تحذير: تحدد Gateway API خيار تغيير المنفذ ديناميكيًا على جانب المشغل. في وقت كتابة هذا المقال، تخصيص المنفذ في Apache APISIX ثابت. الخطة هي جعله ديناميكيًا في المستقبل. يرجى الاشتراك في هذه المشكلة على GitHub لمتابعة التقدم.

الطرق، الطرق، الطرق في كل مكان

حتى الآن، كل شيء كان متعلقًا بالبنية التحتية؛ يمكننا أخيرًا تكوين التوجيه.

أريد نفس التوجيه كما في المشاركة السابقة؛ فرع /left وفرع right. سأحذف الأخير للإيجاز.

apiVersion: gateway.networking.k8s.io/v1alpha2 #1
kind: HTTPRoute #2
metadata:
  name: left
spec:
  parentRefs:
    - name: apisix-gateway #3
  rules:
    - matches: #4
        - path: #4
            type: PathPrefix #4
            value: /left
      backendRefs: #5
        - name: left #5
          port: 80 #5
  1. نفس النطاق كما أعلاه
  2. كائن HTTPRoute
  3. الإشارة إلى Gateway التي تم إنشاؤها أعلاه
  4. قواعد المطابقة. في حالتنا، نطابق بناءً على بادئة المسار، ولكن هناك العديد من القواعد المتاحة. يمكنك المطابقة بناءً على معلمة استعلام، أو رأس، إلخ.
  5. "المصدر" الذي يتم التوجيه إليه. قمنا بتعريف خدمة left في المشاركة السابقة على المدونة.

التحقق من عملها

الآن بعد أن قمنا بتكوين طرقنا، يمكننا التحقق من عملها.

curl localhost:30800/left

عندما قمنا بتثبيت مخطط Helm، أخبرنا Apache APISIX بإنشاء خدمة NodePort على المنفذ 30800. وبالتالي، يمكننا استخدام المنفذ للوصول إلى الخدمة من خارج الكتلة.

left

الخلاصة

هناك العديد من البدائل المتاحة للوصول إلى Pod من خارج الكتلة. أضافت CNCF معظمها لتحسين البدائل السابقة.

Gateway API هو أحدث اقتراح في هذا الصدد. المواصفات قيد التطوير والمنتجات في مراحل مختلفة من التنفيذ. لهذا السبب، من المبكر جدًا بناء إنتاجك على API. ومع ذلك، يجب عليك على الأرجح متابعة التقدم حيث من المرجح أن يكون تحسينًا كبيرًا عن الأساليب السابقة.

يمكن العثور على الكود المصدري الكامل لهذه المشاركة على GitHub.

للمزيد من المعلومات:

Tags: