Wir werden Gitlab CI und manuelles GitOps verwenden, um Canary-Deployments in Kubernetes zu implementieren und zu nutzen.

Artikel aus dieser Reihe:
- (dieser Artikel)
- Canary Deployment mit Istio
- Canary Deployment mit Jenkins-X Istio Flagger
Das Canary-Deployment führen wir manuell über GitOps und die Erstellung/Änderung von Kernressourcen in Kubernetes durch. Dieser Artikel richtet sich in erster Linie an Einsteiger, um zu verstehen, wie das Canary-Deployment in Kubernetes funktioniert, da es effizientere Automatisierungsmethoden gibt, die wir in den folgenden Artikeln behandeln werden.

Canary Deployment
Bei der Canary-Strategie werden die Updates zunächst nur für einen Teil der Benutzer angewendet. Durch Monitoring, Daten aus Logs, manuelle Tests oder andere Feedback-Kanäle wird die Veröffentlichung getestet, bevor sie für alle Benutzer ausgerollt wird.
Kubernetes Deployment (rolling update)
Die Standardstrategie für Kubernetes Deployments ist das Rolling-Update, bei dem eine bestimmte Anzahl von Pods mit neuen Versionen der Images gestartet wird. Wenn sie problemlos erstellt wurden, werden die Pods mit den alten Versionen beendet, während die neuen Pods parallel erstellt werden.
GitOps
Wir verwenden GitOps in diesem Beispiel, da wir:
- Wir verwenden Git als einzige Quelle der Wahrheit.
- Wir nutzen Git-Operationen für den Build und das Deployment (es sind keine Befehle außer git tag/merge erforderlich).
Beispiel
Eine bewährte Praxis ist es, ein Repository für Anwendungs-Code und ein weiteres für die Infrastruktur zu haben.
Anwendungs-Repository
Dies ist eine sehr einfache API auf Python + Flask, die eine Antwort im JSON-Format zurückgibt. Wir werden das Paket über GitLab CI bauen und das Ergebnis in das GitLab-Registry pushen. Im Registry haben wir zwei verschiedene Release-Versionen:
wuestkamp/k8s-deployment-example-app:v1wuestkamp/k8s-deployment-example-app:v2
Der einzige Unterschied zwischen ihnen ist die Änderung der zurückgegebenen JSON-Datei. Wir verwenden diese Anwendung, um die Version, mit der wir kommunizieren, so einfach wie möglich zu visualisieren.
Infrastruktur-Repository
In diesem Repository werden wir über GitLab CI in Kubernetes deployen, .gitlab-ci.yml es sieht folgendermaßen aus:
image: traherom/kustomize-docker
before_script:
- printenv
- kubectl version
stages:
- deploy
deploy test:
stage: deploy
before_script:
- echo $KUBECONFIG
script:
- kubectl get all
- kubectl apply -f i/k8s
only:
- master
Um es selbst zu starten, benötigen Sie ein Cluster, Sie können Gcloud verwenden:
gcloud container clusters create canary --num-nodes 3 --zone europe-west3-b
gcloud compute firewall-rules create incoming-80 --allow tcp:80Sie müssen einen Fork erstellen und eine Variable erstellen KUBECONFIG in GitlabCI, die die Konfiguration für den Zugriff enthält kubectl auf Ihren Cluster.
Wie man die Anmeldedaten für den Cluster (Gcloud) erhält, kann man .
Infrastruktur Yaml
In unserem Infrastruktur-Repository haben wir einen Dienst:
apiVersion: v1
kind: Service
metadata:
labels:
id: app
name: app
spec:
ports:
- port: 80
protocol: TCP
targetPort: 5000
selector:
id: app
type: LoadBalancerund ein Deployment in deploy.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
spec:
replicas: 10
selector:
matchLabels:
id: app
type: main
template:
metadata:
labels:
id: app
type: main
spec:
containers:
- image: registry.gitlab.com/wuestkamp/k8s-deployment-example-app:v1
name: app
resources:
limits:
cpu: 100m
memory: 100Miund ein weiteres Deployment in deploy-canary.yaml:
kind: Deployment
metadata:
name: app-canary
spec:
replicas: 0
selector:
matchLabels:
id: app
type: canary
template:
metadata:
labels:
id: app
type: canary
spec:
containers:
- image: registry.gitlab.com/wuestkamp/k8s-deployment-example-app:v2
name: app
resources:
limits:
cpu: 100m
memory: 100MiBeachten Sie, dass app-deploy derzeit keine definierten Replikate hat.
Durchführung des initialen Deployments
Um das initiale Deployment zu starten, können Sie die GitlabCI-Pipeline manuell im Master-Branch ausführen. Danach kubectl sollte Folgendes ausgegeben werden:

Wir sehen app Bereitstellung mit 10 Replikaten und app-canary auf 0. Es gibt auch einen LoadBalancer, über den wir zugreifen können über curl die externe IP:
while true; do curl -s 35.198.149.232 | grep label; sleep 0.1; done

Wir sehen, dass unsere Testanwendung nur "v1" zurückgibt.
Ausführung des Canary Deployments
Schritt 1: Veröffentlichen Sie eine neue Version für einen Teil der Benutzer
Wir haben die Anzahl der Replikate in der Datei deploy-canary.yaml auf 1 gesetzt und das Image der neuen Version:
kind: Deployment
metadata:
name: app-canary
spec:
replicas: 1
selector:
matchLabels:
id: app
type: canary
template:
metadata:
labels:
id: app
type: canary
spec:
containers:
- image: registry.gitlab.com/wuestkamp/k8s-deployment-example-app:v2
name: app
resources:
limits:
cpu: 100m
memory: 100MiIn der Datei deploy.yaml Wir haben die Anzahl der Replikate auf 9 erhöht:
kind: Deployment
metadata:
name: app
spec:
replicas: 9
selector:
matchLabels:
id: app
...Wir pushen diese Änderungen in das Repository, aus dem das Deployment gestartet wird (über GitlabCI) und sehen letztendlich:

Unser Service wird auf beide Deployments zeigen, da beide den Selector app haben. Aufgrund der zufälligen Verteilung in Kubernetes sollten wir bei ~ 10 % der Anfragen unterschiedliche Antworten sehen:

Der aktuelle Zustand unserer Anwendung (GitOps, aus Git als Single Source Of Truth) zeigt, dass es zwei Deployments mit aktiven Replikaten gibt, eines für jede Version.
~10% der Nutzer lernen die neue Version kennen und testen sie unabsichtlich. Jetzt ist es an der Zeit, die Protokolle und Überwachungsdaten auf Fehler zu überprüfen, um Probleme zu finden.
Schritt 2: Neue Version für alle Nutzer bereitstellen
Wir haben beschlossen, dass alles gut gelaufen ist, und jetzt müssen wir die neue Version für alle Nutzer ausrollen. Dazu aktualisieren wir einfach deploy.yaml das Abbild auf die neue Version und setzen die Anzahl der Replikate auf 10. In deploy-canary.yaml stellen wir die Anzahl der Replikate wieder auf 0. Nach dem Deployment wird das Ergebnis wie folgt aussehen:

Zusammenfassend
Für mich hilft es, das Deployment manuell auf diese Weise zu starten, um zu verstehen, wie einfach es mit k8s konfiguriert werden kann. Da Kubernetes ermöglicht, alles über die API zu aktualisieren, können diese Schritte durch Skripte automatisiert werden.
Eine weitere Sache, die umgesetzt werden muss, ist der Einstiegspunkt für den Tester (LoadBalancer oder über Ingress), über den man nur auf die neue Version zugreifen kann. Er kann manuell zur Einsicht verwendet werden.
In den kommenden Artikeln werden wir weitere automatisierte Lösungen überprüfen, die die meisten der von uns durchgeführten Schritte umsetzen.
Lesen Sie auch andere Artikel in unserem Blog:
Quelle: habr.com
