cgroup v1 CPU Shares’ten v2 CPU Weight’e Yeni Dönüşüm
Kubernetes ekosisteminde cgroup v2’ye geçiş sürecinde uzun süredir tartışılan bir sorun çözüme kavuştu: cgroup v1 CPU shares değerlerinin cgroup v2 CPU weight değerine dönüştürülmesi için yeni bir formül devreye alındı. Bu değişiklik, cgroup v2 altında çalışan Kubernetes iş yüklerinin CPU önceliklendirmesinde yaşanan bozulmaları gidermeyi ve sub-cgroup düzeyinde daha ince ayarlı kaynak dağılımına imkân tanımayı hedefliyor.
Arka plan: shares’ten weight’e geçiş
Kubernetes ilk tasarlandığında cgroup v1 esas alınmıştı. Bu modelde bir konteynerin CPU shares değeri, CPU request değerinden şu formülle türetiliyordu:
cpu.shares = milliCPU × 1024 / 1000
Buradaki 1024, cgroup v1’de cpu.shares için varsayılan değerdir ve millicore ile doğrudan bir ilişkisi yoktur. Örneğin 1 CPU (1000m) isteyen bir konteyner 1024 shares, 100m isteyen bir konteyner ise 102 shares alıyordu.
cgroup v2’ye geçişle birlikte CPU shares kavramının yerini CPU weight aldı. Shares değeri 2 ile 262144 (yani 2¹ – 2¹⁸) arasında değişirken, weight değeri 1 ile 10000 (10⁰ – 10⁴) aralığında tanımlıdır. KEP-2254 kapsamında bu iki aralık arasında şu doğrusal dönüşüm formülü kullanılıyordu:
cpu.weight = 1 + ((cpu.shares - 2) × 9999) / 262142
Formül basit olsa da doğrusal eşleme, hem performans hem de yapılandırma inceliği açısından önemli sorunlara yol açıyordu.
Eski formülün iki temel sorunu
1. Kubernetes dışı iş yüklerine karşı düşen öncelik
cgroup v1’de cpu.shares için varsayılan değer 1024’tür. Bu, 1 CPU isteyen bir konteynerin Kubernetes kapsamı dışında çalışan sistem süreçleriyle eşit önceliğe sahip olması anlamına gelir. cgroup v2’de ise cpu.weight için varsayılan değer 100’dür; ancak eski formül 1 CPU (1000m) isteğini yalnızca yaklaşık 39 weight değerine dönüştürüyordu. Yani varsayılanın %40’ından bile azına.
Bunun pratik sonucu şudur: cgroup v2’ye geçildiğinde Kubernetes (veya OCI) iş yükleri, Kubernetes dışında çalışan sistem süreçlerine kıyasla fiilen düşük öncelikli hale geliyordu. Kaynak sıkışıklığı yaşanan ve pek çok sistem daemon’unun Kubernetes dışında çalıştığı kurulumlarda bu durum ciddi sonuçlar doğurabiliyordu.
2. Yönetilemeyen granülerlik
Eski formül, küçük CPU istekleri için oldukça düşük weight değerleri üretiyordu. Örneğin 100m CPU isteyen bir konteyner:
- cgroup v1’de
cpu.shares = 102 - cgroup v2’de (eski formül)
cpu.weight = 4
102 shares değeri, ana konteyner içinde sub-cgroup’lar oluşturup farklı süreç grupları için ince ayarlı öncelik atamaya yetiyordu. Ancak 4 weight değeri, alt gruplar arasında anlamlı bir dağılım yapmak için yeterince granüler değildir. Ayrıcalıksız konteynerler için yazılabilir cgroup’lara izin veren çalışmalar (bkz. KEP #5474) ilerledikçe bu konu daha da önemli hale geliyor.
Yeni dönüşüm formülü
Yeni formül eskisine göre daha karmaşık; ama cgroup v1 shares ile cgroup v2 weight arasında çok daha isabetli bir eşleme sağlıyor:
cpu.weight = ⌈10^(L²/612 + 125L/612 - 7/34)⌉, L = log2(cpu.shares)
Bu ikinci dereceden fonksiyon, üç kritik noktadan geçecek biçimde tasarlandı:
- (2, 1): Her iki aralığın da minimum değerleri
- (1024, 100): Her iki aralığın da varsayılan değerleri
- (262144, 10000): Her iki aralığın da maksimum değerleri
Eğri “neredeyse doğrusal” görünse de bu üç kritik noktadan geçecek biçimde özenle şekillendirilmiştir.
Sorunları nasıl çözüyor?
Öncelik hizalaması: 1 CPU (1000m) isteyen bir konteyner artık cpu.weight = 102 alıyor. Bu değer, cgroup v2’nin varsayılan 100 değerine oldukça yakın olduğundan Kubernetes iş yükleri ile sistem süreçleri arasındaki beklenen öncelik ilişkisi yeniden kuruluyor.
Daha iyi granülerlik: 100m CPU isteyen bir konteyner artık cpu.weight = 17 alıyor. Bu değer, konteyner içinde ince ayarlı kaynak dağıtımı için çok daha kullanışlı bir taban sunuyor.
Uyumluluk ve OCI runtime tarafı
Bu değişikliğin önemli bir ayrıntısı, uygulamanın Kubernetes’in kendisinde değil OCI katmanında yapılmış olmasıdır. Dolayısıyla yeni formülün kullanıma girmesi tamamen OCI runtime’ın sürümüne bağlıdır:
- runc: Yeni formül 1.3.2 sürümünden itibaren etkin.
- crun: Yeni formül 1.23 sürümünden itibaren etkin.
Mevcut kurulumlara etkisi
Eski doğrusal formülü baz alan bazı araçlar bu değişiklikten etkilenebilir. Özellikle beklenen CPU weight değerlerini eski formüle göre hesaplayan uygulama ve izleme araçlarının güncellenmesi gerekebilir. Bu durum şu alanlarda daha kritiktir:
- CPU weight değerlerini tahmin eden özel kaynak yönetim araçları
- Belirli weight değerlerini doğrulayan izleme sistemleri
- CPU weight değerlerini programatik olarak ayarlayan veya kontrol eden uygulamalar
Bir diğer önemli nokta: cpu.weight değerinden geri milliCPU değerine gitmek her zaman özgün değeri vermez. Bunun iki nedeni vardır. İlki, milliCPU’dan cpu.shares‘e dönüşümde tamsayı kesmesi olur (örneğin 100m, 102.4 değil 102 shares’e karşılık gelir). İkincisi ve daha belirleyici olanı, shares-to-weight eşlemesinin çoktan-bire olmasıdır: örneğin 90 ile 109 arasındaki tüm milliCPU değerleri aynı cpu.weight = 17 sonucunu üretir. Bu nedenle kesin CPU request değerine ihtiyaç duyan araçların, bu bilgiyi cgroup parametrelerinden türetmek yerine doğrudan pod spec’ten okuması önerilir.
Kubernetes projesi, OCI runtime yükseltmesi öncesinde yeni formülün mevcut araç zinciriyle uyumluluğunu üretim dışı ortamlarda test etmeyi tavsiye ediyor.
Kaynaklar ve İleri Okuma
- Kubernetes Blog: New Conversion from cgroup v1 CPU Shares to v2 CPU Weight
- KEP-2254: cgroup v2
- KEP #5474: Unprivileged konteynerler için yazılabilir cgroup’lar
- Kubernetes Issue #131216 – teknik analiz ve tartışma
- runc v1.3.2 sürüm notları
- crun 1.23 sürüm notları
- Kubernetes: Konteyner kaynak yönetimi dokümantasyonu
- SIG Node topluluğu
- Formül için Go Playground örneği







Yorum gönder