GKE effizient managen mit Terraform & Kustomize
GKE-Cluster (k8s) und die darin laufenden Anwendungen im Griff zu behalten, ist für viele von uns zur Dauerbaustelle geworden. Node-Pools, Add-ons, Ingress Controller, SSL-Zertifikatsmanager sowie das Rollout von Anwendungen samt zugehöriger Konfiguration zuverlässig zu verwalten, ist für viele aufwendig geworden. Mit dem Aufkommen von Microservices und ereignisgesteuerten Architekturen mit zahlreichen Komponenten gilt das umso mehr.
GKE- (K8s-)Cluster verwalten
Das Setup eines GKE-/K8s-Clusters ist komplex. Ein guter Ansatz: die Erstellung als IaC-Artefakt automatisieren. In diesem Artikel setzen wir Terraform als IaC-Tool ein.
IaC-Setup
Module mit Parametern und Attributen für jede Ressource sind der Schlüssel zu konsistenten Umgebungen (Parität). Unser Repository enthält 3 Module: 1. ein GKE-Cluster-Modul mit zwei Node-Pools, 2. ein nginx-Ingress-Controller-Modul über den Helm-Chart-Provisioner und 3. ein kcert-Modul als Let's-Encrypt-SSL-Zertifikatsanbieter für Ihre öffentlichen Endpunkte.
Den Code zu allen folgenden Modulen finden Sie in unserem Repository unter: https://github.com/agileguru/gke_nginx_kcert_quick_start
- GKE-Cluster mit mehreren Node-Pools bereitstellen
Dieses Modul enthält main.tf, variables.tf und outputs.tf – jeweils für Bereitstellung, Parametrisierung und wiederverwendbare Metadaten eines GKE-Clusters.

Screenshot des GKE-Terraform-IaC-Moduls
- nginx-Ingress-Controller installieren Dieses Modul enthält main.tf, variables.tf und eine optionale (leere) outputs.tf für Bereitstellung und Parametrisierung des nginx-Controllers.

Screenshot der main.tf des NGINX-Terraform-IaC-Provisioners
- kcert-Let's-Encrypt-SSL-Manager installieren Dieses Modul enthält main.tf, variables.tf und eine optionale (leere) outputs.tf für Bereitstellung und Parametrisierung des kcert-SSL-Controllers.

Screenshot der main.tf des kcert-Terraform-IaC-Provisioners
- Alles zusammen orchestrieren
Nach Fertigstellung der 3 Module legen wir nun eine \"devops\"-K8s-Umgebung an – über das \"devops\"-Modul, das aus dem Main/Root aufgerufen wird und alles zusammenführt.

Screenshot des Devops-K8s-Umgebungsmoduls

Screenshot des Root-Moduls, das das Devops-Modul orchestriert
- Cluster und Controller mit Terraform bereitstellen\* Passen Sie Projekt-, Region- und Zone-Namen in der variables.tf an
\* Passen Sie den Bucket-Namen in der backend.tf an, nachdem Sie ihn in der GCP-Konsole angelegt haben
\* Führen Sie folgende Befehle aus
terraform init
terraform plan -var-file=sample.tfvars (sample.tfvars bei Bedarf anpassen)
terraform apply -var-file=sample.tfvars (sample.tfvars bei Bedarf anpassen)

- Nach Ausführung der Terraform-Befehle erhalten Sie die IP-Adresse des LoadBalancers für die Domain-Registrierung.
- Die kubectl-Konfiguration erhalten Sie mit folgendem Befehl …
gcloud container clusters get-credentials
— zone — project
Deployments mit Kustomize verwalten
Der Cluster ist nun bereit für das Deployment von Workloads. Mit dem Kustomize-Plugin geht das deutlich komfortabler. Für diesen Artikel nehmen wir uns einen einfachen Anwendungsfall vor.
- Wir haben 2 Apps, api-1 und api-2, basierend auf dem tutum/hello-world-Image.
- Außerdem haben wir 2 K8s-Namespaces für die Umgebungen DEV & SIT.
- Der Service soll deployt und über https (SSL) bereitgestellt werden – mit den jeweiligen Konfigurationen sowie Deployment-, Service- und Ingress-Mappings.
- Das Ganze gehört in ein Repository. Für die Demo liegt es in unserem Repository unter https://github.com/agileguru/kustomize_quickstart_demo
Schritt 1: Ordnerstruktur anlegen

Basisordner für Komponenten und Konfigurationen
Schritt 2: Jede Umgebung über Overlays anpassen

Overlay-Ordner für Umgebungen mit Patch-/Merge-Konfiguration über kustomize.yaml
Schritt 3: Ingress-Hostname-Mapping anpassen
Ändern Sie den Hostnamen in dev-ingress-patch.json & sit-ingress-patch.json auf einen gültigen Host bzw. eine gültige Domain. Das sieht etwa so aus wie der folgende Code …
[\
{\
"op": "replace",\
"path": "/spec/rules/0/host",\
"value": "dev.agileguru.org"\
},\
{\
"op": "replace",\
"path": "/spec/tls/0/hosts/0",\
"value": "dev.agileguru.org"\
}\
]
[\
{\
"op": "replace",\
"path": "/spec/rules/0/host",\
"value": "sit.agileguru.org"\
},\
{\
"op": "replace",\
"path": "/spec/tls/0/hosts/0",\
"value": "sit.agileguru.org"\
}\
]
Schritt 4: Anwendungen deployen
$ kubectl apply -k overlays/dev
namespace/dev created
configmap/config-map-api-1 created
configmap/config-map-api-2 created
service/api-1-service created
service/api-2-service created
deployment.apps/api-1-deployment created
deployment.apps/api-2-deployment created
Schritt 5: Anwendungen wieder entfernen
$ kubectl delete -k overlays/dev
namespace "dev" deleted
configmap "config-map-api-1" deleted
configmap "config-map-api-2" deleted
service "api-1-service" deleted
service "api-2-service" deleted
deployment.apps "api-1-deployment" deleted
deployment.apps "api-2-deployment" deleted
ingress.networking.k8s.io "app-ingress" deleted
Best Practices für Kustomize
Das sollten Sie tun
— Setzen Sie die Replica-Anzahl in der Basiskonfiguration auf 0
— Geben Sie den Namespace immer in der kustomization.yaml des Overlays an
— Führen Sie immer einen Dry Run mit YAML-Ausgabe durch, um die Korrektheit zu prüfen
— Setzen Sie auf saubere Namenskonventionen für Ordner und Manifest-Dateien
— Halten Sie das Ingress-Mapping in einem eigenen Ordner
— Hinterlegen Sie für jede Komponente eine override.yaml. 2. Das sollten Sie vermeiden
— _Namespace in Basiskonfigurationen hartcodieren_
— Konfigurationen und Anwendungscode im selben Ordner mischen
— Git-Branches für Umgebungskonfigurationen nutzen (sogenannter Parity Drift)
Ressourcen
- GKE Nginx Kcert Getting-Started-Repo: https://github.com/agileguru/gke_nginx_kcert_quick_start
- Kustomize-Quickstart-Repo: https://github.com/agileguru/kustomize_quickstart_demo
- Kustomize-Doku: https://kustomize.io/
- Kcert auf GitHub: https://github.com/nabsul/kcert
- Nginx Controller: https://kubernetes.github.io/ingress-nginx/
- Let's Encrypt: https://letsencrypt.org/
Nach Abschluss der oben genannten Schritte haben wir: 1. ein Kubernetes, das sich mit nginx und dem kcert-SSL-Zertifikatsmanager leicht verwalten und aktualisieren lässt – ohne dass Sie sich je wieder selbst um SSL-Zertifikate für Ihre öffentlichen Endpunkte kümmern müssen, und 2. einen Mechanismus bzw. ein Framework zur Verwaltung sicherer webbasierter Endpunkte nach IaC-, DevOps- und DRY-Prinzipien.