مقارنة شاملة بين API Gateways و Kubernetes Gateways و Service Meshes
June 9, 2023
لا يزال هناك الكثير من الارتباك حول بوابات API، بوابات Kubernetes، وشبكات الخدمات. يعود الكثير من هذا إلى:
- غالبًا ما يتم ذكر هذه التقنيات بنفس الكلمات الرئيسية، مثل النشر التدريجي (canary deployments)، الحد من المعدل (rate limiting)، واكتشاف الخدمات (service discovery).
- جميع هذه التقنيات تستخدم وكلاء عكسيين (reverse proxies).
- بعض بوابات API لديها بوابات Kubernetes وشبكات خدمات خاصة بها، والعكس صحيح.
- هناك الكثير من المقالات/الفيديوهات التي تقارن بين هذه التقنيات وتستنتج لماذا واحدة أفضل من الأخرى.
في هذه المقالة، سأحاول شرح هذه التقنيات ومشاركة كيف تختلف بشكل أساسي وتلبي حالات استخدام مختلفة.
بوابات API
تقع بوابة API بين تطبيقات العميل وواجهات برمجة التطبيقات (APIs) الخاصة بك. تقبل جميع طلبات العملاء، وتوجهها إلى واجهات برمجة التطبيقات المطلوبة، وتعيد الاستجابة إلى العملاء في حزمة مجمعة.
هي في الأساس وكيل عكسي مع الكثير من الإمكانيات.
بالإضافة إلى ذلك، يمكن أن تحتوي بوابة API على ميزات مثل المصادقة، الأمان، التحكم الدقيق في حركة المرور، والمراقبة، مما يسمح لمطوري واجهات برمجة التطبيقات بالتركيز فقط على الاحتياجات التجارية.
هناك العديد من حلول بوابات API المتاحة. بعض الحلول الشهيرة المجانية والمفتوحة المصدر هي:
- Apache APISIX: بوابة API عالية الأداء وقابلة للتوسيع ومبنية على Nginx.
- Gloo Edge: بوابة API مبنية على وكيل Envoy.
- Kong: بوابة API قابلة للتوصيل ومبنية أيضًا على Nginx.
- Tyk: بوابة API مكتوبة بلغة Go تدعم بروتوكولات REST، GraphQL، TCP، وgRPC.
منصات السحابة مثل GCP، AWS، وAzure لديها أيضًا بوابات API خاصة بها.
تدعم بوابات API، بوابات Kubernetes، وشبكات الخدمات النشر التدريجي (canary deployments) — وهو نشر إصدار جديد من البرنامج تدريجيًا لمجموعة صغيرة من المستخدمين قبل أن يصبح متاحًا للجميع.
يظهر المثال أدناه كيفية تكوين النشر التدريجي في Apache APISIX.
يمكنك إرسال طلب إلى واجهة برمجة تطبيقات إدارة APISIX مع التكوين التالي:
curl http://127.0.0.1:9180/apisix/admin/routes/1 \
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"uri":"/*",
"plugins":{
"traffic-split":{
"rules":[
{
"weighted_upstreams":[
{
"upstream":{
"name":"api-v1",
"type":"roundrobin",
"nodes":{
"api-v1:8080":1
}
},
"weight":95
},
{
"weight":5
}
]
}
]
}
},
"upstream":{
"type":"roundrobin",
"nodes":{
"api-v2:8080":1
}
}
}'
سيقوم APISIX الآن بتوجيه 95% من حركة المرور إلى خدمة api-v1 و5% إلى خدمة api-v2.
بوابات Kubernetes
بوابات Kubernetes هي مجرد بوابات API محلية لـ Kubernetes. أي يمكنك إدارة هذه البوابات باستخدام واجهة برمجة تطبيقات Kubernetes، بشكل مشابه لإدارة حاوية (pod)، خدمة (service)، أو نشر (deployment) في Kubernetes.
في Kubernetes، تكون واجهات برمجة التطبيقات الخاصة بك عبارة عن حاويات وخدمات يتم نشرها في مجموعة (cluster). ثم تستخدم بوابة Kubernetes لتوجيه حركة المرور الخارجية إلى مجموعتك.
توفر Kubernetes واجهتي برمجة تطبيقات لتحقيق ذلك، واجهة برمجة تطبيقات Ingress وواجهة برمجة تطبيقات Gateway.
واجهة برمجة تطبيقات Ingress في Kubernetes
تم إنشاء واجهة برمجة تطبيقات Ingress للتغلب على قيود أنواع الخدمات الافتراضية، NodePort وLoadBalancer، من خلال إدخال ميزات مثل التوجيه وإنهاء SSL. كما قامت بتوحيد كيفية تعريض خدمات Kubernetes لحركة المرور الخارجية.
تتكون من مكونين، Ingress وIngress controller.
يحدد كائن Ingress الأصلي في Kubernetes مجموعة من القواعد حول كيفية وصول حركة المرور الخارجية إلى خدماتك.
يظهر تكوين المثال التالي توجيه حركة المرور بناءً على مسار URI باستخدام كائن Ingress في Kubernetes:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-routes
spec:
ingressClassName: apisix
rules:
- http:
paths:
- backend:
service:
name: api-v1
port:
number: 8080
path: /v1
pathType: Exact
- backend:
service:
name: api-v2
port:
number: 8080
path: /v2
pathType: Exact
يقوم Ingress controller بتنفيذ هذه القواعد وتوجيه حركة المرور إلى مجموعتك باستخدام وكيل عكسي.
هناك أكثر من 20 تنفيذ لـ Ingress controller. لدى APISIX Ingress controller يلف حول بوابة APISIX API ليعمل كـ Ingress في Kubernetes.
يقوم APISIX Ingress controller بتحويل كائن Ingress في Kubernetes إلى تكوين APISIX.
ثم يقوم APISIX بتنفيذ هذا التكوين.
يمكنك استبدال APISIX بأي Ingress controller آخر، حيث أن واجهة برمجة تطبيقات Ingress ليست مرتبطة بأي تنفيذ محدد.
تعمل هذه الحيادية تجاه البائع بشكل جيد للتكوينات البسيطة. ولكن إذا كنت ترغب في القيام بتوجيه معقد مثل النشر التدريجي، يجب عليك الاعتماد على التعليقات التوضيحية الخاصة بالبائع.
يظهر المثال التالي كيفية تكوين النشر التدريجي باستخدام Nginx Ingress. التعليقات التوضيحية المخصصة المستخدمة هنا خاصة بـ Nginx:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "5"
name: api-canary
spec:
rules:
- http:
paths:
- backend:
serviceName: api-v2
servicePort: 8080
path: /
سيقوم التكوين أعلاه بتوجيه 5% من حركة المرور إلى خدمة api-v2.
بالإضافة إلى التعليقات التوضيحية، لدى Ingress controllers مثل APISIX كائنات Kubernetes CRDs مخصصة للتغلب على قيود واجهة برمجة تطبيقات Ingress.
يستخدم المثال التالي كائن APISIX CRD، ApisixRoute لتكوين النشر التدريجي:
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: api-canary
spec:
http:
- name: route
match:
paths:
- /*
backends:
- serviceName: api-v1
servicePort: 8080
weight: 95
- serviceName: api-v2
servicePort: 8080
weight: 5
جعلت هذه الكائنات CRDs المخصصة من السهل تكوين Ingress والاستفادة الكاملة من إمكانيات بوابة API الأساسية ولكن على حساب قابلية النقل.
واجهة برمجة تطبيقات Gateway في Kubernetes
واجهة برمجة تطبيقات Gateway هي كائن Kubernetes جديد يهدف إلى "إصلاح" واجهة برمجة تطبيقات Ingress.
تستلهم من الكائنات CRDs المخصصة التي طورتها Ingress controllers لإضافة مطابقة بناءً على رأس HTTP، تقسيم حركة المرور الموزونة، وميزات أخرى تتطلب تعليقات توضيحية مخصصة مع واجهة برمجة تطبيقات Ingress.
يظهر المثال التالي تكوين النشر التدريجي باستخدام واجهة برمجة تطبيقات Gateway في Kubernetes:
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: HTTPRoute
metadata:
name: api-canary
spec:
rules:
- backendRefs:
- name: api-v1
port: 8080
weight: 95
- name: api-v2
port: 8080
weight: 5
يمكن الآن لأي Ingress controller (الذي ينفذ واجهة برمجة تطبيقات Gateway) تنفيذ هذا التكوين.
تقوم واجهة برمجة تطبيقات Gateway أيضًا بإجراء العديد من التحسينات على واجهة برمجة تطبيقات Ingress، ولكنها لا تزال في مرحلة ألفا، وتنفيذات واجهة برمجة تطبيقات Gateway تتغير باستمرار.
شبكات الخدمات
تعمل بوابات API وبوابات Kubernetes عبر حدود التطبيقات لحل مشاكل الحافة مع تجريد واجهات برمجة التطبيقات الخاصة بك.
تحل شبكات الخدمات تحديًا مختلفًا.
تهتم شبكة الخدمات أكثر بالاتصال بين الخدمات (حركة المرور الشرقية-الغربية) من اتصال الخدمة بالعميل (حركة المرور الشمالية-الجنوبية).
عادةً ما يتم تحقيق ذلك عن طريق نشر وكلاء جانبيين (sidecar proxies) مع واجهات برمجة التطبيقات/الخدمات.
هنا، تقوم الوكلاء الجانبيون بمعالجة الاتصال بين الخدمات بدلاً من أن يقوم المطور بكتابة منطق الشبكات في الخدمات.
هناك العديد من شبكات الخدمات المتاحة. بعضها الشهير:
- Istio: حتى الآن، أكثر شبكات الخدمات شيوعًا. تم بناؤها على أساس وكيل Envoy، والذي تستخدمه العديد من شبكات الخدمات.
- Linkerd: شبكة خدمات خفيفة الوزن تستخدم linkerd2-proxy، مكتوبة بلغة Rust خصيصًا لـ Linkerd.
- Consul Connect: شبكة خدمات تركز على الأمان والمراقبة. يمكنها العمل إما مع وكيل مدمج أو مع Envoy.
تقدم شبكات خدمات جديدة مثل Cilium بدائل لشبكات الخدمات القائمة على الوكلاء الجانبيين باستخدام إمكانيات الشبكات مباشرة من النواة عبر eBPF.
تتطلب شبكة خدمات نموذجية 8 وكلاء جانبيين لـ 8 خدمات بينما لا تتطلب شبكات الخدمات القائمة على eBPF مثل Cilium ذلك. مقتبس من Cilium Service Mesh – Everything You Need to Know.
تحتوي شبكات الخدمات أيضًا على بوابات دخول/خروج أساسية للتعامل مع حركة المرور الشمالية-الجنوبية من وإلى الخدمات. بوابات الدخول هي نقاط دخول حركة المرور الخارجية إلى شبكة الخدمات، وتسمح بوابات الخروج للخدمات داخل الشبكة بالوصول إلى الخدمات الخارجية.
لدى Apache APISIX أيضًا تنفيذ لشبكة الخدمات يسمى Amesh. يعمل مع لوحة تحكم Istio باستخدام بروتوكول xDS ليحل محل وكيل Envoy الافتراضي في الوكيل الجانبي.
تتيح لك شبكة الخدمات تكوين النشر التدريجي. على سبيل المثال، يمكنك تقسيم الطلبات من خدمة واحدة بين إصدارين من خدمة أخرى.
يظهر المثال التالي تكوين النشر التدريجي مع شبكة خدمات Istio:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: api-virtual-service
spec:
hosts:
- api
http:
- route:
- destination:
host: api
subset: v1
weight: 80
- destination:
host: api
subset: v2
weight: 20
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: api-destination-rule
spec:
host: api
subsets:
- name: v1
labels:
version: "1.0"
- name: v2
labels:
version: "2.0"
هذه التكوينات خاصة بـ Istio. للتبديل إلى شبكة خدمات مختلفة، يجب عليك إنشاء تكوين مختلف ولكن يعتمد بشكل مشابه على البائع.
تم إنشاء واجهة شبكة الخدمات (SMI) لحل مشكلة قابلية النقل هذه.
تعتبر مواصفات SMI مجموعة من كائنات Kubernetes CRDs التي يمكن لمستخدم شبكة الخدمات استخدامها لتحديد التطبيقات دون الارتباط بتنفيذات شبكة الخدمات.
لن تنجح محاولة التوحيد إلا إذا شاركت جميع المشاريع. ولكن هذا لم يحدث مع مواصفات SMI، وشارك عدد قليل من المشاريع بشكل فعال.
في الآونة الأخيرة، كانت مجموعة Kubernetes SIG Network تعمل على تطوير واجهة برمجة تطبيقات Gateway لدعم شبكات الخدمات.
مبادرة GAMMA (Gateway API for Mesh Management and Administration) هي مجموعة مخصصة ضمن مشروع واجهة برمجة تطبيقات Gateway تهدف إلى "التحقيق، التصميم، وتتبع موارد واجهة برمجة تطبيقات Gateway، الدلالات، وغيرها من العناصر المتعلقة بتقنية شبكات الخدمات وحالات الاستخدام."
تعتبر واجهة برمجة تطبيقات Gateway الخطوة الطبيعية التالية لواجهة برمجة تطبيقات Ingress، ولكن يجب أن ننتظر لنرى كيف ستنجح مع شبكات الخدمات. أعلنت Istio عن نيتها لاستخدام واجهة برمجة تطبيقات Gateway كواجهة برمجة تطبيقات افتراضية لإدارة حركة المرور وتستمر في دفع المشروع للأمام.
يظهر المثال التالي تكوين النشر التدريجي في Istio باستخدام واجهة برمجة تطبيقات Gateway. الفكرة الأساسية هي استخدام parentRefs للارتباط بخدمات أخرى بدلاً من البوابة:
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: api-canary
spec:
parentRefs:
- kind: Service
name: api-a
port: 8080
rules:
- backendRefs:
- name: api-b-v1
port: 8080
weight: 95
- name: api-b-v2
port: 8080
weight: 5
هناك بعض المخاوف من أن مشروع GAMMA قد يصبح منحازًا لخدمة احتياجات مشروع معين بدلاً من المجتمع الأكبر، مما سيؤدي في النهاية إلى استخدام المشاريع الأخرى لواجهات برمجة تطبيقاتها الخاصة، بشكل مشابه لسيناريو الكائنات CRDs المخصصة بعد واجهة برمجة تطبيقات Ingress في Kubernetes.
ولكن مشروع واجهة برمجة تطبيقات Gateway كان أفضل محاولة لتوحيد إدارة حركة المرور في شبكات الخدمات. انضم مشروع SMI أيضًا إلى مبادرة GAMMA برؤية مشتركة وسيساعد في الدعوة لتنفيذات متسقة لواجهة برمجة تطبيقات Gateway من قبل مشاريع شبكات الخدمات.
كما قامت مشاريع أخرى مثل Flagger وArgo Rollouts بالتكامل مع واجهة برمجة تطبيقات Gateway.
ما الذي يجب عليك استخدامه؟
هناك إجابة واحدة صحيحة على هذا السؤال؛ "يعتمد."
إذا كنت تقوم بتطوير واجهات برمجة التطبيقات وتحتاج إلى المصادقة، الأمان، التوجيه، أو المقاييس، فمن الأفضل استخدام بوابة API بدلاً من بناء هذا بنفسك في واجهات برمجة التطبيقات الخاصة بك.
إذا كنت ترغب في القيام بشيء مشابه في بيئة Kubernetes، يجب عليك استخدام بوابة Kubernetes بدلاً من محاولة إجبار بوابة API الخاصة بك على العمل في Kubernetes. لحسن الحظ، تعمل العديد من بوابات API أيضًا مع تكوينات Kubernetes الأصلية.
ولكن في بعض الأحيان، قد تكون الميزات التي تقدمها بوابة API + Ingress controller مبالغًا فيها لبيئة Kubernetes، وقد ترغب في العودة إلى إدارة حركة المرور البسيطة.
من ناحية أخرى، تحل شبكات الخدمات مجموعة مختلفة تمامًا من المشاكل. كما أنها تجلب بواباتها الخاصة للتعامل مع حركة المرور الشمالية-الجنوبية (عادةً ما تكون كافية) ولكنها تتيح لك أيضًا استخدام بواباتك الخاصة بميزات إضافية.
يجب أن يجعل تقارب بوابة API وشبكة الخدمات من خلال واجهة برمجة تطبيقات Gateway في Kubernetes من السهل على مطور التطبيقات التركيز على حل المشاكل بدلاً من القلق بشأن التنفيذ الأساسي.
تقوم مشاريع مثل Apache APISIX باستخدام نفس التقنية لبناء بوابة API وعروض شبكة الخدمات والتكامل بشكل جيد مع هذه المواصفات، مما يشجع على الاختيارات المحايدة للبائع.
من المحتمل أيضًا أنك لن تحتاج إلى أي من هذه. قد لا تحتاج حتى إلى خدمات صغيرة أو بنية موزعة، ولكن عندما تحتاج إليها، يمكن أن تجعل البوابات والشبكات حياتك أسهل بكثير.