Traffic Split im Apache APISIX Ingress Controller
Fei Han
March 27, 2021
Traffic Split ist eine Funktion, die den Datenverkehr aufteilt und an mehrere Backend-Dienste weiterleitet. Lösungen wie API-Gateways (z. B. Apache APISIX und Traefik) und Service Mesh (z. B. Istio und Linkerd) sind in der Lage, Traffic Splitting durchzuführen und Funktionen wie Canary Release und Blue-Green Deployment zu implementieren.
Traffic Split ist auch eine Schlüsselfunktion in Ingress Controllern. Als Ingress-Schicht in einem Kubernetes-Cluster ist es wünschenswert, das Risiko bei der Veröffentlichung einer neuen Version der Anwendung zu minimieren, indem einige Traffic-Split-Regeln im Ingress Controller eingerichtet werden, sodass nur eine kontrollierbare Menge des Datenverkehrs an neu veröffentlichte Instanzen weitergeleitet wird. In diesem Artikel werden wir das Traffic Splitting (auch Canary Release genannt) in Ingress Nginx und Kong Ingress Controller vorstellen und schließlich das Traffic Splitting im Apache APISIX Ingress Controller erklären.
(PS: Um die Beschreibungen prägnanter zu gestalten, verwenden wir den Begriff "Canary App", um den Backend-Dienst zu beschreiben, der nach dem Treffen der Canary-Regeln weitergeleitet wird, und den Begriff "Stable App", um den Backend-Dienst zu beschreiben, der aufgrund des Nicht-Treffens der Canary-Regeln weitergeleitet wird. Zum Beispiel sind die Canary- und Stable-Apps im folgenden Diagramm "foo-canary" und "foo".)
Ingress Nginx
Ingress Nginx unterstützt den Canary Release, der durch eine Annotation "nginx.ingress.kubernetes.io/canary" gesteuert wird, und es unterstützt mehrere Annotationen, um diese Funktion anzupassen.
- nginx.ingress.kubernetes.io/canary-by-header
Das Ziel wird durch den Wert des Headers (angegeben durch nginx.ingress.kubernetes.io/canary-by-header) bestimmt. Die Canary-App wird weitergeleitet, wenn der Wert "always" ist, andernfalls wird die Stable-App weitergeleitet (der Wert des Headers ist "never").
- nginx.ingress.kubernetes.io/canary-by-header-value
Diese Annotation erweitert nginx.ingress.kubernetes.io/canary-by-header, sodass der Wert des Headers nicht mehr "always" oder "never" sein muss.
- nginx.ingress.kubernetes.io/canary-by-header-pattern
Ähnlich wie nginx.ingress.kubernetes.io/canary-by-header, aber der Wert ist ein PCRE-kompatibler regulärer Ausdruck.
- nginx.ingress.kubernetes.io/canary-by-cookie
Verwendet das Datenfeld im Cookie-Header, um den Backend-Dienst zu bestimmen.
- nginx.ingress.kubernetes.io/canary-weight
Weist einen Gewichtungswert zwischen 0 und 100 zu, der Datenverkehr wird entsprechend dieser Gewichtung weitergeleitet. Ein Gewichtungswert von 0 bedeutet, dass der gesamte Datenverkehr an die Canary-App weitergeleitet wird, und ein Wert von 100 leitet den gesamten Datenverkehr an die Stable-App weiter.
Das folgende YAML-Snippet leitet Anfragen, deren URI-Pfad mit "/get" beginnt und deren User-Agent mit dem Muster ".Mozilla." übereinstimmt, an die Canary-App "foo-canary" weiter.
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-by-header: "User-Agent"
nginx.ingress.kubernetes.io/canary-by-header-pattern:
".*Mozilla.*"
name: ingress-v1beta1
Kong
Der Kong Gateway hat ein Canary-Release-Plugin und macht dieses Plugin über die KongPlugin-Ressource für seinen Ingress Controller verfügbar. Administratoren/Benutzer müssen ein KongPlugin-Objekt erstellen und die Canary-Release-Regel ausfüllen, indem sie eine Annotation "konghq.com/plugins" in den Ziel-Kubernetes-Service einfügen. Alternativ können Sie ein KongClusterPlugin-Objekt erstellen, um diese Canary-Regel im gesamten Cluster wirksam zu machen.
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
name: foo-canary
config:
percentage: 30
upstream_host: foo.com
upstream_fallback: false
upstream_port: 80
plugin: canary
---
apiVersion: v1
kind: Service
metadata:
name: foo-canary
labels:
app: foo
annotations:
konghq.com/plugins: foo-canary
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
name: http
selector:
app: foo
canary: true
Das obige Beispiel markiert den Service "foo-canary" als "canary" und erstellt eine Canary-Release-Regel, um 30 % des Datenverkehrs an diesen Service weiterzuleiten.
Apache APISIX
Apache APISIX teilt den Datenverkehr mit benutzerdefinierten Regeln durch sein Traffic-Split-Plugin, und der Apache APISIX Ingress Controller implementiert die Traffic-Split-Funktion in ApisixRoute (als First-Class-Support, ohne auf Annotationen angewiesen zu sein) durch dieses Plugin und die flexiblen Routenabgleichfähigkeiten in ApisixRoute.
Gewichtungsbasiert
Durch die Konfiguration mehrerer Kubernetes-Services kann die gewichtungsbasierte Canary-Regel wie folgt angewendet werden:
apiVersion: apisix.apache.org/v2alpha1
kind: ApisixRoute
metadata:
name: foo-route
spec:
http:
- name: rule1
match:
hosts:
- foo.org
paths:
- /get*
backends:
- serviceName: foo-canary
servicePort: 80
weight: 10
- serviceName: foo
servicePort: 80
weight: 5
Das obige Beispiel leitet ⅔ der Anfragen, deren Host "foo.org" ist und deren URI-Pfad mit "/get" beginnt, an den Service "foo-canary" weiter und den Rest an "foo".
Das Gewicht für den Canary-Service kann für eine kleine Überprüfung gering sein und durch die Änderung der ApisixRoute vergrößert werden, bis der gesamte Datenverkehr an den Canary-Service weitergeleitet wird, wodurch die Veröffentlichung vollständig abgeschlossen wird.
Regelbasiert
Das Feld Exprs in ApisixRoute ermöglicht es Benutzern, benutzerdefinierte Routenabgleichsregeln zu konfigurieren. Andererseits können mehrere Routenregeln in einem einzigen ApisixRoute-Objekt gruppiert werden, sodass es eine nahtlose Möglichkeit gibt, das regelbasierte Traffic Splitting zu implementieren.
apiVersion: apisix.apache.org/v2alpha1
kind: ApisixRoute
metadata:
name: foo-route
spec:
http:
- name: rule1
priority: 1
match:
hosts:
- foo.org
paths:
- /get*
backends:
- serviceName: foo
servicePort: 80
- name: rule2
priority: 2
match:
hosts:
- foo.org
paths:
- /get*
exprs:
- subject:
scope: Query
name: id
op: In
set:
- "3"
- "13"
- "23"
- "33"
backends:
- serviceName: foo-canary
servicePort: 80
Anfragen, deren Host "foo.org" ist und deren URI-Pfad mit "/get" beginnt, werden in zwei Teile getrennt:
- Der id-Parameter, dessen Wert 3, 13, 23 oder 33 ist, trifft auf Regel2 und wird an foo-canary weitergeleitet;
- Andere treffen auf Regel1 und werden an foo weitergeleitet.
Zusammenfassung
Traffic Split (Canary Release) in Ingress Nginx unterstützt gewichtungsbasierte und header-regelbasierte Schemata, aber es basiert auf Annotationen, deren Semantik schwach ist; Die Kong-Methode unterstützt nur die Konfiguration von Canary Release durch Gewichtung, die Szenarien sind etwas eingeschränkt, und die Konfiguration ist kompliziert (Sie müssen mehrere Ressourcen konfigurieren); Im Gegensatz dazu ist das Traffic Splitting im Apache APISIX Ingress Controller flexibel und einfach zu konfigurieren, es funktioniert gut sowohl für gewichtungsbasierte als auch für regelbasierte Traffic-Split-Schemata.