sunucu.com.tr

Docker Compose'dan Kubernetes'e geçiş

Uygulamanız bugün tek sunucuda docker compose up ile çalışıyorsa Kubernetes'e geçiş sanıldığı kadar büyük değil. Compose'daki her kavramın Kubernetes'te bir karşılığı var; bu rehber tipik bir web uygulaması ve veritabanını adım adım çevirir.

Son güncelleme: 1 Kasım 2026

Rehberler ve içindekiler

Kavramların karşılığı

Docker ComposeKubernetesNot
services.webDeployment + ServiceDeployment podları çalıştırır, Service onlara sabit bir ad verir.
services.db (veri tutan)StatefulSet + ServiceKalıcı kimlik ve diskle tek kopya veritabanı.
ports: "80:3000"Service + IngressDışarıya 80 ve 443 Ingress'ten açılır; otomatik SSL dahil.
environmentConfigMap, SecretParolalar Secret'ta, diğer ayarlar ConfigMap'te.
volumesPersistentVolumeClaimDisk sınıfı yerel: veri düğümün diskinde.
depends_onreadinessProbe, yeniden denemeUygulama hazır olana kadar trafik almaz; bağlantıyı yeniden denemeli.
restart: alwaysVarsayılan davranışÇöken container kendiliğinden yeniden başlar.
build:İmaj kayıt defteri (registry)İmajı derleyip bir registry'ye itersiniz; küme oradan çeker.
Servis adıyla erişim (db:5432)Aynı ad alanında Service adıBağlantı adresi değişmez: db:5432.

Örnek Compose dosyası

Aşağıdaki dosyada bir web uygulaması (web) ve bir veritabanı (db) var. Aynı yapıyı Kubernetes'e taşıyacağız.

docker-compose.yml

services:
  web:
    image: ghcr.io/ornek/magaza:1.4
    ports:
      - "80:3000"
    environment:
      DATABASE_URL: postgres://magaza:gizli@db:5432/magaza
    depends_on:
      - db
    restart: always
  db:
    image: postgres:16
    environment:
      POSTGRES_USER: magaza
      POSTGRES_PASSWORD: gizli
    volumes:
      - dbdata:/var/lib/postgresql/data
volumes:
  dbdata:

1. İmajı bir kayıt defterine itin

Compose build: ile imajı sunucuda derleyebilir; Kubernetes ise imajı bir kayıt defterinden (registry) çeker. İmajınızı derleyip etiketleyin ve kullandığınız registry'ye itin.

Terminal

docker build -t ghcr.io/ornek/magaza:1.4 .
docker push ghcr.io/ornek/magaza:1.4

Registry özelse kümeye okuma izni verin ve Deployment'a imagePullSecrets ekleyin:

Terminal

kubectl create secret docker-registry registry-giris \
  --docker-server=ghcr.io --docker-username=<kullanıcı> --docker-password=<erişim anahtarı>

Etiket kullanın

latest yerine sürüm etiketi (1.4) kullanın; hangi sürümün çalıştığını bilir, gerektiğinde geri dönersiniz.

2. Parolaları Secret'a taşıyın

Compose dosyasında düz yazılmış parolaları Kubernetes Secret'ına alın. Veritabanı ve uygulama aynı Secret'tan okur.

Terminal

kubectl create namespace magaza
kubectl config set-context --current --namespace=magaza
kubectl create secret generic magaza-db \
  --from-literal=POSTGRES_USER=magaza \
  --from-literal=POSTGRES_PASSWORD='uzun-ve-rastgele-bir-parola' \
  --from-literal=DATABASE_URL='postgres://magaza:uzun-ve-rastgele-bir-parola@db:5432/magaza'

3. Veritabanı: StatefulSet ve kalıcı disk

volumes bloğunun karşılığı volumeClaimTemplates'tir. Disk sınıfı yerel; veri, podun çalıştığı düğümün diskinde durur.

db.yaml

apiVersion: v1
kind: Service
metadata:
  name: db
spec:
  selector:
    app: db
  ports:
    - port: 5432
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: db
spec:
  serviceName: db
  replicas: 1
  selector:
    matchLabels:
      app: db
  template:
    metadata:
      labels:
        app: db
    spec:
      containers:
        - name: postgres
          image: postgres:16
          envFrom:
            - secretRef:
                name: magaza-db
          env:
            - name: PGDATA
              value: /var/lib/postgresql/data/pgdata
          ports:
            - containerPort: 5432
          volumeMounts:
            - name: dbdata
              mountPath: /var/lib/postgresql/data
  volumeClaimTemplates:
    - metadata:
        name: dbdata
      spec:
        storageClassName: yerel
        accessModes: ["ReadWriteOnce"]
        resources:
          requests:
            storage: 10Gi

Terminal

kubectl apply -f db.yaml
kubectl get pods -l app=db

Yedek sizde

yerel disk hızlıdır ama düğüm kaybında veri de gider. Veritabanının düzenli dökümünü alın ve küme dışına, örneğin Object Storage kovanıza kopyalayın. Küme yedeğimiz Kubernetes nesnelerini kapsar, disk verisini kapsamaz.

4. Uygulama: Deployment ve Service

Web servisi iki kopya çalışır. readinessProbe, depends_on'un işini daha iyi yapar: uygulama hazır olmadan trafik almaz. Kaynak istekleri, zamanlayıcının podu uygun düğüme koymasını sağlar.

web.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 2
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: web
          image: ghcr.io/ornek/magaza:1.4
          ports:
            - containerPort: 3000
          env:
            - name: DATABASE_URL
              valueFrom:
                secretKeyRef:
                  name: magaza-db
                  key: DATABASE_URL
          readinessProbe:
            httpGet:
              path: /
              port: 3000
          resources:
            requests:
              cpu: 100m
              memory: 256Mi
            limits:
              memory: 512Mi
---
apiVersion: v1
kind: Service
metadata:
  name: web
spec:
  selector:
    app: web
  ports:
    - port: 80
      targetPort: 3000

Terminal

kubectl apply -f web.yaml
kubectl rollout status deployment/web

5. Dışarıya açın: Ingress ve otomatik SSL

Compose'daki ports: "80:3000" satırının yerini Ingress alır. Alan adınızı bir düğüm IP'sine yönlendirip alan adı ve SSL rehberindeki Ingress tanımını uygulayın; Service adı web, port 80.

6. Veriyi taşıyın

Eski sunucuda veritabanının dökümünü alın ve yeni kümedeki veritabanına yükleyin. Geçiş sırasında yazmayı durdurmak için uygulamayı kısa bir süre bakım kipine alın.

Terminal

# Eski sunucuda
docker compose exec -T db pg_dump -U magaza magaza > magaza.sql

# Kümeye yükleme
kubectl exec -i db-0 -- psql -U magaza magaza < magaza.sql

Yükleme bitince DNS kaydını yeni kümeye çevirin. Eski sunucuyu birkaç gün kapatmadan bekletmek, geri dönüş yolunu açık tutar.

Geçişten sonra

  • Yeni sürüm: imaj etiketini değiştirip kubectl set image deployment/web web=ghcr.io/ornek/magaza:1.5 yazın; podlar sırayla yenilenir.
  • Geri dönüş: kubectl rollout undo deployment/web.
  • Ölçekleme: kubectl scale deployment/web --replicas=4; yoğunluğa göre kendiliğinden ölçekleme için kubectl autoscale (kaynak ölçümleri hazır).
  • Günlükler: kubectl logs -f deployment/web.

Kümeniz yoksa

Compose uygulamanızı taşıyacak bir küme için tek düğümle başlayıp, trafik arttıkça çalışan düğüm ekleyebilirsiniz.

  • Küme yönetimi ücretsiz; yalnız düğüm olarak kullanılan bulut sunucuların fiyatını ödersiniz.
  • Giriş denetleyicisi (sınıf web), otomatik SSL (otomatik-ssl), şifreli düğüm trafiği ve 12 saatte bir küme yedeği kurulumla gelir.
  • Tek sunucuyla başlar, büyüdükçe panelden çalışan düğüm eklersiniz.

Hazır yapılar ve canlı fiyat Kubernetes Kümesi sayfasında; kümeyi aynı sayfadaki hesaplayıcıdan oluşturursunuz.

Sık sorulan sorular

Compose dosyamı otomatik çevirebilir miyim?

Çeviri araçları taslak üretir ama sonucu yine elden geçirmeniz gerekir: parolaları Secret'a almak, veri tutan servisi StatefulSet yapmak, readinessProbe ve kaynak istekleri eklemek. Küçük bir uygulamada tanımları elle yazmak çoğu zaman daha hızlıdır.

Veritabanını kümede mi çalıştırmalıyım?

Küçük ve orta uygulamalarda tek kopya veritabanını StatefulSet ve yerel diskle çalıştırmak yaygındır; düzenli döküm alıp küme dışına kopyalamanız şartıyla. Büyük ve kritik veritabanlarını ayrı bir bulut sunucuda çalıştırıp uygulamayı ona bağlamak da bir seçenektir.

Tek sunucuda Compose yerine neden Kubernetes?

Kesintisiz sürüm geçişi, çöken servisin kendiliğinden kalkması, tek komutla ölçekleme ve geri dönüş, otomatik SSL ve büyüdükçe sunucu ekleyebilmek. Tek düğümlü kümeyle aynı alışkanlıklarla başlar, gerektiğinde düğüm eklersiniz.

Docker Compose'dan Kubernetes'e Geçiş · sunucu.com.tr