We zullen Gitlab CI en handmatige GitOps gebruiken voor de implementatie en het gebruik van Canary-deployment in Kubernetes

Artikelen in deze cyclus:
- (dit artikel)
- Canary Deployment met Istio
- Canary Deployment met Jenkins-X Istio Flagger
We zullen de Canary-deployment handmatig uitvoeren via GitOps en het maken/wijzigen van basisresources in Kubernetes. Dit artikel is in de eerste plaats bedoeld om bekend te raken met hoe Canary-deployment in Kubernetes werkt, aangezien er meer efficiƫnte manieren van automatisering zijn die we in de volgende artikelen zullen bespreken.

Canary Deployment
Bij de Canary-strategie worden updates eerst toegepast op een deel van de gebruikers. Via monitoring, loggingdata, handmatige tests of andere feedbackkanalen wordt de release getest voordat deze voor alle gebruikers wordt toegepast.
Kubernetes Deployment (rolling update)
De standaardstrategie voor Kubernetes Deployment is een rolling-update, waarbij een bepaald aantal pods met nieuwe versies van images wordt gestart. Als deze zonder problemen zijn aangemaakt, worden de pods met oude versies van images beƫindigd en worden nieuwe pods parallel aangemaakt.
GitOps
We gebruiken GitOps in dit voorbeeld omdat we:
- Git als enige bron van waarheid gebruiken
- Git Operations voor build en deployment gebruiken (geen commando's behalve git tag/merge nodig zijn)
Voorbeeld
Laten we een goede praktijk nemen ā ƩƩn repository voor de applicatiecode en ƩƩn voor de infrastructuur.
Repository voor applicaties
Dit is een zeer eenvoudige API in Python+Flask die een JSON-antwoord retourneert. We zullen het pakket bouwen via GitlabCI en het resultaat naar de Gitlab Registry pushen. In de registry hebben we twee verschillende versies van releases:
wuestkamp/k8s-deployment-example-app:v1wuestkamp/k8s-deployment-example-app:v2
Het enige verschil tussen hen is de wijziging van het teruggegeven JSON-bestand. We gebruiken deze applicatie voor een zo eenvoudig mogelijke visualisatie van met welke versie we communiceren.
Infrastructuurrepository
In deze repo zullen we via GitlabCI naar Kubernetes deployen, .gitlab-ci.yml er als volgt uit:
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
Om het zelf te starten heeft u een cluster nodig, u kunt Gcloud gebruiken:
gcloud container clusters create canary --num-nodes 3 --zone europe-west3-b
gcloud compute firewall-rules create incoming-80 --allow tcp:80U moet een fork maken en een variabele aanmaken KUBECONFIG in GitlabCI, die de configuratie voor toegang bevat kubectl tot uw cluster.
Hoe je de referenties voor de cluster (Gcloud) kunt verkrijgen, kun je lezen .
Infrastructuur Yaml
In de infrastructuurrepository hebben we service:
apiVersion: v1
kind: Service
metadata:
labels:
id: app
name: app
spec:
ports:
- port: 80
protocol: TCP
targetPort: 5000
selector:
id: app
type: LoadBalancerEn 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: 100MiEn een andere 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: 100MiMerk op dat app-deploy momenteel geen gedefinieerde replica's heeft.
Uitvoeren van de initiƫle deployment
Om de initiƫle deployment te starten, kun je de GitlabCI-pipeline handmatig starten in de masterbranch. Daarna kubectl moet het volgende tonen:

We zien app deployment met 10 replica's en app-canary met 0. Er is ook een LoadBalancer waar we toegang toe hebben via curl met Externe IP:
while true; do curl -s 35.198.149.232 | grep label; sleep 0.1; done

We zien dat onze testapplicatie alleen "v1" retourneert.
Uitvoeren van de Canary deployment
Stap 1: een nieuwe versie uitgeven voor een deel van de gebruikers
We hebben het aantal replica's ingesteld op 1 in het bestand deploy-canary.yaml en het beeld van de nieuwe versie:
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 het bestand deploy.yaml we hebben het aantal replica's verhoogd tot 9:
kind: Deployment
metadata:
name: app
spec:
replicas: 9
selector:
matchLabels:
id: app
...We pushen deze wijzigingen naar de repository, waaruit de deployment (via GitlabCI) zal worden gestart en zien uiteindelijk:

Onze Service zal naar beide deployments wijzen, aangezien beiden de selector app hebben. Door de willekeurige verdeling standaard in Kubernetes, zouden we verschillende antwoorden op ~ 10% van de verzoeken moeten zien:

De huidige staat van onze applicatie (GitOps, genomen uit Git als Single Source Of Truth) is dat er twee deployments zijn met actieve replica's, ƩƩn voor elke versie.
~10% van de gebruikers maken kennis met de nieuwe versie en testen deze onbedoeld. Het is nu tijd om te controleren op fouten in de logbestanden en monitoringsgegevens om naar problemen te zoeken.
Stap 2: een nieuwe versie uitrollen voor alle gebruikers
We hebben besloten dat alles goed is gegaan en nu moeten we de nieuwe versie voor alle gebruikers uitrollen. Hiervoor updaten we gewoon deploy.yaml door de nieuwe versie van de image in te stellen en het aantal replicas op 10. In deploy-canary.yaml stellen we het aantal replicas weer in op 0. Na de deployment zal het resultaat als volgt zijn:

Samenvattend
Voor mij helpt het om de deployment handmatig zo uit te voeren om te begrijpen hoe gemakkelijk het kan worden ingesteld met k8s. Aangezien Kubernetes alles via de API kan updaten, kunnen deze stappen geautomatiseerd worden via scripts.
Een andere zaak die moet worden geĆÆmplementeerd is het toegangspunt voor de tester (LoadBalancer of via Ingress), waarmee alleen toegang tot de nieuwe versie mogelijk is. Dit kan handmatig worden gebruikt om het te bekijken.
In de volgende artikelen zullen we andere geautomatiseerde oplossingen bekijken die de meeste van wat we hebben gedaan implementeren.
Lees ook andere artikelen op onze blog:
Bron: habr.com
