Zero Downtime Deployment Nedir?
Zero downtime deployment, yeni bir sürümü kullanıcıya kesinti yaşatmadan devreye alma yaklaşımıdır. Burada "kesinti" tanımı önemlidir: kısa süreli 5xx hataları da, bakım sayfası da, yavaş yanıtlar da kesinti sayılır. Hedef, trafiğin her an yanıt alması ve kullanıcı oturumlarının bozulmamasıdır.
Bu rehber iki temel stratejiye odaklanır: Blue-Green ve Canary. Rolling deployment gibi diğer yaklaşımlara yeri geldikçe değinilir, ancak ana hat bu iki stratejidir.
Önkoşullar
Bu rehberdeki adımların çoğu aşağıdaki varsayımlara dayanır:
- Uygulama en az iki örnek (instance/container) olarak çalıştırılabiliyor.
- Trafik bir yük dengeleyici (load balancer, reverse proxy veya servis mesh) üzerinden yönlendiriliyor.
- Uygulama durumsuz (stateless) ya da oturum durumu dışarıda tutuluyor (Redis, veritabanı vb.).
- Sağlık kontrolü (health check) endpoint'i mevcut.
- Veritabanı şeması geriye uyumlu biçimde değiştirilebiliyor.
Bu koşullardan biri eksikse, ilgili bölümde uyarı notu bulacaksın.
Blue-Green Deployment
Blue-Green, iki özdeş ortamın (blue ve green) paralel çalıştırılmasına dayanır. Bir ortam canlı trafiği alırken diğeri yeni sürümle hazırlanır. Yeni sürüm doğrulandıktan sonra trafik tek seferde yeni ortama çevrilir.
Adımlar
- Mevcut sürüm (blue) canlıda çalışıyor. Kullanıcı trafiği bu ortama yönlendiriliyor.
- Yeni sürümü green ortamına dağıt. Blue ortamına dokunma; geri dönüş (rollback) için sağlam kalması gerekiyor.
- Green ortamında sağlık kontrollerini çalıştır. Uygulama seviyesinde
/healthgibi bir endpoint yeterli değildir; veritabanı bağlantısı, bağımlı servisler ve kritik iş akışları da doğrulanmalı. - Trafiği green'e çevir. Yük dengeleyicide hedef grubu veya ağırlığı değiştir.
- Blue ortamını bir süre canlı tut. Ani bir sorun çıkarsa trafiği geri alabilmek için birkaç dakika ya da saat beklet.
- Doğrulama sonrası blue'yu kapat veya bir sonraki sürüm için hazırla.
Yük Dengeleyici Yapılandırması
Nginx ile basit bir örnek:
upstream app {
server 10.0.0.10:8080; # blue
# server 10.0.0.11:8080; # green - trafik geçişinde açılır
}
server {
listen 80;
location / {
proxy_pass http://app;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Trafik geçişi için upstream bloğundaki aktif sunucuyu değiştirip nginx -s reload çalıştırılır. Reload sırasında Nginx mevcut bağlantıları kesmez; eski worker süreçleri işlerini bitirir. Bu, sıfır kesinti için önemlidir.
Avantajlar ve Dezavantajlar
Avantajlar:
- Geri dönüş tek adımda yapılır: trafiği eski ortama çevir.
- Test için tam bir üretim benzeri ortam elde edilir.
- Sürüm geçişi atomiktir; kullanıcılar aynı anda tek sürüm görür.
Dezavantajlar:
- İki kat altyapı maliyeti.
- Veritabanı şeması değişiklikleri iki sürümün aynı anda çalışmasını gerektirir; geriye uyumlu migration şart.
- Trafik geçişi tek seferde olduğu için yeni sürümdeki bir hata tüm kullanıcıları etkiler.
Canary Deployment
Canary, yeni sürüme trafiğin küçük bir yüzdesini yönlendirip metrikleri izleyerek kademeli olarak artırma yaklaşımıdır. Blue-Green'in "hep ya da hiç" davranışının riskini azaltır.
Adımlar
- Yeni sürümü ayrı bir örnek grubunda başlat. Bu grup henüz canlı trafiğin tamamını almıyor.
- Trafiğin küçük bir kısmını (örneğin %5) canary'ye yönlendir. Yüzde, yük dengeleyici veya servis mesh üzerinden ayarlanır.
- Metrikleri izle. Hata oranı, gecikme (p50/p95/p99), doygunluk ve iş metriklerini karşılaştır.
- Sorun yoksa yüzdeyi kademeli artır: %5 → %25 → %50 → %100.
- Sorun çıkarsa canary'yi devre dışı bırak. Trafik eski sürüme döner.
Yüzde Bazlı Yönlendirme
Nginx ile ağırlıklı dağıtım:
upstream app {
server 10.0.0.10:8080 weight=95; # mevcut sürüm
server 10.0.0.11:8080 weight=5; # canary
}
Ağırlıkları değiştirip nginx -s reload ile kademeli geçiş yapılabilir. Bu yaklaşım basittir; ancak aynı kullanıcının istekleri farklı sürümlere gidebilir. Oturum tutarlılığı gerekiyorsa sticky session veya kullanıcı bazlı yönlendirme (header, cookie) gerekir.
Kubernetes ile Canary
Kubernetes'te servis mesh (Istio, Linkerd) olmadan sadece Service ve Deployment ile ağırlıklı yönlendirme yapılamaz; Service'in pod seçimi eşit dağıtılır. İki Deployment aynı label'ı taşıyorsa pod sayısı oranında trafik alırlar. Örnek:
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-stable
spec:
replicas: 9
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: app
image: registry.example.com/myapp:1.4.0
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-canary
spec:
replicas: 1
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: app
image: registry.example.com/myapp:1.5.0
Burada 10 pod'un 1'i canary'dir; trafiğin yaklaşık %10'u yeni sürüme gider. Bu yöntem kaba bir orandır ve pod sayısına bağlıdır. Daha hassas kontrol için Istio VirtualService gibi araçlar kullanılır:
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: myapp
spec:
hosts:
- myapp.example.com
http:
- route:
- destination:
host: myapp
subset: stable
weight: 95
- destination:
host: myapp
subset: canary
weight: 5
Bu örnek Istio'nun networking.istio.io/v1beta1 API'sini kullanır. Sürüme göre alan adları değişebilir; kendi kurulumunun API sürümünü doğrula.
Avantajlar ve Dezavantajlar
Avantajlar:
- Hatalı sürümün etkisi küçük bir kullanıcı grubuyla sınırlı kalır.
- Gerçek trafikle doğrulama yapılır.
- Kademeli geçiş, geri dönüşü kolaylaştırır.
Dezavantajlar:
- İki sürüm aynı anda çalıştığı için geriye uyumlu API ve şema gerekir.
- İzleme altyapısı olmadan riskli olur; hangi sürümün sorun çıkardığını ayırt etmek zorlaşır.
- Aynı kullanıcının farklı sürümlere düşmesi tutarsız davranışa yol açabilir.
Ortak Zorluklar
Veritabanı Şeması Değişiklikleri
Zero downtime'ın en sık atlanan kısmı budur. İki sürüm aynı anda çalışırken şema değişikliği geriye uyumlu olmalıdır. Yaygın yaklaşım "expand-contract" desenidir:
- Expand: Yeni kolonu (veya tabloyu) ekle, ancak eski sürüm hâlâ çalışsın. Yeni kolon nullable olmalı veya varsayılan değer taşımalı.
- Migrate: Uygulama her iki kolonu da yazacak şekilde güncellenir.
- Backfill: Mevcut veriler yeni kolona taşınır.
- Contract: Eski sürüm tamamen kaldırıldıktan sonra eski kolon silinir.
Bu adımlar ayrı dağıtımlara yayılır; tek bir migration dosyasında toplanmaz.
Oturum ve Kimlik Doğrulama
Kullanıcı oturumları uygulama belleğinde tutuluyorsa, trafik geçişinde oturumlar kaybolur. Çözüm: oturumları Redis, veritabanı veya imzalı token (JWT) gibi dışarıda tutmak. JWT kullanılıyorsa, iki sürümün aynı imzalama anahtarını ve uyumlu claim setini kabul etmesi gerekir.
Sağlık Kontrolleri
Yük dengeleyici, yeni sürüme trafik göndermeden önce hazır olduğundan emin olmalı. Basit bir TCP kontrolü yetersizdir; uygulama seviyesinde bağımlılıkları doğrulayan bir endpoint gerekir. Kubernetes'te readinessProbe ve livenessProbe ayrımı bu yüzden önemlidir: readiness başarısızsa pod trafik almaz, liveness başarısızsa pod yeniden başlatılır.
Yaygın Hatalar
- Trafik geçişini tek adımda yapmak. Blue-Green'de bu bilinçli bir tercihtir, ancak Canary'de yüzdeyi aniden %100'e çıkarmak riski ortadan kaldırmaz.
- Health check'i yalnızca "process ayakta mı" olarak tanımlamak. Uygulama ayakta olup veritabanına bağlanamıyor olabilir.
- Migration'ları uygulamayla aynı anda çalıştırmak. İki sürümün aynı şemayı farklı beklediği durumlarda hata kaçınılmazdır.
- İzleme olmadan Canary yapmak. Hangi sürümün sorun çıkardığını göremezsen, Canary sadece yavaş bir dağıtımdır.
- Uzun süreli bağlantıları (WebSocket, SSE) hesaba katmamak. Trafik geçişinde bu bağlantılar kopabilir; yeniden bağlanma mantığı gerekir.
- Geri dönüş planı olmadan ilerlemek. Özellikle şema değişikliği yapıldıysa, eski sürüme dönüş her zaman mümkün olmayabilir.
Güvenlik Etkileri
- Eski ortamı açık bırakmak. Blue-Green'de blue ortamı kapatılmadan bırakılırsa, yama almamış bir sürüm ağ üzerinden erişilebilir kalabilir. Trafik almasa bile erişim kısıtlanmalı.
- Canary'ye giden trafiği loglamak. Yeni sürümün logları, hata ayıklama için hassas veri içerebilir. Log seviyesini üretimde ayrı tut.
- Sırların (secret) iki ortamda farklı olması. Trafik geçişinde token doğrulama anahtarları farklıysa oturumlar geçersiz olur. Sırları merkezi bir yönetim aracından dağıt.
- Trafik yönlendirmesini yanlış yapılandırmak. Yanlış ağırlık veya etiket, canary'yi tüm trafiği almaya zorlayabilir; değişiklikleri önce test ortamında doğrula.
Hangi Strateji Ne Zaman?
- Blue-Green: Geri dönüşün tek adımda ve kesin olması gerekiyorsa, altyapı maliyeti sorun değilse, sürüm geçişi atomik olmalıysa.
- Canary: Riskli değişikliklerde, gerçek trafikle doğrulama istiyorsan, izleme altyapın varsa.
- Rolling: Kaynak tasarrufu öncelikliyse ve yavaş geçiş kabul edilebilirse.
İkisi birlikte de kullanılabilir: yeni sürüm önce canary olarak küçük trafik alır, doğrulandıktan sonra blue-green geçişiyle tam trafiğe alınır. Bu, en güvenli ancak en karmaşık yaklaşımdır.
Sonuç
Zero downtime deployment bir araç değil, bir dizi disiplindir. Trafik yönlendirme, sağlık kontrolü, geriye uyumlu şema ve izleme birlikte çalışmadığında hiçbir strateji kesintiyi engellemez. Küçük bir uygulamada Nginx ağırlıklarıyla başlayıp, ihtiyaç büyüdükçe servis mesh ve kademeli yayın (progressive delivery) araçlarına geçmek makul bir yol. Önemli olan, her sürümde geri dönüş planını önceden tanımlamak ve doğrulamayı otomatikleştirmek.