# Container'daki healthcheck'i Dockerfile'a mı yazmalıyım yoksa Kubernetes probe'larına mı bırakmalıyım?

> Readiness, liveness ve startup'ı Kubernetes probe'ları olarak tanımlayın; HEALTHCHECK'i yalnız imaj Compose'da da koşuyorsa tutup aynı endpoint'e bağlayın.

- Soruldu: 2026-07-19
- Yanıtlandı: 2026-07-21
- Soran: Elif
- Etiketler: docker, kubernetes, guvenilirlik
- Kaynak: https://muhammetsafak.com/tr/sor-bakalim/containerdaki-healthchecki-dockerfilea-mi-yazmaliyim-yoksa-kubernetes-probelarina-mi-birakmaliyim/
- Dil: tr-TR
- Yazar: Muhammet Şafak

---
**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?


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](/tr/sor-bakalim/health-check-tasarimi-liveness-ve-readiness-ayrimi/) ayrıntılandırmıştım.

## Neden

1. **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.
2. **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.
3. **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.
4. **HEALTHCHECK'in bir bedeli var.** `CMD curl` imajda `curl` gerektirir (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ı

1. **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.

   ```yaml
   # 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
   ```

2. **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.
3. **HEALTHCHECK'i ya doğru biçimde yazın ya da düşürün.** `CMD curl` yerine binary'nizin kendi `healthcheck` subcommand'ını exec edin; imaj yalnızca k8s'te koşacaksa HEALTHCHECK'i tamamen atın.

   ```dockerfile
   # Yalnızca Compose/düz Docker altında da koşacaksa anlamlı:
   HEALTHCHECK --interval=10s --timeout=2s --retries=3 \
     CMD ["/app/server", "healthcheck"]
   ```

4. **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.

## İlgili Yazılar

- [Container'daki Go worker'ım SIGTERM almıyor ve graceful kapanmıyor, bu bir PID 1 sorunu mu?](https://muhammetsafak.com/tr/sor-bakalim/containerdaki-go-workerim-sigterm-almiyor-pid-1-sorunu/) — Sor Bakalım
- [Container'ı non-root çalıştırınca mount edilen storage dizinine yazamıyorum, izinleri nasıl çözerim?](https://muhammetsafak.com/tr/sor-bakalim/containeri-non-root-calistirinca-mount-edilen-storage-dizinine-yazamiyorum-izinleri-nasil/) — Sor Bakalım
- [Docker imaj boyutunu multi-stage build ve distroless ile nasıl küçültürüm?](https://muhammetsafak.com/tr/sor-bakalim/docker-imaj-boyutunu-multi-stage-ve-distroless-ile-kucultmek/) — Sor Bakalım
