← Kursa Dön
📄 Text · 25 min

Orchestration Neden Gerekli? Scaling, Self-Healing, Service Discovery

Docker ile artık uygulamalarını container'larda çalıştırabiliyorsun, Docker Compose ile birden fazla servisi yönetebiliyorsun, güvenlik konularında farkındalığın oluştu. Şimdi çok önemli bir soruyla karşı karşıyayız: tek sunucu yeterli mi?

Kafe Analojisi

Küçük bir kafe işlettiğini düşün. Tek bir barista, tek bir kasa. Müşteri az olduğunda her şey yolunda. Ama kafe popüler oldu — kuyruklar uzadı, barista yetişemiyor. Ne yaparsın? İkinci bir barista alırsın. Sonra üçüncüsünü. Biri hastalanırsa yerine birini çağırırsın. Yoğun saatlerde ekstra personel çağırırsın, sakin saatlerde azaltırsın.

Bunu elle yapmak bir kafeyle mümkün. Ama 100 şubeli bir zincir olduğunda? Her şubenin personelini, malzemesini, çalışma saatlerini merkezi bir sistemle yönetmen gerekir. İşte burada bir "yönetim sistemi" lazım.

Container orchestration tam bu. Tek bir container çalıştırmak kolay — docker run yeter. Ama düşün ki 50 container'ın var, 10 sunucuda dağıtılmış. Birisi çökerse otomatik olarak yenisi başlamalı, güncelleme yaparken servis kesilmemeli, trafik artınca otomatik ölçeklenmeli... İşte tüm bunları yöneten sisteme orchestrator diyoruz.

Tek Sunucunun Sınırları

Şu ana kadar hep tek sunucuda çalıştık. Docker Compose ile tüm servislerimizi bir sunucuda ayağa kaldırdık. Ama production ortamında bu yaklaşımın ciddi sınırları var:

Sunucu çökerse ne olur? Tek sunucun çöktüğünde, üzerindeki tüm servisler durur. Veritabanı, API, web sunucusu — hepsi aynı anda erişilemez hale gelir. Bu, "tek hata noktası" (Single Point of Failure — SPOF) denen durum.

Kaynak yetmezse ne olur? CPU veya RAM dolduğunda, yeni container ekleyemezsin. Dikey ölçekleme (sunucuyu büyütme) bir yere kadar mümkün, ama sınırı var ve pahalı.

Güncelleme yaparken ne olur? Yeni versiyon deploy ederken, eski container durur ve yenisi başlar. Bu arada kullanıcılar servise erişemez — downtime oluşur.

Trafik artarsa ne olur? Başka bir sunucuya container dağıtamazsın. Tek sunucuda ne kadar kaynak varsa o kadar.

Hadi bunu somutlaştıralım:

# Tek sunucuda Docker Compose ile çalışıyorsun
docker compose up -d
# ✅ Çalışıyor — ama...
# ❌ Sunucu çökerse? → Tüm servisler durur
# ❌ CPU/RAM yetmezse? → Ölçekleyemezsin
# ❌ Güncelleme yapacaksan? → Downtime olur
# ❌ Trafik artarsa? → Başka sunucuya dağıtamazsın

Orchestration Ne Sağlar?

Container orchestration, bu sorunların hepsini çözer. Birden fazla sunucuyu tek bir "cluster" olarak yönetir:

Otomatik Ölçekleme: Trafik arttığında yeni container'lar otomatik oluşturulur, azaldığında kaldırılır.

Self-Healing: Bir container çökerse, orchestrator otomatik olarak yenisini başlatır. Bir sunucu çökerse, üzerindeki container'lar başka sunuculara taşınır.

Rolling Update: Güncelleme yaparken container'lar birer birer güncellenir — hiçbir an hepsi aynı anda durmaz. Kullanıcılar kesinti yaşamaz.

Load Balancing: Gelen trafik, çalışan container'lar arasında otomatik dağıtılır.

Service Discovery: Container'lar birbirlerini otomatik bulur — IP adresleriyle uğraşmana gerek kalmaz.

İki Ana Oyuncu: Docker Swarm ve Kubernetes

Container orchestration dünyasında iki ana araç var:

Docker Swarm

Docker Swarm, Docker Engine'in içine gömülü gelen orchestration aracı. Kurulumu inanılmaz kolay — docker swarm init dediğin anda aktif. Docker CLI'ı zaten biliyorsun, Swarm da aynı komut yapısını kullanıyor. Öğrenme eğrisi çok düşük.

# Swarm'ı başlat — bu kadar!
docker swarm init --advertise-addr 192.168.1.100

# Servis oluştur — docker run'a çok benzer
docker service create --name web --replicas 3 --publish 80:80 nginx:alpine

Üç replica'lı bir Nginx servisi oluşturdun. Swarm bu üç container'ı cluster'daki sunuculara dağıtır. Biri çökerse otomatik yenisini başlatır. Güncelleme yapmak istersen rolling update yapar.

Kubernetes

Kubernetes (kısaca K8s), Google tarafından geliştirilen ve şu anda endüstri standardı olan orchestration platformu. Google, kendi iç sistemlerinde 15 yıl boyunca milyarlarca container yönetti (Borg sistemi). Bu deneyimin açık kaynak hali Kubernetes oldu.

Kubernetes, Swarm'dan çok daha güçlü ve esnek. Ama bu güç, karmaşıklıkla birlikte geliyor. Öğrenme eğrisi yüksek, kurulumu karmaşık. Bunun yerine genellikle managed servisler (AWS EKS, Google GKE, Azure AKS) kullanılır.

# Kubernetes'te aynı Nginx servisi
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: nginx
          image: nginx:1.25-alpine
          ports:
            - containerPort: 80

Gördüğün gibi Kubernetes'te YAML dosyaları daha detaylı. Ama bu detay, daha fazla kontrol sağlıyor — resource limits, health check'ler, auto-scaling politikaları hepsi burada tanımlanabiliyor.

Swarm vs Kubernetes: Hangisini Seçmeli?

Bu sorunun cevabı projenin büyüklüğüne ve ekibinin deneyimine bağlı:

Docker Swarm tercih et eğer:

  • Küçük-orta ölçekli bir projen varsa (2-10 sunucu)

  • Docker'ı zaten biliyorsun ve hızlıca orchestration'a geçmek istiyorsun

  • Basit bir mimarin var ve çok karmaşık ölçekleme gerekmiyorsa

  • Ekibin küçük ve Kubernetes öğrenmeye zaman ayıracak kadar büyük değilse

Kubernetes tercih et eğer:

  • Büyük ölçekli bir projen varsa (10+ sunucu, yüzlerce container)

  • Cloud-native bir mimari istiyorsan (AWS, GCP, Azure entegrasyonu)

  • Otomatik ölçekleme (HPA) kritik bir gereksinimse

  • Ekibin yeterince büyük ve deneyimli ise

  • Managed Kubernetes servisi kullanabiliyorsan (EKS, GKE, AKS)

Genel kural olarak: küçük başla, gerektiğinde büyü:

Küçük projeler → Docker Compose (tek sunucu)
Orta projeler  → Docker Swarm (birkaç sunucu)
Büyük projeler → Kubernetes (cluster)
Cloud-native   → Managed Kubernetes (EKS, GKE, AKS)

Kubernetes Temel Kavramları

Kubernetes'in temel kavramlarını şimdiden tanıyalım — sonraki derslerde derinlemesine inceleyeceğiz:

Pod: En küçük deploy birimi. Bir veya daha fazla container içerir. Docker'daki "container" kavramının karşılığı gibi düşün, ama biraz daha geniş.

Deployment: Pod'ların istenen sayıda çalışmasını garantiler. "3 tane web pod'u olsun" diyorsun, Deployment bunu sürdürür — biri çökerse yenisini oluşturur, güncelleme istersen rolling update yapar.

Service: Pod'lara stabil bir erişim noktası sağlar. Pod'lar gelip gider (çöker, yeniden oluşturulur, IP'leri değişir) ama Service sabit bir DNS adı ve IP sağlar.

Namespace: Cluster'ı mantıksal bölümlere ayırır. Farklı ortamlar (staging, production) veya farklı takımlar için izolasyon sağlar.

Bu kavramları somut örneklerle sonraki derslerde çok daha detaylı işleyeceğiz.

Swarm Temel Kavramları

Swarm'ın da kendi kavramları var:

Node: Cluster'a katılmış bir sunucu. İki türü var — Manager (yönetici) ve Worker (işçi).

Service: Çalıştırmak istediğin uygulamanın tanımı. Image, replica sayısı, port mapping gibi bilgileri içerir.

Task: Bir service'in tek bir container instance'ı. "3 replica web servisi" dediğinde, 3 task oluşur.

Stack: Birden fazla servisi tanımlayan YAML dosyası. Docker Compose'a çok benzer — aslında Compose dosyalarını Swarm'da kullanabilirsin.

Lokal Kubernetes: Öğrenme Ortamları

Kubernetes'i öğrenmek için production cluster'a ihtiyacın yok. Lokal makinende çalıştırabileceğin birkaç seçenek var:

# Docker Desktop — en kolay
# Settings → Kubernetes → Enable Kubernetes ✓

# Minikube — popüler
minikube start --driver=docker --memory=4096

# Kind (Kubernetes in Docker) — hafif
kind create cluster

# k3d (k3s in Docker) — çok hafif
k3d cluster create mycluster

Benim önerim: Docker Desktop kullanıyorsan, oradan Kubernetes'i aktif et — ek kurulum gerekmez. Daha fazla kontrol istiyorsan Kind veya Minikube kullan.

Docker Compose'dan Orchestration'a Geçiş

Eğer şu anda Docker Compose ile çalışıyorsan, orchestration'a geçiş düşündüğünden kolay. Compose dosyandan Kubernetes manifest'lerine geçiş yapan araçlar var:

# Kompose — Compose'u K8s manifest'lerine çevirir
kompose convert -f docker-compose.yml

Bu komut, Compose dosyandaki her servis için Kubernetes Deployment ve Service dosyaları oluşturur. Tabii bu çıktılar "başlangıç noktası" — production-ready hale getirmek için resource limits, health check'ler ve güvenlik ayarları eklemelisin.

Swarm'a geçiş daha da kolay — Compose dosyanı neredeyse olduğu gibi kullanabilirsin. Tek fark, deploy bölümünü eklemen:

services:
  web:
    image: myapp:v1.0
    deploy:
      replicas: 3
      update_config:
        parallelism: 1
        delay: 10s

Ne Zaman Orchestration'a Geçmeli?

"Şu anda tek sunucuda Docker Compose ile çalışıyorum, ne zaman orchestration'a geçmeliyim?" Bu çok sık sorulan bir soru. İşte bazı sinyaller:

  • Tek sunucun yetmiyor — CPU veya RAM sürekli doluyorsa

  • Downtime kabul edilemez — güncelleme yaparken bile servis kesilmemeli

  • Birden fazla sunucuya dağıtım gerekiyor

  • Otomatik ölçekleme istiyorsun — trafik artınca otomatik büyüme

  • Ekibin büyüyor ve farklı takımlar farklı servisleri yönetiyor

Eğer bunların hiçbiri geçerli değilse, Docker Compose'da kalmak doğru karar. Over-engineering yapma — küçük bir proje için Kubernetes kurmak, sivrisinekle savaşmak için tank kullanmak gibi.

Orchestration'ın Mimarisi: Manager ve Worker

Hem Swarm hem Kubernetes'te cluster mimarisi benzer bir mantıkla çalışır: yönetici (manager/control plane) node'lar karar alır, işçi (worker) node'lar bu kararları uygular.

Bunu tekrar kafe analojimizle düşünelim. Kafe zincirinin merkez ofisi var — hangi şubeye kaç personel gideceğine, yeni şube açılacağına, menü değişikliğine merkez karar verir. Şubeler ise müşterilere hizmet veriyor — yani asıl işi yapıyorlar. Merkez ofis çökerse şubeler çalışmaya devam eder (bir süre), ama yeni karar alınamaz. Bir şube çökerse merkez, o şubenin işini diğer şubelere dağıtır.

┌─────────────────────────────────────────────────────────────┐
│                        Orchestration Cluster                 │
│                                                              │
│  ┌────────────────── Yönetim Katmanı ──────────────────┐   │
│  │  Manager/Control Plane                                │   │
│  │  - Karar alma (scheduling)                            │   │
│  │  - Durum yönetimi (state management)                  │   │
│  │  - API endpoint (kullanıcı ile iletişim)             │   │
│  └──────────────────────┬───────────────────────────────┘   │
│                          │                                   │
│  ┌──────────────────────▼───────────────────────────────┐   │
│  │                    İşçi Katmanı                        │   │
│  │                                                        │   │
│  │  Worker 1          Worker 2          Worker 3         │   │
│  │  ┌──────────┐     ┌──────────┐     ┌──────────┐     │   │
│  │  │ web (1)  │     │ web (2)  │     │ web (3)  │     │   │
│  │  │ api (1)  │     │ api (2)  │     │          │     │   │
│  │  │ db       │     │          │     │          │     │   │
│  │  └──────────┘     └──────────┘     └──────────┘     │   │
│  └────────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────┘

Yönetim katmanı "istenen durum" (desired state) ile "mevcut durum" (current state) arasındaki farkı sürekli kontrol eder. "3 web container'ı olsun" dedin ama biri çöktü — şu anda 2 var. Yönetim katmanı bunu fark eder ve hemen bir worker'da yeni bir container başlatır. Bu reconciliation loop (uzlaştırma döngüsü) denen mekanizma, orchestration'ın kalbidir.

Declarative vs Imperative: Felsefe Farkı

Docker'ı şu ana kadar genellikle imperative (emredici) komutlarla kullandık: "şu container'ı başlat", "şu image'ı çek", "şu network'ü oluştur". Her adımı sen söylüyorsun.

Orchestration dünyasında yaklaşım farklı — declarative (bildirimsel): "3 web container'ı olsun, her biri 256MB RAM kullansın, 80 portunda çalışsın." Nasıl yapılacağını söylemiyorsun, ne istediğini söylüyorsun. Orchestrator, istediğin duruma nasıl ulaşılacağını kendisi çözer.

# Imperative — adım adım sen yönetiyorsun
docker run -d --name web1 nginx
docker run -d --name web2 nginx
docker run -d --name web3 nginx
# web2 çöktü — sen fark et ve yenisini başlat
docker run -d --name web2-new nginx

# Declarative — istediğin durumu söylüyorsun
# "3 nginx olsun" → orchestrator gerisini halleder
# Biri çökerse otomatik yenisini başlatır

Bu felsefe farkı çok önemli. Declarative yaklaşımda sen sadece "hedef durumu" tanımlıyorsun. Orchestrator sürekli olarak mevcut durumu hedef durumla karşılaştırıyor ve fark varsa düzeltiyor. Bu sayede sistem self-healing (kendi kendini iyileştiren) oluyor.

Rolling Update: Sıfır Kesinti Güncelleme

Orchestration'ın en değerli özelliklerinden biri rolling update. Bunu anlamak için önce güncelleme olmadan ne olduğuna bakalım:

Geleneksel güncelleme (Docker Compose):

  1. docker compose down — tüm container'lar durur

  2. Kullanıcılar servise erişemez (DOWNTIME!)

  3. docker compose up -d — yeni container'lar başlar

  4. Servis tekrar erişilebilir

Bu yaklaşımda, ne kadar kısa olursa olsun, bir downtime var. E-ticaret sitesinde her saniye para demek — 30 saniyelik downtime bile kabul edilemez.

Rolling update (Orchestration):

  1. Yeni versiyon container'ı başlatılır (eski hâlâ çalışıyor)

  2. Yeni container sağlıklı mı kontrol edilir (health check)

  3. Sağlıklıysa, eski container'lardan biri durdurulur

  4. Bu işlem tüm container'lar güncellenene kadar tekrarlanır

Zaman →

Container 1:  [v1 ██████████] → [v2 başlıyor...] → [v2 ██████████]
Container 2:  [v1 ████████████████████] → [v2 başlıyor...] → [v2 ████]
Container 3:  [v1 ██████████████████████████████] → [v2 başlıyor...] → [v2]

Her an en az 2 container aktif — zero downtime ✅

Her an kullanıcıya hizmet veren en az bir container var — downtime sıfır. Eğer yeni versiyon sorun çıkarırsa, otomatik olarak eski versiyona geri dönülür (rollback).

Service Discovery: Container'lar Birbirini Nasıl Buluyor?

Tek sunucuda Docker Compose kullanırken, container'lar birbirlerini servis adıyla buluyordu — http://db:5432 gibi. Bu, Docker'ın dahili DNS'i sayesinde çalışıyordu.

Orchestration'da bu daha da karmaşık. Container'lar farklı sunucularda çalışıyor, çöktüğünde yeni sunucuda başlıyor, IP adresleri sürekli değişiyor. Ama orchestrator'lar bu sorunu service discovery mekanizmasıyla çözer.

Swarm'da overlay network ve dahili DNS ile, Kubernetes'te Service nesneleri ve CoreDNS ile servis keşfi sağlanır. Sen sadece servis adını kullanırsın — http://api:3000 — ve orchestrator bu isteği doğru container'a yönlendirir, o container hangi sunucuda çalışıyor olursa olsun.

Gerçek Dünya: Ne Zaman Ne Kullanılır?

Son olarak, gerçek dünyada karşılaşabileceğin senaryolara bakalım:

Kişisel blog veya portfolio sitesi: Docker Compose yeterli. Tek sunucu, basit yapı. Orchestration gereksiz karmaşıklık olur.

Küçük-orta SaaS uygulaması (5-10K kullanıcı): Docker Swarm iyi bir seçim. 2-3 sunucu, basit ölçekleme, kolay yönetim.

E-ticaret platformu (100K+ kullanıcı): Kubernetes. Otomatik ölçekleme, yüksek erişilebilirlik, cloud entegrasyonu gerekir.

Büyük teknoloji şirketi (milyonlarca kullanıcı): Managed Kubernetes (EKS/GKE/AKS). Binlerce pod, onlarca servis, karmaşık networking.

Unutma: en iyi mimari, ihtiyacına uygun olan mimaridir. Kubernetes kullanmak seni daha iyi bir mühendis yapmaz — doğru aracı doğru zamanda kullanmak yapar.

Bu Derste Ne Öğrendik?

  • Tek sunucu yaklaşımının sınırları var: SPOF, ölçeklenememe, downtime

  • Container orchestration bu sorunları çözer: scaling, self-healing, rolling update, load balancing

  • Docker Swarm kolay kurulur, düşük öğrenme eğrisi — küçük-orta projeler için ideal

  • Kubernetes endüstri standardı, çok güçlü — büyük projeler ve cloud-native mimariler için

  • Declarative yaklaşım orchestration'ın felsefesidir: ne istediğini söyle, nasıl yapılacağını orchestrator çözsün

  • Rolling update ile sıfır kesinti güncelleme yapılır

  • Küçük başla: Compose → Swarm → Kubernetes yolu en sağlıklısı

  • Orchestration'a geçiş zamanını doğru belirle — erken geçiş gereksiz karmaşıklık, geç kalma ise sorun

Sonraki derste Docker Swarm'ı detaylıca inceleyeceğiz — cluster kurulumu, servis yönetimi, rolling update ve networking konularına bakacağız.