Kısa bir süre önce üretim ortamımızı Kubernetes'e çevirdik. Kapsayıcılarda CPU sınırlarını zorlamak istiyorum. Birbirine uymayan çakışan CPU metrikleri alıyorum. İşte kurulumum:
- DataDog aracıları
Daemonset
- CPU Sınırları olmadan çalışan mevcut uygulamalar
- Söz konusu kaplar çok iş parçacıklı Ruby uygulamalarıdır
- İki ölçüm:
kubernetes.cpu.usage.{avg,max}
vedocker.cpu.usage
c4.xlarge
küme düğümleri (Kubernetes açısından 4 vCPU veya 4000m)
kubernetes.cpu.usage.max
söz konusu kaplar için ~ 600m. docker.cpu.usage
raporlar ~% 60. 1000m CPU limitinin normal çalışma altında yeterli kapasiteden fazla olacağı sonucuna varılır.
Limiti 1000m olarak ayarladım. Sonra docker.container.throttles
önemli ölçüde artar kubernetes.cpu.usage.max
ve docker.cpu.usage
aynı kalır. Sistem bu süre zarfında dizlerinin üzerine çöküyor. Bu benim için bir anlam ifade etmiyor.
Docker istatistiklerini araştırdım. Görünüşe göre docker stats
(ve altta yatan API) yükü CPU çekirdeklerine göre normalleştiriyor . Benim durumumda, docker.cpu.usage
Kubernetes cinsinden% 60'ı (4000m * 0.60) ile 2400m arasında geliyor. Ancak bu, herhangi bir Kubernetes numarasıyla ilişkili değildir. Kubernetes sayılarının yanlış olduğu hipotezimi test etmek için başka bir deney yaptım. Limiti 2600m'ye ayarladım (bazı ekstra tavan boşlukları için). Bu herhangi bir gaz kelebeği ile sonuçlanmadı. Ancak Kubernetes, CPU kullanımının değişmediğini gözlemledi. Bu beni şaşırttı.
Yani sorularım:
- Bu Kubernetes'teki bir hata mı (yoksa yığındaki bir şey mi?)
- Anlayışım doğru mu?
Takip eden sorum, Ruby uygulamaları için CPU'nun nasıl doğru bir şekilde belirleneceğiyle ilgilidir. Bir kap Puma kullanır. Bu, yapılandırılabilir miktarda iş parçacığı içeren çok iş parçacıklı bir web sunucusudur. HTTP istekleri iş parçacıklarından biri tarafından işlenir. İkinci uygulama, dişli sunucuyu kullanan bir tasarruf sunucusudur. Gelen her TCP bağlantısı kendi iş parçacığı tarafından gerçekleştirilir. Bağlantı kapandığında iplik çıkar. Ruby olarak GIL (Global Tercüman Kilidi) sayesinde Ruby kodunu aynı anda yalnızca bir iş parçacığı yürütebilir. Bu, IO ve bunun gibi şeyleri yürüten birden fazla iş parçacığına izin verir.
En iyi yaklaşım her uygulamada çalışan iş parçacığı sayısını sınırlamak ve iş parçacığı sayısına bağlı olarak Kubernetes CPU sınırlarına yaklaşmak olduğunu düşünüyorum. İşlemler çatallanmadığı için toplam CPU kullanımını tahmin etmek daha zordur.
Buradaki soru şudur: CPU uygulamaları ve bu uygulamalar için sınırlar nasıl doğru tahmin edilir?