Kodeloka
  1. Kodeloka
  2. Kelas Kubernetes
  3. Materi

8 · Pengelolaan · Modul 12 dari 14

Helm, Kustomize & GitOps

Mengelola manifest untuk banyak lingkungan tanpa menyalin YAML, dan menjadikan Git sebagai satu-satunya sumber kebenaran keadaan kluster.

Masalahnya: YAML yang Berlipat Ganda

Anda punya tiga lingkungan — dev, staging, produksi — dengan manifest yang 90% sama. Menyalin dan menempel berarti setiap perubahan harus dilakukan tiga kali, dan cepat atau lambat salah satunya terlewat.

Helm: Template dengan Nilai

bagan-saya/
├── Chart.yaml
├── values.yaml              # nilai bawaan
├── values-produksi.yaml     # penimpa untuk produksi
└── templates/
    ├── deployment.yaml
    ├── service.yaml
    └── _helpers.tpl
# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "bagan-saya.fullname" . }}
spec:
  replicas: {{ .Values.replicaCount }}
  template:
    spec:
      containers:
        - name: {{ .Chart.Name }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          resources:
            {{- toYaml .Values.resources | nindent 12 }}
helm install toko ./bagan-saya -f values-produksi.yaml
helm upgrade toko ./bagan-saya --set image.tag=2.5.0
helm rollback toko 3
helm list
helm history toko

# SELALU periksa hasilnya sebelum menerapkan
helm template toko ./bagan-saya -f values-produksi.yaml
helm diff upgrade toko ./bagan-saya    # butuh plugin helm-diff
⚠️ Kelemahan Helm: template Go pada YAML

Helm melakukan substitusi teks pada YAML, dan YAML sangat sensitif terhadap indentasi. Kesalahan nindent menghasilkan pesan kesalahan yang membingungkan tentang baris yang bahkan tidak Anda tulis. Bagan yang rumit dengan banyak kondisi bersarang menjadi sangat sulit dibaca. Selalu jalankan helm template untuk melihat YAML akhir yang sebenarnya.

Kustomize: Menambal, Bukan Menempel

base/
├── kustomization.yaml
├── deployment.yaml
└── service.yaml
overlays/
├── staging/
│   ├── kustomization.yaml
│   └── tambal-replika.yaml
└── produksi/
    ├── kustomization.yaml
    └── tambal-sumberdaya.yaml
# overlays/produksi/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: produksi
resources:
  - ../../base
replicas:
  - name: layanan-pesanan
    count: 5
images:
  - name: registry.contoh.com/pesanan
    newTag: 2.4.0
patches:
  - path: tambal-sumberdaya.yaml
configMapGenerator:
  - name: konfigurasi-aplikasi
    literals:
      - LOG_LEVEL=warn
kubectl kustomize overlays/produksi        # lihat hasilnya
kubectl apply -k overlays/produksi
💡 Helm atau Kustomize?

Helm unggul untuk mendistribusikan perangkat lunak ke orang lain — semua chart pihak ketiga (Prometheus, cert-manager, ingress-nginx) memakai Helm. Ia punya konsep rilis, riwayat, dan rollback.

Kustomize unggul untuk manifest aplikasi Anda sendiri — tidak ada bahasa template yang harus dipelajari, YAML-nya tetap YAML yang valid dan bisa dibaca. Ia sudah terpasang di dalam kubectl.

Banyak tim memakai keduanya: Helm untuk komponen pihak ketiga, Kustomize untuk aplikasi sendiri. Itu kombinasi yang sangat wajar.

GitOps

Cara lama (push):
  Pipeline CI  ──kubectl apply──>  Kluster
  ⚠️ CI butuh kredensial kluster
  ⚠️ Tidak ada yang tahu bila seseorang mengubah kluster secara manual

GitOps (pull):
  Git  <──terus-menerus dibandingkan──  Agen di dalam kluster
  ✅ Kluster menarik sendiri; tidak ada kredensial di CI
  ✅ Perubahan manual otomatis dikembalikan
  ✅ Git menjadi catatan audit yang lengkap
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: layanan-pesanan
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/org/manifest.git
    targetRevision: main
    path: overlays/produksi
  destination:
    server: https://kubernetes.default.svc
    namespace: produksi
  syncPolicy:
    automated:
      prune: true          # hapus objek yang sudah dibuang dari Git
      selfHeal: true       # kembalikan perubahan manual
    syncOptions:
      - CreateNamespace=true
📌 selfHeal mengubah budaya kerja

Dengan selfHeal: true, perubahan yang dilakukan langsung ke kluster akan otomatis dikembalikan ke keadaan yang tertulis di Git. Awalnya terasa mengganggu — perbaikan darurat Anda hilang dalam hitungan detik. Tetapi justru itu intinya: kluster tidak lagi bisa menyimpang diam-diam, dan setiap perubahan harus melewati Git sehingga selalu ada catatan siapa mengubah apa dan kenapa.

Memisahkan Repositori

repo-aplikasi/          repo-manifest/
├── src/                ├── base/
├── Dockerfile          └── overlays/
└── .github/workflows/      ├── staging/
                            └── produksi/

CI di repo aplikasi:
  1. build & uji
  2. bangun image, dorong ke registry
  3. perbarui tag image di repo-manifest
  4. Argo CD melihat perubahan, menerapkannya
⚠️ Kenapa dipisah

Bila manifest berada di repo aplikasi yang sama, langkah "perbarui tag image" akan membuat commit baru yang memicu pipeline CI lagi — dan bisa berputar tanpa henti. Pemisahan juga memungkinkan tim platform mengelola manifest tanpa akses ke kode sumber, dan riwayat Git repo manifest menjadi catatan deploy yang bersih.

Praktik yang Baik

  • Jangan pernah menaruh rahasia mentah di repo manifest — pakai External Secrets atau Sealed Secrets.
  • Sematkan versi chart pihak ketiga. version: 15.2.1, bukan rentang terbuka.
  • Validasi di CI dengan kubeconform atau kubectl apply --dry-run=server.
  • Terapkan kebijakan dengan Kyverno atau OPA Gatekeeper: tolak image :latest, wajibkan resource request, larang pod istimewa.
  • Pantau drift. Aplikasi Argo CD yang terus berstatus OutOfSync adalah gejala ada yang mengubah kluster secara manual.