Traffic Split im Apache APISIX Ingress Controller

Fei Han

March 27, 2021

Products

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".)

1.png

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.

Tags: