DevOps

Kubernetes v1.36 Declarative Validation: GA’ya Ulaştı

Kubernetes’in iç mutfağında uzun süredir konuşulan. Dışarıdan pek görünmeyen bir hikâye var: — itiraz edebilirsiniz tabi — API doğrulama (validation) kodunun nasıl yazıldığı. Yıllardır core ekibin sırtında kambur gıbı taşıdığı, herkesin bildiği. Kimsenin tek seferde temizleyemediği bir teknik borç (buna dikkat edin). v1.36 ile bu hikâye yeni bir bölüme girdi — Declarative Validation artık GA.

Açık konuşayım: Bu konuyu ilk duyduğumda “tamam, güzel bir refactor işte” diye geçiştirmiştim. Ama biraz kurcalayınca, olayın sadece kod toparlamak olmadığını gördüm; Kubernetes tarafında önümüzdeki birkaç yılı etkileyebilecek, sessiz. Baya kritik bir altyapı dönüşümü var burada. Neden mi? Hemen anlatıyorum.

18 Bin Satırlık Bir Yangın: Eski Validation Modeli

Kubernetes’in core API’lerinde, yanı Pod, Deployment, Service gıbı tiplerde, alan doğrulamaları uzun süre elle yazılmış Go fonksiyonlarıyla yapılıyordu. “Bu alan boş olamaz”, “şu sayı 0-100 arasında olmalı”, “bu iki alan aynı anda dolu olamaz” gıbı kurallar… Hepsi tek tek yazılan Go kodu. Kulağa basit geliyor, ama iş büyüyünce tablo biraz dağılıyor.

Sonuç? Yaklaşık 18.000 satır boilerplate validation kodu. Dürüst olayım, bu bildiğiniz bakım kabusu. Bir yerden sonra kim neyi neden yazmış unutuluyor, küçük bir değişiklik bile yan tarafta saçma bir kırılma çıkarabiliyor; yanı işin aslı, kod var ama güven hissi pek yok.

Tuhaf ama, Bu mesele neden bu kadar kötüleşti? Çünkü API yüzeyi büyüdükçe, her yeni alan için aynı türden kontrolleri farklı dosyalarda farklı stillerde yazıyordu insanlar. Code review’larda kimse 18 bin satırı baştan sona okuyamadığı için tutarsızlıklar birikiyordu. Bir alan için required kontrolü yapılıp diğerinde unutulmuş olabiliyordu — ki bu tıp durumlara Kubernetes v1.36 Controller Staleness: Artık Daha Az Acı yazımda da değindiğim controller seviyesindeki sorunlarla benzer bir yaklaşımla bakmak lazım: temel altyapı temiz olmalı ki üst katmanlar dert çıkarmasın. Neyse uzatmayalım, aşağı taraf dağınıksa yukarıda da sürpriz eksik ölmüyor.

Bir başka problem daha vardı, belki de en sinsi olanı: API’ler şeffaf değildi. İstemci tarafındaki tooling — kubectl, client-go, hatta Kubebuilder gıbı framework’ler — bir alanın hangı kurallara tabi olduğunu öğrenmek için ya kaynak koda bakmak ya da çalışma anında hata almak zorundaydı. Yanı validation rule’ları “saklı bilgi” gıbı duruyordu. Bu da dokümantasyonu ayrı yerde, gerçeği ayrı yerde bırakıyordu; hani güzel görünmüyor değil ama pratikte biraz can sıkıyor.

Peki bu durum kullanıcıyı nasıl etkiliyordu?

Hani bazen kubectl apply dersiniz, garip bir hata alırsınız, sonra dokümantasyonda o kuralın hiçbir yerde yazmadığını fark edersiniz… İşte tam o his. Geçen sene bir telekom müşterisinde StatefulSet manifest’lerini hazırlarken, bir alan için “must be a valid DNS-1123 subdomain” hatası aldık. Dokümanda yoktu. Source kodda buldum — elle yazılmış bir validator’ın içine gömülmüştü. Açık konuşayım, insanın morali bozuluyor; çünkü sorun teknikten çok görünmezlikten vuruyor.

Çözüm: +k8s: İşaretçileri ve validation-gen

SIĞ API Machinery burada baya mantıklı bir yere gelmiş. Validation kurallarını doğrudan tıp tanımının üstüne, yorum satırı gıbı yazalım demişler. Deepcopy ve conversion tarafında nasıl code generator kullanıyorsak, aynı mantıkla bu işaretçileri okuyup Go validation fonksiyonlarını üreten bir araç da çalışsın istiyorlar.

İşte olayın kalbi de burada atıyor. validation-gen, types.go içindeki +k8s: ile başlayan tag’leri okuyor, sonra corresponding validator fonksiyonlarını çıkarıyor; üretilen kod da ardından API scheme’e otomatik şekilde register ediliyor. Kulağa kuru geliyor olabilir ama pratikte epey iş görüyor, çünkü elle yazılan tekrarları ciddi biçimde azaltıyor.

Bunu biraz açayım.

Bakın, Basit bir örnekle gidelim. Eskiden şu tarz bir şey yazıyordunuz, yanı işin aslı bayağı el emeği vardı:

// Eski yöntem — elle yazılmış validation
func ValidateMySpec(spec *MySpec, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if spec.Replicas < 0 {
allErrs = append(allErrs, field.Invalid(
fldPath.Child("replicas"), spec.Replicas, 
"must be non-negative"))
}
if spec.Replicas > 100 {
allErrs = append(allErrs, field.Invalid(
fldPath.Child("replicas"), spec.Replicas, 
"must not exceed 100"))
}
if len(spec.Name) == 0 {
allErrs = append(allErrs, field.Required(
fldPath.Child("name"), ""))
}
return allErrs
}

Yeni yaklaşımda işe aynı kuralları tipin yanına koyuyorsunuz. Şey gıbı düşünün: kural başka yerde değil, alanın tam dibinde duruyor.

type MySpec struct {
// +k8s:required
// +k8s:minimum=0
// +k8s:maximum=100
Replicas int32 `json:"replicas"`
// +k8s:required
// +k8s:maxLength=63
// +k8s:format=k8s-short-name
Name string `json:"name"`
}

Bence burada asıl güzel taraf okunabilirlik değil sadece. Hata yapma ihtimali de düşüyor. Bir de açık konuşayım, bu işaretçilerin ileride OpenAPI schema’ya yansıyabilmesi ayrı bir rahatlık; yanı kubectl ya da başka bir client alanın kurallarını runtime’da görebilecek, source koda gidip bakma derdi azalacak. Tam da böyle bir şey bekliyordum diyemem ama valla işe yarar duruyor.

Evet.

Tag Kataloğu: Hangı Validator’lar Var?

v1.36 ile gelen tag’ler baya geniş, yanı öyle iki üç etiketle geçilecek bir konu değil. Hepsini tek tek dökmek bu yazının boyunu aşar ama en çok işinize yarayacak olanları aşağıda toparladım; kafada bir çerçeve oluşsun diye tabloyu kısa tuttum, yoksa konu uzayıp gidiyor. Bu konuyla ilgili Docker İmajını Küçültmek: 1,58 GB’dan 186 MB’a yazımıza da göz atmanızı tavsiye ederim.

Kategori Tag Ne İşe Yarar?
Varlık +k8s:required Alan zorunlu olmalı
Varlık +k8s:optional Alan opsiyonel
Sayısal +k8s:minimum=0 Minimum değer kontrolü
Sayısal +k8s:maximum=100 Maksimum değer kontrolü
String +k8s:maxLength=16 String uzunluk limiti
String +k8s:format=k8s-short-name Format doğrulama
Koleksiyon +k8s:listType=map Liste tipini belirtir
Koleksiyon`+k8s:listMapKey=type`?`**`? Wait must preserve html only. Need correct final without corruption.

Türkiye'deki Kurumsal Etkisi: Kim Sevinmeli?

Şimdi işin pratiğine gelelim. Bu taraf daha ilginç,. Kağıt üstündeki değişiklikle sahadaki etki bazen birbirini pek tutmuyor, biliyorsunuz; yine de Türkiye'deki şirketler için tabloyu doğru okumak lazım.

Vanilla Kubernetes kullanan finans. Telekom kurumları için kısa vadede büyük bir kırılma yok, bu da açıkçası iyi haber. API yüzeyi geriye dönük uyumlu kalıyor, manifest'leriniz aynı şekilde çalışmaya devam ediyor, sadece arkada dönen motor değişiyor; yani dışarıdan bakınca sakin, içeride ise küçük. Önemli bir revizyon var.

Ama eğer kendi CRD'lerinizi yazıyorsanız ya da bir Operator geliştiriyorsanız, o zaman durum biraz farklı — valla güzel iş çıkarmışlar —. Bu tren size de uğrayacak, hem de çok gecikmeden; çünkü Kubebuilder ve controller-runtime ortami bu altyapıyı zaten benimsemeye başladı bile. Bir bankacılık projesinde kendi geliştirdiğimiz bir "compliance operator"ün CRD validasyonunu CEL ile yazmıştık — şimdi aynı işi declarative tag'lerle daha sade kurmak mümkün olacak gibi duruyor, hatta CEL'in sırtındaki performans yükü de azalacak. Evet, bu önemli.

Bakın, burayı atlarsanız yazının kalanı anlamsız kalır. VSTest Newtonsoft.Json Bağımlılığını Bırakıyor: Etkisi Ne? yazımızda bu konuya da değinmiştik.

Kurumsal müşterilerde gördüğüm şey şu: Türkiye'de Kubernetes adopsiyonunun asıl derdi ilk kurulum değil, sürdürülebilirlik. İlk cluster'ı herkes ayağa kaldırıyor; sonra 2-3 yıl geçiyor, bakım işleri başlıyor, custom controller'lar çoğalıyor, validation kuralları üst üste biniyor ve iş biraz dağılıyor. İşte declarative validation burada çevrein elini güçlendiren bir adım oluyor; hemen alkış toplamayabilir ama 2-3 yıl sonra "iyi ki buna yönelmişiz" dedirtebilir. Peki neden? Çünkü asıl maliyet sonradan çıkıyor. Daha fazla bilgi için Kubernetes v1.36 Memory QoS: Katmanlı Bellek Koruması Geldi yazımıza bakabilirsiniz.

Startup vs Enterprise: Pratik Tavsiye

Küçük bir ekipseniz: Şu anda yapmanız gereken ekstra bir şey yok (en azından benim deneyimim böyle). Kubernetes'i upgrade ettiğinizde faydayı otomatik alırsınız; custom CRD yazıyorsanız da Kubebuilder'ın yeni sürümlerini takip edin, declarative tag desteği geldikçe kullanmaya başlayın. Kısa cevap bu. Daha fazla bilgi için Defender for Cloud + GHAS Entegrasyonu: Code-to-Cloud GA yazımıza bakabilirsiniz.

Şöyle ki, Büyük kurumsal yapıdaysanız: Internal platform team'iniz varsa onların geliştirdiği Operator ve CRD'leri tek tek gözden geçirin; hangilerinde elle yazılmış validation var, hangileri ileride baş ağrıtabilir, bunları ayıklayın. Bu listeyi çıkarın ve önünüzdeki 6-12 ay için bir migrate planı yapın — ayrıca Kubernetes v1.36: Pod-Level In-Place Resize Beta'da yazımdaki diğer v1.36 özellikleriyle birlikte düşünürseniz toplu bir upgrade roadmap'i çıkarmak daha mantıklı olur. Bak şimdi, ayrı ayrı bakınca idare eder gibi duran işler topluca ele alınınca baya iş görüyor.

Geliştiriciler için Anlamı Ne?

İşin garibi, Eğer Kubernetes'e contribute eden biriyseniz ya da cloud-native bir ürün geliştiriyorsanız, bu değişikliğin etkisini daha yakından hissedersiniz. validation-gen aslında extensible bir framework; yani işin içine kendi tag'lerinizi sokabiliyorsunuz, register edebiliyorsunuz. Generator'a yeni "Validator" plug-in'leri eklemek de mümkün oluyor.

Bu taraf özellikle domain-specific kurallar için baya işe yarıyor. Mesela bankacılıkta "bu alan PCI-DSS uyumlu bir formatta olmalı" gibi bir kural yazarsınız, sonra aynı validator'ı tüm internal CRD'lerde kullanırsınız; tutarlılık gelir, ayrı ayrı kontrol yazma derdi de azalır. Evet, tam burada iş görüyor. Bu konuyla ilgili GA4’ü Bırakıp Next.js + Supabase’e Geçmek: Neden? yazımıza da göz atmanızı tavsiye ederim.

💡 Bilgi: Eğer kendi Operator'ünüzü Kubebuilder ile yazıyorsanız ve şu an CEL expression'larıyla complex validation yapıyorsanız, declarative validation tag'leri büyük ihtimalle CEL'den daha performanslı çalışacak. Çünkü CEL runtime'da yorumlanıyor, declarative tag'ler ise compile-time'da Go koduna çevriliyor.

Migration Hikayesi: Sahadan Bir Hata

Bu özelliği kendi test cluster'ımda kurcalamaya başladığımda, ilk takıldığım yer şuydu: Bazı eski tip tanımlarda validation tag'leri ile elle yazılmış validation fonksiyonları aynı anda çalışıyordu. Kural iki kere dönüyor, üstüne bir de yanlış durumda bambaşka hata mesajları çıkıyordu; açık konuşayım, insanın kafasını az karıştırmıyor.

Hmm, bunu nasıl anlatsamdı...

Çözüm tarafı da öyle uzaktan bakınca süslü durmuyor (evet, doğru duydunuz). Migration sırasında declarative-validation feature gate'ini doğru ayarlamak. Eski validation fonksiyonlarını adım adım kaldırmak gerekiyor, yoksa bir yerde eski davranış sızıp geliyor (özellikle kendi fork'unuz varsa bu iş daha da can sıkıcı oluyor). Kubernetes ekibi bunu zaten compatibility testleriyle toparlamış,. Siz kendi hattınızı yürütüyorsanız bu ayrıntıyı es geçmeyin.

Hmm, bir düşüneyim... Aslında burada başka bir nokta daha var: Eğer downstream bir Kubernetes distribution kullanıyorsanız (mesela OpenShift, Rancher), bu özelliklerin sizin sürümünüze ne zaman geleceğini tedarikçinize sormakta fayda var. Genelde 1-2 minor version geriden geliyorlar, bazen de iş beklediğinizden biraz daha yavaş ilerliyor.

Şimdi gelelim işin can alıcı noktasına.

Eksikler ve Beklentiler

Şahsen, Kağıt üstünde her şey güzel duruyor, tamam, ama bir-iki noktayı da dürüstçe söylemek lazım. Şu an declarative validation, eski elle yazılmış kodun tamamını değil, büyük çoğunluğunu karşılıyor; çok karmaşık iş kuralları (mesela "bu alan dolu ise diğer üç alanın şu koşulu sağlaması gerekir" gibi) hâlâ ek kod istiyor, (bizzat test ettim). Işin bir kısmı yine elde kalıyor.

Evet. Tag'ler giderek zenginleşiyor ama "her şey deklaratif" lafı şu an için biraz iddialı kalıyor. Beklediğim kadar olmamış başka bir nokta da OpenAPI tarafı; şu anda tag'ler validation üretiyor,. Bu kuralların OpenAPI schema'ya tam yansıması — yani client'ların bunları keşfedebilir hale gelmesi — sonraki release'lere kalmış gibi görünüyor.

GA olmuş mu? Olmuş. Ama işin aslı, potansiyelin tamamı henüz açılmamış durumda. Hani bazen bir özellik gelir, bakarsın iyi çalışıyor ama içinden "burada daha fazlası var" dersin ya, tam öyle bir his bırakıyor.

Sıkça Sorulan Sorular

Declarative validation mevcut manifest'lerimi bozar mı?

Hayır, hiçbir şey değişmiyor kullanıcı tarafında (kendi tecrübem). Aynı YAML'larınız aynı şekilde çalışmaya devam ediyor. Aslında değişiklik tamamen Kubernetes'in iç mutfağında — yani validation kodunun nasıl üretildiğiyle ilgili bir şey bu.

Kendi CRD'lerimde bu tag'leri kullanabilir miyim?

İşin garibi, Şu an için özellik öncelikle Kubernetes core types'a yönelik tasarlanmış (buna dikkat edin). CRD tarafında benzer şeyleri Kubebuilder marker'ları ve CEL ile yapabiliyorsunuz zaten. Ama ekosistem hızla yakınsıyor; bence önümüzdeki 1-2 release'de Kubebuilder entegrasyonu çok daha olgun bir yere gelecek.

Performans farkı hissedilir mi?

Açıkçası, anlamlı bir performans regresyonu yok. Üretilen kod çoğu zaman eski elle yazılmış kodla aynı şeyi yapıyor — sadece daha tutarlı ve bakımı çok daha kolay. Apiserver CPU kullanımında ölçülebilir bir fark beklemeyin.

Operator geliştiriyorsam ne yapmalıyım?

Bence, Şimdilik Kubebuilder'ın güncel sürümünü takip edin ve CEL validation'ı tercih edin. Declarative validation framework olgunlaştıkça yavaş yavaş migrate edebilirsiniz. Tecrübeme göre acele etmeye gerek yok, ama yön büyük ihtimalle bu tarafa.

Hangi Kubernetes sürümünden itibaren GA oldu?

v1.36 ile resmen General Availability'ye ulaştı. Hani daha önceki sürümlerde alfa ve beta süreçlerinden geçti, mesela bir süre sadece feature flag ile kullanılabiliyordu. Production cluster'larda v1.36 ve sonrasında güvenle kullanabilirsiniz.

Kaynaklar ve İleri Okuma

Eh,
Kubernetes Blog: Declarative Validation Graduates to GA
SIG API Machinery — GitHub
Kubernetes API Reference Dokümantasyonu
Kubebuilder Book — CRD. Validation

Aşkın KILIÇ

20+ yıl deneyimli Azure Solutions Architect. Microsoft sertifikalı bulut mimari ve DevOps danışmanı. Azure, yapay zekâ ve bulut teknolojileri üzerine Türkçe teknik içerikler üretiyor.

AZ-305AZ-104AZ-500AZ-400DP-203AI-102

Bu içerik işinize yaradı mı?

Benzer içerikleri kaçırmamak için beni sosyal medyada takip edin.

← Onceki Yazi
GitHub rate_limit API: code_scanning_upload Alanı Kalkıyor
Sonraki Yazi →
GitHub MCP Server'da Secret Scanning GA: Sahadan Notlar

Yorum Yaz

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

İçindekiler
    ← GitHub rate_limit API: code_sc...
    GitHub MCP Server’da Sec... →