Kubernetes'i binlerce CRD kullanacak şekilde ölçeklendirmek
(blog.upbound.io)Upbound tarafından geliştirilen Crossplane, Kubernetes üzerinde bulut control plane'i sunar. Bu nedenle AWS, Azure ve GCP gibi bulut kaynaklarına karşılık gelen yüzlerce CRD (Custom Resource Definition) vardır. Crossplane bunlara MR (Managed Resource) adını verir.
İleri seviye Kubernetes kullanıcıları bile genelde birkaç düzine kadar CR'yi makul şekilde işletirken, Crossplane'de yüzlerce MR kullanmak gerektiği için Kubernetes'in ne kadar çok CRD'yi işleyebileceğinin sınırlarına bakılmaya başlandı.
Bu konu istemci tarafı sorunları ve sunucu tarafı sorunları olarak ikiye ayrılabilir.
İstemci tarafı sorunları
- İstemci tarafında sorun discovery sürecidir.
kubectlgibi istemciler, sunucunun hangi API'leri sunduğunu bulmak için discovery yapar; bu da tüm API endpoint'lerinin bir kez dolaşılmasını gerektirir.- CR'ler API endpoint'i olarak sunulur.
https://example.org/apis/rds.aws.upbound.io/v1/instances/cool-dbgibi bir MR'ı sorgulamak için öncehttps://example.org/apis/altında desteklenen API gruplarını, ardındanhttps://example.org/apis/rds.aws.upbound.ioaltında desteklenen sürümleri ve son olarakhttps://example.org/apis/rds.aws.upbound.io/v1altında desteklenen CR'leri bulmak gerekir.- AWS, Azure ve GCP bulut sağlayıcılarını sunan Crossplane MR'ları yaklaşık 2.000 adettir ve 300 API grubu ile sürüme bölünmüştür.
- İstemci discovery için 300 HTTP isteği gönderir.
- Günümüz ağ koşullarında bu büyük bir sorun değildir, ancak ortaya çıkan sorunlar rate limit ve cache oldu.
İstemci rate limit'i
- Ortalama saniyede 5 istek rate limit'i uygulanıyordu (100'e kadar burst) ve discovery cache'i her 10 dakikada bir geçersiz kılınıyordu.
- Bu, rate limit artırılarak çözülebilir; şu anda da saniyede 5 istek olsa da 300'e kadar yükseltilebilecek hale geldi.
- Bu sınırın yükseltilmesi için
kubectlv1.22'de bir issue açıldı ve discovery cache'i de 10 dakika yerine 5 saate ayarlandı; böylece Kubernetes v1.25'te istemci artırılmış limiti kullanabilir hale geldi.
İstemci cache'i
- Rate limit kapatılarak test edildiğinde bile 300 API grubunu sorgulamak yaklaşık 20 saniye sürüyordu.
- İlk başta bunun ağ sorunu olduğu düşünüldü, ancak inceleme sonucunda cache dosyalarını sorgularken oluşan bir problem olduğu görüldü.
- Kubernetes 1.25'te yapılan düzeltmeyle macOS'ta 25 kat, Linux'ta ise 2 kat hızlanma sağlandı.
Gelecekte istemci iyileştirmeleri
- İstemci tarafında rate limit uygulamak makul olsa da gerçekte sunucuyu düzgün biçimde korumaz.
- Kubernetes 1.20'de tanıtılan API Priority and Fairness (AP&F), sunucu tarafında queue ve trafik şekillendirme sağlayarak API sunucusunu korur.
- Discovery için tek bir toplu HTTP endpoint'i KEP'te onaylandı ve 1.26'da alpha olarak desteklenmesi planlanıyor.
Sunucu tarafı sorunları
OpenAPI şema hesaplama
- Yüzlerce CRD kaydedildikten sonra API isteklerinin neredeyse bir saat boyunca çok yavaşladığı fark edildi.
- Profiling ile bu sorunun OpenAPI v2 şemasını hesaplayan mantıktan kaynaklandığı bulundu.
- Bir CRD eklendiğinde veya güncellendiğinde, OpenAPI controller'ı CR'nin swagger spec'ini oluşturuyor, bunu tüm CR'lerin swagger'larıyla birleştirip büyük bir spec haline getiriyor ve ardından JSON olarak serileştirip
/openapi/v2üzerinden sunuyordu. /openapi/v2için lazy evaluation uygulanarak, hesaplama yalnızca gerçek CR endpoint'i istendiğinde yapılacak şekilde değiştirildi.- Bu düzeltme v1.24.0'a girdi ve 1.20.13, 1.21.7, 1.22.4 sürümlerine backport edildi.
etcd istemcisi
- OpenAPI sorunu çözüldükten sonra bulunan yeni darboğaz buydu.
- API sunucusunun CRD başına 4MiB bellek kullandığı anlaşıldı.
- Bu, GKE ve EKS gibi yönetilen Kubernetes ortamlarında daha da sorunlu; çünkü API sunucusunun CPU ve belleği sınırlandırılmış durumda. Daha fazla kaynak gerekirse API sunucusu otomatik ölçekleniyor, ancak ne yazık ki CRD ekleme bu ölçekleme kararında dikkate alınan bir etken değil. Bu yüzden API sunucusu tekrar tekrar OOM killed olmadığı sürece ölçeklenmiyor.
- GKE, AKE ve EKS üzerinde test edildiğinde otomatik iyileşme çalışıyordu, ancak API sunucusu 5 saniye ile 1 saat arasında kullanılamaz hale geliyordu. Küme tamamen durmasa da tüm reconciliation işlemleri duruyordu.
- Profiling sonucunda, bir logging kütüphanesi olan Zap'in belleğin %20'sini kullandığı görüldü.
- API sunucusu, CR'nin her sürümü için bir etcd istemcisi oluşturuyor ve her etcd istemcisi de bir Zap logger üretiyordu.
- Sonuç olarak yalnızca yinelenen logger'lar nedeniyle bellek artmıyor, ayrıca API sunucusu ile etcd arasında gereksiz TCP bağlantıları da oluşuyordu.
- Tüm CR endpoint'leri için tek bir etcd istemcisi kullanmanın doğru olduğu konusunda maintainer'lar da hemfikirdi; ancak Kubernetes 1.25 sürümü çok yaklaştığı için her şeyi düzeltmek zordu. Bunun yerine daha küçük bir değişiklik yapılarak tüm etcd istemcilerinin tek bir logger'ı paylaşması sağlandı.
-Bu değişikliğin 1.25'e dahil edilmesi ve 1.22, 1.23, 1.24 sürümlerine backport edilmesi planlanıyor. Bellek kullanımını %20 azaltacak.
Gelecekte sunucu tarafı iyileştirmeleri
- CR'nin her sürümü için oluşturulan etcd istemcileri yerine, transport başına bir adet (her etcd kümesi için) oluşturulması planlanıyor.
- GKE, EKS ve AKE mühendislik ekipleriyle de çok sayıda Crossplane CRD kurulumunu yönetebilmek için iş birliği yapılıyor.
2 yorum
Ücretsizleştirme -> geçersiz kılma
Klayıngent -> İstemci