StatefulSet #

StatefulSet adalah resource Kubernetes untuk menjalankan aplikasi stateful — aplikasi yang perlu mengingat siapa dirinya, di mana datanya, dan dalam urutan apa ia berjalan. Database, message queue, dan distributed cache adalah kandidat utama. Jika Deployment memperlakukan semua Pod sebagai identik dan bisa saling menggantikan, StatefulSet memberikan setiap Pod identitas yang unik dan persisten.

Perbedaan Fundamental dengan Deployment #

Deployment:
  Pod bernama: api-abc123, api-def456, api-ghi789 (nama random)
  Pod bisa mati dan diganti dengan nama baru
  Semua Pod punya storage yang sama (atau tidak punya storage persisten)
  Urutan startup tidak dijamin

StatefulSet:
  Pod bernama: postgres-0, postgres-1, postgres-2 (nama ordinal, tetap)
  Pod yang sama selalu mendapat nama yang sama setelah restart
  Setiap Pod punya PersistentVolume sendiri yang tidak bisa diambil Pod lain
  Startup, scaling, dan update dilakukan secara berurutan

Stabilitas identitas ini yang membuat StatefulSet cocok untuk workload seperti database replicated — setiap replica perlu identitas yang konsisten agar primary tahu siapa secondary-nya, dan agar secondary tahu di mana datanya.


Struktur Manifest StatefulSet #

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: postgres
  namespace: production
spec:
  serviceName: "postgres"          # headless service yang diperlukan
  replicas: 3
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
      - name: postgres
        image: postgres:15
        ports:
        - containerPort: 5432
        env:
        - name: POSTGRES_PASSWORD
          valueFrom:
            secretKeyRef:
              name: postgres-secret
              key: password
        volumeMounts:
        - name: data
          mountPath: /var/lib/postgresql/data

  # PVC template — setiap Pod mendapat PVC sendiri
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: "standard-ssd"
      resources:
        requests:
          storage: 10Gi

Field volumeClaimTemplates adalah pembeda kunci dari Deployment. Kubernetes akan otomatis membuat PVC terpisah untuk setiap Pod:

  • data-postgres-0 untuk Pod postgres-0
  • data-postgres-1 untuk Pod postgres-1
  • data-postgres-2 untuk Pod postgres-2

Identitas Stabil: Nama dan DNS #

Setiap Pod StatefulSet mendapat nama yang terprediksi dan tidak berubah:

StatefulSet "postgres" dengan 3 replicas:

Pod yang dibuat:
  postgres-0   ← selalu indeks 0, nama ini tidak berubah
  postgres-1
  postgres-2

DNS name untuk setiap Pod (via Headless Service):
  postgres-0.postgres.production.svc.cluster.local
  postgres-1.postgres.production.svc.cluster.local
  postgres-2.postgres.production.svc.cluster.local

Format: <pod-name>.<service-name>.<namespace>.svc.cluster.local

Ini memungkinkan Pod untuk saling menemukan satu sama lain dengan nama yang deterministik. Primary postgres bisa mengkonfigurasi secondary di postgres-1.postgres dan postgres-2.postgres — dan konfigurasi itu tetap valid meskipun Pod di-restart.


Headless Service #

StatefulSet membutuhkan Headless Service — Service tanpa ClusterIP yang memberikan DNS record untuk setiap Pod secara individual.

apiVersion: v1
kind: Service
metadata:
  name: postgres         # nama ini harus sama dengan spec.serviceName di StatefulSet
  namespace: production
spec:
  clusterIP: None        # ← ini yang menjadikannya headless
  selector:
    app: postgres
  ports:
  - port: 5432
    targetPort: 5432

Tanpa headless service, DNS pod individual tidak akan berfungsi. Dengan headless service:

  • postgres.production.svc.cluster.local → mengembalikan IP semua Pod (untuk discovery)
  • postgres-0.postgres.production.svc.cluster.local → mengembalikan IP Pod spesifik

Ordered Operations #

StatefulSet memastikan Pod dibuat, dihapus, dan di-update secara berurutan:

Scaling up dari 0 ke 3:
  1. Buat postgres-0, tunggu sampai Ready
  2. Buat postgres-1, tunggu sampai Ready
  3. Buat postgres-2, tunggu sampai Ready

  Tidak ada Pod berikutnya dibuat sebelum Pod sebelumnya Ready.
  Ini penting untuk database cluster yang butuh
  primary berjalan sebelum secondary bisa join.

Scaling down dari 3 ke 1:
  1. Hapus postgres-2, tunggu sampai benar-benar hilang
  2. Hapus postgres-1, tunggu sampai benar-benar hilang
  3. postgres-0 tetap berjalan

  Selalu hapus dari indeks tertinggi — secondary sebelum primary.

Update Strategy #

StatefulSet mendukung dua update strategy:

RollingUpdate (default) — update Pod satu per satu, dari indeks tertinggi ke terendah:

  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      partition: 0       # update semua Pod (default)
      # partition: 2 → hanya update Pod dengan indeks >= 2
      #             → berguna untuk canary di StatefulSet

OnDelete — Pod tidak di-update secara otomatis; update terjadi hanya ketika Pod dihapus secara manual:

  updateStrategy:
    type: OnDelete       # kamu yang kontrol kapan update terjadi

OnDelete berguna untuk database cluster di mana kamu ingin mengontrol secara manual kapan setiap replica di-upgrade, untuk memastikan tidak terjadi masalah replication.


PVC Tidak Ikut Terhapus #

Ini adalah perilaku yang perlu dipahami: ketika StatefulSet dihapus atau di-scale down, PVC tidak ikut terhapus. Ini disengaja — Kubernetes melindungi data kamu dari penghapusan yang tidak sengaja.

# Hapus StatefulSet
kubectl delete statefulset postgres

# PVC masih ada
kubectl get pvc
# NAME             STATUS   VOLUME        CAPACITY   AGE
# data-postgres-0  Bound    pv-abc123     10Gi       30d
# data-postgres-1  Bound    pv-def456     10Gi       30d
# data-postgres-2  Bound    pv-ghi789     10Gi       30d

# Jika StatefulSet dibuat ulang, PVC yang sama akan di-bind kembali
# ke Pod dengan nama yang sama → data tidak hilang

Untuk benar-benar menghapus data, kamu harus menghapus PVC secara manual:

kubectl delete pvc data-postgres-0 data-postgres-1 data-postgres-2

Kapan Menggunakan StatefulSet #

Gunakan StatefulSet untuk:
  ✓ Database dengan replication (PostgreSQL, MySQL, MongoDB)
  ✓ Distributed cache dengan persistence (Redis Cluster)
  ✓ Message queue (Kafka, RabbitMQ)
  ✓ Distributed coordination service (ZooKeeper, Consul)
  ✓ Aplikasi yang butuh identitas node yang stabil

Jangan gunakan StatefulSet untuk:
  ✗ Aplikasi stateless (API, web server) → gunakan Deployment
  ✗ Aplikasi yang butuh shared storage (bukan per-Pod storage)
    → Deployment dengan shared PVC lebih tepat
  ✗ Database tunggal tanpa replication
    → StatefulSet bisa digunakan, tapi Deployment dengan PVC juga bisa
       (lebih sederhana untuk kasus ini)
Menjalankan database di Kubernetes dengan StatefulSet bisa dilakukan, tapi butuh perencanaan yang matang — terutama soal backup, failover, dan storage performance. Untuk production workload kritikal, pertimbangkan menggunakan managed database service (RDS, Cloud SQL) dan biarkan Kubernetes fokus untuk menjalankan aplikasi stateless.

Ringkasan #

  • Pod punya identitas permanen — nama ordinal (postgres-0, postgres-1) dan DNS individual yang tidak berubah meskipun Pod di-restart.
  • Setiap Pod punya PVC sendiri — lewat volumeClaimTemplates; data Pod satu tidak bercampur dengan Pod lain.
  • Headless Service wajib — tanpa clusterIP: None, DNS per-Pod tidak berfungsi; nama headless service harus cocok dengan spec.serviceName StatefulSet.
  • Ordered startup dan shutdown — Pod dibuat dari indeks terkecil ke terbesar, dihapus dari terbesar ke terkecil; Pod berikutnya baru dibuat setelah sebelumnya Ready.
  • PVC tidak ikut terhapus — proteksi dari penghapusan data yang tidak disengaja; PVC harus dihapus manual jika memang ingin membuang data.
  • Partition update untuk canary StatefulSetrollingUpdate.partition memungkinkan hanya sebagian Pod yang di-update, cocok untuk testing versi baru di secondary sebelum primary.

← Sebelumnya: Deployment   Berikutnya: DaemonSet →

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