Merhaba arkadaşlar, bugün sizlere Docker konteynerlerinizi Kubernetes ortamına daha sağlam ve güvenilir bir şekilde hazırlamanın kritik bir adımından bahsedeceğim. Özellikle production ortamlarında çalıştırdığımız uygulamalar için konteynerin sağlık durumunu (health check) Kubernetes'e bildirmek çok önemli. Bunun için de Dockerfile'ımıza Readiness ve Liveness Probe'larını eklememiz gerekiyor. Bu rehberde, bu probe'ların ne işe yaradığını ve pratikte nasıl Dockerfile'a entegre edeceğimizi adım adım göreceğiz.
Probe'lar Neden Bu Kadar Önemli?
Kubernetes, bir konteynerin sağlıklı olup olmadığını anlamak için bu probe'lara güvenir. Benim sunucularda genelde kullandığım yöntem, her uygulama için bu kontrolleri mutlaka tanımlamaktır.
- Liveness Probe: Konteynerin "yaşıyor" olup olmadığını kontrol eder. Eğer bu probe başarısız olursa, Kubernetes konteyneri yeniden başlatır (restart). Örneğin, uygulamanız kilitlendiğinde (deadlock) bu probe devreye girer.
- Readiness Probe: Konteynerin trafik almak için "hazır" olup olmadığını kontrol eder. Bu probe başarısız olursa, Kubernetes bu pod'a gelen trafiği geçici olarak keser. Uygulamanız başlarken veritabanı bağlantısı kurması veya büyük bir veri dosyasını yüklemesi gerekiyorsa, bu süreç bitene kadar trafik gönderilmemesi için idealdir.
Bu iki mekanizmayı doğru yapılandırmazsanız, Kubernetes uygulamanızın durumunu anlayamaz ve bu da kesintilere veya hatalı restart'lara yol açabilir.
Dockerfile'a HEALTHCHECK Eklemek
Kubernetes probe'larını doğrudan Dockerfile'da tanımlayamayız, ancak Kubernetes'in kullanabileceği bir `HEALTHCHECK` komutu tanımlayabiliriz. Bu, konteyner imajının içine gömülü, temel bir sağlık kontrolüdür. Kubernetes manifest dosyanızda (`deployment.yaml`) bu komutu kullanabilir veya kendi probe tanımınızı yapabilirsiniz. İlk adım olarak Dockerfile'ımıza `HEALTHCHECK` ekleyelim.
Şu ayara çok dikkat etmelisiniz: Sağlık kontrolü, uygulamanızın gerçekten "sağlıklı" olduğunu anlatan bir endpoint'e veya komuta dayanmalı. Sadece process'in çalıştığını değil, kritik bağımlılıkların da (cache, DB) hazır olduğunu kontrol etmeli.
İşte tipik bir Node.js uygulaması için örnek bir Dockerfile:
Buradaki `--start-period=30s` parametresi çok önemli. Bu, konteynerin başlangıç aşaması için tanınan süredir. Bu süre içinde probe başarısız olsa bile konteyner "unhealthy" sayılmaz. Bu, uygulamanın başlama süresine göre mutlaka ayarlanmalıdır.
Kubernetes Manifest'inde Probe Tanımlamak
Dockerfile'daki `HEALTHCHECK` güzel bir başlangıçtır, ancak Kubernetes'te probe'ları manifest dosyasında ayrıntılı olarak yapılandırmak daha esnek ve güçlüdür. İşte aynı uygulama için bir `deployment.yaml` örneği. Burada hem `livenessProbe` hem de `readinessProbe` ayrı ayrı tanımlanmıştır.
Gördüğünüz gibi, `readinessProbe` için farklı bir endpoint (`/health/ready`) kullandım. Bu endpoint'in, uygulamanın tüm harici bağımlılıklarına (veritabanı, redis, vs.) erişimi kontrol etmesi benim önerimdir. Böylece bağımlılıklardan biri çökse bile, Kubernetes bu pod'a yeni trafik göndermez ve kullanıcılar hata almaz.
Dikkat Edilmesi Gerekenler
1. Endpoint Güvenliği: `/health` gibi endpoint'lerinizi dış dünyaya açık bırakmayın. Sadece internal cluster network'ünden erişilebilir olmalılar. Eğer dışarıya açmanız gerekiyorsa, basit bir IP kısıtlaması veya secret header kontrolü ekleyin.
2. Zaman Ayarı (Timeouts): `timeoutSeconds` değerini, uygulamanızın ortalama cevap süresinin biraz üzerinde tutun. Çok düşük bir timeout, sağlıklı pod'ların yanlışlıkla öldürülmesine neden olabilir.
3. Başlangıç Gecikmesi (Initial Delay): `initialDelaySeconds` değeri, uygulamanızın ayağa kalkma süresinden kesinlikle daha uzun olmalı. Aksi takdirde uygulamanız henüz başlamadan probe kontrolü yapılır ve pod sürekli restart yer. Bunu ölçmek için test ortamında birkaç deneme yapmanızı şiddetle tavsiye ederim.
4. Komut Tabanlı Probe: Eğer HTTP endpoint'iniz yoksa, `exec` komutu ile bir script çalıştırarak da probe yapabilirsiniz. Örneğin:
Sonuç
Docker konteynerlerinize `HEALTHCHECK` eklemek ve Kubernetes deployment'larınızda `livenessProbe` ile `readinessProbe`'ları doğru yapılandırmak, production'daki uygulama dayanıklılığınızı (resilience) inanılmaz artırır. Bu sayede uygulamalarınız kendi kendini iyileştirebilir (self-healing) ve kullanıcılarınıza kesintisiz hizmet verebilir.
Kubernetes, bir konteynerin sağlıklı olup olmadığını anlamak için bu probe'lara güvenir. Benim sunucularda genelde kullandığım yöntem, her uygulama için bu kontrolleri mutlaka tanımlamaktır.
- Liveness Probe: Konteynerin "yaşıyor" olup olmadığını kontrol eder. Eğer bu probe başarısız olursa, Kubernetes konteyneri yeniden başlatır (restart). Örneğin, uygulamanız kilitlendiğinde (deadlock) bu probe devreye girer.
- Readiness Probe: Konteynerin trafik almak için "hazır" olup olmadığını kontrol eder. Bu probe başarısız olursa, Kubernetes bu pod'a gelen trafiği geçici olarak keser. Uygulamanız başlarken veritabanı bağlantısı kurması veya büyük bir veri dosyasını yüklemesi gerekiyorsa, bu süreç bitene kadar trafik gönderilmemesi için idealdir.
Bu iki mekanizmayı doğru yapılandırmazsanız, Kubernetes uygulamanızın durumunu anlayamaz ve bu da kesintilere veya hatalı restart'lara yol açabilir.
Kubernetes probe'larını doğrudan Dockerfile'da tanımlayamayız, ancak Kubernetes'in kullanabileceği bir `HEALTHCHECK` komutu tanımlayabiliriz. Bu, konteyner imajının içine gömülü, temel bir sağlık kontrolüdür. Kubernetes manifest dosyanızda (`deployment.yaml`) bu komutu kullanabilir veya kendi probe tanımınızı yapabilirsiniz. İlk adım olarak Dockerfile'ımıza `HEALTHCHECK` ekleyelim.
Şu ayara çok dikkat etmelisiniz: Sağlık kontrolü, uygulamanızın gerçekten "sağlıklı" olduğunu anlatan bir endpoint'e veya komuta dayanmalı. Sadece process'in çalıştığını değil, kritik bağımlılıkların da (cache, DB) hazır olduğunu kontrol etmeli.
İşte tipik bir Node.js uygulaması için örnek bir Dockerfile:
Kod:
# Temel imajı belirle
FROM node:18-alpine
# Çalışma dizinini oluştur
WORKDIR /usr/src/app
# Paket dosyalarını kopyala ve bağımlılıkları yükle
COPY package.json ./
RUN npm ci --only=production
# Uygulama kaynak kodunu kopyala
COPY . .
# Uygulama portunu aç
EXPOSE 3000
# SAĞLIK KONTROLÜ (HEALTHCHECK) EKLEYELİM
# Bu komut, 30 saniye bekledikten sonra, her 10 saniyede bir,
# /health endpoint'ine istek atarak konteynerin sağlığını kontrol eder.
# 3 başarısız deneme sonunda konteyner 'unhealthy' olarak işaretlenir.
HEALTHCHECK --interval=10s --timeout=3s --start-period=30s --retries=3 \
CMD wget --quiet --tries=1 --spider http://localhost:3000/health || exit 1
# Uygulamayı başlat
CMD ["node", "server.js"]
Buradaki `--start-period=30s` parametresi çok önemli. Bu, konteynerin başlangıç aşaması için tanınan süredir. Bu süre içinde probe başarısız olsa bile konteyner "unhealthy" sayılmaz. Bu, uygulamanın başlama süresine göre mutlaka ayarlanmalıdır.
Dockerfile'daki `HEALTHCHECK` güzel bir başlangıçtır, ancak Kubernetes'te probe'ları manifest dosyasında ayrıntılı olarak yapılandırmak daha esnek ve güçlüdür. İşte aynı uygulama için bir `deployment.yaml` örneği. Burada hem `livenessProbe` hem de `readinessProbe` ayrı ayrı tanımlanmıştır.
YAML:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nodejs-app
spec:
replicas: 3
selector:
matchLabels:
app: nodejs-app
template:
metadata:
labels:
app: nodejs-app
spec:
containers:
- name: nodejs-app
image: your-username/nodejs-app:latest
ports:
- containerPort: 3000
# Liveness Probe: Uygulama canlı mı?
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 30 # Konteyner başladıktan 30 saniye sonra ilk kontrol.
periodSeconds: 10 # Her 10 saniyede bir kontrol et.
timeoutSeconds: 3 # 3 saniye içinde cevap vermezse timeout.
failureThreshold: 3 # 3 kez ard arda başarısız olursa, konteyneri yeniden başlat.
# Readiness Probe: Uygulama trafik almaya hazır mı?
readinessProbe:
httpGet:
path: /health/ready # Daha detaylı bir "hazırlık" endpoint'i örneği.
port: 3000
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 2
successThreshold: 1
failureThreshold: 2 # 2 kez başarısız olursa, pod'u "Not Ready" yap ve trafiği kes.
resources:
requests:
memory: "128Mi"
cpu: "100m"
Gördüğünüz gibi, `readinessProbe` için farklı bir endpoint (`/health/ready`) kullandım. Bu endpoint'in, uygulamanın tüm harici bağımlılıklarına (veritabanı, redis, vs.) erişimi kontrol etmesi benim önerimdir. Böylece bağımlılıklardan biri çökse bile, Kubernetes bu pod'a yeni trafik göndermez ve kullanıcılar hata almaz.
1. Endpoint Güvenliği: `/health` gibi endpoint'lerinizi dış dünyaya açık bırakmayın. Sadece internal cluster network'ünden erişilebilir olmalılar. Eğer dışarıya açmanız gerekiyorsa, basit bir IP kısıtlaması veya secret header kontrolü ekleyin.
2. Zaman Ayarı (Timeouts): `timeoutSeconds` değerini, uygulamanızın ortalama cevap süresinin biraz üzerinde tutun. Çok düşük bir timeout, sağlıklı pod'ların yanlışlıkla öldürülmesine neden olabilir.
3. Başlangıç Gecikmesi (Initial Delay): `initialDelaySeconds` değeri, uygulamanızın ayağa kalkma süresinden kesinlikle daha uzun olmalı. Aksi takdirde uygulamanız henüz başlamadan probe kontrolü yapılır ve pod sürekli restart yer. Bunu ölçmek için test ortamında birkaç deneme yapmanızı şiddetle tavsiye ederim.
4. Komut Tabanlı Probe: Eğer HTTP endpoint'iniz yoksa, `exec` komutu ile bir script çalıştırarak da probe yapabilirsiniz. Örneğin:
YAML:
livenessProbe:
exec:
command:
- cat
- /tmp/app-is-healthy
Docker konteynerlerinize `HEALTHCHECK` eklemek ve Kubernetes deployment'larınızda `livenessProbe` ile `readinessProbe`'ları doğru yapılandırmak, production'daki uygulama dayanıklılığınızı (resilience) inanılmaz artırır. Bu sayede uygulamalarınız kendi kendini iyileştirebilir (self-healing) ve kullanıcılarınıza kesintisiz hizmet verebilir.