Ein umfassender Vergleich von API Gateways, Kubernetes Gateways und Service Meshes
June 9, 2023
Es gibt immer noch viel Verwirrung über API-Gateways, Kubernetes-Gateways und Service-Meshes. Ein Großteil davon liegt daran:
- Menschen erwähnen diese Technologien oft mit denselben Schlagwörtern, wie Canary-Deployments, Rate-Limiting und Service-Discovery.
- Alle diese Technologien verwenden Reverse-Proxys.
- Einige API-Gateways haben ihre eigenen Kubernetes-Gateways und Service-Meshes und umgekehrt.
- Es gibt viele Artikel/Videos, die die drei Technologien vergleichen und daraus schließen, warum eine besser ist als die andere.
In diesem Artikel werde ich versuchen, diese Technologien zu erklären und zu teilen, wie sie sich grundlegend unterscheiden und unterschiedliche Anwendungsfälle abdecken.
API-Gateways
Ein API-Gateway sitzt zwischen Ihren Client-Anwendungen und Ihren APIs. Es akzeptiert alle Client-Anfragen, leitet sie an die erforderlichen APIs weiter und gibt die Antworten an die Clients in einem kombinierten Paket zurück.
Es handelt sich im Grunde um einen Reverse-Proxy mit vielen Funktionen.
Darüber hinaus kann ein API-Gateway auch Funktionen wie Authentifizierung, Sicherheit, fein abgestimmte Verkehrskontrolle und Überwachung bieten, sodass sich die API-Entwickler nur auf die geschäftlichen Anforderungen konzentrieren müssen.
Es gibt viele API-Gateway-Lösungen. Einige der beliebten kostenlosen und Open-Source-Lösungen sind:
- Apache APISIX: Ein hochleistungsfähiges, erweiterbares, cloud-natives API-Gateway, das auf Nginx basiert.
- Gloo Edge: Ein API-Gateway, das auf dem Envoy-Proxy basiert.
- Kong: Ein pluggables API-Gateway, das ebenfalls auf Nginx basiert.
- Tyk: Ein in Go geschriebenes API-Gateway, das REST, GraphQL, TCP und gRPC-Protokolle unterstützt.
Cloud-Plattformen wie GCP, AWS und Azure haben auch ihre eigenen proprietären API-Gateways.
API-Gateways, Kubernetes-Gateways und Service-Meshes unterstützen Canary-Deployments – das schrittweise Rollout einer neuen Softwareversion für eine kleine Teilmenge von Benutzern, bevor sie allgemein verfügbar gemacht wird.
Das folgende Beispiel zeigt, wie man ein Canary-Deployment in Apache APISIX konfiguriert.
Sie können eine Anfrage an die APISIX Admin API mit der folgenden Konfiguration senden:
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 wird nun 95 % des Datenverkehrs an den api-v1-Dienst und 5 % an den api-v2-Dienst weiterleiten.
Kubernetes-Gateways
Kubernetes-Gateways sind einfach Kubernetes-native API-Gateways. Das bedeutet, Sie können diese API-Gateways mit der Kubernetes-API verwalten, ähnlich wie einen Kubernetes-Pod, Service oder Deployment.
In Kubernetes sind Ihre APIs Pods und Services, die in einem Cluster bereitgestellt werden. Sie verwenden dann ein Kubernetes-Gateway, um externen Datenverkehr in Ihren Cluster zu leiten.
Kubernetes bietet zwei APIs, um dies zu erreichen: die Ingress API und die Gateway API.
Kubernetes Ingress API
Die Ingress API wurde geschaffen, um die Einschränkungen der Standard-Service-Typen NodePort und LoadBalancer zu überwinden, indem Funktionen wie Routing und SSL-Terminierung eingeführt wurden. Sie standardisiert auch, wie Sie Kubernetes-Services für externen Datenverkehr verfügbar machen.
Sie besteht aus zwei Komponenten: dem Ingress und dem Ingress-Controller.
Das Kubernetes-native Ingress-Objekt definiert eine Reihe von Regeln, wie externer Datenverkehr auf Ihre Services zugreifen kann.
Diese Beispielkonfiguration zeigt das Routing von Datenverkehr basierend auf dem URI-Pfad mit dem Kubernetes-Ingress-Objekt:
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
Ein Ingress-Controller implementiert diese Regeln und leitet den Datenverkehr mit einem Reverse-Proxy in Ihren Cluster.
Es gibt über 20 Ingress-Controller-Implementierungen. APISIX hat einen Ingress-Controller, der das APISIX-API-Gateway umschließt, um als Kubernetes-Ingress zu fungieren.
Der APISIX-Ingress-Controller konvertiert das Kubernetes-Ingress-Objekt in eine APISIX-Konfiguration.
APISIX implementiert dann diese Konfiguration.
Sie können APISIX durch jeden anderen Ingress-Controller ersetzen, da die Ingress API nicht an eine bestimmte Implementierung gebunden ist.
Diese Anbieterneutralität funktioniert gut für einfache Konfigurationen. Wenn Sie jedoch komplexes Routing wie ein Canary-Deployment durchführen möchten, müssen Sie sich auf anbieterspezifische Anmerkungen verlassen.
Das folgende Beispiel zeigt, wie man ein Canary-Deployment mit Nginx Ingress konfiguriert. Die hier verwendeten benutzerdefinierten Anmerkungen sind spezifisch für 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: /
Die obige Konfiguration leitet 5 % des Datenverkehrs an den api-v2-Dienst.
Zusätzlich zu Anmerkungen haben Ingress-Controller wie APISIX benutzerdefinierte Kubernetes-CRDs, um die Einschränkungen der Ingress API zu überwinden.
Das folgende Beispiel verwendet die APISIX-CRD ApisixRoute, um ein Canary-Deployment zu konfigurieren:
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
Diese benutzerdefinierten CRDs machten es viel einfacher, Ingress zu konfigurieren und die volle Funktionalität des darunterliegenden API-Gateways zu nutzen, allerdings auf Kosten der Portabilität.
Kubernetes Gateway API
Die Gateway API ist ein neues Kubernetes-Objekt, das die Ingress API „reparieren“ soll.
Es lässt sich von den benutzerdefinierten CRDs inspirieren, die von Ingress-Controllern entwickelt wurden, um HTTP-Header-basiertes Matching, gewichtete Verkehrsaufteilung und andere Funktionen hinzuzufügen, die mit der Ingress API benutzerdefinierte, proprietäre Anmerkungen erfordern.
Das folgende Beispiel zeigt die Konfiguration eines Canary-Deployments mit der Kubernetes Gateway API:
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
Jeder Ingress-Controller (der die Gateway API implementiert) kann nun diese Konfiguration implementieren.
Die Gateway API macht auch viele Verbesserungen gegenüber der Ingress API, befindet sich jedoch noch in der Alpha-Phase, und die Implementierungen der Gateway API brechen ständig.
Service-Meshes
API-Gateways und Kubernetes-Gateways arbeiten über Anwendungsgrenzen hinweg und lösen Edge-Probleme, während sie Ihre APIs abstrahieren.
Service-Meshes lösen eine andere Herausforderung.
Ein Service-Mesh ist mehr an der Kommunikation zwischen Diensten (East-West-Verkehr) interessiert als an der Kommunikation zwischen Dienst und Client (North-South-Verkehr).
Typischerweise wird dies durch die Bereitstellung von Sidecar-Proxys mit APIs/Diensten erreicht.
Hier übernehmen die Sidecar-Proxys die Kommunikation zwischen den Diensten, anstatt dass der Entwickler die Netzwerklogik in die Dienste codieren muss.
Es gibt viele Service-Meshes. Einige der beliebtesten sind:
- Istio: Bisher das beliebteste Service-Mesh. Es basiert auf dem Envoy-Proxy, den viele Service-Meshes verwenden.
- Linkerd: Ein leichtgewichtiges Service-Mesh, das linkerd2-proxy verwendet, das speziell für Linkerd in Rust geschrieben wurde.
- Consul Connect: Ein Service-Mesh, das Sicherheit und Beobachtbarkeit betont. Es kann entweder mit einem eingebauten Proxy oder mit Envoy arbeiten.
Neue Service-Mesh-Angebote wie Cilium bieten Alternativen zu Sidecar-basierten Service-Meshes, indem sie Netzwerkfunktionen direkt aus dem Kernel über eBPF nutzen.
Ein typisches Service-Mesh benötigt 8 Proxys für 8 Dienste, während eBPF-basierte Service-Meshes wie Cilium dies nicht tun. Adaptiert von Cilium Service Mesh – Everything You Need to Know.
Service-Meshes haben auch grundlegende Ingress/Egress-Gateways, um den North-South-Verkehr zu und von den Diensten zu handhaben. Ingress-Gateways sind die Einstiegspunkte für externen Datenverkehr in ein Service-Mesh, und Egress-Gateways ermöglichen es Diensten innerhalb eines Meshes, auf externe Dienste zuzugreifen.
Apache APISIX hat auch eine Service-Mesh-Implementierung namens Amesh. Es arbeitet mit Istios Control Plane über das xDS-Protokoll und ersetzt den standardmäßigen Envoy-Proxy im Sidecar.
Ein Service-Mesh ermöglicht es Ihnen, Canary-Deployments zu konfigurieren. Beispielsweise können Sie die Anfragen von einem Dienst zwischen zwei Versionen eines anderen Dienstes aufteilen.
Das folgende Beispiel zeigt die Konfiguration eines Canary-Deployments mit Istio Service Mesh:
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"
Diese Konfigurationen sind spezifisch für Istio. Um zu einem anderen Service-Mesh zu wechseln, müssen Sie eine andere, aber ähnlich anbieterspezifische Konfiguration erstellen.
Die Service Mesh Interface (SMI)-Spezifikation wurde geschaffen, um dieses Portabilitätsproblem zu lösen.
Die SMI-Spezifikation ist eine Reihe von Kubernetes-CRDs, die ein Service-Mesh-Benutzer verwenden kann, um Anwendungen zu definieren, ohne sich an Service-Mesh-Implementierungen zu binden.
Ein Standardisierungsversuch wird nur funktionieren, wenn alle Projekte an Bord sind. Dies geschah jedoch nicht mit der SMI-Spezifikation, und nur wenige Projekte beteiligten sich aktiv.
Kürzlich hat die Kubernetes SIG Network die Gateway API weiterentwickelt, um Service-Meshes zu unterstützen.
Die GAMMA (Gateway API for Mesh Management and Administration)-Initiative ist eine dedizierte Gruppe innerhalb des Gateway-API-Projekts mit dem Ziel, „Ressourcen, Semantik und andere Artefakte der Gateway API im Zusammenhang mit Service-Mesh-Technologien und Anwendungsfällen zu untersuchen, zu entwerfen und zu verfolgen.“
Die Gateway API ist ein natürlicher nächster Schritt zur Ingress API, aber wir müssen abwarten, wie sie für Service-Meshes funktionieren wird. Istio hat angekündigt, die Gateway API als Standard-API für alle Verkehrsmanagementaufgaben zu verwenden, und treibt das Projekt weiter voran.
Das folgende Beispiel zeigt die Konfiguration eines Canary-Deployments in Istio mit der Gateway API. Die zugrunde liegende Idee ist die Verwendung von parentRefs, um sich an andere Dienste anstatt an das Gateway anzuhängen:
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
Es gibt einige Bedenken, dass das GAMMA-Projekt eher die Bedürfnisse eines bestimmten Projekts als die der größeren Community bedienen könnte, was letztendlich dazu führen könnte, dass andere Projekte ihre eigenen APIs verwenden, ähnlich wie beim benutzerdefinierten CRD-Szenario nach der Kubernetes-Ingress-API.
Aber das Gateway-API-Projekt war der bisher beste Versuch, das Verkehrsmanagement in Service-Meshes zu standardisieren. Das SMI-Projekt hat sich auch der GAMMA-Initiative angeschlossen mit einer gemeinsamen Vision und wird dazu beitragen, konsistente Implementierungen der Gateway API durch Service-Mesh-Projekte zu fördern.
Andere Projekte wie Flagger und Argo Rollouts haben sich ebenfalls in die Gateway API integriert.
Was sollten Sie verwenden?
Es gibt nur eine richtige Antwort auf diese Frage: „Es kommt darauf an.“
Wenn Sie APIs entwickeln und Authentifizierung, Sicherheit, Routing oder Metriken benötigen, ist es besser, ein API-Gateway zu verwenden, als dies selbst in Ihren APIs zu implementieren.
Wenn Sie etwas Ähnliches in einer Kubernetes-Umgebung tun möchten, sollten Sie ein Kubernetes-Gateway verwenden, anstatt zu versuchen, Ihr API-Gateway für Kubernetes zu optimieren. Glücklicherweise funktionieren viele API-Gateways auch mit Kubernetes-nativen Konfigurationen.
Manchmal können die Funktionen eines API-Gateways + Ingress-Controllers jedoch für eine Kubernetes-Umgebung übertrieben sein, und Sie möchten möglicherweise zu einem einfachen Verkehrsmanagement zurückkehren.
Service-Meshes hingegen lösen eine völlig andere Reihe von Problemen. Sie bringen auch ihre eigenen Gateways mit, um den North-South-Verkehr zu handhaben (was in der Regel ausreicht), ermöglichen es Ihnen aber auch, Ihre eigenen Gateways mit mehr Funktionen zu verwenden.
Die Konvergenz des API-Gateways und des Service-Meshes durch die Kubernetes Gateway API sollte es dem Anwendungsentwickler erleichtern, sich auf die Lösung von Problemen zu konzentrieren, anstatt sich um die zugrunde liegende Implementierung zu kümmern.
Projekte wie Apache APISIX verwenden dieselbe Technologie, um das API-Gateway und die Service-Mesh-Angebote zu erstellen, und integrieren sich gut in diese Spezifikationen, was anbieterneutrale Entscheidungen fördert.
Es ist auch wahrscheinlich, dass Sie keines davon benötigen. Sie brauchen möglicherweise nicht einmal Microservices oder eine verteilte Architektur, aber wenn Sie sie benötigen, können Gateways und Meshes Ihr Leben erheblich erleichtern.