Ringkasan Utama
KYAML adalah subset YAML yang ketat dengan flow style, yang dinaikkan ke Stable oleh Kubernetes SIG CLI di v1.37. Setiap file KYAML adalah YAML yang valid, jadi manifest lama tidak perlu diubah. kubectl get -o kyaml menghasilkan string ber-double-quote, kurung kurawal dan kurung siku, sehingga diff kebal whitespace dan type coercion diam-diam seperti Norway bug berhenti.
Kegagalan yang disasar KYAML itu sunyi. Manifest dengan indentasi salah bisa tetap valid sebagai YAML tetapi mendeskripsikan objek yang berbeda, dan nilai tanpa quote bisa terbaca sebagai tipe lain tanpa error apa pun. Tidak ada yang gagal, dan di review perubahannya tampak seperti noise whitespace. Proyek Kubernetes kini memasukkan jawaban yang lebih ketat ke kubectl dan menyebutnya Stable.
Post ini membahas apa yang sebenarnya dirilis Kubernetes ketika KYAML naik ke Stable di v1.37 pada 26 Agustus 2026. Saya membaca release notes v1.37, blog post SIG CLI tentang pretty-print, teks KEP 5295, referensi kuberc, dan dokumentasi yamlfmt. Saya tidak menjalankan benchmark apa pun. Bila sebuah perintah di bawah adalah rakitan saya sendiri dari potongan yang terdokumentasi, saya menyebutkannya.
Apa yang naik ke Stable, dan apa yang tidak berubah
Release post v1.37 menyebut KYAML sebagai subset YAML yang lebih aman dan tidak ambigu, dirancang khusus untuk Kubernetes, dan menegaskan bahwa ini bukan pengganti YAML. Setiap file KYAML adalah YAML yang valid, sehingga valid sebagai input untuk kubectl versi mana pun, dan file spec tidak harus ditulis dalam KYAML agar bisa di-parse. Post itu menyatakan manifest, tooling, dan pipeline yang ada tidak perlu diubah.
Riwayat stage-nya: Alpha di v1.34, Beta di v1.35, dan Stable di v1.37 dengan conformance testing selesai. Release notes memasukkannya ke dalam 16 enhancement yang dipromosikan ke Stable di rilis itu. Hasil konkret bagi pengguna cukup satu kalimat: kubectl get -o kyaml sekarang Stable. KEP 5295, milik SIG CLI, menyebut tiga syarat untuk menghapus gate: spesifikasi yang dipublikasikan, output KYAML di sebagian besar contoh Kubernetes, dan tidak ada bug report baru.
Dua bug yang ingin dihapus KYAML
Bagian motivasi di KEP menyebut masalahnya. Struktur YAML berbasis indentasi sulit dibuat benar, dan sistem templating memperburuknya karena pengguna harus mengatur whitespace di luar konteks YAML. Lalu nilai tanpa quote bisa di-coerce diam-diam menjadi tipe lain: sebagian kata terbaca sebagai boolean, dan sebagian nilai yang dipisah underscore atau titik dua terbaca sebagai angka. Post SIG CLI memberi contoh klasik, Norway bug, ketika NO tanpa quote di-parse sebagai boolean false, bukan string NO.
| Aspek | YAML block style | JSON | KYAML |
|---|---|---|---|
| Struktur | Ditentukan oleh indentasi | Kurung kurawal dan kurung siku | Kurung kurawal dan kurung siku, indentasi hanya kosmetik |
| Nilai string | Biasanya tanpa quote, jadi type coercion mungkin terjadi | Selalu double-quote | Selalu double-quote |
| Komentar | Boleh | Tidak didukung | Boleh |
| Trailing comma | Tidak berlaku | Ditolak | Boleh, dan selalu dihasilkan |
| Key | Tanpa quote | Wajib di-quote | Tanpa quote kecuali tidak jelas aman |
| Header dokumen | Opsional | Tidak ada | Baris tiga tanda hubung di awal, agar tidak tertukar dengan JSON |
Tabel itu adalah seluruh argumen desainnya. KYAML mempertahankan yang disukai tim dari YAML, yaitu komentar dan trailing comma, lalu mengambil struktur eksplisit dan tipe eksplisit dari JSON. Post SIG CLI menempatkannya di antara JSON dan YAML, dan mencatat bahwa YAML menyebut ini flow style, berlawanan dengan block style. Manfaat praktisnya ada di templating: karena struktur tidak lagi bergantung pada whitespace, mem-patch manifest dari Helm atau template engine lain tidak bisa mengubah bentuknya secara diam-diam.
Bentuk output dan aturan persisnya
Pod yang sama dari post SIG CLI, pertama sebagai YAML biasa lalu sebagai KYAML. KEP menambahkan detail format yang tidak ada di post itu: indentasi dua spasi, koleksi kosong dirender sebagai kurung kosong, kurung berpasangan diletakkan satu baris dengan item sebelumnya kecuali komentar butuh barisnya sendiri, dan string multi-baris ditulis dengan newline yang di-escape serta line folding, bukan block literal.
# Standard YAML (the SIG CLI post's example Pod)
apiVersion: v1
kind: Pod
metadata:
name: my-pod
labels:
app: demo
spec:
containers:
- name: nginx
image: nginx:1.20
# The same Pod as KYAML: leading --- header, braces and brackets,
# every value double-quoted, trailing commas always emitted.
---
{
apiVersion: "v1",
kind: "Pod",
metadata: {
name: "my-pod",
labels: {
app: "demo",
},
},
spec: {
containers: [{
name: "nginx",
image: "nginx:1.20",
}],
},
}
# Why it exists: in block-style YAML this line parses as boolean false,
# not the string "NO" (the "Norway bug"). KYAML would emit country: "NO".
country: NOBaca versi KYAML untuk melihat apa yang hilang. Tidak ada tempat di mana perubahan indentasi mengubah makna, dan image tag nginx:1.20 adalah string ber-quote apa pun tampilannya bagi parser angka. Trailing comma setelah item terakhir bukan typo. KEP menyatakan trailing comma diperbolehkan dan selalu dihasilkan, yang seharusnya menjaga perubahan satu baris tetap menjadi diff satu baris.
Karena outputnya deterministik, KEP mencantumkan konversi yang konsisten sebagai tujuan: konversi berulang harus menghasilkan output yang sama. Sifat itulah yang membuat KYAML bisa dipakai sebagai bentuk kanonik di repository, dan bagian CI di bawah bergantung padanya.
Versi kubectl yang mendukung, dan jebakan default output
Pembagian versi penting untuk fleet. Menghasilkan KYAML dengan kubectl butuh 1.34 atau lebih baru, dan di 1.34 hanya dengan environment variable. Membaca KYAML tidak butuh apa-apa, karena itu YAML. Jadi sebuah repository bisa mengadopsi file KYAML hari ini tanpa menunggu kubectl setiap engineer di-upgrade.
| Rilis Kubernetes | Stage KYAML | Cara memakainya |
|---|---|---|
| v1.34 | Alpha | Set KUBECTL_KYAML=true, lalu jalankan kubectl get dengan -o kyaml |
| v1.35 | Beta | Aktif secara default, tetapi Anda tetap memberi -o kyaml; mengatur variabel ke false mematikannya |
| v1.37 | Stable | Gate dihapus dan format selalu tersedia; conformance testing selesai |
| Versi mana pun | Input | File KYAML adalah YAML yang valid, jadi kubectl mana pun bisa membacanya sebagai manifest |
Post SIG CLI menyatakan saat ini tidak ada rencana menjadikan KYAML format output default. Jika ingin menjadikannya default untuk diri sendiri, jalurnya adalah kuberc, yang oleh dokumentasi ditandai Beta sejak Kubernetes v1.34 dan berada di direktori home pada .kube/kuberc. Post itu memberi perintah untuk 1.36 ke atas, dan penulisan berbeda untuk 1.33 sampai 1.35 yang masih butuh prefix alpha.
# Kubernetes 1.35+ (Beta, enabled by default): the flag is still required.
kubectl get deployment my-app -o kyaml
# Kubernetes 1.34 (Alpha, opt-in): set the gate first.
export KUBECTL_KYAML=true
kubectl get deployment my-app -o kyaml
# Save it; this writes the live object as KYAML.
kubectl get deployment my-app -o kyaml > my-app.kyaml
# Make it your own default for get (no plan to change the cluster-wide default).
# Kubernetes 1.36+:
kubectl kuberc set --section defaults --command get --option output=kyaml
# Kubernetes 1.33 to 1.35 (alpha prefix still required):
kubectl alpha kuberc set --section defaults --command get --option output=kyaml
# My own composition, not copied from the docs: the defaults shape from the
# kuberc reference (which documents interactive for delete) with output for get.
# ~/.kube/kuberc
apiVersion: kubectl.config.k8s.io/v1beta1
kind: Preference
defaults:
- command: get
options:
- name: output
default: kyamlBentuk file di bawah adalah rakitan saya sendiri. Ia menyalin bentuk defaults dari referensi kuberc, yang contoh terdokumentasinya mengatur interactive untuk delete, lalu mengganti dengan perintah get dan opsi output yang diatur oleh perintah di blog. Jalankan perintah terdokumentasinya sekali dan baca apa yang ditulisnya sebelum memercayai versi saya.
Memakai kubectl get -o kyaml di diff CI
Kasus pemakaian yang layak jadi alasan adopsi adalah diff pull request yang hanya menampilkan perubahan makna. Dua pemeriksaan mengikuti dari perilaku yang terdokumentasi. Pertama, gate format untuk manifest yang di-commit ke repository: yamlfmt milik Kubernetes mencetak versi KYAML sebuah file ke stdout, sehingga gate bisa membandingkan file yang di-commit dengan bentuk kanoniknya sendiri. Kedua, snapshot objek live, yang ditulis lewat kubectl.
#!/usr/bin/env bash
# Composed from the documented commands. NOT run against a cluster by me:
# test the exit-code handling before you let it gate a merge.
set -euo pipefail
# 1. Formatting gate. sigs.k8s.io/yaml/yamlfmt prints KYAML to STDOUT and
# never edits the file, so compare its output with the committed file.
go install sigs.k8s.io/yaml/yamlfmt@latest # pin a real version in CI
status=0
for f in k8s/*.yaml; do
tmp="$(mktemp)"
yamlfmt -o=kyaml "$f" > "$tmp"
if ! diff -u "$f" "$tmp"; then
echo "not canonical KYAML: $f" >&2
status=1
fi
rm -f "$tmp"
done
# 2. Drift snapshot of a live object. Compare it with the previous snapshot
# of the SAME object; status and other server fields make a diff against
# the source manifest noisy.
kubectl get deployment my-app -o kyaml > "snapshots/my-app.$(date +%F).kyaml"
exit "$status"
# Wrong: yamlfmt -o=kyaml k8s/app.yaml > k8s/app.yaml (truncates the file first)
# Right: write to a temp file, inspect it, then mv it into place.Saya merakit script dari perintah terdokumentasi dan belum menjalankannya di cluster, jadi anggap penanganan exit code sebagai bagian yang harus diuji lebih dulu. Satu ekspektasi yang akan saya verifikasi, bukan saya asumsikan: objek live membawa field yang diisi server seperti status, sehingga diff snapshot terhadap manifest sumber akan berisik. Bandingkan snapshot objek live dengan snapshot sebelumnya dari objek yang sama, bukan dengan file di git.
Pin versi formatter. KEP 5295 mencantumkan lock-in pada output tingkat byte sebagai risiko dan menyatakan spesifikasi akan memberi ruang di tempat yang belum yakin. Memasang dengan tag latest di CI berarti upgrade formatter bisa menulis ulang semua manifest sekaligus. Pin satu versi dan upgrade dengan sengaja.
Tiga cara menghasilkan KYAML: kubectl dan dua tool yamlfmt
Post SIG CLI menyebut tiga jalur. kubectl mengonversi objek live. yamlfmt Kubernetes, di sigs.k8s.io/yaml, mengonversi file; ia mencetak ke stdout, menerima direktori, dan punya flag diff. yamlfmt dari Google menambahkan formatter kyaml khusus di v0.21.0, yang juga tersedia sebagai pre-commit hook dan Docker image untuk CI.
Konfigurasi untuk tool Google hanya dua baris. Post itu menyatakan formatter kyaml tidak punya konfigurasi tambahan dan tidak berbagi opsi dengan formatter default, jadi mencampur keduanya menyebabkan error. Jika repository Anda sudah punya file yamlfmt dengan opsi indentasi atau line-length, opsi itu harus dihapus saat Anda mengganti tipe formatter.
# .yamlfmt (Google's yamlfmt, kyaml formatter added in v0.21.0)
formatter:
type: kyaml
# The kyaml formatter takes no extra options and shares none with the default
# formatter; leaving indent or line_length keys in this file is an error.
# yamlfmt -dry k8s/app.yaml preview without modifying the file
# yamlfmt k8s/app.yaml rewrite in place
# yamlfmt ./k8s/ convert a whole directoryMana yang dipilih adalah soal workflow, bukan soal kualitas. Pakai tool Kubernetes untuk konversi sekali jalan atau pengecekan stdout di script. Pakai tool Google bila Anda ingin formatter yang menulis ulang file di tempat, berjalan di pre-commit, dan membaca file konfigurasi.
Trade-off dan cara ini bisa gagal
KEP cukup jujur soal risiko, dan itu daftar periksa yang tepat. Keterbacaan yang justru lebih buruk: flow style dengan kurung bersarang bisa lebih sulit dipindai daripada block style, sebab itu rencananya diuji dengan banyak contoh dan mengumpulkan feedback. Output tidak valid: encoder bisa menghasilkan YAML tidak valid, yang dianggap bug. Dan rasa aman palsu: KYAML menghindari jebakan YAML tetapi tidak memperbaiki YAML itu sendiri.
Risiko ketiga adalah yang akan saya sampaikan ke tim. Memberi quote pada setiap string menghentikan Norway bug di file yang ditulis atau diformat sebagai KYAML. Itu tidak berbuat apa-apa untuk manifest block style tulisan tangan di sebelahnya yang punya nilai tanpa quote, dan tidak memvalidasi bahwa manifest itu objek Kubernetes yang benar. Validasi schema tetap harus dilakukan di tempat lain.
yamlfmt Kubernetes menulis file hasil konversi ke stdout. Ia tidak mengedit file. Menjalankannya pada sebuah file dan mengharapkan penulisan ulang di tempat tidak mengubah apa-apa, dan mengarahkan outputnya ke path yang sama bisa memotong file sumber sebelum sempat terbaca. Tulis ke file sementara, periksa, lalu pindahkan ke tempatnya.
Ada juga biaya praktis yang tidak bisa dihapus dokumentasi. Konversi sekali jalan menulis ulang setiap baris di setiap manifest, jadi pull request pertamanya tidak terbaca secara desain. Lakukan konversi di commit tersendiri tanpa perubahan lain, dan beri tahu reviewer bahwa yang ini diperiksa dengan menjalankan formatter, bukan dengan membacanya.
Yang dilakukan hari Senin
Perlakukan KYAML sebagai keputusan format untuk satu direktori, bukan migrasi seluruh organisasi. KEP mencantumkan mewajibkan proyek beralih secara default sebagai non-goal, dan tidak ada di v1.37 yang memaksa Anda.
- Cek apa yang menghasilkan KYAML di fleet Anda: jalankan kubectl version dan catat apa pun yang lebih lama dari 1.34.
- Coba kubectl get pada satu deployment live dengan -o kyaml, dan baca outputnya berdampingan dengan -o yaml yang setara.
- Pilih satu direktori manifest dan konversi dalam satu commit yang tidak berisi hal lain, memakai yamlfmt dengan versi yang di-pin.
- Tambahkan formatter sebagai pre-commit hook atau pengecekan CI yang gagal bila diff tidak kosong.
- Putuskan apakah Anda ingin kuberc menjadikan output get Anda default ke kyaml, dan biarkan default anggota tim lain.
# 1. What can produce KYAML in your fleet? Anything below 1.34 cannot.
kubectl version
# 2. Read the two formats side by side on one live object.
kubectl get deployment my-app -o yaml > /tmp/my-app.yaml
kubectl get deployment my-app -o kyaml > /tmp/my-app.kyaml
# 3. See what converting one committed manifest would change (diff, no write).
yamlfmt -o=kyaml -d k8s/app.yamlSetelah sebulan, ajukan pertanyaan konkret: apakah ada review yang menangkap kesalahan whitespace atau type coercion yang akan tersembunyi oleh format lama? Jika tidak, Anda mendapat repository yang lebih rapi dan tidak lebih, yang tetap hasil wajar untuk perubahan format.
KYAML yang mencapai Stable tidak mengubah satu pun manifest yang sudah Anda punya. Yang diberikannya adalah bentuk kanonik yang kebal whitespace dan selalu ber-quote, yang bisa dihasilkan kubectl dan ditegakkan formatter, dengan setiap file tetap terbaca oleh kubectl mana pun. Adopsi di tempat diff itu penting, pin tool yang menghasilkannya, dan pisahkan validasi schema, karena sintaks yang lebih aman belum tentu manifest yang benar.
Sumber dan bacaan lanjutan
- Blog Kubernetes: rilis Kubernetes v1.37, KYAML naik ke Stable
- Blog Kubernetes: cara pretty-print YAML Kubernetes sebagai KYAML
- Kubernetes enhancements: KEP-5295, KYAML
- Dokumentasi Kubernetes: kuberc, preferensi pengguna untuk kubectl
- google/yamlfmt: referensi file konfigurasi, formatter kyaml
- StrictYAML: kenapa implicit typing dihapus, masalah Norway

