Skip to main content
BlogDevOps

KYAML di Kubernetes 1.37: Subset YAML Stable dan kubectl -o kyaml

KYAML menjadi Stable di Kubernetes v1.37. Apa yang dipaksakan formatnya, versi kubectl yang mendukung, dan cara memakai kubectl get -o kyaml serta yamlfmt di CI.

Matthews Wong

Software Engineer

Oktober 202611 menit baca
KYAML di Kubernetes 1.37: Subset YAML Stable dan kubectl -o kyaml

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.

AspekYAML block styleJSONKYAML
StrukturDitentukan oleh indentasiKurung kurawal dan kurung sikuKurung kurawal dan kurung siku, indentasi hanya kosmetik
Nilai stringBiasanya tanpa quote, jadi type coercion mungkin terjadiSelalu double-quoteSelalu double-quote
KomentarBolehTidak didukungBoleh
Trailing commaTidak berlakuDitolakBoleh, dan selalu dihasilkan
KeyTanpa quoteWajib di-quoteTanpa quote kecuali tidak jelas aman
Header dokumenOpsionalTidak adaBaris 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: NO

Baca 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 KubernetesStage KYAMLCara memakainya
v1.34AlphaSet KUBECTL_KYAML=true, lalu jalankan kubectl get dengan -o kyaml
v1.35BetaAktif secara default, tetapi Anda tetap memberi -o kyaml; mengatur variabel ke false mematikannya
v1.37StableGate dihapus dan format selalu tersedia; conformance testing selesai
Versi mana punInputFile 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: kyaml

Bentuk 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 directory

Mana 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.

  1. Cek apa yang menghasilkan KYAML di fleet Anda: jalankan kubectl version dan catat apa pun yang lebih lama dari 1.34.
  2. Coba kubectl get pada satu deployment live dengan -o kyaml, dan baca outputnya berdampingan dengan -o yaml yang setara.
  3. Pilih satu direktori manifest dan konversi dalam satu commit yang tidak berisi hal lain, memakai yamlfmt dengan versi yang di-pin.
  4. Tambahkan formatter sebagai pre-commit hook atau pengecekan CI yang gagal bila diff tidak kosong.
  5. 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.yaml

Setelah 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.

FAQ

Pertanyaan Umum

Jawaban singkat untuk pertanyaan yang paling sering diajukan pembaca tentang topik ini.

Apa itu KYAML di Kubernetes?

KYAML adalah subset YAML yang lebih aman dan tidak ambigu, dirancang untuk Kubernetes, dan setiap file KYAML adalah YAML yang valid. Ia selalu memberi double-quote pada string, memakai kurung kurawal untuk map dan kurung siku untuk list, membolehkan komentar dan trailing comma, serta diawali header tiga tanda hubung. Ia tidak menggantikan YAML.

Kubernetes versi berapa yang membuat KYAML Stable?

KYAML naik ke Stable di Kubernetes v1.37, dengan conformance testing selesai dan kubectl get -o kyaml kini Stable. Sebelumnya Alpha di v1.34 dan Beta di v1.35. Pekerjaan ini dilacak di KEP 5295 di bawah SIG CLI.

Bagaimana cara memakai kubectl get -o kyaml?

Jalankan kubectl get deployment my-app -o kyaml di Kubernetes 1.35 atau lebih baru. Di 1.34 Anda harus lebih dulu mengatur KUBECTL_KYAML=true. Arahkan output ke file bila ingin menyimpannya.

Apakah saya harus menulis ulang manifest lama sebagai KYAML?

Tidak. Release notes v1.37 menyatakan manifest, tooling, dan pipeline yang ada tidak perlu diubah. Karena KYAML adalah YAML yang valid, kubectl versi mana pun bisa membaca file KYAML, dan YAML block style tetap berfungsi.

Apakah KYAML memperbaiki Norway bug di YAML?

Di file yang ditulis sebagai KYAML, ya, karena setiap string di-double-quote sehingga tidak bisa di-coerce menjadi boolean atau angka. Ia tidak melindungi manifest block style tulisan tangan yang punya nilai tanpa quote. KEP 5295 sendiri mencantumkan rasa aman palsu sebagai risiko, karena KYAML tidak memperbaiki YAML itu sendiri.