Uitwerking
In week 3 heb ik een Blue-Green deployment opgezet voor de applicatie uit week 1 en 2, met Google Artifact Registry als container registry in plaats van Docker Hub. Daarnaast heb ik een CI/CD pipeline ingericht met GitHub Actions.
Blue-Green strategie
selector in de Service aan te passen.| Slot | Branch | Docker image tag | Status |
|---|---|---|---|
| Blue | main | blue | Productie - ontvangt live verkeer |
| Green | development | green | Test - draait parallel, ontvangt geen verkeer |
Hoe de pipeline werkt
- Push naar
main: CI workflow bouwt het:blueimage en deployed naardeployment-blue - Push naar
development: CI workflow bouwt het:greenimage en deployed naardeployment-green
Beide deployments draaien tegelijkertijd. Dit maakt het mogelijk om nieuwe functionaliteiten te ontwikkelen op development, te testen in de green slot, en daarna te switchen via de switch-slot workflow.
Switchen tussen slots
De switch-slot workflow is een handmatige workflow (workflow_dispatch) die via GitHub Actions gestart wordt. Bij het starten kies ik blue of green, waarna de Service selector wordt aangepast met:
kubectl patch service public-cloud-concepts \
-p '{"spec":{"selector":{"slot":"<blue|green>"}}}'De pipeline gebruikt kubectl apply zodat de Service ook aangemaakt wordt als die nog niet bestaat. Na de switch verifieert de pipeline de actieve slot en toont de draaiende pods.
Stap 1: Kubernetes Cluster aanmaken
Als basis gebruik ik de Week 2-omgeving: een GKE cluster, opnieuw opgezet als week3-cluster. Standaard cluster, 2 nodes, e2-medium (2 vCPU, 4 GB RAM), europe-west4-a.
gcloud container clusters get-credentials week3-cluster \
--region europe-west4-a \
--project project-5b8c5498-4fe2-42b9-bc3

Stap 2: Service Account aanmaken
Een Service Account voor GitHub Actions om met GCP te communiceren:


Naam: Github Pipeline Account. Rollen:
- Artifact Registry Reader
- Artifact Registry Writer
- Kubernetes Engine Developer


Stap 3: JSON Key aanmaken
Bij het aanmaken van de key verschijnt een foutmelding:

Een Organization Policy (iam.disableServiceAccountKeyCreation) blokkeert dit.


Opgelost via Cloud Shell:
gcloud organizations list
gcloud organizations add-iam-policy-binding 774668784967 \
--member="user:stentijhuis861@gmail.com" \
--role="roles/orgpolicy.policyAdmin"
gcloud resource-manager org-policies disable-enforce iam.disableServiceAccountKeyCreation \
--project=project-5b8c5498-4fe2-42b9-bc3



Stap 4: GitHub Secrets instellen
De JSON key en projectgegevens als repository secrets via Settings > Secrets and variables > Actions:


Stap 5: Artifact Registry
Artifact Registry repository aangemaakt: public-cloud-concepts, Docker-formaat, europe-west4. Container Scanning API ingeschakeld voor kwetsbaarheidsscans.




IAM-configuratie
Er zijn twee identiteiten betrokken:
GitHub Pipeline Account - wordt door GitHub Actions gebruikt om images te pushen naar Artifact Registry en kubectl-opdrachten te sturen naar GKE.
Compute Engine default service account - wordt door de GKE-nodes gebruikt om images te pullen bij het starten van pods. Zonder Artifact Registry Reader op dit account krijg je een ImagePullBackOff fout, ook als het pipeline account wel de juiste rechten heeft.


Resultaat




Beide deployments parallel testen
Beide deployments draaien tegelijkertijd. De Service bepaalt via de selector welke slot verkeer ontvangt. Switchen kan op twee manieren: via de commandline of via een GitHub Actions workflow.
Optie 1: Commandline (kubectl)
kubectl patch past direct de selector in de Service aan. Kubernetes stuurt verkeer meteen door naar de nieuwe pods, zonder herstart of downtime.
# Naar green switchen
kubectl patch service public-cloud-concepts \
-p '{"spec":{"selector":{"slot":"green"}}}'
# Terug naar blue
kubectl patch service public-cloud-concepts \
-p '{"spec":{"selector":{"slot":"blue"}}}'Controleer daarna welke slot actief is:
kubectl get service public-cloud-concepts \
-o jsonpath='Actieve slot: {.spec.selector.slot}{"\n"}'kubectl patch is de aanbevolen manier voor blue-green switching in Kubernetes. Het is atomisch: de selector-update is één API-call en Kubernetes zorgt dat verkeer direct naar de nieuwe pods gaat. De pipeline gebruikt kubectl apply (idempotent: maakt de Service ook aan als die nog niet bestaat), maar voor handmatig switchen is patch sneller en directer.Optie 2: GitHub Actions workflow (GUI)
Voor wie niet via de commandline wil switchen, is er de switch-slot workflow: een handmatige workflow (workflow_dispatch) die je vanuit de GitHub Actions UI kunt starten. Je kiest blue of green, en de pipeline doet de rest.

De workflow toont na de switch de actieve slot en de draaiende pods:
Actieve slot: blue
NAME READY STATUS RESTARTS AGE
deployment-blue-78c48bc59-m7xqm 1/1 Running 0 7m48s
deployment-green-7fbf59cf77-q2nxj 1/1 Running 0 7m32sJe hebt dus zowel een commandline-optie als een kleine GUI; beide leiden tot hetzelfde resultaat.




Cluster verbinden en status controleren
Verbinden met het cluster
Kubeconfig instellen voor kubectl-toegang:
gcloud container clusters get-credentials week3-cluster \
--region europe-west4-a \
--project <GCP_PROJECT_ID>Extern IP-adres ophalen
Het externe IP ophalen via de LoadBalancer Service:
kubectl get service public-cloud-conceptsUitvoer:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
public-cloud-concepts LoadBalancer 10.X.X.X <EXTERNAL-IP> 80:XXXXX/TCP XmHet EXTERNAL-IP-veld is het publieke IP-adres waarop de applicatie bereikbaar is via poort 80. Dit adres wordt toegewezen door de Google Cloud load balancer.
Actieve slot controleren
Welke slot momenteel verkeer ontvangt:
kubectl get service public-cloud-concepts \
-o jsonpath='{.spec.selector.slot}'Dit geeft blue of green terug.
Overzicht van draaiende deployments
Alle deployments en hun status:
kubectl get deploymentsNAME READY UP-TO-DATE AVAILABLE AGE
deployment-blue 1/1 1 1 Xm
deployment-green 1/1 1 1 XmPods inclusief hun slot-label:
kubectl get pods -l app=public-cloud-concepts --show-labelsDit is ook zichtbaar in de Google Cloud Console. In de Cloud Shell terminal zijn de kubectl patch-opdrachten en het IP-adres te zien:

Argo CD en Flux CD
Wat is Argo CD?
Argo CD is een GitOps-tool die continu het Kubernetes-cluster synchroniseert met wat er in een Git-repository staat. Het idee achter GitOps is dat Git de enige bron van waarheid is: de gewenste staat van het cluster staat in YAML-bestanden in Git. Argo CD bewaakt het cluster en vergelijkt het continu met die bestanden. Als er een verschil is, herstelt Argo CD dat automatisch.
Argo CD heeft een webinterface waar je per applicatie kunt zien of het cluster overeenkomt met Git (Synced) of niet (OutOfSync). Je kunt handmatig synchroniseren of auto-sync aanzetten. Het geeft ook een boomstructuur van alle Kubernetes-resources die bij een applicatie horen, inclusief pods, services en deployments.
Praktisch werkt het zo: je deployt Argo CD in je cluster, je maakt een Application-object aan dat verwijst naar een Git-repository en een pad daarin, en Argo CD houdt dat pad in de gaten. Als je een nieuw image-tag in een YAML-bestand commit, trekt Argo CD die wijziging op en past het cluster aan.
Wat is Flux CD?
Flux CD doet hetzelfde als Argo CD (GitOps, pull-model), maar werkt heel anders van binnen. Flux bestaat uit een stel Kubernetes-controllers die je installeert in het cluster. Er is geen aparte webinterface. Alles wat Flux doet, is terug te zien via kubectl.
Flux heeft losse controllers voor verschillende taken:
- Source Controller let op Git-repositories, Helm-repositories en OCI-registries en downloadt nieuwe versies.
- Kustomize Controller past Kustomize-overlays toe op wat de Source Controller ophaalt.
- Helm Controller installeert of updatet Helm charts op basis van een HelmRelease-object in Git.
- Notification Controller stuurt berichten naar Slack, Teams of webhooks bij events.
Omdat alles via Kubernetes-objects gaat, is Flux goed te integreren in bestaande GitOps-workflows en makkelijk te beheren via CI/CD-tools die al met kubectl werken.
Vergelijking met GitHub Actions
| GitHub Actions | Argo CD | Flux CD | |
|---|---|---|---|
| Model | Push: pipeline stuurt actief naar het cluster | Pull: Argo CD haalt wijzigingen op uit Git | Pull: Flux controllers halen wijzigingen op |
| Trigger | Event in GitHub (push, PR) | Continu polling van Git, of webhook | Continu polling, of webhook |
| Cluster-toegang | Runner buiten het cluster heeft directe toegang nodig | Argo CD draait in het cluster zelf | Flux draait in het cluster zelf |
| Drift detectie | Geen, pipeline runt alleen bij events | Automatisch, herstelt zonder trigger | Automatisch, herstelt zonder trigger |
| UI | Geen ingebouwde Kubernetes-UI | Uitgebreide webinterface | Geen UI, alles via kubectl |
| Geschikt voor | CI: bouwen, testen, pushen van images | CD: deployen en bewaken van de staat | CD: volledig geautomatiseerde omgevingen |
Wanneer gebruik je wat?
GitHub Actions is goed voor het bouwen van images, draaien van tests en pushen naar een registry. Dat is CI. Voor de deployment zelf (CD) zijn Argo CD en Flux CD beter geschikt, omdat ze het cluster continu in sync houden met Git en afwijkingen automatisch herstellen.
In een typische productie-setup combineer je beide: GitHub Actions bouwt het image en schrijft de nieuwe tag terug naar een YAML-bestand in Git. Argo CD of Flux CD detecteert die wijziging en deployt de nieuwe versie naar het cluster.
Argo CD kies je als je een visueel overzicht wil van wat er in het cluster draait en wat de staat is. Flux kies je als je een puur declaratieve aanpak wil zonder extra UI, of als je al werkt met Kustomize of complexe Helm-setups.