Skip to content

Kubernetes Kapsamlı Rehber (Comprehensive Kubernetes Guide)

Full-stack geliştiriciler için pratik Kubernetes referans rehberi.

Ne zaman Kubernetes kullanmalıyım?

Kullan: Container orkestrasyon, büyük projeler, auto-scaling, yüksek erişilebilirlik (HA), mikroservis mimarisi

⚠️ Opsiyonel: Küçük proje -- Docker Compose yeterli olabilir

Gereksiz: Tek container çalıştırmak (Docker yeterli)

Alternatifler: Docker Swarm (basit orkestrasyon), HashiCorp Nomad (esnek scheduler)


Kubernetes (K8s) Nedir? (What is Kubernetes?)

Kubernetes, container'laştırılmış uygulamaların dağıtımını, ölçeklendirmesini ve yönetimini otomatikleştiren açık kaynaklı bir orkestrasyon platformudur. Google tarafından geliştirilmiş, CNCF'e devredilmiştir.

Docker Compose vs Kubernetes

ÖzellikDocker ComposeKubernetes
AmaçTek makine, dev/test ortamıÜretim, çoklu makine (cluster)
ÖlçeklendirmeManuel (scale komutu)Otomatik (HPA, VPA)
Self-healingYokVar (pod restart, reschedule)
Service discoveryContainer adı ileDNS + Service objesi
Load balancingBasit round-robinGelişmiş (Service, Ingress)
Rolling updateSınırlıTam destek (zero-downtime)
Config yönetimi.env dosyasıConfigMap, Secret
DepolamaDocker volumesPV, PVC, StorageClass
Öğrenme eğrisiDüşükYüksek

Temel Kavramlar (Core Concepts)

Cluster Mimarisi (Cluster Architecture)

Kubernetes Cluster
├── Control Plane (Master)
│   ├── kube-apiserver          # API gateway
│   ├── etcd                    # Cluster state deposu
│   ├── kube-scheduler          # Pod'ları node'lara atar
│   └── kube-controller-manager # Controller'ları yönetir
└── Worker Nodes
    ├── kubelet                 # Pod yaşam döngüsü yönetimi
    ├── kube-proxy              # Network kuralları
    └── Container Runtime       # containerd, CRI-O

Pod

Kubernetes'teki en küçük deploy edilebilir birimdir. Bir veya birden fazla container içerir. Pod içindeki container'lar aynı network namespace ve storage'ı paylaşır. Pod'lar geçici (ephemeral) birimlerdir; doğrudan oluşturmak yerine Deployment kullanılmalıdır.

ReplicaSet

Belirtilen sayıda Pod kopyasının her zaman çalışır durumda olmasını sağlar. Doğrudan oluşturmak yerine Deployment kullanmak tercih edilir.

Deployment

Uygulamanın istenen durumunu tanımlar. Rolling update ve rollback yeteneği sağlar. ReplicaSet'leri otomatik yönetir.

Service

Pod'lara sabit erişim noktası sağlar. Pod IP'leri değişken olduğu için Service bu sorunu çözer.

Service TipiAçıklamaKullanım
ClusterIPCluster içi erişim (varsayılan)Servisler arası iletişim
NodePortHer node'da sabit port açar (30000-32767)Geliştirme, test
LoadBalancerBulut sağlayıcı LB oluştururÜretim (AWS, GCP, Azure)
ExternalNameHarici DNS'e CNAME yönlendirmeDış servis entegrasyonu

Namespace

Cluster içinde mantıksal izolasyon sağlar. Farklı ortamları veya takımları ayırmak için kullanılır. Varsayılan namespace'ler: default, kube-system, kube-public, kube-node-lease.

Ingress

HTTP/HTTPS trafiğini cluster içindeki Service'lere yönlendirir. URL path veya hostname bazlı routing sağlar. Kullanmak için bir Ingress Controller (nginx-ingress, traefik) kurulu olmalıdır.


kubectl Komutları (kubectl Commands)

Temel Komutlar (Basic Commands)

KomutAçıklamaÖrnek
kubectl getKaynakları listelekubectl get pods -o wide
kubectl describeDetaylı bilgikubectl describe pod nginx
kubectl applyYAML'dan oluştur/güncellekubectl apply -f deploy.yaml
kubectl deleteKaynak silkubectl delete pod nginx
kubectl logsPod loglarıkubectl logs -f nginx
kubectl execPod içinde komut çalıştırkubectl exec -it nginx -- bash
kubectl scaleReplica sayısını değiştirkubectl scale deploy nginx --replicas=5
kubectl rolloutGüncelleme durumukubectl rollout status deploy/nginx

Kaynak Listeleme (Resource Listing)

bash
kubectl get pods                          # Pod listesi
kubectl get pods -o wide                  # Detaylı (IP, node)
kubectl get pods -A                       # Tüm namespace'ler
kubectl get pods -l app=nginx             # Label filtresi
kubectl get pod nginx -o yaml             # YAML çıktı
kubectl get all                           # Tüm kaynaklar
kubectl get all -n kube-system            # Belirli namespace

Kaynak Oluşturma ve Silme (Create & Delete Resources)

bash
kubectl apply -f deployment.yaml          # Oluştur/güncelle
kubectl apply -f ./k8s/                   # Dizindeki tüm YAML'lar
kubectl apply -f deploy.yaml --dry-run=client  # Test (uygulamadan)
kubectl delete -f deployment.yaml         # YAML'dan sil
kubectl delete pods -l app=nginx          # Label ile toplu sil
kubectl delete pod nginx --grace-period=0 --force  # Zorla sil

Log ve Exec

bash
kubectl logs nginx-pod                    # Loglar
kubectl logs -f nginx-pod                 # Canlı takip
kubectl logs --tail=100 nginx-pod         # Son 100 satır
kubectl logs --since=1h nginx-pod         # Son 1 saat
kubectl logs nginx-pod -c sidecar         # Belirli container
kubectl logs nginx-pod --previous         # Önceki container
kubectl exec -it nginx-pod -- /bin/bash   # Shell erişimi
kubectl exec nginx-pod -- ls /var/log     # Tek komut

Rollout Yönetimi (Rollout Management)

bash
kubectl rollout status deployment/nginx   # Güncelleme durumu
kubectl rollout history deployment/nginx  # Geçmiş
kubectl rollout undo deployment/nginx     # Geri al
kubectl rollout undo deployment/nginx --to-revision=2  # Belirli revision
kubectl rollout pause deployment/nginx    # Duraklat
kubectl rollout resume deployment/nginx   # Devam ettir

Faydalı Komutlar (Useful Commands)

bash
kubectl cluster-info                      # Cluster bilgisi
kubectl get nodes                         # Node listesi
kubectl top pods                          # Kaynak kullanımı
kubectl top nodes                         # Node kaynak kullanımı
kubectl port-forward pod/nginx 8080:80    # Port yönlendirme
kubectl config get-contexts               # Context listesi
kubectl config use-context my-cluster     # Context değiştir
kubectl config set-context --current --namespace=staging
kubectl run debug --image=busybox --rm -it -- sh  # Geçici debug pod

YAML Manifestları (YAML Manifests)

Pod

yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
    app: nginx
spec:
  containers:
    - name: nginx
      image: nginx:1.25-alpine
      ports:
        - containerPort: 80

Deployment

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.25-alpine
          ports:
            - containerPort: 80

Service

yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  type: ClusterIP
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80

Ingress

yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
    - host: app.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: frontend-service
                port:
                  number: 80
          - path: /api
            pathType: Prefix
            backend:
              service:
                name: backend-service
                port:
                  number: 8080
  tls:
    - hosts:
        - app.example.com
      secretName: app-tls-secret

ConfigMap ve Secret

ConfigMap

Yapılandırma verilerini pod tanımlarından ayırmak için kullanılır.

yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  APP_ENV: production
  APP_PORT: "3000"
  nginx.conf: |
    server {
      listen 80;
      location / { proxy_pass http://localhost:3000; }
    }
bash
# Komut satırından oluşturma
kubectl create configmap app-config --from-literal=APP_ENV=production
kubectl create configmap nginx-config --from-file=nginx.conf

Pod içinde kullanma:

yaml
spec:
  containers:
    - name: app
      image: myapp:1.0
      envFrom:
        - configMapRef:
            name: app-config
      volumeMounts:
        - name: config-vol
          mountPath: /etc/nginx/conf.d
  volumes:
    - name: config-vol
      configMap:
        name: app-config
        items:
          - key: nginx.conf
            path: default.conf

Secret

Hassas verileri (şifre, token) saklamak için kullanılır. Veriler base64 ile encode edilir.

yaml
apiVersion: v1
kind: Secret
metadata:
  name: db-secret
type: Opaque
data:
  DB_USERNAME: YWRtaW4=           # echo -n "admin" | base64
  DB_PASSWORD: cGFzc3dvcmQxMjM=   # echo -n "password123" | base64
bash
kubectl create secret generic db-secret \
  --from-literal=DB_USERNAME=admin \
  --from-literal=DB_PASSWORD=password123

Pod içinde kullanma:

yaml
spec:
  containers:
    - name: app
      image: myapp:1.0
      envFrom:
        - secretRef:
            name: db-secret

Secret'lar varsayılan olarak etcd'de şifresiz saklanır. Üretimde encryption at rest yapılandırılmalı, HashiCorp Vault veya Sealed Secrets tercih edilmelidir.


PV ve PVC (Persistent Volume & Persistent Volume Claim)

Pod'lar geçici olduğu için veriler pod silindiğinde kaybolur. Kalıcı depolama için PV/PVC kullanılır.

yaml
# PersistentVolume (yönetici tarafından sağlanır)
apiVersion: v1
kind: PersistentVolume
metadata:
  name: app-pv
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce       # RWO: tek node okuma/yazma
  storageClassName: standard
  hostPath:
    path: /data/app-pv
---
# PersistentVolumeClaim (pod tarafından talep edilir)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: app-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
  storageClassName: standard
Access ModeKısaltmaAçıklama
ReadWriteOnceRWOTek node'dan okuma/yazma
ReadOnlyManyROXÇoklu node'dan salt okunur
ReadWriteManyRWXÇoklu node'dan okuma/yazma

Pod içinde kullanma:

yaml
spec:
  containers:
    - name: app
      volumeMounts:
        - name: data
          mountPath: /app/data
  volumes:
    - name: data
      persistentVolumeClaim:
        claimName: app-pvc

Health Probes (Sağlık Kontrolleri)

ProbeAmaçBaşarısızlık Durumu
livenessProbeContainer çalışıyor mu?Container yeniden başlatılır
readinessProbeTrafik almaya hazır mı?Service endpoint'lerinden çıkarılır
startupProbeUygulama başlatıldı mı?Diğer probe'lar bekletilir
yaml
spec:
  containers:
    - name: web
      image: myapp:1.0
      startupProbe:
        httpGet:
          path: /healthz
          port: 3000
        failureThreshold: 30
        periodSeconds: 10
      livenessProbe:
        httpGet:
          path: /healthz
          port: 3000
        periodSeconds: 15
        failureThreshold: 3
      readinessProbe:
        httpGet:
          path: /ready
          port: 3000
        initialDelaySeconds: 5
        periodSeconds: 10

Probe kontrol yöntemleri (probe check methods):

yaml
# HTTP GET
livenessProbe:
  httpGet:
    path: /healthz
    port: 8080

# TCP soket
livenessProbe:
  tcpSocket:
    port: 3306

# Komut çalıştırma
livenessProbe:
  exec:
    command: ["cat", "/tmp/healthy"]

Resource Limits (Kaynak Sınırları)

yaml
spec:
  containers:
    - name: app
      image: myapp:1.0
      resources:
        requests:           # Garanti edilen minimum
          memory: "128Mi"
          cpu: "250m"       # 0.25 CPU core
        limits:             # Maksimum sınır
          memory: "512Mi"
          cpu: "1000m"      # 1 CPU core
  • CPU: 1000m = 1 core. Limit aşıldığında throttle yapılır.
  • Bellek: Mi (mebibyte), Gi (gibibyte). Limit aşıldığında pod OOMKilled olur.

LimitRange ve ResourceQuota

yaml
# Namespace varsayılan limitleri
apiVersion: v1
kind: LimitRange
metadata:
  name: default-limits
spec:
  limits:
    - default:
        cpu: "500m"
        memory: "256Mi"
      defaultRequest:
        cpu: "100m"
        memory: "128Mi"
      type: Container
---
# Namespace toplam kotası
apiVersion: v1
kind: ResourceQuota
metadata:
  name: namespace-quota
spec:
  hard:
    pods: "20"
    requests.cpu: "4"
    requests.memory: "8Gi"
    limits.cpu: "8"
    limits.memory: "16Gi"

Helm

Helm, Kubernetes için paket yöneticisidir (package manager). Chart adı verilen paketler halinde uygulamaları tanımlar, kurar ve yönetir.

Neden Helm? (Why Helm?)

  • Tekrarlanan YAML dosyalarını şablonlaştırır
  • Ortam bazlı yapılandırma (dev, staging, prod)
  • Versiyon yönetimi ve rollback
  • Topluluk chart'ları ile hızlı kurulum (nginx, PostgreSQL, Redis)

Chart Yapısı (Chart Structure)

my-chart/
├── Chart.yaml          # Metadata (isim, versiyon)
├── values.yaml         # Varsayılan değerler
├── charts/             # Bağımlılıklar
├── templates/          # K8s manifest şablonları
│   ├── deployment.yaml
│   ├── service.yaml
│   ├── ingress.yaml
│   ├── _helpers.tpl    # Yardımcı fonksiyonlar
│   └── NOTES.txt       # Kurulum sonrası notlar
└── .helmignore

Temel Komutlar (Basic Commands)

bash
# Repository yönetimi
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update

# Arama
helm search repo nginx

# Kurulum
helm install my-release bitnami/nginx
helm install my-release bitnami/nginx -f custom-values.yaml
helm install my-release bitnami/nginx --set replicaCount=3
helm install my-release bitnami/nginx -n production --create-namespace

# Listeleme
helm list -A

# Güncelleme
helm upgrade my-release bitnami/nginx -f updated-values.yaml

# Rollback
helm rollback my-release 1

# Geçmiş
helm history my-release

# Silme
helm uninstall my-release

# İnceleme ve test
helm show values bitnami/nginx
helm install my-release bitnami/nginx --dry-run --debug
helm template my-release bitnami/nginx -f values.yaml

Local Development (Yerel Geliştirme)

Minikube

bash
# Başlatma
minikube start --cpus=4 --memory=8192 --driver=docker

# Dashboard
minikube dashboard

# Service erişimi
minikube service nginx-service
minikube tunnel                          # LoadBalancer için

# Eklentiler
minikube addons enable ingress
minikube addons enable metrics-server

# Durdurma/silme
minikube stop
minikube delete

K3s

Lightweight Kubernetes dağıtımıdır. Düşük kaynak tüketimiyle üretim ortamına yakın deneyim sunar.

bash
curl -sfL https://get.k3s.io | sh -
sudo k3s kubectl get nodes
sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config

Docker Desktop Kubernetes

Docker Desktop > Settings > Kubernetes > "Enable Kubernetes" seçeneğini etkinleştir. En kolay yerel geliştirme seçeneğidir.


İpuçları (Tips & Best Practices)

  • kubectl apply kullanın, kubectl create yerine (idempotent).
  • Her kaynak için labels tanımlayın.
  • Namespace belirtin, varsayılana güvenmeyin.
  • YAML dosyalarını Git'te tutun.
  • Image'larda latest tag'i kullanmayın, sabit versiyon belirtin.
  • Tüm container'lara resource requests/limits tanımlayın.
  • Readiness probe olmadan deployment yapmayın.

Güvenlik (Security)

yaml
# Pod'ları root olarak çalıştırmayın
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
  containers:
    - name: app
      securityContext:
        allowPrivilegeEscalation: false
        readOnlyRootFilesystem: true
  • Secret'ları YAML'da plaintext commit etmeyin. Sealed Secrets veya External Secrets kullanın.
  • NetworkPolicy ile pod'lar arası trafiği kısıtlayın.
  • RBAC ile en az yetki prensibini uygulayın.

Debugging (Hata Ayıklama)

bash
kubectl describe pod <pod-name>           # Event'leri kontrol et
kubectl logs <pod-name> --previous        # Önceki container logları
kubectl exec -it <pod-name> -- sh         # Pod içine gir
kubectl debug -it <pod-name> --image=busybox  # Debug container
kubectl get events --sort-by='.lastTimestamp' # Event geçmişi
kubectl get events -w                     # Canlı event izleme

Otomatik Ölçeklendirme (Auto Scaling)

bash
kubectl autoscale deployment nginx --min=2 --max=10 --cpu-percent=70
yaml
# Pod Disruption Budget
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: nginx-pdb
spec:
  minAvailable: 2
  selector:
    matchLabels:
      app: nginx

DevOps & Tools

Diğer Kategoriler (Other Categories)

Developer Guides & Technical References