Kubernetes'te Production: Çoğu Ekibin Gözden Kaçırdığı 10 Şey
Bir SRE’nin masasına ilk kez düşen Kubernetes cluster’larının çoğu ortak bir örüntü paylaşır: temel şeyler çalışır, ama güvenlik ağları eksiktir. En sık gördüğüm eksikler şunlar.
1. Resource request veya limit yok
Bir pod’un requests değeri yoksa, scheduler’ın iyi bir yerleştirme kararı vermek için hiçbir dayanağı olmaz. limits değeri yoksa, bir memory leak node’u — ve üzerinde çalışan her şeyi — çökertir.
Her container’ın ikisine de ihtiyacı var. Açık değer verilmemiş workload’ların arada kaybolmaması için makul varsayılanlar tanımlayan bir LimitRange kullanın.
2. Liveness ve readiness probe’ların aynı şeyi kontrol etmesi
Çok agresif bir liveness probe, yük altındaki sağlıklı pod’ları yeniden başlatır. Çok toleranslı bir readiness probe ise henüz hazır olmayan pod’lara trafik yönlendirir.
Aradaki fark önemli: liveness “bu pod yeniden başlatılmalı mı?” sorusuna, readiness ise “bu pod trafik almalı mı?” sorusuna cevap verir. İkisi farklı şeyleri kontrol etmeli ve farklı eşik değerleri kullanmalı.
3. PodDisruptionBudget yok
PDB olmadan, node bakımı için yapılan bir kubectl drain, bir deployment’ın tüm replica’larını aynı anda düşürebilir. İki dakikalık bir bakım penceresi bir outage’a dönüşür.
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: app-pdb
spec:
minAvailable: 1
selector:
matchLabels:
app: backend
Tek bir manifest. Atlamak için hiçbir gerekçe yok.
4. Secret’ların ConfigMap içinde tutulması
ConfigMap’ler varsayılan olarak rest’te şifrelenmez. Database şifreleri, API key’ler ve token’lar Secret’ların içine ait — ve ideal olarak External Secrets Operator ile senkronize edilen harici bir secrets manager’a (Vault, Azure Key Vault, AWS Secrets Manager) taşınmalı.
Database credential’larının, source control’e commit edilmiş bir ConfigMap içinde base64 ile kodlanmış halde durduğu production cluster’lar gördüm. Encoding, encryption değildir.
5. Network Policy yok
Varsayılan olarak, bir Kubernetes cluster’ındaki her pod diğer her pod’a erişebilir. Namespace’ler arasında otomatik bir network izolasyonu yoktur. Ele geçirilmiş bir pod, tüm cluster’ı tarayabilir.
Her namespace için bir default-deny policy tanımlayın ve yalnızca gerçekten var olması gereken bağlantıları whitelist’e alın.
6. Service account’lara bağlanmış cluster-admin
“Kolaylık olsun” diye cluster-admin yetkisine sahip service account’lar birçok cluster’da hâlâ duruyor. Bu, Kubernetes’in root olarak çalıştırma karşılığıdır.
ClusterRoleBinding’lerinizi denetleyin:
kubectl get clusterrolebindings \
-o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.roleRef.name}{"\n"}{end}' \
| grep cluster-admin
Muhtemelen orada olmaması gereken şeyler bulacaksınız.
7. Production’da imagePullPolicy: Always
Bu, her pod restart’ının registry’den bir pull tetiklemesi demek. Kısmi bir network kesintisinde, imaj node üzerinde zaten cache’lenmiş olsa bile pod restart’ları başarısız olur.
Açıkça tag’lenmiş imajlarla IfNotPresent kullanın — asla latest değil. Tam reproducibility için bir digest’e pin’leyin.
8. Horizontal Pod Autoscaler yok
Sabit replica sayıları, normal yükte fazla provizyonlu ya da spike anlarında yetersiz provizyonlu olduğunuz anlamına gelir. Makul bir CPU/memory hedefine sahip bir HPA yapılandırması basittir ve bir incident kategorisinin tamamının önüne geçer.
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: backend-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: backend
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
9. Multi-zone dağılım yok
Tüm replica’ları aynı availability zone’a deploy etmek, replication’ın sağlaması gereken redundancy’yi anlamsız kılar. Workload’ları zone’lar ve node’lar arasında dağıtmak için topologySpreadConstraints veya pod anti-affinity kullanın.
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app: backend
10. Sık görülen failure mode’lar için bir runbook yok
Bir pod gece 2’de crash-loop’a girdiğinde, nöbetçi mühendisin şunlar için dokümante edilmiş bir yolu olmalı: log’lar nasıl kontrol edilir, nasıl rollback yapılır, HPA yanıt vermiyorsa manuel olarak nasıl scale edilir, bu servisin sahibi kim. Bu yoksa, önleyebileceğiniz incident’lara para ödüyorsunuz demektir.
Bu bir başlangıç noktası, eksiksiz bir liste değil. Production readiness sürekli bir süreçtir.
Cluster’ınızın production olgunluğu hakkında bağımsız bir değerlendirme isterseniz, ücretsiz 30 dakikalık teknik değerlendirme randevusu alın.