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.
Kısa cevap
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. Probe’ların kendi içindeki ayrımı — liveness neyi, readiness neyi ölçmeli — health check tasarımı kaydında ayrıntılandırmıştım.
Neden
- 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.
- Kavramların sahibi Kubernetes tarafıdır. 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.
- 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. - HEALTHCHECK’in bir bedeli var.
CMD curlimajdacurlgerektirir (distroless’ta yoktur). 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.
Ne yapmalı
-
Probe’ları Deployment/Pod spec’inde tanımlayın. Trafiği ve restart’ı asıl belirleyen katman burasıdır; readiness, liveness ve startup’ı burada açıkça yazın.
# 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 -
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’i ya doğru biçimde yazın ya da düşürün.
CMD curlyerine binary’nizin kendihealthchecksubcommand’ını exec edin; imaj yalnızca k8s’te koşacaksa HEALTHCHECK’i tamamen atın.# Yalnızca Compose/düz Docker altında da koşacaksa anlamlı: HEALTHCHECK --interval=10s --timeout=2s --retries=3 \ CMD ["/app/server", "healthcheck"] -
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.
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.