Kubernetes’te üretimi “gerçekten” ayakta tutan şey yalnızca node sayısı değil; kontrol düzleminin (API Server) nefes alabilmesidir. Birçok kurum API Server sorununu ancak şu belirtilerle fark eder:
kubectlkomutları asılı kalır / çok yavaşlar- controller’lar “desired state”e yetişemez (rollout durur)
- admission/validasyon zinciri domino etkisiyle deploy’u kilitler
Bu yazıda, API Priority and Fairness (APF) ile kontrol düzlemini bir “paylaşımlı kaynak” gibi yönetmenin sahada işe yarayan yaklaşımını anlatacağım: kritik istekleri garantile, gürültüyü adil sıraya al, overload’ı incident olmadan yönetecek sinyalleri kur.
APF neyi çözer (ve neyi çözmez)?
APF, API Server’a gelen istekleri sınıflara ayırıp iki şey yapar:
- Öncelik: Bazı sınıflar (örn.
kube-system, node/lease akışları) daha yüksek öncelikte işlenir. - Fairness (adil paylaşım): Gürültülü ama “çok sayıda” istek üreten sınıflar (örn. CI’nin list/watch dalgası) tek başına kapasiteyi tüketemez; kuyruk ve pay mekanizmasına girer.
APF’nin çözmediği şeyler:
- Etcd yavaşsa APF mucize üretmez (önce etcd sağlığı ve IO/bellek bütçesi)
- Admission webhook’larınız kırmızıysa APF yalnızca “kim önce acı çekecek?” sorusunu yönetir (webhook sorununu ayrıca çözmek gerekir)
1) “Kritik” istek nedir? (Sahadaki doğru sınıflandırma)
Kritik sınıflar tipik olarak şunlardır:
- Node/lease / heartbeat akışları (node’ların “yaşıyor” bilgisini taşır)
kube-systemcontroller’ları (scheduler/controller-manager, DNS, CNI)- Cluster autoscaler veya node lifecycle (ölçek ve toparlanma)
- Güvenlik/operasyon amaçlı “kısıtlı ama önemli” otomasyonlar (örn. acil RBAC değişimi)
Gürültülü sınıflar:
- CI/CD sistemlerinin aynı anda yaptığı
list/watchyoğunluğu - Çok geniş label selector’larla yapılan keşif
- Yanlış yazılmış “polling” client’lar
Buradaki hedef “CI’ı kapat” değil. Hedef: CI trafiği büyüse bile control-plane’in çekirdeği ölmesin.
2) Ölçmeden APF açma: minimum sinyal seti
APF kurulumundan önce şu sinyalleri görünür kılın:
- API Server
apiserver_request_totalve latency histogramları (p95/p99) 429(Too Many Requests) oranıapiserver_flowcontrol_*metrikleri (queue, rejected, dispatched)- Etcd request latency ve fdb/IO sinyalleri (API’nin gerçek dar boğazını kaçırmayın)
Bu metrikler kurumdan kuruma Prometheus/Grafana isimlerinde farklı olabilir; amaç aynı: kuyruk, reddetme ve latency.
3) Başlangıç stratejisi: “kademeli guardrail”
APF’de en yaygın hata “çok detaylı sınıflandırma” ile başlamaktır. Benim sahada en stabil sonuç aldığım yaklaşım:
- Default davranışı koru, sadece “gürültüyü” ayrı sınıfa al
- Gürültü sınıfına düşük öncelik + limitli pay ver
- Sonra kritik sınıfları kademeli ayır
Bu model, ilk gün hem riskinizi hem de sürprizleri azaltır.
4) Örnek konfigürasyon: FlowSchema + PriorityLevel (minimal ama etkili)
APF mantığı iki CRD ile yürür:
PriorityLevelConfiguration: bu sınıfın “kuyruk/pay” davranışıFlowSchema: hangi isteklerin bu sınıfa düşeceği (kullanıcı/grup/namespace/verb vb.)
Aşağıdaki örnekler “tüm cluster’a aynen uygula” diye değil; şablon olarak düşünülmeli.
A) Gürültülü client’ları düşük önceliğe al (CI gibi)
apiVersion: flowcontrol.apiserver.k8s.io/v1beta3
kind: PriorityLevelConfiguration
metadata:
name: low-ci
spec:
type: Limited
limited:
nominalConcurrencyShares: 10
lendablePercent: 0
limitResponse:
type: Queue
queuing:
queues: 64
handSize: 8
queueLengthLimit: 200
---
apiVersion: flowcontrol.apiserver.k8s.io/v1beta3
kind: FlowSchema
metadata:
name: ci-list-watch
spec:
priorityLevelConfiguration:
name: low-ci
matchingPrecedence: 9000
distinguisherMethod:
type: ByUser
rules:
- subjects:
- kind: Group
group:
name: ci-readers
resourceRules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["get", "list", "watch"]
Bu desenin pratik mesajı: CI’nin “çok sayıda” list/watch’ı, API Server’ı kilitlemesin.
B) kube-system için garantili pay (kritik)
apiVersion: flowcontrol.apiserver.k8s.io/v1beta3
kind: PriorityLevelConfiguration
metadata:
name: system-critical
spec:
type: Limited
limited:
nominalConcurrencyShares: 80
lendablePercent: 50
limitResponse:
type: Reject
---
apiVersion: flowcontrol.apiserver.k8s.io/v1beta3
kind: FlowSchema
metadata:
name: kube-system-critical
spec:
priorityLevelConfiguration:
name: system-critical
matchingPrecedence: 1000
distinguisherMethod:
type: ByNamespace
rules:
- subjects:
- kind: Group
group:
name: system:serviceaccounts
resourceRules:
- apiGroups: ["*"]
resources: ["*"]
namespaces: ["kube-system"]
verbs: ["*"]
Burada amaç, kube-system içindeki kritik akışların “her şey yansa bile” bir slot bulabilmesi.
5) Rollout planı: “önce görün, sonra sık”
APF’i üretimde açarken şu sırayı öneririm:
- Metrikleri görünür kıl (APF dashboard + 429/latency alarmı)
- Gürültüyü ayır (low priority + queue)
- Kritik sınıfları ayır (system-critical)
- Sonrasında daha ince sınıflar (örn. break-glass admin, platform automation)
Bu sırayı bozup her şeyi ilk gün sınıflandırırsanız, incident anında “hangi değişiklik ne yaptı?” sorusunu cevaplamak zorlaşır.
6) Incident runbook: API Server overload gördüğünde
APF varken incident triage daha deterministik olur:
- API Server latency artışı + 429 → hangi flow/priority seviyesi etkileniyor?
apiserver_flowcontrol_dispatched_requests_totalile “kim slot yiyor?”u bulun- Gürültülü akışa geçici daraltma:
- queue length limit düşür
- nominal share azalt
- gerekirse kısa süreli
Reject(son çare)
- Kök neden: admission/webhook, etcd, network, client davranışı?
Sonuç
APF, Kubernetes’te “gürültüyle yaşama” yeteneği kazandırır: kritik istekleri korurken geri kalanını adil biçimde sıraya alır. Sahada fark yaratan nokta; YAML yazmak değil, kimlik bazlı sınıflandırma, ölçüm, kademeli rollout ve incident runbook disiplinidir. Kontrol düzlemini koruyan kurumlar, daha az “sürpriz deploy kilidi” ve daha çok öngörülebilir operasyon üretir.