Konfigurasi #

Salah satu pilar utama yang menjadikan Kubernetes begitu sukses dan diadopsi secara luas di industri adalah keputusannya untuk mendesain manajemen Konfigurasi secara Deklaratif (Declarative Configuration). Kita tidak lagi mengelola server dengan mengirimkan serangkaian instruksi baris perintah satu per satu, melainkan mendefinisikan seluruh infrastruktur kita ke dalam file manifest tertulis.

Memahami bagaimana Kubernetes membaca, menyimpan, menerapkan, serta mendistribusikan konfigurasi ini ke kontainer aplikasi merupakan hal dasar yang wajib dikuasai untuk membangun arsitektur deployment yang bersih, aman, dan mudah direproduksi.


Filosofi Deklaratif: Cara Kerja kubectl apply #

Dalam pengelolaan server tradisional (Imperatif), kita memberikan instruksi berupa urutan perintah: “Buat server baru, unduh Docker, jalankan kontainer, buka port”. Jika salah satu langkah gagal, kita harus melacak kondisi sistem secara manual.

Kubernetes mengubah paradigma ini dengan model Deklaratif: “Saya ingin ada 3 replika aplikasi nginx berjalan di port 80”. Kita menulis dokumen manifest YAML yang menggambarkan kondisi akhir tersebut, lalu mengirimkannya ke API Server menggunakan perintah:

# BENAR: Menerapkan konfigurasi secara deklaratif
kubectl apply -f deployment.yaml

Di balik layar, perintah kubectl apply tidak sekadar mengirimkan file. Kubernetes menggunakan mekanisme pintar yang disebut Three-Way Merge Patch untuk memperbarui sistem. Mekanisme ini membandingkan tiga sumber data secara bersamaan:

  1. File Manifest Lokal: File YAML yang saat ini kita kirimkan dari komputer kita.
  2. Konfigurasi Aktif di Kluster (Live Configuration): Kondisi riil objek yang saat ini sedang disimpan di dalam etcd kluster.
  3. Anotasi Last-Applied-Configuration: Metadata khusus yang disisipkan Kubernetes pada objek kluster untuk mengingat seperti apa isi manifes lokal pada saat eksekusi apply sebelumnya.

Dengan membandingkan ketiganya, Kubernetes dapat mengetahui field mana saja yang sengaja kita tambahkan, ubah, atau hapus di file lokal, lalu hanya memperbarui perbedaan (diff) tersebut pada kluster aktif. Ini memastikan proses ad-hoc modifikasi di kluster tidak bentrok dan tetap aman.


Format Manifes YAML Kubernetes #

Semua objek di Kubernetes dikonfigurasi melalui dokumen manifest berformat YAML (atau JSON). Setiap manifes, tanpa terkecuali, wajib memiliki empat field utama pada level teratasnya:

apiVersion: apps/v1          # 1. Versi API grup objek
kind: Deployment             # 2. Jenis objek yang ingin dibuat
metadata:                    # 3. Data identitas objek
  name: api-server
  namespace: production
  labels:
    app: api
spec:                        # 4. Spesifikasi teknis objek (Desired State)
  replicas: 3
  template:
    # ... detail konfigurasi Pod

Penjelasan 4 Field Utama: #

  • apiVersion: Menentukan versi skema API yang digunakan untuk membaca manifes. Kubernetes membagi API ke dalam beberapa grup (misal: core v1 untuk Pod/Service, apps/v1 untuk Deployment/StatefulSet, networking.k8s.io/v1 untuk Ingress).
  • kind: Menentukan jenis objek apa yang sedang dideklarasikan (Pod, Service, ConfigMap, Secret, Ingress, dll).
  • metadata: Berisi informasi untuk mengidentifikasi objek secara unik, seperti name (nama objek), namespace (lokasi logis), dan labels (tag pengelompokan).
  • spec: Blok spesifikasi teknis yang mendeskripsikan kondisi akhir yang kita inginkan. Isi dari blok spec ini berbeda-beda secara dramatis tergantung jenis objek yang ditentukan pada kind.

Pemisahan Kode dan Konfigurasi: ConfigMap vs Secret #

Berdasarkan metodologi pengembangan aplikasi modern (Twelve-Factor App), salah satu prinsip mutlak adalah memisahkan kode program dengan konfigurasi lingkungan runtime. Kita harus dapat mendeploy image kontainer yang sama di lingkungan Development, Staging, maupun Produksi tanpa melakukan kompilasi ulang kode.

Kubernetes menyediakan dua objek khusus untuk memisahkan konfigurasi dari kontainer:

1. ConfigMap (Konfigurasi Non-Sensitif) #

Digunakan untuk menyimpan parameter konfigurasi umum yang tidak mengandung rahasia. Contoh: nama host database, port aplikasi, feature flags, atau konfigurasi logging.

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
  namespace: production
data:
  DB_HOST: "postgres-prod.company.local"
  DB_PORT: "5432"
  LOG_LEVEL: "info"

2. Secret (Kredensial Sensitif) #

Digunakan untuk menyimpan data rahasia seperti password database, API keys, token OAuth, sertifikat SSL, atau kredensial SSH.

apiVersion: v1
kind: Secret
metadata:
  name: app-secret
  namespace: production
type: Opaque
data:
  # Nilai data wajib dienkripsi ke format Base64
  DB_PASSWORD: cG9zdGdyZXMxMjM0NTY= # representasi base64 dari "postgres123456"

ANTI-PATTERN: Menyimpan Secret Base64 Langsung di Repositori Git
// KITA MELAKUKAN:
- Menulis manifes `kind: Secret` seperti contoh di atas.
- Melakukan push file YAML tersebut ke repositori Github/Gitlab tim.
// KONSEKUENSI DI PRODUKSI:
- Keamanan Ilusi: Base64 bukanlah enkripsi, melainkan hanya pengodean karakter (*encoding*). Siapa pun yang memiliki akses baca ke repositori git kita dapat men-decode password tersebut dalam 1 detik dengan perintah `echo cG9zdGdyZXMxMjM0NTY= | base64 --decode`.
- Kebocoran Kredensial Produksi secara masif.
✓ SOLUSI YANG BENAR:
- Gunakan tools enkripsi manifes Git seperti [Mozilla SOPS](https://github.com/mozilla/sops) atau [Sealed Secrets](https://github.com/bitnami-labs/sealed-secrets). Sealed Secrets mengenkripsi manifes Secret menggunakan kunci publik kluster, sehingga aman disimpan di git. Hanya kluster target yang memiliki kunci privat untuk mendekripsinya.
- Lebih baik lagi: gunakan **External Secrets Operator** yang menyinkronkan data sensitif secara aman dari cloud secret vault (seperti HashiCorp Vault, AWS Secrets Manager, atau GCP Secret Manager) langsung ke memori kluster saat runtime.

Metode Injeksi Konfigurasi ke Pod #

Setelah kita membuat objek ConfigMap dan Secret, kita dapat menyuntikkan (inject) nilainya ke dalam kontainer Pod melalui dua metode utama:

1. Injeksi Sebagai Environment Variables #

Nilai dari key tertentu di ConfigMap/Secret dibaca dan dijadikan variabel lingkungan di dalam sistem operasi kontainer.

# Contoh Injeksi via Environment Variable
spec:
  containers:
  - name: api
    image: my-app:v1
    env:
    - name: DB_HOST
      valueFrom:
        configMapKeyRef:
          name: app-config
          key: DB_HOST
    - name: DB_PASS
      valueFrom:
        secretKeyRef:
          name: app-secret
          key: DB_PASSWORD

Karakteristik: Sederhana dan didukung oleh hampir seluruh framework aplikasi. Namun, nilai variabel bersifat statis. Jika kita mengubah nilai ConfigMap, kontainer harus direstart agar dapat membaca nilai variabel lingkungan yang baru.

2. Injeksi Sebagai File (Volume Mount) #

Kubernetes me-mount objek ConfigMap atau Secret sebagai direktori file virtual di dalam filesystem kontainer. Setiap key di dalam data akan menjadi sebuah file teks biasa, dengan isi file berupa nilai dari key tersebut.

# Contoh Injeksi via Volume Mount
spec:
  containers:
  - name: api
    image: my-app:v1
    volumeMounts:
    - name: config-volume
      mountPath: /etc/app-config # ConfigMap akan dimount sebagai direktori file di sini
  volumes:
  - name: config-volume
    configMap:
      name: app-config

Karakteristik: Sangat cocok untuk konfigurasi berukuran besar (seperti file application.yaml Spring Boot, config Nginx, atau config Prometheus). Keunggulan terbesarnya adalah mendukung pembaruan dinamis (Hot Reload). Ketika isi ConfigMap diubah, Kubelet secara otomatis akan memperbarui file virtual di dalam kontainer dalam beberapa detik tanpa perlu merestart Pod. Aplikasi kita hanya perlu di-desain untuk mendeteksi perubahan file tersebut (file watch).


Prinsip Infrastruktur Imut (Immutable Infrastructure) #

Kubernetes sangat menekankan kepatuhan terhadap prinsip Immutable Infrastructure (Infrastruktur Imut). Artinya, sekali kluster server dan kontainer dideploy ke produksi, kita tidak boleh melakukan perubahan konfigurasi, pembaruan library, atau modifikasi langsung secara manual pada sistem yang sedang berjalan.

Jika kita ingin mengganti port aplikasi atau memperbarui file HTML, kita dilarang melakukan SSH/exec ke kontainer untuk mengubahnya.

Pola Alur Perubahan Konfigurasi yang Benar:

1. Ubah file manifes lokal (YAML) atau ubah pipeline code.
2. Commit perubahan ke Git (GitOps).
3. Jalankan `kubectl apply -f deployment.yaml` atau biarkan GitOps controller mendeteksi perubahan.
4. Kubernetes membuat Pod baru dengan konfigurasi baru secara bertahap.
5. Pod lama yang membawa konfigurasi usang dihapus secara aman.

Dengan mematuhi prinsip ini, kita menjamin bahwa kondisi kluster produksi selalu identik dengan apa yang tertulis di repositori Git (Infrastructure as Code). Ini menghilangkan masalah klasik “di server saya jalan, tapi di server staging error” dan mempermudah pemulihan bencana (disaster recovery).


Ringkasan #

  • Model Konfigurasi Deklaratif — Kita hanya mendefinisikan desired state akhir sistem lewat manifest YAML, dan biarkan Kubernetes (API Server & Control Loop) yang bekerja mencapainya.
  • Three-Way Merge Patch — Mekanisme pintar kubectl apply yang membandingkan manifest lokal, live state kluster, dan konfigurasi apply terakhir untuk meminimalkan bentrokan pembaruan.
  • ConfigMap vs Secret — ConfigMap digunakan untuk parameter konfigurasi non-sensitif biasa, sedangkan Secret digunakan khusus untuk kredensial sensitif.
  • Enkripsi Bukan Encoding — Secret di Kubernetes hanya dikodekan ke format Base64 secara default. Lindungi data rahasia kluster dengan tools enkripsi git (seperti Sealed Secrets) atau external vault integrations.
  • Variabel Lingkungan vs Volume Mount — Environment variables bersifat statis dan butuh restart Pod jika diubah. Volume mount file ConfigMap dapat diperbarui secara dinamis (hot-reload) saat runtime kluster tanpa restart Pod.

← Sebelumnya: Pod   Berikutnya: Kontrak Infrastruktur →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact