Einführung
Canary-Bereitstellungen sind hilfreich für die Einführung neuer Versionen von Diensten, da sie eine Möglichkeit bieten, neue Funktionen schrittweise bereitzustellen. Wenn ein Update eingeführt wird, wird es schrittweise für einen kleinen Prozentsatz der Benutzer bereitgestellt. Dadurch können Entwickler sehen, wie das Update funktioniert, bevor es allen zur Verfügung gestellt wird.
Kubernetes wurde entwickelt, um Canary-Bereitstellungen nativ durchzuführen. Der Nachteil dieses Ansatzes besteht jedoch darin, dass die Begrenzung des Datenverkehrs zur Canary-Bereitstellung (durch Ändern der Replikatverhältnisse) manuell erfolgen muss. Die Lösung zur Rationalisierung dieses Prozesses besteht in der Verwendung eines Service-Mesh wie Open-Source-Istio, um die Verteilung des Datenverkehrs und die Anzahl der Replikate zu entkoppeln.
In dieser Anleitung erfahren Sie, wie Sie die Canary-Version einer App in einem Istio-fähigen Cluster bereitstellen und Istio so einrichten, dass das Traffic-Routing gesteuert wird.

Voraussetzungen
- Kubernetes-Cluster (Minikube)
- kubectl-Befehlszeilentool
- Istio installiert
- Docker Hub-Konto
- Grafana-Dashboard
Schritt 1:Erstellen Sie das Docker-Image und den Container für Canary Build
Um mit der Bereitstellung des Canary-Builds Ihrer App zu beginnen, erstellen Sie zunächst ein Docker-Image mit der Version, die Sie bereitstellen möchten.
- Gehen Sie in das Verzeichnis, das die notwendigen Dateien für das Bild enthält. Das Beispiel verwendet eine App namens test-canary , gespeichert im gleichnamigen Verzeichnis:
cd test-canary
2. Verwenden Sie den docker build
Befehl, um das Docker-Image zu erstellen. Folgen Sie dem Befehl mit Ihrem Docker-Hub-Benutzernamen und dem Image-Namen:
docker build -t [dockerhub-username]/test-canary .
Die Ausgabe bestätigt die erfolgreiche Image-Erstellung:

3. Verwenden Sie die docker images
Befehl, um eine Liste Ihrer Bilder anzuzeigen und zu prüfen, ob das neue Bild darunter ist:
docker images

4. Verwenden Sie als Nächstes den docker run
Befehl, um einen Container mit dem zuvor erstellten Image zu erstellen. Geben Sie dem Container einen Namen und wählen Sie einen Port für den Zugriff:
docker run --name [name] -p [port]:8080 -d [dockerhub-username]/test-canary
Wenn die Operation erfolgreich ist, gibt das System die vollständige ID des neu erstellten Containers aus:

5. Verwenden Sie docker ps
Befehl zum Überprüfen der laufenden Container:
docker ps

6. Verwenden Sie nun den Port, den Sie dem Container zugewiesen haben, um über einen Browser darauf zuzugreifen:
http://localhost:[port]
Der Browser zeigt den Inhalt der App an:

7. Nachdem Sie bestätigt haben, dass die App funktioniert, stoppen Sie den Container mit docker stop
Befehl. Fügen Sie dem Befehl die Container-ID hinzu, die Sie aus der ersten Spalte von docker ps
kopieren können Ausgabe:
docker stop [container-id]

8. Um das Image schließlich per Push auf Ihr Docker-Hub-Konto zu übertragen, melden Sie sich über die Befehlszeile bei Docker-Hub an:
docker login -u [dockerhub-username]
Das System fragt nach dem Passwort. Geben Sie das Passwort ein und drücken Sie Enter :

9. Pushen Sie nun das Image mit docker push
:
docker push [dockerhub-username]/test-canary

Schritt 2:Ändern Sie die App-Bereitstellung
Um die Canary-Bereitstellung zu Ihrer allgemeinen App-Bereitstellung hinzuzufügen, verwenden Sie einen Texteditor, um die Datei zu bearbeiten, die Dienst- und Bereitstellungsspezifikationen enthält.
Das Beispiel verwendet das Anwendungsmanifest namens app-manifest.yaml
:
nano app-manifest.yaml
Das Manifest sollte dem folgenden Inhalt ähneln:
apiVersion: v1
kind: Service
metadata:
name: nodejs
labels:
app: nodejs
spec:
selector:
app: nodejs
ports:
- name: http
port: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nodejs
labels:
version: v1
spec:
replicas: 1
selector:
matchLabels:
app: nodejs
template:
metadata:
labels:
app: nodejs
version: v1
spec:
containers:
- name: nodejs
image: markopnap/test-prod
ports:
- containerPort: 8080
Das obige Beispielmanifest beschreibt eine Produktionsversion einer Node.js-App, deren Container in markopnap/test-prod
gespeichert ist . Um die Canary-Version der Anwendung einzuschließen, bearbeiten Sie zunächst die Bereitstellung Abschnitt der Datei und fügen Sie -v1
hinzu zum Namen der App:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nodejs-v1
Hängen Sie nun einen weiteren Deployment-Abschnitt mit Spezifikationen für den Canary-Build an das Ende der Datei an:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nodejs-v2
labels:
version: v2
spec:
replicas: 1
selector:
matchLabels:
app: nodejs
template:
metadata:
labels:
app: nodejs
version: v2
spec:
containers:
- name: nodejs
image: markopnap/test-canary
ports:
- containerPort: 8080
Nachdem Sie die Datei bearbeitet haben, speichern Sie sie und aktualisieren Sie dann die Systemkonfiguration mit kubectl apply
:
kubectl apply -f app-manifest.yaml
Schritt 3:Konfigurieren Sie den virtuellen Istio-Dienst
Erstellen Sie eine neue YAML-Datei zum Speichern der Istio-Konfiguration. Das Beispiel verwendet die Datei mit dem Titel istio.yaml
, aber Sie können ihm einen Namen Ihrer Wahl geben:
nano istio.yaml
Wenn Sie zuvor Istio für die Bereitstellung einer Produktionsversion verwendet haben, ist die Datei bereits vorhanden und sollte etwa so aussehen:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: nodejs-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: nodejs
spec:
hosts:
- "*"
gateways:
- nodejs-gateway
http:
- route:
- destination:
host: nodejs
Die Datei hat zwei Abschnitte, die Gateway definieren und VirtualService Objekte. Um beide Versionen der Anwendung einzuführen und die Routingregel für die Verteilung an Benutzer festzulegen, ändern Sie die http
Abschnitt ganz unten. Der Abschnitt muss zwei Ziele mit unterschiedlichen Teilmengen enthalten und Gewichte :
http:
- route:
- destination:
host: nodejs
subset: v1
weight: 90
- destination:
host: nodejs
subset: v2
weight: 10
Das Gewicht Der Parameter teilt Istio mit, welcher Prozentsatz des Datenverkehrs an ein bestimmtes Ziel weitergeleitet werden soll. Im obigen Beispiel gehen 90 % des Datenverkehrs an die Produktionsversion, während 10 % an den Canary-Build geleitet werden.
Nachdem Sie den Abschnitt Virtueller Dienst bearbeitet haben, hängen Sie die folgenden Zeilen an das Ende der Datei an, um eine Zielregel zu erstellen :
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: nodejs
spec:
host: nodejs
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
Der Zweck der Definition der Zielregel besteht darin, den eingehenden Datenverkehr zu verwalten und an die angegebenen Versionen der Anwendung zu senden.
Speichern Sie die Datei und verwenden Sie kubectl apply
um es zu aktivieren:
kubectl apply -f istio.yaml
Schritt 4:Canary-Bereitstellung testen
Die im vorherigen Schritt festgelegte Konfiguration führt das Traffic-Routing zu Ihren Produktions- und Canary-Bereitstellungen durch. Um dies zu testen, greifen Sie über die externe IP von istio-ingressgateway
auf die Anwendung zu , die Istio als Load Balancer verwendet.
Suchen Sie nach istio-ingressgateway
service in der Liste der im istio-system
verfügbaren Dienste Namensraum. Verwenden Sie kubectl get
um die Dienste aufzulisten:
kubectl get svc -n istio-system

Kopieren Sie istio-ingressgateway
externe IP-Adresse in die Adressleiste Ihres Browsers:
http://[ingressgateway_ip]
Der Browser zeigt wahrscheinlich die Produktionsversion der Anwendung an. Klicken Sie auf Aktualisieren mehrmals drücken, um Verkehr zu simulieren:

Nach ein paar Mal sollten Sie die Canary-Version der App sehen:

Wenn Sie das Grafana-Add-On installiert haben, überprüfen Sie die Statistiken zu eingehenden Anforderungen, um den Routing-Prozentsatz für jede Bereitstellung anzuzeigen. Klicken Sie in Grafana auf die Startseite Symbol:

In den Dashboards Wählen Sie im Abschnitt Istio aus , und klicken Sie dann auf Istio Service Dashboard :

Suchen Sie im Dashboard den Dienst Feld und wählen Sie den Ihrer Anwendung entsprechenden Service aus. In diesem Beispiel heißt der Dienst nodejs.default.svc.cluster.local
. Sobald Sie den Dienst ausgewählt haben, gehen Sie zu den Dienstarbeitslasten Abschnitt:

Wählen Sie das Diagramm mit dem Titel Eingehende Anfragen nach Ziel-Workload und Antwortcode aus . Das Diagramm zeigt den Traffic, den Sie durch die Aktualisierung der Seite generiert haben. In diesem Beispiel ist ersichtlich, dass Istio den nodejs-v1
bereitgestellt hat Version der App häufiger als die Canary nodejs-v2
Version.
