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'da Last State: OOMKilled kontrol 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 - Released veya Failed durumunu 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-system namespace'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 kubelet ve journalctl -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çin crictl 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 systemd veya cgroupfs kullanmalı)
  • Adım 5 - Disk baskısı: /var/lib/kubelet ve /var/lib/containerd üzerinde df -h
  • Yaygın nedenler: Sertifika süresi dolması, API server bağlantı sorunları, bozuk kubelet durumu (/var/lib/kubelet/cpu_manager_state kaldı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: Never veya 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-hard ve --eviction-soft gibi 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-config kullanın
  • Yapılandırma boyutunu kontrol edin: istioctl proxy-status config 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.