Kubernetes v1.36: Workload-Aware Scheduling Yeni Boyutta
Geçen hafta bir telekom müşterimizde AI eğitim cluster’ı tasarlarken ekipten genç bir mühendis şunu sordu: “Hocam, 64 GPU’lu bir training job’ı Kubernetes’e atıyoruz, neden bazen 60 pod ayağa kalkıp 4’ü pending’de kalınca tüm iş çakılı kalıyor?”. Klasik mesele. Klasik cevap da belli: gang scheduling yoksa, ya hep ya hiç mantığı bir yerde duvara tosluyor.
İşte tam burada Kubernetes v1.36 ile gelen workload-aware scheduling güncellemeleri devreye giriyor. v1.35’te temel atılmıştı, şimdi iş biraz daha oturmuş durumda. Lafı gevelemeden söyleyeyim — bu sürüm, batch ve AI/ML iş yüklerini Kubernetes’te düzgün koşturmak isteyenler için baya önemli bir dönemeç.
Kısa bir not düşeyim buraya.
Önce Şu Workload API’yi Doğru Anlayalım
v1.35’te Workload nesnesi hem şablon hem de runtime state’i aynı yerde tutuyordu. Yanı aynı obje hem “ben böyle bir grup pod istiyorum” diyordu, hem de “şu an grubun 3 üyesi running, 1’i pending” bilgisini taşıyordu. Kağıt üstünde sade dürüyor ama pratikte… eh, işler öyle yürümüyor.
Hani, Şöyle düşünün: 500 replikalı bir batch job’ınız var. Her status update’i tek bir Workload nesnesine yazmaya kalkarsanız, etcd tarafında write contention görmeniz işten bile değil. Logosoft’ta bir bankacılık projesinde benzer bir mimarı yüzünden API server’ın yığıldığını görmüştük — o yüzden bu ayrıştırma bana oldukça mantıklı geliyor.
Kısa bir not düşeyim buraya.
v1.36’da gelen yeni model şu: Workload artık sadece bir static template. PodGroup işe runtime’da yaşayan, replika başına shard edilebilen ayrı bir nesne. API grubu da değişti: scheduling.k8s.io/v1alpha2. v1alpha1 büyük ölçüde rafa kalktı, yanı eski yamaları bir gözden geçirmek lazım.
Yeni Workload Tanımı Nasıl Görünüyor?
apiVersion: scheduling.k8s.io/v1alpha2
kind: Workload
metadata:
name: training-job-workload
namespace: ml-prod
spec:
podGroupTemplates:
— name: workers
schedulingPolicy:
gang:
# 4 pod aynı anda çalışamıyorsa hiçbiri başlamaz
minCount: 4
Bu template’ten controller’lar (mesela Job controller) runtime’da PodGroup instance’ları üretiyor. Her PodGroup kendi status’ünü ayrı tuttuğu için yatay ölçeklenme daha rahat hâle geliyor. Scheduler artık Workload’u sürekli watch etmek zorunda da değil — doğrudan PodGroup’a bakıyor. Küçük gibi duran bu detay aslında scheduler’ın CPU yükünü ciddi azaltan bir hamle.
Gang Scheduling: Ya Hep Ya Hiç Mantığı
Araya gireyim: AI/ML eğitimi yapanların en iyi bildiği konu bu zaten. Distributed training’de 8 worker’dan biri ayağa kalkamazsa, bir düşüneyim… diğer 7’si boş yere CPU/GPU yakıyor. Default-scheduler işe pod pod bakıp kaynak varsa atadığı için bu senaryoda patlıyor.
v1.36’daki PodGroup scheduling cycle, tam olarak bunu toparlamak için tasarlanmış. Scheduler artık PodGroup’u atomik bir blok gibi değerlendiriyor. Yanı ya grup üyelerinin hepsi için yeterli node bulunuyor. Topluca bind ediliyor, ya da hiçbiri yerleşmiyor; beklemede kalıyorlar. Daha fazla bilgi için Daha fazla bilgi için
Küçük Startup mı, Büyük Enterprise mi?
Açık konuşayım; eğer elinizde sadece 3-5 node’lük basit bir cluster varsa ve batch workload’larınız çok karmaşık değilse bu özelliklerle uğraşmaya gerek olmayabilir.
Default scheduler çoğu zaman işinizi görür.
Volcano kurmak da şart değil genelde.
Ama 50+ node’lu, çok kiracılı, AI training ile inference’ı aynı cluster’da çalıştırdığınız bir ortam varsa — v1.36’yı yakından takip edin derim.
Stabil hâle geldiğinde (muhtemelen v1.,38 civarı beta çizgisine yaklaşır) ciddi fayda sağlayacak gibi dürüyor.
Emin değilim. Sanırım yön o tarafa gidiyor.
Tam da öyle.
Job Controller Entegrasyonu: İlk Adım
Burası biraz “başlangıç var. Yol uzun” hissi veriyor doğrusu.
Bu sürümle birlikte Job controller, yeni Workload API ile entegrasyonun ilk fazını sunuyor; yanı standart bir batch/v1 Job tanımladığınızda controller arka planda Workload + PodGroup nesnelerini üretebiliyor (feature gate açık olmak şartıyla).
Bu entegrasyon henüz tüm Job özelliklerini kapsamıyor.
IndexedJob ve completionMode=Indexed gibi varyasyonlar için ayrı fazlarda destek gelecek.
Yanı karmaşık Job pattern’leri kullanıyorsanız test ortamında deneyin; prod’a acele etmeyin.
Peki neden?
Çünkü bazı köşe durumları hâlâ netleşmiş değil.
Karşılaştırma Tablosu : v1.35 vs v1.36
| Özellik | v1.35 | v1.36 |
|---|---|---|
| API versiyonu | v1alpha1 | v1alpha2 (breaking) |
| Workload yapısı | Template + runtime tek nesnede | Workload (template) + PodGroup (runtime) ayrı |
| Status sharding | Yok | Per-replica shard |
| Topology-aware | Yok | İlk tekrar (alpha) |
| Workload-aware preemption | Yok | İlk iterasyon (alpha) |
| DRA / ResourceClaim | Pod seviyesinde | PodGroup seviyesinde |
| Job controller entegrasyonu | Yok | Faz 1 |
Maliyet Tarafı: TL Bazında Bir Düşünelim
Azure’da NC A100 v4 serisi bir node’un saatlik fiyatı hatırı sayılır rakamlarda — döviz kuruyla TL’ye çevirdiğinizde aylık olarak ciddi bir kalem olabiliyor. Bir müşterimde 4 node’lük A100 cluster’ı vardı, ayda altı haneli faturalar görüyorduk.
Eğer gang scheduling olmadan training job’larınızın %15-20’si “yarısı ayakta, yarısı pending” şeklinde takılıyorsa, o boşa giden GPU saatlerini direkt çöpe atmış gibi düşünün. Workload-aware scheduling’in olgunlaşması, bu tip kayıpları azaltacak. Bir arkadaşımın firmasında benzer bir optimizasyon sonrası aylık GPU faturasında belirgin düşüş olduğunu paylaşmıştı — abartmadan söylüyorum, fark ciddiydi.
Pratik Adımlar: Nereden Başlayayım?
Eğer bu özellikleri test etmek istiyorsanız önerim şu sıra:
- Kubernetes v1.36 ile bir test cluster ayağa kaldırın (kind veya küçük bir AKS preview cluster yeter).
WorkloadAwareSchedulingfeature gate’ini açın.- Önce basit bir Job + Workload + PodGroup kombinasyonu deneyin, 4-5 replikalı.
- Sonra preemption testi yapın: düşük öncelikli grup ayağa kaldır, üstüne yüksek öncelikli olan.
- Logları izleyin, scheduler event’lerine bakın.
- Topoloji constraint’lerini ekleyin ve node affinity ile etkileşimi gözlemleyin.
Ben kendi lab ortamımda ilk denediğimde scheduler pod’unda “PodGroup CRD bulunamadı” hatası aldım. Sebep: feature gate’ini açtım ama CRD’leri kurmayı unuttum. kubectl apply -f scheduling.k8s.io_v1alpha2_crds.yaml çalıştırınca düzeldi. Belgelerde bu adım net belirtilmiyor, dikkat edin.
Eksik Yanları da Konuşalım
(Yazının başında dedim ya — sadece öven yazı AI işareti.) Bu özelliklerin eksik tarafları da var. Önce şunu söyleyeyim: observability tarafı henüz ham. PodGroup’un neden schedule olmadığını anlamak için scheduler loglarına bakmak gerekiyor; güzel metric’ler yok. Prometheus’ta gang scheduling kuyruğunu izleyecek doğru düzgün bir exporter da yok şimdilik.
Sıradaki mesele: çoklu scheduler senaryoları belirsiz. Eğer cluster’ınızda hem default scheduler hem custom scheduler (mesela Volcano) varsa, hangisinin PodGroup’u sahipleneceği konusunda kafa karışıklığı çıkabilir. Production’a geçmeden önce bu sınır durumlarını test edin.
Üçüncüsü — ve bence en önemlisi — Kubernetes’in Pod-Level In-Place Resize Beta’ya Yükseldi özelliğiyle bu yeni scheduling katmanının nasıl etkileşeceği henüz tam netleşmedi; ikisini birlikte kullanmadan önce dikkatli test etmekte fayda var.







2 comments