Container'daki healthcheck'i Dockerfile'a mı yazmalıyım yoksa Kubernetes probe'larına mı bırakmalıyım?
Soru
İmajımda bir `HEALTHCHECK` tanımlı ama Kubernetes bunu görmezden geliyor gibi. Bir yandan da Deployment spec'inde readiness/liveness probe'ları var. Hangi katmanın "hazır mıyım" kararını sahiplendiğini çıkaramıyorum. Healthcheck'i Dockerfile'a mı yazmalıyım, Kubernetes probe'larına mı bırakmalıyım, yoksa ikisi birden mi olmalı? Aralarındaki ilişki tam olarak nedir?
Cevap
Kısa cevap: Kubernetes’te readiness/liveness’ı probe’lar sahiplenir; kubelet, imajdaki HEALTHCHECK durumunu tasarım gereği hiç okumaz. Ama HEALTHCHECK’i Compose/düz Docker için tutmakta fayda var — çöp değil, sadece farklı bir runtime içindir.
Kafa karışıklığı anlaşılır: iki katman da sağlığı sahipleniyormuş gibi görünür, ama belirli bir runtime’da gerçekten yalnızca biri dikkate alınır. Önce imajın gerçekte hangi runtime’da koşacağını netleştirin; cevap kendiliğinden oradan çıkar.
- Kubernetes, Dockerfile HEALTHCHECK’i tasarım gereği yok sayar. kubelet kendi liveness/readiness/startup probe’larını çalıştırır ve imajın HEALTHCHECK sonucunu hiç okumaz. Yani k8s’te bu satır ölü ağırlıktır — zararsız ama trafiği belirleyen şey değildir.
- Hangi katman neyi sahiplenir. Readiness (trafik geçişi), liveness (restart) ve startup (yavaş boot) kavramlarının hepsi Kubernetes probe kavramlarıdır. “Bu pod servis verebilir mi?” kararını sahiplenen katman budur; onları Deployment/Pod spec’inde tanımlayın.
- Docker/Compose HEALTHCHECK’e uyar. Lokal geliştirmede Compose’un
depends_on: condition: service_healthyözelliği ve düz Docker/Swarm, container’ı “healthy” olarak işaretlemek için HEALTHCHECK’i kullanır. Yani işe yaramaz değildir; sadece farklı bir tüketiciye hizmet eder. - Mantığı çoğaltmayın, endpoint’i paylaşın. Aynı
/healthz(liveness) ve/readyz(readiness) HTTP endpoint’lerini açın; hem Dockerfile HEALTHCHECK’ini hem de k8s probe’larını bunlara yöneltin. Tek implementasyon, iki tüketici. - HEALTHCHECK’in bir bedeli var.
CMD curlimajdacurlgerektirir (distroless’ta yoktur); bunun yerine binary’nizin kendihealthchecksubcommand’ını exec edin, ya da imaj yalnızca k8s’te koşacaksa HEALTHCHECK’i tamamen atın. Shell formundaki bir HEALTHCHECK ayrıca her interval’da bir süreç başlatır; sonucu hiç okunmayan bir container’da bu boşa iştir. - Probe’ları ucuz ve doğru tutun. Aynı altın kural: liveness bağımlılıksız olsun, readiness bağımlılıkları kontrol etsin ama sonucunu birkaç saniye cache’lesin. Aksi hâlde probe’lar veritabanınızı DDoS’lar.
# Yalnızca Compose/düz Docker altında da koşacaksa anlamlı:
HEALTHCHECK --interval=10s --timeout=2s --retries=3 \
CMD ["/app/server", "healthcheck"]
# Kubernetes'te trafiği ve restart'ı asıl belirleyen katman budur:
readinessProbe:
httpGet: { path: /readyz, port: 8080 }
periodSeconds: 5
livenessProbe:
httpGet: { path: /healthz, port: 8080 }
periodSeconds: 10
Sonuç: Ben olsam readiness/liveness/startup’ı Kubernetes probe’ları olarak tanımlardım — çünkü trafiğe ve restart’a karar veren katman odur. HEALTHCHECK’i Dockerfile’da yalnızca aynı imaj Compose/düz Docker altında da koşuyorsa, ikisini de aynı /healthz + /readyz endpoint’lerine bağlayarak tutardım. İmaj sadece k8s içinse, “bir şey yapıyor” yanılsamasını önlemek için HEALTHCHECK’i düşürürdüm.
Yorumlar
Yorum yapmak için GitHub hesabınızla giriş yapmanız yeterli. Yorumlar GitHub Discussions üzerinde saklanır.