ConfigMap

Pemisahan konfigurasi dari image melalui ConfigMap: variabel lingkungan, berkas, dan pola mounting.

Daftar isi

ConfigMap adalah objek Kubernetes yang menyimpan pasangan kunci dan nilai konfigurasi yang tidak bersifat rahasia, sehingga nilai-nilai yang berubah antara lingkungan tidak perlu dibangun ulang ke dalam image. Topik ini membahas cara mengisi data pada ConfigMap, menggunakannya sebagai variabel lingkungan, mounting sebagai berkas di dalam container, serta opsi immutable dan pola pembaruannya. Di akhir topik, manifest ConfigMap dibaca ulang secara terprogram untuk memverifikasi pemetaan kuncinya.

Pemisahan konfigurasi dari image#

Image yang baik bersifat netral terhadap lingkungan, sedangkan nilai yang membedakan lingkungan pengembangan dari lingkungan produksi, misalnya alamat basis data dan tingkat log, berada di luar image. ConfigMap menjadi tempat penyimpanan nilai-nilai tersebut pada API server, dan Pod membacanya saat berjalan. Isinya berupa pasangan kunci dan nilai dalam bentuk teks pendek maupun isi berkas konfigurasi utuh, sehingga satu ConfigMap dapat menggantikan banyak berkas pengaturan yang sebelumnya ditanam ke dalam image.

Manifest ConfigMap berikut memuat tiga kunci skalar dan satu kunci berupa isi berkas properti:

yaml configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: catatan-config
data:
  LOG_LEVEL: "info"
  DB_HOST: "db-catatan"
  DB_PORT: "5432"
  pengaturan.properties: |
    ukuran.halaman=10
    mode.simpan=draf

Kunci pada data boleh berupa nama variabel lingkungan yang lazim, misalnya LOG_LEVEL, maupun nama berkas valid seperti pengaturan.properties. Blok | pada YAML mempertahankan baris baru, sehingga nilai kunci terakhir benar-benar berbentuk isi berkas dengan dua baris. Nilai angka ditulis dengan tanda kutip agar tetap terbaca sebagai teks, karena ConfigMap menyimpan semua nilai sebagai string. Ukuran total satu ConfigMap dibatasi hingga sekitar 1 MiB, sehingga ConfigMap bukan tempat untuk berkas besar, dan data biner disimpan pada bidang binaryData dengan encoding base64.

Variabel lingkungan dari ConfigMap#

Cara paling sederhana mengonsumsi ConfigMap adalah menyuntikkannya sebagai variabel lingkungan container. Kubernetes menyediakan dua mekanisme dengan cakupan berbeda. Bidang envFrom menyuntikkan seluruh kunci sekaligus, dan nama variabelnya sama dengan nama kuncinya:

yaml Contoh: seluruh kunci sebagai variabel lingkungan
envFrom:
  - configMapRef:
      name: catatan-config

Apabila hanya satu kunci yang diperlukan, bidang valueFrom mengambil satu kunci dari ConfigMap dan menaruhnya ke dalam satu variabel dengan nama yang ditentukan sendiri:

yaml Contoh: satu kunci ke satu variabel
env:
  - name: LOG_LEVEL
    valueFrom:
      configMapKeyRef:
        name: catatan-config
        key: LOG_LEVEL

Kedua mekanisme berbagi satu sifat yang penting dipahami: nilai variabel lingkungan dibaca pada saat container dimulai, lalu tidak pernah berubah selama container tersebut masih hidup. Pembaruan pada ConfigMap tidak mengalir ke variabel lingkungan Pod yang sudah berjalan. Kunci berupa isi berkas panjang juga sebaiknya tidak disuntikkan melalui variabel lingkungan, karena nilainya menjadi satu teks raksasa yang sulit diurai oleh aplikasi.

Apabila kedua bidang digunakan sekaligus, entri pada env diterapkan setelah seluruh nilai dari envFrom, sehingga variabel bernama sama pada env menimpa hasil envFrom. Aturan urutan ini berguna untuk mengganti satu nilai secara selektif tanpa menyalin seluruh daftar kunci. Selain itu, nama variabel yang dihasilkan envFrom sama persis dengan nama kuncinya, sehingga kunci sebaiknya ditulis dengan pola huruf besar dan garis bawah agar aman dibaca aplikasi.

Mounting ConfigMap sebagai berkas#

Pola konsumsi kedua menampilkan kunci ConfigMap sebagai berkas di dalam filesystem container. Pod mendeklarasikan volume bertipe configMap, kemudian setiap container me-mount volume tersebut ke sebuah direktori. Manifest Pod berikut memadukan kedua pola, yaitu envFrom untuk kunci skalar dan mounting untuk berkas properti:

yaml catatan-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: catatan
spec:
  containers:
    - name: catatan
      image: busybox:1.36
      command: ["sh", "-c", "sleep 3600"]
      envFrom:
        - configMapRef:
            name: catatan-config
      volumeMounts:
        - name: konfigurasi
          mountPath: /etc/catatan
          readOnly: true
  volumes:
    - name: konfigurasi
      configMap:
        name: catatan-config
        items:
          - key: pengaturan.properties
            path: pengaturan.properties

Bidang items memetakan kunci ConfigMap ke nama berkas pada volume, sehingga tidak semua kunci harus muncul sebagai berkas. Dengan mountPath: /etc/catatan, container membaca berkas /etc/catatan/pengaturan.properties seolah-olah berkas itu tertanam secara normal, sedangkan isi direktori lain di /etc tetap utuh. Bidang readOnly: true mencegah container mengubah berkas konfigurasinya, karena perubahan dari sisi container akan tertimpa pada pembaruan berikutnya.

Pembaruan konfigurasi dan opsi immutable#

ConfigMap yang sudah dibuat tetap dapat diperbarui dengan mengaplikasikan manifest yang sudah disunting, dan berkas yang di-mount mengikuti pembaruan tersebut. Untuk konfigurasi yang jarang berubah, bidang immutable pada tingkat atas menutup kemungkinan pembaruan tersebut:

yaml Contoh: bidang immutable pada ConfigMap
immutable: true

Apabila immutable: true sudah diterapkan, setiap percobaan perubahan ditolak API server dengan error, dan satu-satunya cara mengubah isi adalah menghapus ConfigMap lalu membuatnya ulang. Dua keuntungan yang menyertainya adalah perlindungan dari perubahan yang tidak disengaja dan penghentian pemantauan kubelet terhadap objek tersebut, sehingga beban pemantauan pada kluster besar menurun.

Karena variabel lingkungan tidak pernah berubah, aplikasi yang mengonsumsi ConfigMap melalui envFrom hanya melihat nilai baru setelah Pod dibuat ulang:

bash
# tidak-dijalankan
# hapus pod agar dibuat ulang dengan nilai ConfigMap terbaru
kubectl delete pod catatan

# terapkan ulang manifest pod
kubectl apply -f catatan-pod.yaml
text Contoh keluaran
pod "catatan" deleted
pod/catatan created

Pendekatan yang lebih disiplin adalah menghindari pencampuran pola, yaitu nilai yang sering berubah ditempatkan pada berkas yang di-mount dan aplikasinya dirancang untuk membaca ulang, sedangkan nilai yang jarang berubah boleh berada di variabel lingkungan.

Membaca ConfigMap dengan Python#

Manifest ConfigMap dapat diverifikasi secara terprogram agar pemetaan kunci ke nilai tidak diperiksa secara manual. Pemeriksaan manual yang dilakukan berulang pada banyak lingkungan mudah melewatkan kunci yang salah ketik, sedangkan skrip yang sama berjalan identik di mana pun. Skrip berikut membaca configmap.yaml dari bundle menggunakan PyYAML, mencetak setiap kunci beserta nilainya, lalu meniru aturan penamaan kunci pada kubectl create configmap --from-file, yaitu nama berkas menjadi kunci dan isinya menjadi nilai:

python
import yaml

# baca manifest ConfigMap dari bundle topik
with open("configmap.yaml") as f:
    cm = yaml.safe_load(f)

print(f"ConfigMap {cm['metadata']['name']} memuat {len(cm['data'])} kunci:")
for kunci, nilai in cm["data"].items():
    baris = len(nilai.splitlines())
    if baris > 1:
        print(f"  {kunci} = {baris} baris isi")
    else:
        print(f"  {kunci} = {nilai}")

# meniru kubectl create configmap --from-file: nama berkas menjadi kunci
berkas = {
    "pengaturan.properties": "ukuran.halaman=10\nmode.simpan=draf\n",
    "piket.txt": "Senin: Ali\nSelasa: Budi\n",
}
print("kunci bila dibuat dengan --from-file:")
for nama in sorted(berkas):
    print(f"  {nama}")
text Keluaran
ConfigMap catatan-config memuat 4 kunci:
  LOG_LEVEL = info
  DB_HOST = db-catatan
  DB_PORT = 5432
  pengaturan.properties = 2 baris isi
kunci bila dibuat dengan --from-file:
  pengaturan.properties
  piket.txt

Keluaran menegaskan bahwa nilai skalar tersimpan apa adanya sebagai string, sedangkan nilai berkas dihitung sebagai beberapa baris. Aturan --from-file menunjukkan mengapa kunci boleh berupa nama berkas, karena nama berkas itu sendiri menjadi kunci di dalam data. Skrip dengan bentuk yang sama dapat dibagikan ke rekan tim agar pembuatan ConfigMap baru mengikuti pola penamaan yang sudah disepakati.

Kesalahan umum#

  • Kunci pada configMapKeyRef tidak ada di ConfigMap. Pod menolak dimulai dan statusnya berulang kali masuk ke CreateContainerConfigError karena API server tidak menemukan kunci yang dirujuk. Perbaikannya adalah menyamakan nama kunci pada Pod dan ConfigMap, lalu memeriksa daftar kunci dengan kubectl describe configmap.
  • Mengharapkan variabel lingkungan berubah setelah ConfigMap diperbarui. Variabel lingkungan hanya dibaca sekali saat container dimulai, sehingga Pod lama terus menggunakan nilai lama tanpa pesan error apa pun. Perbaikannya adalah memulai ulang Pod atau memindahkan nilai tersebut ke berkas yang di-mount.
  • Me-mount satu berkas dari ConfigMap dengan subPath. Mount dengan subPath tidak menerima pembaruan dari kubelet, sehingga aplikasi terus membaca isi lama meskipun ConfigMap sudah berubah. Perbaikannya adalah me-mount direktori volume dan menaruh berkas di dalamnya, sesuai pola pada manifest Pod di atas.

Ringkasan#

  • ConfigMap menyimpan pasangan kunci dan nilai non-rahasia yang terpisah dari image, dengan batas ukuran total sekitar 1 MiB.
  • envFrom menyuntikkan seluruh kunci sebagai variabel lingkungan, sedangkan valueFrom menyuntikkan satu kunci ke satu variabel bernama.
  • Volume bertipe configMap menampilkan kunci sebagai berkas yang diperbarui kubelet secara berkala, sedangkan variabel lingkungan tidak pernah berubah selama container berjalan.
  • Bidang immutable: true menolak setiap pembaruan dan menghentikan pemantauan kubelet terhadap ConfigMap tersebut.

Referensi#

  • ConfigMaps — Kubernetes — Dokumentasi konsep ConfigMap, mencakup pola variabel lingkungan, mounting berkas, dan opsi immutable.