Kustomize uitleg

Kustomize: complete gids voor Kubernetes manifest beheer

Kustomize is een ingebouwde Kubernetes-tool voor het aanpassen van YAML-manifesten zonder templates. In tegenstelling tot Helm gebruik je geen placeholders of Go-syntax — je werkt met je eigen YAML-bestanden en past die aan via overlays. Kustomize is standaard ingebouwd in kubectl vanaf versie 1.14 en is een examendoel voor CKA en CGOA.

Kernconcepten

  • Base — de gedeelde basismanifesten voor alle omgevingen
  • Overlay — omgeving-specifieke aanpassingen bovenop de base (dev, staging, productie)
  • kustomization.yaml — het centrale configuratiebestand dat alles bij elkaar brengt
  • Patch — een aanpassing op een specifieke resource (strategic merge patch of JSON patch)
  • Generator — automatisch aanmaken van ConfigMaps of Secrets vanuit bestanden of literals
  • Transformer — labels, annotaties of naamsprefixen toevoegen aan alle resources tegelijk

Installatie

# Kustomize is ingebouwd in kubectl (geen aparte installatie nodig)
kubectl version --client  # Controleer kubectl-versie

# Standalone Kustomize installeren (nieuwere versie dan kubectl)
curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash
sudo mv kustomize /usr/local/bin/

# Versie controleren
kustomize version
kubectl kustomize --help

Basisstructuur: base en overlays

# Typische mappenstructuur
mijn-app/
├── base/
│   ├── kustomization.yaml
│   ├── deployment.yaml
│   ├── service.yaml
│   └── configmap.yaml
└── overlays/
    ├── dev/
    │   ├── kustomization.yaml
    │   └── replica-patch.yaml
    ├── staging/
    │   ├── kustomization.yaml
    │   └── resource-patch.yaml
    └── productie/
        ├── kustomization.yaml
        ├── replica-patch.yaml
        └── hpa.yaml

base/kustomization.yaml

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

# Welke bestanden worden beheerd
resources:
  - deployment.yaml
  - service.yaml
  - configmap.yaml

# Labels toevoegen aan ALLE resources
commonLabels:
  app: mijn-app
  managed-by: kustomize

# Annotaties toevoegen aan ALLE resources
commonAnnotations:
  team: platform-engineering

# Naamprefix of -suffix toevoegen
namePrefix: "prod-"
# nameSuffix: "-v2"

base/deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mijn-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mijn-app
  template:
    metadata:
      labels:
        app: mijn-app
    spec:
      containers:
      - name: mijn-app
        image: mijn-registry/mijn-app:1.0.0
        resources:
          requests:
            cpu: 100m
            memory: 128Mi
          limits:
            cpu: 500m
            memory: 256Mi

overlays/productie/kustomization.yaml

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

# Verwijst naar de base
resources:
  - ../../base

# Image-tag overschrijven (handig voor CI/CD)
images:
  - name: mijn-registry/mijn-app
    newTag: "2.1.0"

# Patches toepassen
patches:
  - path: replica-patch.yaml
  - path: resource-patch.yaml

# Extra resources toevoegen aan productie
resources:
  - ../../base
  - hpa.yaml
  - poddisruptionbudget.yaml

Patches — twee stijlen

Strategic Merge Patch (meest gebruikt)

# overlays/productie/replica-patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mijn-app      # Moet overeenkomen met de base-resource
spec:
  replicas: 5         # Overschrijft de base-waarde van 1

---
# Resource-limieten aanpassen
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mijn-app
spec:
  template:
    spec:
      containers:
      - name: mijn-app     # Naam moet overeenkomen
        resources:
          requests:
            cpu: 500m
            memory: 512Mi
          limits:
            cpu: 2000m
            memory: 1Gi

JSON Patch (voor fijnere controle)

# overlays/dev/json-patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mijn-app
spec:
  template:
    spec:
      containers:
      - name: mijn-app

# kustomization.yaml
patches:
  - target:
      kind: Deployment
      name: mijn-app
    patch: |-
      - op: replace
        path: /spec/replicas
        value: 1
      - op: add
        path: /spec/template/spec/containers/0/env
        value:
          - name: DEBUG
            value: "true"

ConfigMap en Secret generators

# ConfigMap genereren vanuit literals
configMapGenerator:
  - name: app-config
    literals:
      - LOG_LEVEL=debug
      - DATABASE_HOST=db.voorbeeld.nl
      - FEATURE_FLAG_X=true

# ConfigMap genereren vanuit bestanden
configMapGenerator:
  - name: app-config
    files:
      - config.properties
      - application.yaml=mijn-app-config.yaml

# Secret genereren (base64-encodering automatisch)
secretGenerator:
  - name: db-secret
    literals:
      - password=MijnGeheimWachtwoord123
      - username=dbgebruiker
    type: Opaque

# Secret vanuit bestand
secretGenerator:
  - name: tls-secret
    files:
      - tls.crt
      - tls.key
    type: kubernetes.io/tls

💡 Kustomize voegt automatisch een hash-suffix toe aan gegenereerde ConfigMaps en Secrets (bijv. app-config-k7t5m8f). Dit zorgt ervoor dat Deployments automatisch herstarten als de configuratie wijzigt.

Image-tags beheren

# kustomization.yaml
images:
  - name: mijn-registry/mijn-app
    newName: mijn-andere-registry/mijn-app  # Repository wijzigen
    newTag: "2.1.0"                          # Tag wijzigen

  - name: nginx
    newTag: "1.25.3"

  # Digest in plaats van tag (voor reproduceerbare builds)
  - name: mijn-registry/mijn-app
    digest: sha256:abc123def456...

# Handig in CI/CD: tag via command line overschrijven
kustomize edit set image mijn-registry/mijn-app:$CI_COMMIT_SHA

Kustomize toepassen

# Bekijken wat er wordt gegenereerd (zonder toepassen)
kubectl kustomize overlays/productie
kustomize build overlays/productie

# Toepassen op het cluster
kubectl apply -k overlays/productie

# Verwijderen
kubectl delete -k overlays/productie

# Droge run
kubectl apply -k overlays/productie --dry-run=client

# Opslaan naar bestand
kustomize build overlays/productie > productie-manifesten.yaml
kubectl apply -f productie-manifesten.yaml

Geavanceerde functies

Components — herbruikbare functionaliteit

# components/monitoring/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1alpha1
kind: Component

resources:
  - servicemonitor.yaml

patches:
  - path: add-metrics-port.yaml

# Gebruik in overlay
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - ../../base
components:
  - ../../components/monitoring
  - ../../components/security-context

Replacements (variabelen doorgeven)

# kustomization.yaml
replacements:
  - source:
      kind: Service
      name: mijn-app
      fieldPath: metadata.name
    targets:
      - select:
          kind: Ingress
        fieldPaths:
          - spec.rules.0.http.paths.0.backend.service.name

Kustomize in CI/CD

# GitLab CI voorbeeld
deploy:
  stage: deploy
  script:
    # Image-tag instellen op de commit SHA
    - cd overlays/productie
    - kustomize edit set image mijn-registry/mijn-app:$CI_COMMIT_SHA
    - cd ../..

    # Manifesten genereren en toepassen
    - kustomize build overlays/productie | kubectl apply -f -

    # Of via kubectl direct
    - kubectl apply -k overlays/productie

    # Wacht tot deployment gereed is
    - kubectl rollout status deployment/mijn-app -n productie --timeout=5m

Kustomize in GitOps (Argo CD en Flux)

# Argo CD Application met Kustomize
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: mijn-app
  namespace: openshift-gitops
spec:
  source:
    repoURL: https://github.com/mijnorg/mijn-app
    targetRevision: main
    path: overlays/productie    # Kustomize wordt automatisch herkend
  destination:
    server: https://kubernetes.default.svc
    namespace: productie

# Flux Kustomization
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: mijn-app
  namespace: flux-system
spec:
  interval: 5m
  sourceRef:
    kind: GitRepository
    name: mijn-app
  path: ./overlays/productie
  prune: true

Kustomize vs Helm

EigenschapKustomizeHelm
TemplatingGeen — werkt met gewone YAMLGo-templates met {{ .Values.x }}
LeercurveLaag — YAML kennis volstaatHoger — templates leren
HerbruikbaarheidVia components en basesVia chart-repositories
VersioningGeen ingebouwde versioningVersiebeheer + rollback
Ingebouwd in kubectlJaNee (apart installeren)
Geschikt voorOmgeving-specifieke aanpassingenComplexe, configureerbare applicaties
Argo CD / FluxIngebouwde ondersteuningIngebouwde ondersteuning

Kustomize in relatie tot certificeringen

  • CKA — Kustomize is een examendoel: manifesten toepassen via kubectl apply -k
  • CKAD — Kustomize voor omgeving-specifieke deployments
  • CGOA — Kustomize als manifest-formaat naast Helm voor GitOps-workflows
  • EX380 — Kustomize in combinatie met OpenShift GitOps (Argo CD)

Veelgemaakte fouten

  • kustomization.yaml vergeten — kubectl apply -k werkt niet zonder dit bestand
  • Verkeerd pad naar base — gebruik relatieve paden (../../base), niet absolute
  • Strategic merge patch matcht niet — de metadata.name in een patch moet exact overeenkomen met de resource in de base
  • Hash-suffix vergeten — gegenereerde ConfigMaps en Secrets krijgen een hash-suffix; verwijs ernaar via de gegenereerde naam, niet de opgegeven naam

Veelgestelde vragen

Wanneer kies ik voor Kustomize, wanneer voor Helm?

Kustomize is de betere keuze als je eigen YAML-bestanden hebt die je per omgeving wilt aanpassen — geen templating nodig, lage leercurve. Helm is beter voor complexe applicaties die door anderen worden gedistribueerd (bijv. Prometheus, Ingress Nginx) en waarbij je waarden wilt instellen via een clean interface. In de praktijk worden beide gecombineerd: Helm voor externe applicaties, Kustomize voor eigen manifesten.

Is Kustomize hetzelfde als de kustomize-plugin in kubectl?

Bijna — maar de standalone Kustomize-binary is meestal nieuwer dan de versie ingebouwd in kubectl. Als je de nieuwste functies (zoals Components) nodig hebt, installeer dan de standalone binary. Voor examenomgevingen is de kubectl-ingebouwde versie voldoende.