We zullen Gitlab CI en handmatige GitOps gebruiken om Canary-implementatie in Kubernetes te implementeren en te gebruiken

Artikelen uit deze serie:
- (Dit artikel)
- Canary-implementatie met Istio
- Canary-implementatie met Jenkins-X Istio Flagger
We voeren de Canary-implementatie handmatig uit via GitOps en maken/wijzigen de belangrijkste Kubernetes-resources. Dit artikel is vooral bedoeld als inleiding. met hoe de implementatie van Kubernetes Canary werkt, omdat er efficiëntere manieren zijn om dit te automatiseren. We zullen deze manieren in toekomstige artikelen bespreken.

Canarische inzet
Met de Canary-strategie worden updates in eerste instantie slechts op een subgroep gebruikers toegepast. Via monitoring, loggegevens, handmatige tests of andere feedbackkanalen wordt de release getest voordat deze op alle gebruikers wordt toegepast.
Kubernetes-implementatie (doorlopende update)
De standaardstrategie voor Kubernetes Deployment is rolling-update, waarbij een bepaald aantal pods met nieuwe imageversies wordt gestart. Als deze zonder problemen worden aangemaakt, worden de pods met oude imageversies beëindigd en worden nieuwe pods parallel aangemaakt.
Gitops
We gebruiken GitOps in dit voorbeeld omdat we:
- Gebruik Git als enige bron van waarheid
- Gebruik Git Operations voor het bouwen en implementeren (geen andere opdrachten dan git tag/merge nodig)
Voorbeeld
Laten we een goede gewoonte aannemen: één opslagplaats voor applicatiecode en één voor infrastructuur.
Repository voor applicaties
Dit is een zeer eenvoudige Python+Flask API die een JSON-respons retourneert. We bouwen het pakket via GitlabCI en pushen het resultaat naar de Gitlab Registry. In de registry hebben we twee verschillende releaseversies:
wuestkamp/k8s-deployment-example-app:v1wuestkamp/k8s-deployment-example-app:v2
Het enige verschil is de verandering in het geretourneerde JSON-bestand. We gebruiken deze applicatie om zo eenvoudig mogelijk te visualiseren met welke versie we communiceren.
Infrastructuuropslagplaats
In deze repo zullen we via GitlabCI implementeren in Kubernetes, .gitlab-ci.yml ziet er zo 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 kunnen uitvoeren heb je een cluster nodig. Hiervoor kun je Gcloud gebruiken:
gcloud container clusters create canary --num-nodes 3 --zone europe-west3-b
gcloud compute firewall-rules create incoming-80 --allow tcp:80Je moet een vork maken en een variabele aanmaken KUBECONFIG in GitlabCI, dat de configuratie voor toegang zal bevatten kubectl naar jouw cluster.
Hier kunt u lezen hoe u inloggegevens voor een cluster kunt verkrijgen (Gcloud) .
Infrastructuur Yaml
In de infrastructuurrepository hebben we een service:
apiVersion: v1
kind: Service
metadata:
labels:
id: app
name: app
spec:
ports:
- port: 80
protocol: TCP
targetPort: 5000
selector:
id: app
type: LoadBalancerEn inzet 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 nog een inzet 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: 100MiHoud er rekening mee dat app-deploy nog geen replica's heeft gedefinieerd.
De eerste implementatie uitvoeren
Om de eerste implementatie uit te voeren, kunt u de GitlabCI-pijplijn handmatig starten op de masterbranch. Daarna: kubectl zou het volgende moeten opleveren:

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

We zien dat onze testapplicatie alleen “v1” retourneert.
Canary-implementatie uitvoeren
Stap 1: Een nieuwe versie vrijgeven aan een aantal gebruikers
We stellen het aantal replica's in op 1 in het bestand deploy-canary.yaml en de nieuwe versie-image:
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 bestand deploy.yaml We hebben het aantal replica's gewijzigd naar 9:
kind: Deployment
metadata:
name: app
spec:
replicas: 9
selector:
matchLabels:
id: app
...We pushen deze wijzigingen naar de repository van waaruit de implementatie wordt gestart (via GitlabCI) en bekijken het resultaat:

Onze service verwijst naar beide implementaties, omdat beide een app-selector hebben. Vanwege de standaard willekeurige verdeling in Kubernetes zouden we voor ongeveer 10% van de verzoeken verschillende reacties moeten zien:

De huidige status van onze applicatie (GitOps, overgenomen van Git als Single Source Of Truth) is twee implementaties met actieve replica's, één voor elke versie.
Ongeveer 10% van de gebruikers leert de nieuwe versie kennen en test deze onbedoeld. Nu is het tijd om te controleren op fouten in logs en monitoringgegevens om problemen te vinden.
Stap 2: De nieuwe versie vrijgeven aan alle gebruikers
We hebben besloten dat alles goed is gegaan en dat we nu de nieuwe versie voor alle gebruikers moeten implementeren. Hiervoor hoeven we alleen maar de update uit te voeren. deploy.yaml een nieuwe versie van de image installeren en het aantal replica's gelijk aan 10. deploy-canary.yaml We zetten het aantal replica's terug naar 0. Na implementatie zal het resultaat als volgt zijn:

Samengevat
Door de implementatie op deze manier handmatig uit te voeren, begrijp ik hoe eenvoudig het is om deze met k8s in te stellen. Omdat je met Kubernetes alles via de API kunt bijwerken, kunnen deze stappen worden geautomatiseerd met scripts.
Een andere vereiste is een tester-toegangspunt (LoadBalancer of via Ingress) dat alleen toegang heeft tot de nieuwe versie. Dit kan worden gebruikt voor handmatige beoordeling.
In toekomstige artikelen zullen we andere geautomatiseerde oplossingen bekijken die het grootste deel van wat wij hebben gedaan, implementeren.
Lees ook andere artikelen op onze blog:
Bron: www.habr.com
