Skip to content

Ketika monitor versi membangunkan untuk kondisi yang disengaja

Adityo Guni Waluyo

PROBLEM jam lima pagi untuk fleet yang sehat dan sengaja lebih baru dari Docker Hub. Perbandingan versi ternyata buta arah.

Ringkasan

Script monitor gue ngamuk jam 5 pagi gara-gara versi fleet beda sama Docker Hub. Ternyata semua host sehat dan sengaja di-upgrade ke versi custom, yang nggak kejar malah Docker Hub-nya. Akhirnya gue perbaiki logika perbandingannya: versi dihitung numerik kayak SemVer dan fleet lebih baru dari Hub dianggap rollout yang disetujui, bukan masalah.

Jam lima pagi, layar terminal menampilkan satu baris merah dari 9router-version-watch.py: PROBLEM, fleet tidak sinkron dengan Docker Hub. Refleks pertama saya yang salah: pasti ada host yang gagal upgrade, tinggal cari yang mana. Saya buka daftar versi per host satu-satu, siap mengerjakan rollback. Kenyataannya justru memalukan dalam arti yang baik: keenam host sehat, seragam, dan sengaja saya dorong ke versi custom 0.5.81 sehari sebelumnya. Yang "tertinggal" bukan fleet-nya, melainkan Docker Hub yang masih berhenti di 0.5.75 [6]. Monitor itu membangunkan saya untuk sebuah kondisi yang justru saya rancang sendiri.

Di titik itu saya sadar tebakan awal saya memang keliru dari fondasinya. Saya mencari host yang bermasalah, padahal yang bermasalah adalah logika perbandingannya. Skrip itu sejak awal diasumsikan Hub latest adalah satu-satunya kebenaran: fleet ≠ Hub berarti ada yang salah. Padahal registry bisa saja tertinggal dari realitas yang sudah disetujui, dan tanpa konsep arah, "berbeda" otomatis dibaca sebagai "rusak".

Membandingkan versi itu ada arahnya

Perbaikannya cuma tujuh belas baris, tapi menuntut saya menyusun ulang cara berpikir soal perbandingan versi. Pertama, urutan versi nggak boleh dibandingkan sebagai string. Angka 0.5.9 akan tampak "lebih besar" dari 0.5.75 kalau dibanding leksikografis, padahal secara versi jelas lebih kecil. Standar SemVer menetapkan bahwa versi MAJOR.MINOR.PATCH dibandingkan per komponen secara numerik: MAJOR untuk perubahan yang memecah kompatibilitas, MINOR untuk fitur baru yang kompatibel, PATCH untuk perbaikan bug [1]. Karena itu saya tambahkan helper kecil bernama _vkey: memecah string versi jadi tuple angka, sehingga 0.5.81 memang lebih besar dari 0.5.75 seperti yang diharapkan mata manusia.

Kedua, dan ini yang paling penting: arah perbandingan harus punya makna berbeda. Gate 2b yang baru menetapkan: kalau seluruh fleet seragam dan lebih baru dari Hub, itu berarti rollout custom yang disetujui. Skrip diam dengan exit 0 dan terus memantau menunggu Hub menyusul. Sebaliknya, versi campuran antar host atau fleet yang lebih tua dari Hub tetap memicu PROBLEM seperti sebelumnya, karena dua kondisi itu memang berbahaya. Kabar baiknya, pola ini bukan karangan saya sendiri. Dokumen resmi Kubernetes punya aturan version skew yang eksplisit soal arah: kubelet boleh lebih lama sampai tiga minor version dari kube-apiserver, tapi dilarang lebih baru [4]. Arah skew selalu membawa arti operasional yang berbeda.

Dunia nyata sudah punya kata untuk ini

Setelah kejadian itu saya mulai membaca ulang dokumentasi, dan ternyata pola "state yang tampak salah padahal disengaja" sudah lama diakui di ekosistem yang berbeda-beda. npm misalnya: publish sebuah package otomatis memindahkan tag latest, kecuali kita sengaja memakai --tag lain seperti beta atau canary [5]. Artinya yang terpasang di produksi bisa saja jauh lebih baru dari yang dilihat konsumen default, dan itu perilaku normal yang didokumentasikan resmi. Kalau saya bikin monitor yang membandingkan "apa yang jalan di produksi" dengan "apa yang dilihat pengguna npm install", saya akan dapat false alarm yang sama persis.

Yang bikin saya agak kesal sebenarnya bukan bug-nya, tapi insomnia yang saya rancang sendiri. Prinsip alerting yang sehat sudah dijelaskan di SRE Workbook: tujuannya adalah diberi tahu hanya untuk significant event, yaitu kejadian yang benar-benar menggerus error budget [2]. Panduan praktik Prometheus merangkum filosofi yang sama dengan kata yang lebih blak-blakan: alert harus sederhana, memantau gejala, dan menghindari pager yang isinya tidak ada yang bisa dikerjakan [3]. Baris PROBLEM jam lima pagi untuk fleet yang sehat adalah contoh sempurna dari pager yang tidak minta tindakan apa pun. Enam host, nol pekerjaan, satu manusia kehilangan tidur.

Pelajaran yang saya bawa: sebuah monitor hanya sepadat pemahamannya tentang keadaan "disengaja". Selama saya nggak mengajari skrip tentang rollout custom yang disetujui, dia akan terus melaporkan keputusan saya sendiri sebagai kegagalan. Tujuh belas baris _vkey dan gate 2b membelikan hal yang jauh lebih berharga daripada log yang lebih senyap: saya jadi tahu persis kondisi mana yang layak membangunkan saya, dan kondisi mana yang cukup dicatat lalu didiamkan.

Artikel terkait