Optimisation et performance cluster
Un cluster Kubernetes mal configuré consomme des ressources inutilement, schedule les pods de façon sous-optimale, et réagit lentement aux changements. L'optimisation couvre plusieurs dimensions : ressources des pods, scheduling, performances etcd, et configuration des composants du control plane.
Right-sizing des pods
Sur-provisionner les requests gaspille de la capacité et empêche un scheduling dense. Sous-provisionner provoque des OOMKills et du throttling CPU. Les outils :
# Utilisation réelle vs requests (metrics-server)
kubectl top pods -A --sort-by=memory
kubectl resource-capacity --pods --sort cpu.util # plugin krew
# Recommandations VPA (après quelques jours de données)
kubectl describe vpa myapp-vpa | grep -A 20 "Recommendation"
# Goldilocks : génère des recommandations VPA pour tout le cluster
helm install goldilocks fairwinds-stable/goldilocks -n goldilocks --create-namespace
kubectl label namespace production goldilocks.fairwinds.com/enabled=true
kubectl port-forward svc/goldilocks-dashboard -n goldilocks 8080:80Scheduling avancé
Node Affinity et Pod Affinity
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/arch
operator: In
values: ["amd64"]
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: web
topologyKey: kubernetes.io/hostname # Spread sur différents noeudsTopology Spread Constraints
Distribue les pods uniformément sur des zones de disponibilité ou des noeuds :
spec:
topologySpreadConstraints:
- maxSkew: 1 # Max 1 pod d'écart entre zones
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app: webPriority et Preemption
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: high-priority
value: 1000000
globalDefault: false
---
spec:
priorityClassName: high-priorityPerformance etcd
etcd est souvent le bottleneck des grands clusters. Diagnostics :
# Métriques etcd
ETCDCTL_API=3 etcdctl endpoint status --write-out=table
ETCDCTL_API=3 etcdctl check perf
# Latence des opérations (Prometheus)
histogram_quantile(0.99, rate(etcd_disk_wal_fsync_duration_seconds_bucket[5m]))
# > 10ms = problème de disque
# Compactage et defrag (à faire périodiquement)
ETCDCTL_API=3 etcdctl compact $(etcdctl endpoint status --write-out="json" | jq '.[0].Status.header.revision')
ETCDCTL_API=3 etcdctl defragPerformance API server
# Métriques API server
kubectl get --raw /metrics | grep apiserver_request_duration
# Objets qui surchargent le watch (trop d'events)
kubectl get events -A --sort-by='.lastTimestamp' | tail -50
# Audit log pour identifier les appels fréquents
grep '"verb":"list"' /var/log/kubernetes/audit.log | jq '.requestURI' | sort | uniq -c | sort -rn | head -20Tuning CoreDNS
# Métriques DNS
kubectl top pods -n kube-system -l k8s-app=kube-dns
# Requêtes DNS par pod
kubectl exec -n kube-system $(kubectl get pod -n kube-system -l k8s-app=kube-dns -o name | head -1) -- cat /var/log/coredns.log | grep SERVFAIL | sort | uniq -c | sort -rnOptimisations CoreDNS : augmenter le cache (plugin cache 60), activer autopath pour réduire les requêtes ndots, scaler le nombre de replicas CoreDNS pour les clusters à fort volume de requêtes DNS.