Kubernetes ConfigMap pada Aplikasi Dinamis

Reyhan Sofian Haqqi
Pujangga Teknologi
Published in
6 min readFeb 24, 2019

Apa Itu ConfigMap?

ConfigMap allows you to decouple configuration artifacts from image content to keep containerized applications portable.

Menurut penjelasan resmi dari dokumentasi Kubernetes, ConfigMap adalah sebuah mekanisme untuk memisahkan konfigurasi dari sebuah aplikasi yang sudah dikontainerkan. Hal ini dapat membuat aplikasi tersebut lebih portabel dan membuat konfigurasinya lebih mudah untuk diubah dan dimanage, dan juga mengurangi kemungkinan konfigurasi yang langsung ditulis ke dalam sebuah Pod.

ConfigMap cocok digunakan untuk menyimpan konfigurasi yang tidak sensitif atau konfigurasi yang tidak perlu dienkripsi, seperti variabel lingkungan.

Bagaimana Cara Kerja ConfigMap?

Gambar 1 .1 — Membuat ConfigMap (referensi: SlideShare)

Pada Gambar 1.1 kita membuat ConfigMap terlebih dahulu. Ada 3 cara untuk membuat ConfigMap:

  1. Menggunakan opsi --from-file.
    Contoh: kubectl create configmap myConfigMap --from-file /my/path/to/directory/or/file
  2. Menggunakan opsi --from-literal.
    Contoh: kubectl create configmap myConfigMap --from-literal KEY1=VALUE1 KEY2=VALUE2
  3. Menggunakan manifest dengan tipe ConfigMap (lihat gambar 2.1).
    Untuk menggunakan cara ini kita perlu membuat sebuah file dengan ekstensi .yaml dan sesuai dengan spesifikasi, lalu mengunggah file tersebut dengan perintah kubectl apply -f myConfigMap.yaml
Gambar 1.2 — Unggah ConfigMap (reference: SlideShare)

Perintah kubectl create configmapmaupunkubectl apply -f akan mengunggah ConfigMap tersebut ke apiserver yang ada di dalam cluster Kubernetes.

Gambar 1.3 — Apiserver mendistribusikan ConfigMap (reference: SlideShare)

Lalu apiserver akan mendistribusikan ConfigMap tersebut ke semua Pod yang membutuhkan yang berada di dalam cluster Kubernetes.

Bagaimana Cara Menggunakan ConfigMap?

Ada 2 cara untuk menggunakan ConfigMap:

1. Sebagai environment variable

Sebagai contoh, kita memiliki sebuah ConfigMap seperti berikut

Gambar 2.1 — ConfigMap

Penjelasan nomor pada gambar:

  1. Nama ConfigMap
  2. Blok data untuk sebuah ConfigMap

Lalu kita gunakan nilai dari ConfigMap “special-config” tersebut ke sebuah Pod dengan menggunakan env seperti berikut

Gambar 2.2 — Pod Config

Penjelasan nomor pada gambar:

  1. Nama environment variable yang akan digunakan oleh aplikasi
  2. Referensi ke ConfigMap yang akan digunakan. Dalam contoh ini mengacu kepada ConfigMap di gambar 2.1
  3. Key dari sebuah ConfigMap yang akan dipakai nilainya
  4. Referensi ke ConfigMap lain tanpa harus mendefinisikan key yang akan digunakan

2. Sebagai volume yang dipasang ke sebuah pod

ConfigMap juga dapat digunakan dengan menggunakan plugin volume. Kita ambil contoh dengan menggunakan konfigurasi ConfigMap yang sama dengan di atas (gambar 2.1). Kita buat konfigurasi Pod seperti berikut:

Penjelasan nomor pada gambar:

  1. Referensi ke nama volume yang akan digunakan. Dalam contoh ini nomor 1 akan menggunakan volume dari nomor 3, yaitu volume “config-volume”
  2. Path yang akan digunakan oleh volume tersebut di dalam Pod
  3. Nama volume
  4. Nama ConfigMap yang dijadikan referensi oleh volume “config-volume” (nomor 3)

Menggunakan ConfigMap sebagai variabel lingkungan dengan menggunakan volume membuka peluang untuk mengubah variabel lingkungan yang ada didalam sebuah container atau Pod tanpa harus melakukan restart. Metode seperti ini biasa disebut dengan “live-update” atau “hot config”.

Kenapa “live-update” dibutuhkan? Karena di dalam dunia kontainerisasi, jika kita setel variabel lingkungan dengandocker run -e <KEY>=<VALUE> atau menggunakan env pada konfigurasi Pod, kita tidak bisa langsung menggantinya pada saat aplikasi berjalan. Sehingga kita perlu cara lain untuk membaca variabel lingkungan, yaitu dengan membaca dari sebuah file. Dalam konteks kali ini akan kita menggunakan ConfigMap yang sudah dipasang ke sebuah Pod.

Sebelum kita mulai, mari kita lihat apa yang terjadi jika ConfigMap berubah dengan contoh konfigurasi ConfigMap seperti ini

Gambar 3.1 — Konfigurasi ConfigMap
Gambar 3.2 — ConfigMap di dalam sebuah container sebelum berubah

Jika kita perhatikan, setiap variabel yang kita definisikan di dalam ConfigMap akan menjadi sebuah file di dalam kontainer. File-file ini memiliki tautan (symlink) ke dalam sebuah folder ..data dengan nama file yang sama. Misal ENV_IS_MAINTENANCE memiliki tautan ke file ..data/ENV_IS_MAINTENACE , dst. Dan folder ..data mengarah kepada sebuah folder yang memiliki nama ..2019_02_22_04_00_47.246998214

Sekarang mari kita coba membuat sebuah aplikasi sederhana menggunakan NodeJS dan ExpressJS yang membaca variabel lingkungan dari ConfigMap, lalu kita kemas ke dalam sebuah kontainer

Kode di atas akan melihat dan melakukan perubahan jika terjadi event “rename” di dalam folder /etc/config.

Setelah itu kita buat sebuah konfigurasi Deployment dan Service untuk sebuah Pod seperti berikut, lalu kita unggah ke Kubernetes dengan kubectl apply -f test-k8s.yaml

Selanjutnya mari kita ubah konfigurasi ConfigMap di atas menjadi

Gambar 3.3 — Perubahan konfigurasi ConfigMap pada key “ENV_IS_MAINTENTANCE”
Gambar 3.4 — ConfigMap di dalam sebuah container setelah berubah

Dari gambar di atas dapat kita lihat bahwa tautan antara file-file variabel lingkungan tidak berubah sama sekali. Hanya tautan folder ..data yang berubah tautannya menuju folder baru yang namanya ..2019_02_23_19_01_09.591362024

Untuk melihat bagaimana “live-update” beraksi, mari kita simak animasi berikut

Dari animasi di atas dapat kita lihat bagaimana mudahnya mengubah variabel lingkungan tanpa harus mengubah konfigurasi Deployment, Service, atau Pod sama sekali bahkan tanpa harus restart aplikasi tersebut.

Beberapa hal yang harus kita ingat jika menggunakan ConfigMap:

  1. ConfigMap hanya “hidup” di dalam satu namespace saja. Yang artinya kita tidak bisa menggunakan ConfigMap yang berada di namespace lain.
  2. Proses sinkronisasi ConfigMap tidak langsung terjadi atau biasa disebut “eventually consistent”. Hal ini terjadi karena frekuensi sinkronisasi dari kubelet standardnya adalah 60 detik. Jika ingin proses sinkronisasi lebih cepat dapat menggunakan opsi --sync-frequency . Untuk lebih jelasnya bisa baca dari dokumentasi resmi Kubernetes di sini

Ekstra!

Jika kita amati, implementasi “live-update” di atas hanya bisa bekerja untuk NodeJS saja karena NodeJS memiliki pustaka standar untuk sistem file yang bisa melihat perubahan suatu file (fs.watch). Apabila kita ingin implementasi di bahasa lain, maka kode server dan konfigurasi Deployment, Service dan Pod di atas perlu sedikit penyesuaian

Mari kita perhatikan konfigurasi containers di atas

Kita menambahkan kontainer jimmidyson/configmap-reload dengan beberapa konfigurasinya ke dalam Pod untuk membaca perubahan ConfigMap.

Untuk kode server kita menambahkan satu endpoint supaya bisa menerima webhook dari kontainer configmap-reload.

Jika kita menggunakan metode seperti ini, maka alur kerjanya akan menjadi seperti berikut

  1. Kontainer configmap-reload akan melihat apakah ConfigMap yang dipasang sebagai volume mengalami perubahan atau tidak
  2. Jika ConfigMap mengalami perubahan, kontainer configmap-reload akan memberikan notifikasi kepada aplikasi yang memiliki endpoint /-/reload (sesuai dengan konfigurasi --webhook-url)
  3. Aplikasi yang menerima notifikasi akan membaca ulang semua variabel lingkungan yang ada di ConfigMap lalu menyimpan ulang ke sebuah variabel global. Karena contoh di atas menggunakan NodeJS, maka akan disimpan ke variabel process.env

Dengan metode seperti ini, kita bisa implementasi “live-update” dengan bahasa pemrograman apapun. Selamat bereksperimen!

--

--