Controller Manager #

Controller Manager adalah komponen yang menghidupkan konsep declarative Kubernetes. Ketika kamu mendeklarasikan “saya ingin 3 replica Pod ini berjalan”, tidak ada keajaiban yang membuat itu terjadi — ada sebuah controller yang terus-menerus memantau dan memastikan deklarasi kamu terpenuhi. Controller Manager adalah proses tunggal yang menjalankan puluhan controller semacam itu secara paralel.

Pola Reconciliation Loop #

Semua controller di Kubernetes mengikuti pola yang sama: reconciliation loop. Pola ini adalah jantung dari seluruh sistem declarative Kubernetes.

Reconciliation Loop (sama untuk semua controller):

┌─────────────────────────────────────────────┐
│                                             │
│   Observe ──► Compare ──► Act ──► (ulang)   │
│                                             │
└─────────────────────────────────────────────┘

Observe:  Baca current state dari cluster (via API Server/cache)
Compare:  Bandingkan dengan desired state dari spec resource
Act:      Ambil tindakan untuk mendekatkan current ke desired state

Pola ini punya sifat penting: idempotent. Tidak peduli berapa kali reconciliation loop berjalan, hasilnya selalu sama — sistem menuju desired state. Ini berarti jika sebuah controller crash dan restart, ia tidak akan “kehilangan langkah” — ia cukup mulai dari awal lagi dan hasilnya tetap benar.

Contoh reconciliation Deployment Controller:

Desired state (dari Deployment spec): replicas: 3
Current state (dari cluster): 2 Pod berjalan (1 baru saja crash)

Controller:
  current (2) != desired (3)
  → Buat 1 Pod baru
  → Panggil API Server: POST /api/v1/namespaces/default/pods

Loop berikutnya:
  current (3) == desired (3)
  → Tidak ada tindakan diperlukan

Controller-Controller Utama #

Controller Manager menjalankan banyak controller. Berikut yang paling penting untuk dipahami:

Deployment Controller #

Memastikan jumlah Pod yang berjalan sesuai dengan yang dideklarasikan di Deployment, dengan cara mengelola ReplicaSet.

Kamu membuat Deployment:
  spec.replicas: 3
  spec.template: { image: api:v1 }

Deployment Controller:
  → Buat ReplicaSet dengan template yang sama
  → ReplicaSet Controller: buat 3 Pod

Kamu update Deployment (image: api:v2):
  Deployment Controller:
  → Buat ReplicaSet BARU dengan template baru
  → Scale up ReplicaSet baru secara bertahap
  → Scale down ReplicaSet lama secara bertahap
  → Ini adalah implementasi rolling update

Deployment menyimpan history ReplicaSet lama (default: 10)
→ Ini yang memungkinkan rollback ke versi sebelumnya

ReplicaSet Controller #

Memastikan jumlah Pod yang berjalan sesuai dengan .spec.replicas di ReplicaSet. Lebih rendah levelnya dari Deployment Controller.

ReplicaSet Controller bekerja sederhana:

while true:
  running_pods = hitung Pod dengan label yang cocok dan status Running/Pending
  desired = spec.replicas

  if running_pods < desired:
    buat (desired - running_pods) Pod baru

  if running_pods > desired:
    hapus (running_pods - desired) Pod (pilih secara acak atau berdasarkan priority)

Node Controller #

Memantau kondisi semua node dalam cluster dan mengambil tindakan saat node bermasalah.

Node Controller workflow:

Setiap ~5 detik: cek heartbeat semua node

Node tidak kirim heartbeat > 40 detik:
  → Tandai node condition sebagai Unknown

Node tetap Unknown > 5 menit:
  → Tambahkan taint "node.kubernetes.io/not-ready:NoExecute" ke node
  → Efek: Pod dengan tolerationSeconds tertentu mulai dievict
  → Pod tanpa toleration langsung dievict ke node lain

Ini yang menyebabkan Pod berpindah ke node sehat saat sebuah node mati.

Job Controller #

Mengelola siklus hidup Job — workload yang dijalankan sekali sampai selesai, bukan terus-menerus.

Job dengan spec.completions: 5, spec.parallelism: 2:

Job Controller membuat 2 Pod (parallelism = 2)

Pod 1 selesai (exit 0) → Job Controller buat Pod 3
Pod 2 selesai (exit 0) → Job Controller buat Pod 4
Pod 3 selesai (exit 0) → Job Controller buat Pod 5
Pod 4 selesai (exit 0) → Tunggu Pod 5
Pod 5 selesai (exit 0) → completions terpenuhi → Job status: Complete

Jika Pod gagal (exit != 0):
  → Job Controller buat Pod pengganti (sampai backoffLimit tercapai)

Endpoint Controller #

Memperbarui daftar IP di dalam Endpoint object setiap kali Pod yang cocok dengan selector Service dibuat, dihapus, atau kondisinya berubah.

Service "api-service" dengan selector: { app: api }

Endpoint Controller terus memantau:
  Pod baru berlabel app=api dibuat dan Running → tambahkan IP-nya ke Endpoints
  Pod berlabel app=api mati → hapus IP-nya dari Endpoints
  Pod berlabel app=api tidak lolos readiness probe → hapus IP-nya

kube-proxy di semua node watch Endpoints object ini
→ Saat Endpoints berubah, kube-proxy update iptables rules

Ini mekanisme yang membuat Service secara otomatis
hanya mengirim traffic ke Pod yang sehat.

Namespace Controller #

Ketika sebuah namespace dihapus, Namespace Controller memastikan semua resource di dalamnya juga dihapus secara bersih — Pod, Service, ConfigMap, Secret, dan semua resource lainnya.


Leader Election #

Karena Controller Manager berjalan sebagai satu proses yang berisi semua controller, ada masalah HA: jika dijalankan di beberapa node (untuk HA), hanya boleh satu instance yang aktif pada satu waktu. Jika dua Controller Manager aktif bersamaan, mereka akan saling berkompetisi dan membuat keputusan yang konfliktual.

Kubernetes menyelesaikan ini dengan leader election menggunakan Lease object di API Server:

Controller Manager Leader Election:

[Startup]
  Semua instance Controller Manager mencoba "mengklaim" Lease object
  Satu instance berhasil → menjadi leader, mulai menjalankan semua controller

[Operasi normal]
  Leader memperbarui Lease setiap beberapa detik (heartbeat)
  Instance lain watch Lease tapi tidak melakukan apa-apa

[Leader mati]
  Lease tidak diperbarui lebih dari leaseDuration (default: 15 detik)
  Instance lain berlomba mengklaim Lease
  Satu instance menang → menjadi leader baru
  Gap leadership: 15-30 detik → controller tidak berjalan selama ini
  Setelah leader baru aktif, cluster kembali normal

Gap ini acceptable karena Kubernetes dirancang untuk eventual consistency — controller yang tidak berjalan selama 30 detik tidak menyebabkan kerusakan, hanya delayed reconciliation.


Custom Controller #

Salah satu kekuatan terbesar Kubernetes adalah kemampuan untuk membuat controller kustom. Ini adalah fondasi dari Operator pattern — cara untuk mengotomasi operasional software kompleks (database, message queue, ML platform) di atas Kubernetes.

Operator = Custom Resource Definition + Custom Controller

1. Definisikan Custom Resource (CR):
   apiVersion: databases.example.com/v1
   kind: PostgresCluster       ← resource kustom yang kamu definisikan
   metadata:
     name: production-db
   spec:
     replicas: 3
     version: "15"
     backup:
       schedule: "0 2 * * *"

2. Custom Controller memantau CR ini:
   → "Ada PostgresCluster baru dengan 3 replica"
   → Buat 3 StatefulSet, 3 PVC, konfigurasi replication
   → Pastikan backup berjalan sesuai jadwal
   → Handle failover jika primary mati

Tools populer untuk membuat custom controller: controller-runtime (Go), kubebuilder, dan Operator SDK.


Ringkasan #

  • Reconciliation loop adalah pola fundamental — Observe, Compare, Act; idempotent dan resilient terhadap crash karena tidak menyimpan state di luar cluster.
  • Controller Manager adalah satu proses, banyak controller — puluhan control loop berjalan paralel di dalam satu binary.
  • Deployment Controller mengelola ReplicaSet — rolling update diimplementasi dengan membuat ReplicaSet baru dan scale down yang lama secara bertahap.
  • Node Controller yang memindahkan Pod saat node mati — setelah 5 menit tanpa heartbeat, Pod di-evict ke node yang sehat.
  • Endpoint Controller menghubungkan Service ke Pod — Endpoints diperbarui real-time saat Pod dibuat, mati, atau gagal readiness probe.
  • Leader election mencegah split-brain — di setup HA, hanya satu instance Controller Manager yang aktif pada satu waktu; instance lain standby.

← Sebelumnya: Scheduler   Berikutnya: Etcd & Cluster Consistency →

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