Gestire GKE in modo efficace con Terraform e Kustomize
Gestire i cluster GKE (k8s) e le applicazioni che vi girano sopra è diventata una battaglia senza fine per molti di noi. Tenere sotto controllo con precisione attributi come node-pool, add-on, ingress controller, gestore dei certificati SSL, rollout delle applicazioni e relative configurazioni è diventato oneroso per molti. Una difficoltà sempre più diffusa, complice l'ascesa dei microservizi e delle architetture event-driven, composte da numerosi componenti.
Gestire i cluster GKE (K8S)
Configurare un cluster GKE/K8S è un processo complesso. Un buon approccio consiste nell'automatizzarne la creazione come artefatto IAC. In questo articolo useremo Terraform come strumento IAC.
Setup IAC
Creare moduli con parametri e attributi per ogni risorsa è la chiave per garantire la coerenza (parità) tra gli ambienti. Nel nostro repository avremo 3 moduli: 1. modulo cluster GKE con due node pool; 2. modulo ingress controller nginx tramite provisioner Helm chart; 3. modulo provider di certificati SSL kcert Let's Encrypt per gli endpoint pubblici.
Il codice di tutti i moduli che seguono è disponibile nel nostro repository all'indirizzo : https://github.com/agileguru/gke_nginx_kcert_quick_start
- Provisioning di un cluster GKE con più node-pool
In questo modulo troviamo i file main.tf, variables.tf e outputs.tf, dedicati rispettivamente al provisioning, alla parametrizzazione e ai metadati riutilizzabili di un cluster GKE.

Screenshot del modulo IAC Terraform per GKE
- Installazione dell'ingress controller nginx In questo modulo troviamo i file main.tf, variables.tf e un outputs.tf opzionale (vuoto), dedicati rispettivamente al provisioning e alla parametrizzazione del controller nginx.

Screenshot del file main.tf del provisioner IAC Terraform per NGINX
- Installazione del gestore SSL kcert Let's Encrypt In questo modulo troviamo i file main.tf, variables.tf e un outputs.tf opzionale (vuoto), dedicati rispettivamente al provisioning e alla parametrizzazione del controller SSL kcert.

Screenshot del file main.tf del provisioner IAC Terraform per kcert
- Mettere tutto insieme
Completati i 3 moduli, creiamo ora un ambiente k8s "devops" tramite il modulo "devops", richiamato dal main/root per orchestrare il tutto.

Screenshot del modulo dell'ambiente k8s Devops

Screenshot del root che orchestra la creazione del modulo Devops
- Provisioning del cluster e dei controller con Terraform\* Modificare il nome di project/region/zone in variables.tf
\* Modificare il nome del bucket in backend.tf dopo averlo creato dalla console GCP
\* Eseguire i comandi seguenti
terraform init
terraform plan -var-file=sample.tfvars (modificare sample.tfvars se necessario)
terraform apply -var-file=sample.tfvars (modificare sample.tfvars se necessario)

- Una volta eseguiti i comandi Terraform, otterrai l'indirizzo IP del LoadBalancer da usare per la registrazione del dominio.
- Per ottenere la configurazione di kubectl, usa il comando…
gcloud container clusters get-credentials <nome cluster> — zone <zona cluster> — project <id progetto contenente il cluster>
Gestire i deployment con Kustomize
Il cluster è ora pronto per il deployment dei workloads. Per semplificarne la gestione useremo il plugin Kustomize. In questo articolo prendiamo in esame un caso d'uso semplice.
- Abbiamo 2 app, api-1 e api-2, basate sull'immagine tutum/hello-world.
- Abbiamo inoltre 2 namespace k8s che corrispondono agli ambienti DEV e SIT.
- Dobbiamo distribuire il servizio ed esporlo via https (ssl), con le rispettive configurazioni, deployment, service e mappatura ingress.
- Tutto questo va salvato in un repository. Per la demo è disponibile nel nostro repository all'indirizzo https://github.com/agileguru/kustomize_quickstart_demo
Step 1: creare la struttura delle cartelle

Cartelle base dei componenti e delle configurazioni
Step 2: personalizzare ogni ambiente con gli overlay

Cartelle overlay per gli ambienti, con patch/merge config gestite tramite kustomize.yaml
Step 3: modificare la mappatura dell'hostname dell'ingress
Modifica l'hostname in dev-ingress-patch.json e sit-ingress-patch.json indicando un host/dominio valido. Il risultato è simile al codice qui sotto…
[\
{\
"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"\
}\
]
Step 4: distribuire le applicazioni
$ 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
Step 5: rimuovere il deployment delle applicazioni
$ 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 practice di Kustomize
Cosa fare
— Tieni il replica count a 0 nella configurazione base
— Specifica sempre il namespace nel kustomization.yaml dell'overlay
— Esegui sempre un dry run con output yaml per verificare l'accuratezza
— Adotta convenzioni di denominazione chiare per cartelle e file manifest
— Tieni la mappatura ingress in una cartella dedicata
— Prevedi sempre un override.yaml per ogni componente. 2. Cosa non fare
— _Hard-coding del namespace nelle configurazioni base_
— Mescolare configurazioni e codice applicativo nella stessa cartella
— Usare branch Git per la configurazione degli ambienti (il cosiddetto parity drift)
Risorse
- Repository Getting Started GKE Nginx Kcert: https://github.com/agileguru/gke_nginx_kcert_quick_start
- Repository Quick Start Kustomize: https://github.com/agileguru/kustomize_quickstart_demo
- Documentazione Kustomize: https://kustomize.io/
- GitHub Kcert: https://github.com/nabsul/kcert
- Nginx Controller: https://kubernetes.github.io/ingress-nginx/
- Let's Encrypt: https://letsencrypt.org/
Dopo aver completato i passaggi precedenti otteniamo: 1. un cluster k8s semplice da gestire e aggiornare, con nginx e il gestore di certificati SSL kcert, che ti libera dalla necessità di gestire i certificati SSL per i tuoi endpoint pubblici; 2. un meccanismo/framework per gestire endpoint web sicuri seguendo i principi IAC/DevOps/DRY.