Canary Deployment in Kubernetes #3: Istio

Verwendung von Istio+Kiali zur Ausführung und Visualisierung eines Canary Deployments

Canary Deployment in Kubernetes #3: Istio

Artikel dieser Reihe

  1. Canary Deployment in Kubernetes #1: Gitlab CI
  2. Canary Deployment in Kubernetes #2: Argo Rollouts
  3. (dieser Artikel)
  4. Canary Deployment mit Jenkins-X Istio Flagger

Canary Deployment

Wir hoffen, dass Sie gelesen haben den ersten Teil, in dem wir kurz erklärt haben, was Canary Deployments sind und gezeigt haben, wie man es mit den Standardressourcen von Kubernetes umsetzt.

Istio

Und wir nehmen an, dass Sie beim Lesen dieses Artikels bereits wissen, was Istio ist. Falls nicht, können Sie mehr darüber lesen hier.

Testanwendung

Canary Deployment in Kubernetes #3: Istio

Jeder Pod enthält zwei Container: unsere Anwendung und istio-proxy.

Wir werden eine einfache Testanwendung mit den Pods frontend-nginx und backend in Python verwenden. Der Pod mit nginx wird einfach jede Anfrage an den Pod mit backend weiterleiten und als Proxy fungieren. Details können in den folgenden YAMLs genauer angesehen werden:

Starten Sie die Testanwendung selbstständig

Wenn Sie meinem Beispiel folgen und diese Testanwendung selbstständig nutzen möchten, lesen Sie bitte die Readme des Projekts.

Initiales Deployment

Beim Start des ersten Deployments sehen wir, dass die Pods unserer Anwendung jeweils nur 2 Container haben, d.h. der Istio Sidecar wird gerade implementiert:

Canary Deployment in Kubernetes #3: Istio

Und wir sehen auch den Istio Gateway Loadbalancer im Namespace istio-system:

Canary Deployment in Kubernetes #3: Istio

Erzeugen von Traffic

Wir werden die folgende IP verwenden, um Traffic zu generieren, der von den Frontend-Pods empfangen und an die Backend-Pods weitergeleitet wird:

while true; do curl -s --resolve 'frontend.istio-test:80:35.242.202.152' frontend.istio-test; sleep 0.1; done

Wir werden auch frontend.istio-test in unsere hosts-Datei hinzufügen.

Mesh über Kiali anzeigen

Wir haben die Testanwendung und Istio zusammen mit Tracing, Grafana, Prometheus und Kiali installiert (näheres siehe Readme des Projekts). Daher können wir Kiali über Folgendes verwenden:

istioctl dashboard kiali # admin:admin

Canary Deployment in Kubernetes #3: Istio

Kiali visualisiert den aktuellen Traffic durch das Mesh

Wie wir sehen, gehen 100% des Traffics an den Frontend-Service und dann an den Frontend-Pod mit dem Label v1, da wir einen einfachen nginx-Proxy verwenden, der Anfragen an den Backend-Service weiterleitet, der sie wiederum an die Backend-Pods mit dem Label v1 weiterleitet.

Kiali funktioniert hervorragend mit Istio und bietet eine umfassende Lösung zur Visualisierung des Mesh. Einfach großartig.

Canary Deployment

Unser Backend hat bereits zwei K8s Deployments, eines für v1 und eines für v2. Jetzt müssen wir nur sagen, dass Istio einen bestimmten Prozentsatz der Anfragen an v2 weiterleitet.

Schritt 1: 10%

Und alles, was wir tun müssen, ist, das Gewicht des VirtualService anzupassen in istio.yaml:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: backend
  namespace: default
spec:
  gateways: []
  hosts:
  - "backend.default.svc.cluster.local"
  http:
  - match:
    - {}
    route:
    - destination:
        host: backend.default.svc.cluster.local
        subset: v1
        port:
          number: 80
      weight: 90
    - destination:
        host: backend.default.svc.cluster.local
        subset: v2
        port:
          number: 80
      weight: 10

Canary Deployment in Kubernetes #3: Istio

Wir sehen, dass 10 % der Anfragen auf v2 umgeleitet werden.

Schritt 2: 50 %

Und jetzt reicht es aus, ihn auf 50 % zu erhöhen:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: backend
  namespace: default
spec:
...
    - destination:
        host: backend.default.svc.cluster.local
        subset: v1
        port:
          number: 80
      weight: 50
    - destination:
        host: backend.default.svc.cluster.local
        subset: v2
        port:
          number: 80
      weight: 50

Canary Deployment in Kubernetes #3: Istio

Schritt 3: 100 %

Jetzt kann das Canary-Deployment als abgeschlossen betrachtet werden, und der gesamte Verkehr wird auf v2 umgeleitet:

Canary Deployment in Kubernetes #3: Istio

Manuelle Testung von Canary

Angenommen, wir leiten jetzt 10 % aller Anfragen an das Backend v2 weiter. Was, wenn wir v2 manuell testen möchten, um sicherzustellen, dass alles wie erwartet funktioniert?

Wir können eine spezielle Übereinstimmungsregel hinzufügen, die auf HTTP-Headern basiert:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: backend
  namespace: default
spec:
  gateways: []
  hosts:
  - "backend.default.svc.cluster.local"
  http:
  - match:
    - headers:
        canary:
          exact: "canary-tester"
    route:
    - destination:
        host: backend.default.svc.cluster.local
        subset: v2
        port:
          number: 80
      weight: 100
  - match:
    - {}
    route:
    - destination:
        host: backend.default.svc.cluster.local
        subset: v1
        port:
          number: 80
      weight: 90
    - destination:
        host: backend.default.svc.cluster.local
        subset: v2
        port:
          number: 80
      weight: 10

Jetzt können wir mit curl v2 anfordern, indem wir den Header senden:

Canary Deployment in Kubernetes #3: Istio

Anfragen ohne Header werden weiterhin im Verhältnis 1/10 behandelt:

Canary Deployment in Kubernetes #3: Istio

Canary für zwei abhängige Versionen

Jetzt betrachten wir das Szenario, in dem wir sowohl für das Frontend als auch für das Backend die Version v2 haben. Für beide haben wir angegeben, dass 10 % des Traffics zu v2 gehen sollen:

Canary Deployment in Kubernetes #3: Istio

Wir sehen, dass das Frontend v1 und v2 den Verkehr im Verhältnis 1/10 an Backend v1 und v2 weiterleiten.

Was wäre, wenn wir den Verkehr von frontend-v2 nur an backend-v2 weiterleiten müssten, weil er nicht mit v1 kompatibel ist? Dafür richten wir ein Verhältnis von 1/10 für das Frontend ein, das steuert, welcher Verkehr zu backend-v2 gelangt, basierend auf sourceLabels :

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: backend
  namespace: default
spec:
  gateways: []
  hosts:
  - "backend.default.svc.cluster.local"
  http:
...
  - match:
    - sourceLabels:
        app: frontend
        version: v2
    route:
    - destination:
        host: backend.default.svc.cluster.local
        subset: v2
        port:
          number: 80
      weight: 100

Das Ergebnis ist das, was wir brauchen:

Canary Deployment in Kubernetes #3: Istio

Unterschiede zum manuellen Canary-Ansatz

Im ersten Teils Wir haben das Canary Deployment manuell durchgeführt, ebenfalls mit zwei k8s Deployments. Dort haben wir das Verhältnis der Anfragen gesteuert, indem wir die Anzahl der Replikate geändert haben. Dieser Ansatz funktioniert, hat jedoch erhebliche Nachteile.

Istio ermöglicht es, das Verhältnis der Anfragen unabhängig von der Anzahl der Replikate zu definieren. Das bedeutet zum Beispiel, dass wir HPAs (Horizontal Pod Autoscalers) verwenden können und es nicht notwendig ist, diese gemäß dem aktuellen Zustand des Canary Deployments zu konfigurieren.

Fazit

Istio funktioniert ausgezeichnet und in Kombination mit Kiali erhalten wir eine sehr leistungsstarke Kombination. Das Nächste, was mich interessiert, ist die Kombination von Spinnaker mit Istio für Automatisierung und Canary-Analytik.

Quelle: habr.com

60GB SSD 8Gb DDR4