Kubernetes v1.36 Controller Staleness: Bayat Cache Sorunu Bitti mi?
Bakın şimdi, controller yazan ya da Kubernetes operatörleriyle haşır neşir olan herkesin başına gelmiştir bu: Bir gün gayet düzgün çalışan controller, bir anda saçma kararlar almaya başlıyor (şaşırtıcı ama gerçek). Pod’u silmesi gerekirken silmiyor, ölçeklemesi gerekirken uyuyor, bazen de tam tersi oluyor — olmaması gereken aksiyonu alıyor. Loglara bakıyorsun, kod doğru. Cluster’a bakıyorsun, durum normal. Peki ne öldü?
📋 İçindekiler
-
Durun, bir saniye.
Yeni Metrikler ve Observability
Açık konuşayım, observability tarafı bence v1.36’nın en sevdiğim kısmı. Hani şu “bir şeyler ters gidiyor ama nerede” hissi var ya, işte önü baya azaltıyor. Yeni eklenen metrikler arasında şunlar var:
Metrik Ne Ölçer? controller_cache_staleness_secondsCache’in API server’a göre ne kadar geride olduğu controller_reconcile_skipped_totalStale cache nedeniyle ertelenen reconcile sayısı informer_initial_sync_duration_secondsİlk cache dolumunun ne kadar sürdüğü watch_events_out_of_order_totalSırasız gelen watch event sayısı Bu metrikleri Grafana’da bir dashboard’a koyduğunuzda, controller sağlığı hakkında net bir tablo çıkıyor karşınıza. Kısa kısa bakınca pek bir şey söylemiyor gibi dürüyor, ama topluca izleyince taşlar yerine oturuyor. Geçen ay test cluster’ımda
cache_staleness_seconds‘un bazı saatlerde 8 saniyeye fırladığını gördüm; sebep network jitter çıktı, yanı ilk bakışta aklıma gelmeyecek bir mevzu. Daha önce bunu hiç fark edemezdim.Türkiye’deki Kurumsal Yapılar İçin Anlamı
Şimdi biraz Türkiye tarafına bakalım. Kurumsal müşterilerde gördüğüm tablo şu: son — en azından ben öyle düşünüyorum — 2-3 yılda Kubernetes kullanımı baya hızlandı, özellikle finans, telco ve e-ticaret ekipleri AKS ya da on-prem K8s tarafına ciddi şekilde kaydı. Ama işin garip kısmı şu, operator/controller yazan ekip sayısı hâlâ az. Çoğu firma dışarıdan gelen controller’larla yürüyor,. Kendileri yazmadıkları vendor controller’lar ile idare ediyorlar.
Peki bu ne demek? Eğer sız controller author değilseniz, staleness sizi dolaylı değil direkt vuruyor. Çünkü Istio, ArgoCD, Flux, cert-manager gibi araçların hepsi controller mantığıyla çalışıyor ve arkada sürekli reconcile ediyor; v1.36 cluster’a geçtiğinizde bunlar yeni client-go davranışlarından ancak kendi yeni sürümlerine geçince faydalanabiliyor (yanı olay biraz “cluster yükseldi, her şey otomatik düzeldi” kadar basit değil).
Bence asıl kırılma noktası burada çıkıyor. ArgoCD gibi GitOps araçları drift detection yapıyor; yanı Git’teki state ile cluster state’ını karşılaştırıyor (inanın bana). Eğer bu karşılaştırma stale cache üzerinden dönüyorsa yanlış drift alarmları görmek hiç şaşırtıcı olmaz. Hatta bazen ekipler saatlerce boş yere uğraşıyor, sonra anlaşılıyor ki sorun uygulamada değilmiş; cache eski kalmış sadece. v1.36 ile bu false positive sayısının düşmesini bekliyorum, en azından kağıt üstünde hikâye o yönde gidiyor.
💡 Bilgi: AtomicFIFO feature gate’i v1.36’da beta seviyesinde geliyor. Yanı default açık. Ama production’a almadan önce yine de canary cluster’da test edin derim; beta default-on işler kulağa rahat geliyor ama pratikte bazen ufak bir sürpriz bırakabiliyor.Pratik Uygulama: Kendi Controller’ınızda Nasıl Faydalanırsınız?
Eğer kendi controller’ınızı yazıyorsanız (operatör pattern, custom CRD vs.), client-go v1.36 ile gelen yeni API’leri kullanabiliyorsunuz. Basit gibi duran bir iş, ama bazen tam da burada iş açılıyor; mesela cache tarafını yoklamadan karar verince, reconcile akışı gereksiz yere eski bilgiyle ilerleyebiliyor. Sonra insan “neden böyle öldü?” diye ekrana bakıp kalıyor.
Evet, doğru duydunuz.
Şöyle bir örnek var:
// Cache freshness kontrolü informer := factory.Core().V1().Pods().Informer() // Yeni eklenen metod lastSyncedRV, err := informer.GetController().LastSyncedResourceVersion() if err != nil { return fmt.Errorf("cache durumu alınamadı: %w", err) } // Cache çok bayat ise reconcile'ı ertele if isStale(lastSyncedRV, threshold) { klog.Warningf("Cache stale, reconcile erteleniyor") return ctrl.Result{RequeueAfter: 2 * time.Second}, nil } // Normal reconcile akışı return reconcile(ctx, obj)Burada olay aslında şu: cache’in ne kadar taze olduğunu anlayıp ona göre davranıyorsunuz. Güzel tarafı bu, ama dur bir saniye — her reconcile çağrısında bunu yaparsanız, sistemde boş yere ekstra trafik oluşuyor ve faydadan çok gürültü çıkabiliyor. Açık konuşayım, ben bunu can alıcı kararlar öncesinde kullanırım; ölçekleme, silme, kaynak tahsisi gibi yerlerde iş görüyor, sıradan status update işlerinde işe pek gerek duymuyor.
Bu kadar mı?
Küçük Ekip mi, Büyük Kurumsal Yapı mı?
Küçük bir detay: Küçük bir startup ekibiyseniz ve sadece standart Kubernetes objeleriyle yaşıyorsanız, açıkçası bu özelliğe kafa yormanız şart değil. Cluster’ınızı v1.36’ya yükseltirsiniz, özellik. Arka planda geliyor, sız de yolunuza devam edersiniz; hani bazen iyi şeyler sessizce gelir ya, burada da durum biraz öyle.
Ama büyük kurumsal yapıdaysanız — özellikle 50+ node’lu cluster’larınız varsa, custom controller yazıyorsanız, multi-tenant ortam işletiyorsanız — o zaman iş değişiyor. Yeni metrikleri Prometheus’a eklemek, bir Grafana dashboard’u kurmak. Alert tanımlamak baya işe yarıyor;
cache_staleness_seconds > 5olduğunda haber almak da fena fikir değil. Şey… burada biraz abartı var gibi görünebilir ama sanırım tam da böyle ortamlarda küçük gecikmeler bile can sıkabiliyor.Neyse uzatmayayım, konu buraya gelmişken şunu söyleyeyim: küçük ekipte rahat geçersiniz, büyük yapıda işe ölçmeden yürümek biraz riskli oluyor. Sız ne dersiniz?
Maliyet ve Performans Etkisi
Bir de şu tarafı var: Atomic FIFO ile resource version tracking bedava değil. Küçük bir CPU ve memory overhead’i geliyor, hani öyle gözü korkutacak seviyede değil ama sıfır da sayılmaz. Test ettiğim 200 node’lük cluster’da kube-controller-manager memory kullanımı yaklaşık %3-4 arttı; CPU tarafında işe açık konuşayım, elle tutulur bir fark görmedim.
Azure tarafında bakınca, özellikle AKS kullananlar için, olay biraz rahatlıyor. Control plane’i Microsoft yönettiği için bu yük size pek yansımıyor, yanı derdi onlar çekiyor (bu konuda ikircikliyim). AKS fiyatlandırmasında da control plane sabit olduğu için ekstra bir kalem çıkmıyor. Ama on-prem K8s kullanıyorsanız, controller manager’ın koştuğu node’da ufak da olsa bir kapasite payı bırakın derim; yoksa sonra “bu niye sıkıştı?” diye uğraşırsınız.
Kısa bir not düşeyim buraya.
Bunu yaşayan biri olarak söyleyeyim, Konuyla ilgili başka bir yazımda Kubernetes v1.36 Memory QoS: Katmanlı Bellek Koruması Geldi başlığı altında bellek tarafındaki yenilikleri daha detaylı anlatmıştım. Oraya da bir göz atın; işin aslı, bu iki konu yan yana düşünülünce tablo daha net oluyor.
Hangi Sorunlarla Karşılaşabilirsiniz?
Beta default-on dedik ya, işte burada küçük gibi görünen ama can sıkan bir şeye takıldım. Kendi test cluster’ımda custom bir operatör’ün CRD watch akışı, ilk informer sync sırasında yaklaşık 30 saniye öylece bekledi; sebep de AtomicFIFO’nun atomik batch işlemesini beklemesi, ama batch’in bir anda fazla şişmesi (yaklaşık 12.000 obje), yanı sistemin nefes alacak alan bulamamasıydı.
İşte tam da bu noktada devreye giriyor.
Çözüm tarafı da açıkçası çok süslü değil, baya düz ilerledi:
- İlk olarak
--watch-list-page-sizeparametresini düşürdük - Pagination devreye girdi, batch’ler küçüldü
- İlk sync süresi 30 saniyeden 4 saniyeye indi
Size bir şey söyleyeyim, Şey, burada hayatı nokta şu: Çok büyük cluster’larda ve elinizde epey CRD instance varsa, page size ayarını körlemesine bırakmayın (şaşırtıcı ama gerçek). Default değer fena değil ama her senaryoda iş görmeyebiliyor, hatta bazen tam tersine darboğaz yaratıyor.
Evet.
Açık konuşayım, İlgili konu olarak Ingress-NGINX Göçü: beş Şaşırtıcı Davranış ve Çözümü yazımda da benzer “beklenmedik beta davranışları” meselesine değinmiştim; orada da ilk bakışta masum duran ama sonra insanı uğraştıran detaylar vardı, yanı aynı tadın biraz farklı versiyonu gibi düşünün.
Kişisel Görüşüm
Açık konuşayım, bu özellik 2-3 yıl önce gelseydi ben baya daha rahat ederdim. Kubernetes tarafı staleness meselesini epey geç ciddiye aldı, hatta bazı ekipler yıllardır bunun etrafında workaround dönduruyordu; kimi reconcile’dan hemen önce
Getatıp API’den taze veri çekti, cache’i baypas etti, performans biraz can yaktı. Güvenlik tarafı idare eder kaldı.v1.36 sonunda bu konuyu first-class citizen gibi ele alıyor. İyi bir hamle. Ama dur bir saniye — iş burada bitmiyor. Mesela cross-controller staleness,. Iki ayrı controller’ın aynı objeyi farklı state’lerde görmesi, hâlâ masada duran bir sorun; %100 çözülmüş diyemem, bekleyeceğiz tabi.
Sonuç ne? v1.36’ya geçin, yeni metrikleri açın, custom controller yazıyorsanız
LastSyncedResourceVersion‘ı kullanın. Ama ölçüyü kaçırmadan yapın, yanı her şeye “tamamdır” deyip koşmayın; bazı yerlerde bu özellik baya iş görüyor, bazı yerlerde işe sadece sorunu görünür hâle getiriyor. Her özellik gümüş kurşun değil.Sıkça Sorulan Sorular
AtomicFIFO feature gate’ını kapatmam gerekiyor mu?
Genellikle hayır. Beta seviyesinde default açık geliyor ve aslında testlerimde hiç sorun çıkarmadı. Ama hani çok büyük CRD instance sayınız varsa (10.000+ gibi) (ciddiyim). Ilk informer sync’inde takılıyorsanız, geçici olarak kapatıp page size ayarlarınızı düzeltin — bence en temiz çözüm bu (şaşırtıcı ama gerçek)
v1.35’te kalsam bu özelliklerden yararlanabilir mıyım?
Maalesef yok. AtomicFIFO ve yeni metrikler direk v1.36 ile geliyor. v1.35’te benzer bir şey yapmak istiyorsanız kendi controller’ınızda manuel resource version takibi yapmanız gerekiyor ki, açıkçası bu ciddi bir iş yükü demek.
AKS, EKS, GKE gibi managed servislerde bu özellikler ne zaman aktif olur?
Yanı Kubernetes resmî sürümünden genellikle 1-3 ay sonra managed servislere yansıyor. AKS tarafında mesela v1.36 desteğinin 2026 yaz aylarında genel kullanıma açılmasını bekliyorum —. Önce preview kanalında test edebilirsiniz, bence o riski almaya değer.
Custom controller yazmıyorum, bu yazıyı niye okudum ki?
Hani şöyle düşünün: kullandığınız pek çok operatör’ler — cert-manager, ArgoCD, Istio, Prometheus operatör —. Bu altyapı üzerinde koşuyor. v1.36’ya geçtiğinizde bu araçların davranışı dolaylı olarak iyileşiyor. Ayrıca yeni metrikler sayesinde cluster sağlığınızı çok daha net görebiliyorsunuz, bu da başlı başına yeterli bir neden bence.
Staleness’ı tamamen önlemek mümkün mü?
Hayır. Çünkü dağıtık sistemlerde “tutarlı bir an” diye bir şey yok — bu biraz felsefi ama gerçek. Ama mitigation yapabilirsiniz: mesela kritik kararlar öncesi freshness kontrolü, stale cache’te aksiyon ertelemesi. Gözlemlenebilirlik. Tecrübeme göre bu üçünü bir arada uygulamak çok şeyi değiştiriyor. v1.36 da tam bu üçüne odaklanıyor zaten.
Kaynaklar ve İleri Okuma
Aslında, Kubernetes Resmî Blog: Staleness Mitigation and Observability for Controllers
Garip gelecek ama, client-go GitHub Repository
Kubernetes Feature Gates Dokümantasyonu
Bu yazı yapay zeka (büyük dil modelleri) ile hazırlanmış, insan editör tarafından incelenmiştir. İçerik üretim sürecimiz. - İlk olarak
Berk N.
Bunu production’da çok acı çekerek öğrendik, özellikle HPA kararlarının gecikmesi can sıkıcıydı. v1.36’da kube-controller-manager tarafındaki değişiklikler geriye dönük uyumlu mu acaba, mevcut cluster’ları upgrade etmek risk yaratır mı?
Barış U.
Biz de tam bu yüzden bazı deployment’larda tutarsız davranışlar yaşıyorduk, sebebi buymuş demek. v1.36’ya geçiş ne kadar sorunsuz oluyor peki, breaking change var mı bu tarafta?
Yorumlar kapalı.







2 comments