Kubernetes Gerçek Hayatta: 15 Kritik Senaryo ve Çözüm
Kubernetes eğitimlerde zarif görünür, ancak üretim ortamı farklı bir hikaye anlatır. İşte junior operatörleri deneyimli mühendislerden ayıran 15 gerçek dünya senaryosu—her biri için uygulanabilir çözümlerle.
⚔️ Derinlemesine Hata Ayıklama
1. Pod CrashLoopBackOff'ta takılı kaldı, log yok, hata yok
kubectl logs ve describe'ın ötesinde nasıl hata ayıklarsınız?
- Önceki konteyner loglarını kontrol edin:
kubectl logs <pod> --previous- konteyner log yazmadan önce çökebilir - Debug shell ile konteynere girin:
kubectl debug -it <pod> --image=busybox --target=<container> - Node seviyesinde eventleri inceleyin:
kubectl get events --field-selector involvedObject.name=<pod> - Init konteynerlerini kontrol edin: Genellikle suçlu, ana konteynerinizden önce çalışan başarısız bir init konteyneridir
- Konteyner entrypoint'ini gözden geçirin: Süreç hemen çıkış yapıyor olabilir—imajı yerel olarak test edin:
docker run -it <image> sh - Kaynak limitlerini kontrol edin: OOMKilled konteynerleri her zaman log bırakmaz—
kubectl describe pod'daLast State: OOMKilledkontrol edin
2. StatefulSet pod'u node çökmesinden sonra PVC'sini yeniden bağlamıyor
Depolamayı yeniden oluşturmadan nasıl kurtarırsınız?
- PV durumunu kontrol edin:
kubectl get pv-ReleasedveyaFaileddurumunu arayın - Takılı pod'u zorla silin:
kubectl delete pod <pod> --force --grace-period=0 - VolumeAttachment nesnelerini kontrol edin:
kubectl get volumeattachments- eski attachmentlar yeniden bağlanmayı engelleyebilir - Eski VolumeAttachment'ı silin:
kubectl delete volumeattachment <name> - CSI driver sağlığını doğrulayın:
kube-systemnamespace'indeki CSI driver pod'larını kontrol edin - Son çare - PV'yi düzenleyin: Yeniden bağlanmaya izin vermek için
claimRef'i kaldırın:kubectl patch pv <pv-name> -p '{"spec":{"claimRef": null}}'
3. Pod'lar Pending durumunda, Cluster Autoscaler ölçeklendirmiyor
En önemli 3 hata ayıklama adımı:
- Adım 1 - Autoscaler loglarını kontrol edin:
kubectl logs -n kube-system -l app=cluster-autoscaler- "scale up" kararlarını ve neden reddedildiklerini arayın - Adım 2 - Node grubu kısıtlamalarını doğrulayın: Maksimum node limitine ulaşılıp ulaşılmadığını, gerekli instance tipinin bölgenizde mevcut olup olmadığını ve yeterli IAM izinlerinin olup olmadığını kontrol edin
- Adım 3 - Pod zamanlama gereksinimlerini inceleyin: Hiçbir node grubunun karşılayamayacağı nodeSelector, affinity kuralları veya taint'leri kontrol edin.
kubectl describe podçalıştırın ve zamanlama hataları için Events bölümüne bakın - Yaygın suçlular: Scale-down'ı engelleyen (ve scale-up döngülerini engelleyen) PodDisruptionBudget, yeniden zamanlanamayan yerel depolamaya sahip pod'lar ve bulut sağlayıcısında yetersiz kota
4. NetworkPolicy namespace'ler arası trafiği engelliyor
En az ayrıcalık kurallarını nasıl tasarlar ve güvenle test edersiniz?
- Denetim moduyla başlayın: Uygulamadan önce nelerin engelleneceğini görmek için Cilium'un policy audit modunu kullanın
- Tasarım deseni - Varsayılan reddet + açık izin:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
- Namespace'ler arası trafiğe açıkça izin verin:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-from-frontend
namespace: backend
spec:
podSelector:
matchLabels:
app: api
ingress:
- from:
- namespaceSelector:
matchLabels:
name: frontend
podSelector:
matchLabels:
app: web
- Güvenli test: Bir debug pod dağıtın ve policy değişikliklerinden önce ve sonra bağlantıyı test etmek için
nc -zv <service> <port>kullanın - Policy görselleştirmesi kullanın: Cilium Hubble veya Calico'nun policy board'u gibi araçlar trafik akışlarını görselleştirmeye yardımcı olur
5. Servis, cluster içinde VPN üzerinden harici DB'ye bağlanmalı
HA + güvenlik için nasıl mimari tasarlarsınız?
- Seçenek 1 - Sidecar VPN konteyneri: DB erişimi gereken pod'larda sidecar olarak bir VPN istemcisi çalıştırın. İzolasyon için iyi ama bağlantıları çoğaltır.
- Seçenek 2 - Ayrılmış VPN gateway pod'ları: Bir Service ile VPN gateway pod'larından oluşan DaemonSet veya Deployment dağıtın. NetworkPolicy kullanarak trafiği bu gateway'ler üzerinden yönlendirin.
- Seçenek 3 - Node seviyesi VPN (HA için önerilen):
# hostNetwork: true ile DaemonSet kullanın
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: vpn-gateway
spec:
selector:
matchLabels:
app: vpn-gateway
template:
spec:
hostNetwork: true
containers:
- name: vpn
image: your-vpn-image
securityContext:
capabilities:
add: ["NET_ADMIN"]
- Güvenlik hususları: VPN kimlik bilgileri için Kubernetes Secrets kullanın, hangi pod'ların VPN gateway'e ulaşabileceğini kısıtlamak için NetworkPolicy uygulayın, VPN çözümünüz destekliyorsa mTLS etkinleştirin
- HA mimarisi: Kullanılabilirlik bölgelerinde birden fazla VPN pod'u çalıştırın, istemci tarafı yük dengeleme ile headless Service kullanın, gerçek DB bağlantısını doğrulayan sağlık kontrolleri uygulayın
🧱 Güvenlik + Mimari
6. Çok kiracılı EKS cluster'ı çalıştırma
RBAC, kotalar ve ağ segmentasyonu ile iş yüklerini nasıl izole edersiniz?
- Namespace izolasyonu: Katı RBAC ile kiracı başına bir namespace
# Kiracı namespace'ine sınırlı Role
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: tenant-a
name: tenant-role
rules:
- apiGroups: ["", "apps"]
resources: ["pods", "deployments", "services"]
verbs: ["get", "list", "create", "update", "delete"]
- Kiracı başına kaynak kotaları:
apiVersion: v1
kind: ResourceQuota
metadata:
name: tenant-quota
namespace: tenant-a
spec:
hard:
requests.cpu: "10"
requests.memory: 20Gi
limits.cpu: "20"
limits.memory: 40Gi
pods: "50"
- Ağ segmentasyonu: Namespace başına varsayılan-reddet NetworkPolicy, yalnızca gerekli kiracılar arası iletişim için açık izin kuralları
- Ek güçlendirme: Kısıtlanmış politikaları uygulamak için PodSecurityAdmission kullanın, özel politikalar için OPA/Gatekeeper uygulayın, hassas iş yükleri için kiracı başına ayrılmış node havuzları düşünün
7. Kubelet bir node'da sürekli yeniden başlıyor
İlk önce nereye bakarsınız – systemd, container runtime veya cgroups?
- Adım 1 - systemd durumunu kontrol edin:
systemctl status kubeletvejournalctl -u kubelet -f - Adım 2 - OOM kill'leri arayın:
dmesg | grep -i "oom\|killed"- kubelet OOM killed alıyor olabilir - Adım 3 - Container runtime'ı doğrulayın:
systemctl status containerd(veya docker), ardından runtime'ın yanıt verip vermediğini kontrol etmek içincrictl ps - Adım 4 - cgroup yapılandırmasını kontrol edin: cgroup driver'ın kubelet ve container runtime arasında eşleştiğinden emin olun (ikisi de
systemdveyacgroupfskullanmalı) - Adım 5 - Disk baskısı:
/var/lib/kubeletve/var/lib/containerdüzerindedf -h - Yaygın nedenler: Sertifika süresi dolması, API server bağlantı sorunları, bozuk kubelet durumu (
/var/lib/kubelet/cpu_manager_statekaldırmayı deneyin)
8. Kritik pod node baskısı nedeniyle çıkarıldı
QoS sınıflarını ve eviction politikalarını açıklayın:
- QoS Sınıfları (çıkarma sırası):
- BestEffort (ilk çıkarılan): Request veya limit ayarlanmamış
- Burstable (ikinci çıkarılan): Request < Limit veya yalnızca bazı konteynerlerin limiti var
- Guaranteed (son çıkarılan): TÜM konteynerler için Request = Limit
# Guaranteed QoS örneği
resources:
requests:
memory: "1Gi"
cpu: "500m"
limits:
memory: "1Gi"
cpu: "500m"
- Kritik pod'ları koruyun:
preemptionPolicy: Neverveya yüksek öncelik değeri ile PriorityClass kullanın
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: critical-workload
value: 1000000
globalDefault: false
preemptionPolicy: PreemptLowerPriority
description: "Çıkarılmaması gereken kritik iş yükleri"
- Eviction eşikleri: Bellek/disk baskı eşiklerini ayarlamak için
--eviction-hardve--eviction-softgibi kubelet bayraklarını yapılandırın
9. Rolling update kesintiye neden oldu
Readiness/startup probe veya deployment yapılandırmanızda ne yanlış gitti?
- Yaygın suçlular:
- Eksik readiness probe: Uygulama hazır olmadan trafik yönlendirildi
- Agresif probe ayarları: Yavaş başlayan uygulamalar için
initialDelaySecondsçok kısa - Yanlış endpoint: Probe, zaman aşımına uğrayan ağır bir endpoint'e isabet ediyor
# Doğru probe yapılandırması
readinessProbe:
httpGet:
path: /health/ready
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
failureThreshold: 3
startupProbe: # Yavaş başlayan uygulamalar için
httpGet:
path: /health/started
port: 8080
failureThreshold: 30
periodSeconds: 10
- Gözden geçirilecek Deployment ayarları:
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 0 # Asla sağlıklı pod'ları kaldırma
maxSurge: 1 # Her seferinde bir yeni pod ekle
minReadySeconds: 30 # Available olarak işaretlemeden önce bekle
- preStop hook'larını unutmayın: SIGTERM'den önce graceful shutdown'a izin verin
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 15"]
10. Ingress Controller yük altında başarısız oluyor
Routing'i nasıl hata ayıklar ve verimli şekilde ölçeklendirirsiniz?
- Hata ayıklama adımları:
- Controller loglarını kontrol edin:
kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx - Bağlantı metriklerini izleyin:
nginx_ingress_controller_nginx_process_connections'a bakın - Config reload fırtınalarını kontrol edin: Sık Ingress değişiklikleri reload'lara neden olur
- Ölçeklendirme stratejileri:
- Yatay ölçeklendirme: Replica'ları artırın ve dağıtım için pod anti-affinity kullanın
- Worker process'lerini ayarlayın: ConfigMap'te
worker-processes: "auto"ayarlayın - Keep-alive etkinleştirin: Upstream keep-alive ile bağlantı overhead'ini azaltın
# Ingress ConfigMap ayarlaması
data:
worker-processes: "auto"
max-worker-connections: "65536"
upstream-keepalive-connections: "200"
keep-alive: "75"
- Bölmeyi düşünün: Farklı trafik sınıfları için (dahili vs harici) ayrı Ingress controller'lar kullanın
⚙️ Performans + Güvenilirlik
11. Istio sidecar uygulamanızdan daha fazla CPU tüketiyor
Mesh performansını nasıl profiller ve optimize edersiniz?
- Önce profil çıkarın: Envoy yapılandırmasını incelemek için
istioctl proxy-configkullanın - Yapılandırma boyutunu kontrol edin:
istioctl proxy-statusconfig sync durumunu gösterir - Optimizasyon stratejileri:
- Sidecar kapsamını sınırlayın:
apiVersion: networking.istio.io/v1beta1
kind: Sidecar
metadata:
name: default
namespace: my-app
spec:
egress:
- hosts:
- "./*" # Yalnızca yerel namespace
- "istio-system/*" # Control plane
- Kaynak limitlerini ayarlayın:
# IstioOperator'da
spec:
values:
global:
proxy:
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
cpu: 200m
memory: 256Mi
- Gereksiz özellikleri devre dışı bırakın: Access logging'i kapatın, tracing sampling oranını azaltın
- Sidecar-less'ı düşünün: Istio ambient mesh, L4 trafiği için sidecar'ları kaldırır
12. etcd control plane operasyonlarını yavaşlatıyor
Kök nedenler + güvenle nasıl ayarlarsınız?
- Yaygın kök nedenler:
- Disk I/O gecikmesi (etcd disk performansına çok duyarlı)
- Çok fazla nesne (secrets, configmaps, events)
- etcd üyeleri arasında ağ gecikmesi
- Büyük nesne boyutları (büyük verilere sahip secrets)
- Teşhis:
# etcd metriklerini kontrol edin
etcdctl endpoint status --write-out=table
etcdctl endpoint health
# İzlenecek önemli metrikler
- etcd_disk_wal_fsync_duration_seconds (< 10ms olmalı)
- etcd_disk_backend_commit_duration_seconds
- etcd_server_slow_apply_total
- Güvenli ayarlama:
- SSD/NVMe depolama kullanın (IOPS > 3000, gecikme < 1ms)
- Alan kotasına ulaşıyorsanız
--quota-backend-bytes'ı artırın - Otomatik sıkıştırmayı etkinleştirin:
--auto-compaction-retention=1 - Düzenli defragmentasyon (bakım pencerelerinde)
- Event birikimini sınırlamak için event TTL'ini azaltın
13. Yalnızca güvenilir dahili registry'den imaj zorunluluğu
Gatekeeper, Kyverno veya özel Admission Webhook – tercihini ne?
- Öneri: Basitlik için Kyverno, karmaşık politikalar için Gatekeeper
- Kyverno yaklaşımı (daha basit):
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: restrict-image-registries
spec:
validationFailureAction: Enforce
rules:
- name: validate-registries
match:
any:
- resources:
kinds:
- Pod
validate:
message: "İmajlar dahili registry'den gelmelidir"
pattern:
spec:
containers:
- image: "registry.internal.com/*"
initContainers:
- image: "registry.internal.com/*"
- Gatekeeper yaklaşımı (daha esnek):
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sAllowedRepos
metadata:
name: repo-is-internal
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
parameters:
repos:
- "registry.internal.com/"
- Özel webhook: Yalnızca harici sistemlerle entegrasyon veya policy engine'lerinin işleyemeyeceği özel mantık gerekiyorsa
- Pro ipucu: Tedarik zinciri güvenliği için Cosign + Kyverno ile imaj imza doğrulaması da uygulayın
14. Pod'lar sonsuza kadar ContainerCreating'de takılı
CNI attach gecikmesi? OverlayFS bozulması? Kök neden sürecinizi anlatın:
- Adım 1 - Pod'u tanımlayın:
kubectl describe pod <pod>- belirli hatalar için Events bölümünü kontrol edin - Adım 2 - CNI'ı kontrol edin:
# CNI plugin pod'larını kontrol edin
kubectl get pods -n kube-system -l k8s-app=calico-node # veya CNI'nız
# CNI loglarını kontrol edin
kubectl logs -n kube-system -l k8s-app=calico-node
# CNI config'in var olduğunu doğrulayın
ls /etc/cni/net.d/
- Adım 3 - Container runtime'ı kontrol edin:
# Containerd
crictl ps
crictl logs <container-id>
journalctl -u containerd
# Takılı sandbox konteynerlerini kontrol edin
crictl pods | grep NotReady
- Adım 4 - Depolamayı kontrol edin:
# Overlay filesystem sorunları
df -h /var/lib/containerd
mount | grep overlay
# Bozuksa temizleyin
crictl rmi --prune
- Adım 5 - Kaynak tükenmesini kontrol edin: CNI subnet'inde IP adresleri tükendi, node'da çok fazla pod, inotify watch limiti aşıldı
15. Pod'larda rastgele DNS hataları
CoreDNS, kube-proxy ve conntrack etkileşimlerini nasıl hata ayıklarsınız?
- Adım 1 - Pod'dan DNS'i test edin:
kubectl run -it --rm debug --image=busybox -- nslookup kubernetes
kubectl run -it --rm debug --image=busybox -- nslookup google.com
- Adım 2 - CoreDNS'i kontrol edin:
# CoreDNS pod durumu
kubectl get pods -n kube-system -l k8s-app=kube-dns
# CoreDNS logları
kubectl logs -n kube-system -l k8s-app=kube-dns
# CoreDNS metriklerini kontrol edin
kubectl top pods -n kube-system -l k8s-app=kube-dns
- Adım 3 - kube-proxy'yi kontrol edin:
# kube-proxy modunu doğrulayın
kubectl get cm -n kube-system kube-proxy -o yaml | grep mode
# iptables/ipvs kurallarını kontrol edin
iptables -t nat -L | grep coredns
ipvsadm -ln | grep <coredns-ip>
- Adım 4 - Conntrack sorunları (yaygın suçlu):
# conntrack tablosunu kontrol edin
conntrack -S
cat /proc/sys/net/netfilter/nf_conntrack_count
cat /proc/sys/net/netfilter/nf_conntrack_max
# Limite ulaşıyorsanız artırın
sysctl -w net.netfilter.nf_conntrack_max=524288
- Adım 5 - Race condition düzeltmesi: UDP kaynak port tükenmesini önlemek için pod spec'ine ekleyin:
dnsConfig:
options:
- name: single-request-reopen
- name: ndots
value: "2"
- Pro ipucu: DNS trafiği için CoreDNS yükünü azaltmak ve conntrack sorunlarından kaçınmak için NodeLocal DNSCache kullanın
Özet
Bu 15 senaryo, üretimde Kubernetes çalıştırmanın gerçekliğini temsil eder. Temel çıkarımlar:
- Her zaman önce veri toplayın: Değişiklik yapmadan önce Events, loglar, metrikler ve node durumu
- Savunmalarınızı katmanlayın: RBAC + NetworkPolicy + Resource Quotas + Pod Security
- Başarısızlık için tasarlayın: Uygun QoS sınıfları, priority sınıfları ve PodDisruptionBudget'lar
- Control plane'i izleyin: etcd ve kubelet sağlığı kritiktir
- Uygulamadan önce test edin: Politikalar için audit modu, değişiklikler için canary deployment'lar
Üretim Kubernetes'i sistematik bir hata ayıklama yaklaşımı ve altta yatan bileşenlerin derin anlaşılmasını gerektirir. Bu senaryolarda ustalaşın ve cluster'larınızın atacağı her şeye hazır olacaksınız.