Anti-Pattern Configuration #

Dalam ekosistem cloud-native, miskonfigurasi (misconfiguration) secara konsisten menempati peringkat teratas sebagai celah keamanan paling kritis sekaligus penyebab utama kegagalan operasional di produksi (merujuk pada laporan OWASP Top 10 Kubernetes). Kubernetes menyediakan objek abstraksi yang sangat fleksibel seperti ConfigMap dan Secret untuk membantu kita memisahkan konfigurasi dari kode aplikasi. Namun, fleksibilitas ini sering kali menjadi pedang bermata dua ketika tim developer atau platform engineer menerapkan pola-pola pengelolaan konfigurasi yang menyimpang dari prinsip-prinsip arsitektur dasar.

Sering kali, masalah konfigurasi yang buruk tidak langsung terlihat pada saat deployment awal. Masalah ini bekerja secara senyap di balik layar hingga suatu saat meledak menjadi insiden besar: kredensial produksi bocor ke publik, kegagalan startup loop yang melumpuhkan layanan saat autoscaling, atau kondisi split-brain di mana replika Pod yang berbeda berjalan dengan parameter yang berbeda pula. Artikel ini mengulas secara mendalam tujuh anti-pattern konfigurasi yang paling sering ditemui di lapangan, menganalisis konsekuensi fatalnya, serta menyajikan solusi teruji untuk mengatasinya.


Peta Risiko Miskonfigurasi (Risk Assessment Map) #

Sebelum kita membahas masing-masing anti-pattern, mari kita tinjau diagram alur berikut untuk mengidentifikasi area mana saja dari pengelolaan konfigurasi kita yang saat ini rentan terhadap risiko keamanan atau kegagalan operasional:

flowchart TD
    Start["Evaluasi Sistem Konfigurasi Aplikasi"] --> Q1{"Apakah ada Secret / Token<br>yang tersimpan dalam repositori Git?"}
    
    Q1 -- "Ya" --> RiskGit["RISIKO TINGGI:<br>Kebocoran Kredensial secara Global"]
    Q1 -- "Tidak" --> Q2{"Apakah satu ConfigMap/Secret<br>memuat konfigurasi untuk seluruh service?"}
    
    Q2 -- "Ya" --> RiskMono["RISIKO MEDIUM:<br>Monolithic Config & Blast Radius Besar"]
    Q2 -- "Tidak" --> Q3{"Apakah Dockerfile berisi perintah ENV<br>spesifik untuk production?"}
    
    Q3 -- "Ya" --> RiskDocker["RISIKO RENDAH-MEDIUM:<br>Pelanggaran Build-Once Run-Anywhere"]
    Q3 -- "Tidak" --> Q4{"Apakah Service Account Pod memiliki akses<br>'list/watch' ke seluruh Secret?"}
    
    Q4 -- "Ya" --> RiskRBAC["RISIKO TINGGI:<br>Privilege Escalation & Attacker Lateral Movement"]
    Q4 -- "Tidak" --> SafeConfig["Konfigurasi Sesuai Praktik Terbaik"]
    
    style RiskGit stroke:#d32f2f,stroke-width:2px
    style RiskMono stroke:#f57c00,stroke-width:2px
    style RiskDocker stroke:#f57c00,stroke-width:2px
    style RiskRBAC stroke:#d32f2f,stroke-width:2px
    style SafeConfig stroke:#388e3c,stroke-width:2px

Anti-Pattern 1: Menyimpan Kredensial Sensitif di Repositori Git (Hardcoded Secrets) #

Anti-pattern yang paling berbahaya dan masih sering terjadi adalah melakukan commit file konfigurasi yang memuat kredensial plaintext—seperti password database, JWT signing key, atau API token—ke dalam repositori kontrol versi Git (baik publik maupun privat). Sering kali, pengembang beranggapan bahwa menaruh Secret di repositori privat adalah hal yang aman.

# ✗ ANTI-PATTERN: Menyimpan Secret produksi langsung di dalam file values Helm di Git
# values-production.yaml
global:
  database:
    host: "postgres-prod.company.com"
    username: "prod_db_user"
    password: "SuperSecretProductionPassword123" # ← KRITIS: Kredensial bocor ke riwayat Git
  stripe:
    apiKey: "sk_live_51Nz8xxxxxxxxxxxxxxxxxxxxxxxx" # ← KRITIS: API Key live bocor

Mengapa Ini Berbahaya? #

  1. Eksposur Luas: Siapa pun yang memiliki akses baca ke repositori Git (termasuk developer magang, sistem CI/CD pihak ketiga, atau tools scanning) dapat melihat kredensial produksi.
  2. Keabadian Riwayat Git: Sekadar menghapus file atau mengganti nilainya dengan placeholder di commit terbaru tidak menghapus Secret dari riwayat Git. Penyerang dengan mudah dapat menelusuri riwayat commit lama untuk menemukan kredensial tersebut.
  3. Blast Radius Kebocoran: Jika repositori Git bocor karena serangan phishing pada akun developer atau kesalahan konfigurasi visibilitas repositori menjadi publik, seluruh sistem produksi kita akan terekspos seketika.

Solusi Terbaik #

Gunakan pendekatan referensi dinamis. Kita hanya menyimpan metadata referensi di Git, sedangkan nilai sensitif sebenarnya disuntikkan secara dinamis saat runtime dari repositori luar menggunakan External Secrets Operator (ESO) atau enkripsi file lokal menggunakan Mozilla SOPS / Sealed Secrets.

# ✓ SOLUSI: Menggunakan SealedSecrets terenkripsi yang aman disimpan di Git
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
  name: app-credentials-production
  namespace: payment
spec:
  # Data ini dienkripsi menggunakan public key cluster.
  # Hanya private key di dalam cluster yang dapat mendekripsinya.
  # Aman di-commit ke Git karena tidak dapat didekripsi oleh pihak luar.
  encryptedData:
    DB_PASSWORD: "AgB6B3D...[Ratusan karakter hash enkripsi]..."
    STRIPE_API_KEY: "AgF8C4A...[Ratusan karakter hash enkripsi]..."

Anti-Pattern 2: Satu ConfigMap atau Secret Raksasa untuk Semua Layanan (Monolithic Config) #

Beberapa tim engineering memilih untuk membuat satu ConfigMap raksasa (misalnya bernama global-config) yang menampung seluruh variabel lingkungan untuk semua microservice yang berjalan di dalam satu namespace.

# ✗ ANTI-PATTERN: Satu ConfigMap raksasa untuk seluruh layanan microservice
apiVersion: v1
kind: ConfigMap
metadata:
  name: monolithic-global-config
  namespace: core
data:
  # Variabel untuk Service A
  SERVICE_A_PORT: "8081"
  SERVICE_A_LOG_LEVEL: "debug"
  # Variabel untuk Service B
  SERVICE_B_PORT: "8082"
  SERVICE_B_LOG_LEVEL: "info"
  # Variabel database global
  DB_HOST: "postgres-shared"
  DB_NAME: "main_db"
  # Konfigurasi nginx proxy utuh
  nginx.conf: |
    server {
        listen 80;
        location / { proxy_pass http://localhost:8081; }
    }    

Mengapa Ini Berbahaya? #

  1. Limitasi Ukuran etcd: Database etcd membatasi ukuran maksimum satu objek ConfigMap atau Secret sebesar 1 MB. File konfigurasi besar atau bundel sertifikat yang ditumpuk dalam satu objek akan dengan cepat membentur batas ini dan menggagalkan deployment.
  2. Masalah Hak Akses (Least Privilege Violation): Service A tidak memiliki alasan untuk mengetahui variabel lingkungan milik Service B. Dengan menyatukannya dalam satu ConfigMap, kita melanggar batas isolasi keamanan.
  3. Overhead Rolling Update: Jika kita memperbarui satu nilai kecil (misalnya SERVICE_A_LOG_LEVEL), Kubernetes akan mendeteksi perubahan pada objek ConfigMap global. Hal ini memicu rolling restart pada seluruh Pod (Service A, Service B, Nginx Proxy) yang mengonsumsi ConfigMap tersebut, menyebabkan pemborosan resource dan risiko ketidakstabilan sistem secara massal.

Solusi Terbaik #

Pecah ConfigMap berdasarkan ruang lingkup fungsional (domain) dan siklus hidup (lifecycle) perubahan data.

# ✓ SOLUSI: Konfigurasi khusus untuk Service A
apiVersion: v1
kind: ConfigMap
metadata:
  name: service-a-config
  namespace: core
data:
  PORT: "8081"
  LOG_LEVEL: "debug"
---
# ✓ SOLUSI: Konfigurasi khusus untuk Nginx Proxy
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-proxy-config
  namespace: core
data:
  nginx.conf: |
    server {
        listen 80;
        location / { proxy_pass http://localhost:8081; }
    }    

Anti-Pattern 3: Hardcode Parameter Lingkungan di Docker Image Layer (Build-Time Config) #

Pola ini terjadi ketika pengembang menulis instruksi ENV yang spesifik untuk lingkungan produksi langsung di dalam berkas Dockerfile saat proses pembuatan image kontainer (build-time).

# ✗ ANTI-PATTERN: Menulis konfigurasi produksi langsung di dalam Dockerfile
FROM python:3.11-slim
# Mengunci parameter database di dalam layer image kontainer
ENV APP_ENV=production
ENV DB_HOST=postgres-prod.internal.company.com
ENV DB_PORT=5432
COPY . /app
WORKDIR /app
CMD ["python", "app.py"]

Mengapa Ini Berbahaya? #

  1. Melanggar Aturan Build-Once Run-Anywhere: Image kontainer yang sama seharusnya dapat dideploy ke Development, Staging, maupun Production tanpa perubahan apa pun. Jika konfigurasi di-hardcode saat build, kita terpaksa memelihara pipeline build yang berbeda untuk masing-masing lingkungan kerja.
  2. Ketidaksesuaian Pengujian: Kita tidak dapat menjamin bahwa apa yang kita uji di Staging berjalan dengan identik di Production, karena kita menggunakan image kontainer fisik yang berbeda secara teknis.
  3. Kesulitan Re-konfigurasi: Setiap kali ada perubahan kecil (seperti migrasi database ke host baru), kita harus menjalankan ulang seluruh pipeline CI/CD untuk membuild image kontainer baru dari awal.

Solusi Terbaik #

Biarkan Dockerfile bersih dari variabel lingkungan spesifik infrastruktur. Gunakan ConfigMap dan Secret untuk menyuntikkan nilai dinamis saat Pod kontainer diinisialisasi (runtime).

# ✓ SOLUSI: Dockerfile agnostik tanpa parameter lingkungan produksi
FROM python:3.11-slim
COPY . /app
WORKDIR /app
# Jalankan aplikasi. Kode Python membaca variabel via os.environ["DB_HOST"]
CMD ["python", "app.py"]
# Dan suntikkan nilainya saat runtime via deployment manifest
spec:
  containers:
  - name: app
    image: company/app:v1.0.0 # Image yang sama persis digunakan di dev, staging, prod
    envFrom:
    - configMapRef:
        name: app-config-prod # Di-inject dinamis sesuai environment target

Anti-Pattern 4: Menggunakan Referensi ConfigMap/Secret Non-Optional Tanpa Validasi Eksistensi #

Sering kali kita mendefinisikan referensi ConfigMap atau Secret di dalam manifes Deployment, tetapi lupa untuk membuat objek ConfigMap/Secret tersebut terlebih dahulu di cluster sebelum melakukan deployment.

# ✗ ANTI-PATTERN: Deployment merujuk secara kaku ke ConfigMap yang belum tentu ada
apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-processor
spec:
  template:
    spec:
      containers:
      - name: processor
        image: company/processor:v1.2.0
        envFrom:
        - configMapRef:
            name: order-settings-config # ← Jika ConfigMap ini belum dibuat di namespace, Pod akan stuck

Mengapa Ini Berbahaya? #

Pod kontainer kita akan gagal beroperasi dan stuck pada status CreateContainerConfigError atau CreateContainerError. Jika ini terjadi pada saat proses update otomatis (rolling update), Deployment controller akan menghentikan proses deploy tetapi membiarkan Pod baru dalam status error tanpa memberikan informasi yang intuitif di dashboard monitoring aplikasi.

Solusi Terbaik #

Gunakan properti optional: true jika variabel lingkungan tersebut tidak wajib ada demi kelancaran startup aplikasi. Namun, jika variabel tersebut bersifat kritis, pastikan pipeline CI/CD kita menerapkan pemeriksaan eksistensi (pre-flight check) sebelum menjalankan deployment.

# ✓ SOLUSI: Menggunakan opsi 'optional: true' jika variabel bersifat opsional
spec:
  containers:
  - name: processor
    envFrom:
    - configMapRef:
        name: order-settings-config
        optional: true # Pod tetap berjalan meskipun objek ConfigMap belum dideploy

Anti-Pattern 5: Absennya Validasi Sintaksis & Semantik Konfigurasi saat Startup (Fail-Late) #

Aplikasi mengonsumsi seluruh variabel lingkungan secara membabi buta tanpa melakukan validasi tipe data atau logika di awal fase startup aplikasi.

# ✗ ANTI-PATTERN: Aplikasi langsung berjalan tanpa memvalidasi input variabel lingkungan
import os
import redis

# Jika REDIS_PORT bernilai string bukan angka, aplikasi baru error ketika ada request masuk
redis_client = redis.Redis(
    host=os.getenv("REDIS_HOST"),
    port=os.getenv("REDIS_PORT"), # Mengasumsikan format port selalu valid
    db=0
)

Mengapa Ini Berbahaya? #

Hal ini memicu pola kegagalan lambat (fail-late). Aplikasi mungkin berhasil melakukan startup awal dan ditandai sebagai Ready oleh Kubernetes. Namun, ketika lalu lintas pengguna (traffic) masuk dan aplikasi mencoba mengeksekusi fungsi tertentu menggunakan variabel tersebut, aplikasi akan mengalami crash di memori. Hal ini menyulitkan tim pemantau untuk mendiagnosis akar masalah.

Solusi Terbaik #

Terapkan pola Fail-Fast. Buat skema validasi konfigurasi yang ketat pada fungsi main aplikasi saat startup. Jika konfigurasi tidak valid (misalnya port bernilai negatif, URL memiliki format salah, atau kredensial kosong), segera hentikan proses aplikasi dengan mengembalikan kode keluar sys.exit(1) disertai log kesalahan yang jelas.

# ✓ SOLUSI: Validasi konfigurasi dengan skema ketat saat startup aplikasi
import os
import sys

def validate_and_load_config():
    errors = []
    
    redis_host = os.getenv("REDIS_HOST")
    if not redis_host:
        errors.append("REDIS_HOST wajib didefinisikan.")
        
    redis_port_raw = os.getenv("REDIS_PORT")
    if not redis_port_raw:
        errors.append("REDIS_PORT wajib didefinisikan.")
    else:
        try:
            port = int(redis_port_raw)
            if port < 1 or port > 65535:
                errors.append(f"REDIS_PORT tidak valid (1-65535): {redis_port_raw}")
        except ValueError:
            errors.append(f"REDIS_PORT harus berupa angka: {redis_port_raw}")
            
    if errors:
        for error in errors:
            print(f"✗ CONFIGURATION VALIDATION ERROR: {error}", file=sys.stderr)
        # Hentikan kontainer dengan kegagalan eksplisit agar terdeteksi oleh Kubelet
        sys.exit(1)
        
    return {"host": redis_host, "port": int(redis_port_raw)}

# Jalankan validasi sebelum membuka koneksi database atau socket port
config = validate_and_load_config()

Anti-Pattern 6: Memperbarui ConfigMap In-Place Tanpa Memicu Rolling Restart #

Tim operator memperbarui data di dalam ConfigMap langsung di cluster menggunakan perintah kubectl edit configmap atau menimpanya melalui manifes CI/CD, tetapi tidak melakukan tindakan apa pun pada Deployment terkait.

# ✗ ANTI-PATTERN: Update ConfigMap in-place tanpa melakukan restart Deployment
kubectl edit configmap app-config -n production
# Nilai LOG_LEVEL diubah dari "info" ke "debug"
# Akibatnya: Pod yang sedang berjalan via variabel lingkungan tetap memegang nilai "info" (tidak terupdate).
# Kondisi cluster saat ini tidak konsisten (Drifted State).

Mengapa Ini Berbahaya? #

Jika kontainer mengonsumsi ConfigMap melalui variabel lingkungan (env atau envFrom), variabel tersebut tidak akan pernah diperbarui di dalam memori kontainer yang sedang berjalan. Nilai baru hanya akan berlaku pada Pod baru yang dibuat setelah ConfigMap berubah.

Hal ini melahirkan kondisi split-brain yang sangat membingungkan: jika salah satu Pod mati secara acak dan digantikan oleh Pod baru, Pod baru tersebut akan berjalan dengan konfigurasi baru, sementara Pod lama lainnya tetap memegang konfigurasi lama. Perilaku aplikasi di produksi akan menjadi tidak konsisten dan sangat sulit di-debug.

Solusi Terbaik #

Gunakan taktik anotasi checksum (seperti di Helm) atau manfaatkan fitur generator hash nama dari Kustomize agar setiap perubahan data konfigurasi menghasilkan resource baru yang secara otomatis memicu proses rolling restart yang terkontrol pada Deployment.

# ✓ SOLUSI: Menggunakan Checksum Annotation pada template Pod Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: payment-api
  namespace: payment
spec:
  replicas: 3
  template:
    metadata:
      annotations:
        # Jika nilai ConfigMap berubah, checksum SHA256 ini berubah, 
        # memaksa Kubernetes melakukan rolling update secara aman.
        checksum/config: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
    spec:
      containers:
      - name: api
        image: company/payment-api:v2.0.0

Anti-Pattern 7: Hak Akses RBAC ke API Secret Terlalu Permisif (Over-Privileged RBAC) #

Memberikan akses RBAC yang sangat luas kepada service account yang digunakan oleh Pod aplikasi untuk berinteraksi dengan API Server Kubernetes.

# ✗ ANTI-PATTERN: Memberikan izin ClusterRole get/list ke seluruh Secret di cluster
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: application-runner-role
rules:
- apiGroups: [""]
  resources: ["secrets"]
  # Memberikan hak akses untuk melihat seluruh Secret milik semua namespace di cluster
  verbs: ["get", "list", "watch"] 

Mengapa Ini Berbahaya? #

Jika salah satu aplikasi kita mengalami kerentanan keamanan (misalnya terkena serangan Remote Code Execution/RCE), penyerang dapat memanfaatkan token service account yang terpasang di dalam kontainer untuk melakukan kueri ke API Server.

Penyerang dapat menarik (list) seluruh Secret yang ada di cluster, termasuk kredensial database utama, sertifikat TLS internal, hingga token otorisasi cluster lainnya. Skenario ini memicu eskalasi hak istimewa (privilege escalation) yang dapat melumpuhkan seluruh cluster secara lateral.

sequenceDiagram
    participant Attacker as Penyerang (Exploited Pod)
    participant Kubelet as Pod Service Account Token
    participant API as Kubernetes API Server
    participant etcd as Cluster Database (etcd)
    
    Attacker->>Kubelet: Ambil token SA dari /var/run/secrets/
    Attacker->>API: Jalankan 'GET /api/v1/secrets' dengan token SA
    Note over API: RBAC Check: Permisif (Akses Diberikan)
    API->>etcd: Tarik seluruh Secret cluster
    etcd-->>API: Data Secret Plaintext
    API-->>Attacker: Kredensial seluruh database bocor!

Solusi Terbaik #

Terapkan prinsip Zero-Trust dan Least Privilege. Gunakan manifes Role (terbatas pada namespace tertentu, bukan ClusterRole), batasi akses hanya ke objek Secret spesifik menggunakan parameter resourceNames, dan batasi kata kerja (verbs) hanya untuk fungsi get (hindari list atau watch).

# ✓ SOLUSI: Batasi akses RBAC hanya untuk Secret yang benar-benar dibutuhkan
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: payment-api-role
  namespace: payment # Terisolasi di dalam namespace ini
rules:
- apiGroups: [""]
  resources: ["secrets"]
  # Hanya berikan akses ke Secret spesifik milik aplikasi ini
  resourceNames: ["db-credentials-payment", "stripe-keys"]
  # Hanya izinkan membaca entri tunggal, tidak boleh mendaftar (list) seluruh objek
  verbs: ["get"] 

Panduan Pemulihan Insiden Kredensial Bocor di Git #

Jika kita mendeteksi adanya kredensial produksi yang tidak sengaja ter-commit ke dalam repositori Git, lakukan langkah-langkah pemulihan darurat berikut secara berurutan:

Langkah 1: Rotasi Kredensial Segera (Rotate Immediately) #

Jangan habiskan waktu untuk menghapus commit Git terlebih dahulu. Asumsikan kredensial tersebut sudah dieksploitasi oleh pihak luar. Hubungi penyedia layanan terkait (misalnya cloud provider, administrator database, Slack, Stripe) dan lakukan rotasi/invalidation pada kunci akses lama tersebut saat itu juga.

Langkah 2: Bersihkan Riwayat Git (Purge History) #

Gunakan alat khusus seperti git-filter-repo atau BFG Repo-Cleaner untuk menghapus file secara permanen dari seluruh riwayat commit Git. Jangan gunakan perintah git rm biasa karena cara itu tidak menghapus file dari riwayat kompresi Git.

# Contoh menghapus file .env dari seluruh riwayat Git menggunakan git-filter-repo
git filter-repo --path .env --invert-paths

Langkah 3: Force Push dan Beritahu Tim #

Lakukan force push (git push origin --force --all) ke cabang utama (main branch) untuk memperbarui riwayat di server hosting (GitHub/GitLab). Instruksikan seluruh anggota tim pengembang untuk menghapus salinan repositori lokal mereka dan melakukan clone ulang guna menghindari penggabungan (merge) riwayat lama yang rusak kembali ke repositori utama.


Checklist Audit Konfigurasi Produksi #

Sebelum merilis manifest konfigurasi ke lingkungan produksi, pastikan tim reviewer melakukan verifikasi menggunakan checklist audit berikut:

HARDENING KEAMANAN:
  □ File manifest di repositori Git bebas dari kredensial plaintext.
  □ Data sensitif disimpan di dalam objek Secret, bukan ConfigMap.
  □ Kredensial di etcd telah dilindungi dengan mekanisme EncryptionConfiguration (KMS).
  □ Akses RBAC ke Secret di cluster menerapkan aturan granularitas 'resourceNames'.

DESAIN ARSITEKTUR:
  □ ConfigMap dan Secret dipecah menjadi modul modular per domain layanan (bukan monolithic).
  □ Image kontainer tidak menyimpan layer konfigurasi spesifik environment (build-time).
  □ Nilai konfigurasi divalidasi secara ketat menggunakan pola 'Fail-Fast' saat startup aplikasi.

OPERASIONAL CLUSTER:
  □ Perubahan ConfigMap/Secret secara otomatis memicu rolling restart Pod via checksum annotation.
  □ Pemasangan volume ConfigMap/Secret dinamis menghindari penggunaan properti 'subPath'.
  □ Batas ukuran total ConfigMap/Secret dipastikan berada jauh di bawah limitasi etcd (1 MB).

Ringkasan #

  • Rotate sebelum menghapus — Saat kredensial tidak sengaja ter-commit ke Git, rotasi kredensial tersebut terlebih dahulu di sisi penyedia layanan sebelum mencoba membersihkan riwayat repositori Git.
  • Pecah konfigurasi secara modular — Hindari pembuatan ConfigMap raksasa; pisahkan konfigurasi berdasarkan domain fungsional layanan untuk memperkecil blast radius rolling restart Pod.
  • Jaga kebersihan Dockerfile — Dockerfile harus agnostik terhadap infrastruktur target; suntikkan seluruh parameter operasional pada saat runtime kontainer menggunakan ConfigMap/Secret.
  • Terapkan pola Fail-Fast — Jangan biarkan aplikasi berjalan dengan parameter rusak; lakukan parsing dan validasi skema konfigurasi secara ketat pada fase inisialisasi startup.
  • Batasi RBAC Secret secara granular — Gunakan filter resourceNames dan isolasi tingkat Role untuk mencegah eskalasi lateral penyerang saat terjadi eksploitasi Pod.
  • Hindari split-brain dengan checksum — Selalu sertakan anotasi hash checksum pada template Pod Deployment agar pembaruan data ConfigMap/Secret memicu rolling restart Pod baru secara sinkron.

← Sebelumnya: Multi-Environment Configuration   Berikutnya: Deployment Strategy Overview →

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