deniz.in

Piyasalar

Hava durumu

Hava durumu yükleniyor

· kaynak dev.to (home feed)

Kubernetes 1.37 apply, null veya tilde olarak ayarlanan alanları sessizce düşürüyor: canlı test gösterdi

Kubernetes 1.37.0 API sunucusuna karşı yapılan uygulamalı bir test, null veya tilde değerli ConfigMap anahtarlarının apply sırasında kaybolduğunu ve sunucu tarafı dry-run'ın başarı bildirdiğini ortaya koydu. Yeni KYAML çıktı formatı bunu çözüyor.

Kubernetes 1.37 apply, null veya tilde olarak ayarlanan alanları sessizce düşürüyor: canlı test gösterdi

Canlı test ne gösterdi

dev.to üzerinde belgelenen uygulamalı bir deney, Kubernetes 1.37'nin belirsiz YAML ile karşılaştığında tam olarak ne yaptığını haritalıyor. Değeri ~ veya null olarak yazılmış bir ConfigMap uygulandığında, nesne o alan olmadan oluşturuluyor — yazarın bulabildiği kadarıyla hata, uyarı veya log kaydı yok. Buna karşılık, sürümün YAML belirsizliğine yönelik öne çıkan çözümü olan ve yeni稳定 hale gelen KYAML çıktı formatı, iddia edildiği gibi çalışıyor; ama yalnızca onu gerçekten kullanan manifestler için.

Neler test edildi

Kubernetes 1.37, KYAML'ı (KEP-5295) stable olarak sundu: ağır şekilde tırnaklanan ve süslü parantezlerle sınırlanan, daha katı bir YAML lehçesi; kubectl get -o kyaml bunu üretebiliyor ve kubectl apply girdi olarak kabul ediyor, çünkü altında yatan yapı geçerli YAML olmaya devam ediyor. Belirtilen amacı, YAML 1.1'in "Norveç sorunu"nu ortadan kaldırmak: tırnaksız bir NO, ülke kodundan adını alan bu sorunda "NO" stringi yerine false boolean'ı olarak ayrıştırılıyor.

dev.to yazarı duyuruya güvenmek yerine canlı bir cluster'ı gözlemlemek istedi. Önce bir kind cluster ayağa kaldırmak başarısız oldu: hem 1.37.0 hem de 1.36.1 node imajlarındaki kubelet, cgroup v1 hiyerarşisine sahip hostlarda başlamayı kesin olarak reddediyor ve bu 1.37'de yeni bir durum değil. Bunun yerine yazar, 1.37.0 kube-apiserver ve etcd 3.5.17 binary'lerini doğrudan süreçler olarak çalıştırdı; bu, kubelet veya bir container runtime olmadan gerçek bir apply ve get gidiş-dönüşü için yeterli oldu.

İki hata modu, biri sessiz

Her biri bir belirsiz değer içeren on üç elle yazılmış ConfigMap manifesti canlı sunucuya gönderildi. Onu doğrudan reddedildi: sekiz boolean'a benzeyen değer (NO, no, Yes, OFF, y, n, true, False) ve iki sayıya benzeyen değer (1.0 ve 010). ConfigMap.data, Go API'de map[string]string olarak tiplendiğinden decoder BadRequest döndürüyor — bir boolean'ı string alana zorlamayı reddediyor — ve hiçbir şey yazılmıyor. Can sıkıcı ama güvenli.

null ve ~ farklı davranıyor. Bunlar ne string ne de boolean, bu yüzden reddedilecek bir tip uyumsuzluğu yok. Decoder, null bir map değerini boş olarak değerlendiriyor ve anahtarı girişte düşürüyor. Nesne, o anahtar tamamen eksik şekilde oluşturuluyor — boş string olarak ayarlanmıyor, sadece yok.

Sunucu tarafı dry-run da kaçırıyor

Yazıya göre --dry-run=server boolean ve sayı reddetmelerini yakalıyor ve nesne oluşturulmadan aynı BadRequest'i döndürüyor. Null durumunu yakalamıyor: dry-run başarı bildiriyor ve zaten hasar görmüş nesneyi yazdırıyor. Manifestin data bloğunda iki anahtar vardı; çıktıda bir tanesi göründü. Alanları saymadığınız sürece hiçbir şey yanlış görünmüyor.

Kendi kodunuzdaki aynı kütüphane daha da kötü

Apiserver'ın katı tipli decode'u tüm ekosistem değil. client-go, sigs.k8s.io/yaml'ı herhangi bir controller'a veya CLI'ya taşıyor ve pek çok kod bunu doğrudan çağırıyor. Aynı değerleri map[string]string alanına unmarshal eden on satırlık bir Go programı, on dört değerden on birini değiştirirken hata döndürmedi: NO, no, OFF, n ve False string "false" olarak döndü (son durumda büyük/küçük harf normalleştirilerek), Yes ve y "true" olarak, null ve tilde boş string olarak, 1.0 "1" olarak ve 010 "8" olarak döndü, çünkü baştaki sıfır stringe dönüştürülmeden önce sekizlik olarak okundu. KYAML'ın var olma nedeni olan sessiz bozulma bu ve API sunucusunun içinde değil, uygulama kodunda yaşıyor.

KYAML ayakta duruyor

Aynı değerleri kubectl -o kyaml ile render edip sonucu Go unmarshaller'ından geçirmek hiçbir şeyi bozmadı, çünkü her değer tırnaklı. Düz JSON'da yasak olan bir yorum ve sondaki virgül içeren elle yazılmış bir KYAML manifesti canlı sunucuya sorunsuz uygulandı; sunucu dosyayı sıradan YAML olarak değerlendirdi. Yazar, formatın duyuruyla uyumlu olarak her kubectl sürümüyle çalıştığını doğruluyor. Bedeli boyut: aynı ConfigMap 548 byte YAML, 693 byte KYAML (yaklaşık %26 daha fazla) ve 762 byte JSON olarak render edildi.

Neden önemli

Tilde durumu tam da her şeyin başarı bildirmesi nedeniyle tehlikeli. Sunucu tarafı doğrulama, tip sistemi ve hatta CI'daki bir sunucu dry-run'u, bir alanı sessizce silen bir apply'ı onaylıyor; bu yüzden null veya tilde'yi bilinçli bir değer olarak kullanan manifestler hiçbir sinyal almıyor. Test ayrıca bir manifest ile saklanan veri arasında farklı katılıkta iki decoder olduğunu gösteriyor: apiserver'ınki tip uyumsuzluklarını yüksek sesle reddederken, kendi controller'larınızdaki sigs.k8s.io/yaml değerleri yerinde yeniden yazıyor. KYAML, her değeri makul bir boyut bedeliyle açık tırnaklara zorlayarak bu boşluğu kapatıyor ve hâlâ YAML olduğu için her kubectl ile kademeli olarak benimsenebilir. O zamana kadar, başıboş bir ~ her kontrolden geçen bir alan silme işlemi olmaya devam ediyor.

  • #kubernetes
  • #yaml
  • #kubectl
  • #configmap
  • #devops

İlgili yazılar