Docker konteyneri ayakta görünebilir fakat uygulama gerçekte cevap vermiyor olabilir. Port kapanabilir, işlem durabilir veya veritabanı bağlantısı düşebilir. Healthcheck, bu sessiz şekilde oluşan sorunları otomatik olarak tespit etmek için devreye girer. Bunun doğru çalışması, uygulama içinde tanımlanan hafif bir health endpoint sayesinde mümkündür. Çünkü sistemin gerçek durumunu en net şekilde ortaya koyan yer bu küçük kontrol adresidir.
Docker Healthcheck Komutu Nasıl Tanımlanır?
Healthcheck tanımlamak için Dockerfile içinde önce temel şablonu oluşturalım. Bu örnekte bir Node.js uygulamasının çalıştığını kabul edelim. Başlangıç olarak Dockerfile’ı açalım ve ihtiyaç duyulan kısımları ekleyelim.
FROM node:18-alpine
WORKDIR /app
COPY . .
RUN npm install
# Buraya healthcheck ekleyeceğizŞimdi healthcheck’i ekleyelim
HEALTHCHECK --interval=20s --timeout=5s --retries=3 \
CMD wget -qO- http://localhost:3000/health || exit 1Böylelikle her 20 saniyede bir uygulamanın /health endpoint’ine istek gönderiyoruz. Cevap 5 saniye içinde gelmezse test başarısız sayılıyor. Bu durum 3 kez tekrar ederse Docker konteyneri unhealthy olarak işaretliyor.
Healthcheck Parametreleri Nasıl Çalışır?
Healthcheck’i doğru kurgulamak için kullanılan parametrelerin ne işe yaradığını şöyle özetleyelim.
–health-cmd
Konteynerin durumunu test etmek için çalıştırılacak komutu belirtir. Bu komutun döndürdüğü sonuç sağlık bilgisini belirler.
–health-interval
Kontrolün hangi periyotlarla yapılacağını ifade eder. Örneğin 5 saniyelik bir değer, testin her beş saniyede bir tekrar edeceği anlamına gelir.
–health-retries
Bir kontrol başarısız olduğunda kaç kez daha tekrar test yapılacağını belirler. Bu sayı aşılırsa konteyner sağlıksız kabul edilir.
–health-start-interval
Konteyner çalışır çalışmaz sağlık kontrolünü hemen başlatmak yerine belirli bir süre beklemesini sağlar. Özellikle açılış süresi uzun olan uygulamalarda başlangıç hatalarını engeller.
–health-start-period
Uygulamanın başlangıç aşamasında yapılacak kontrollerin daha toleranslı olmasını sağlar. Başlangıç evresinde meydana gelen hataların yok sayılmasına yardımcı olur.
–health-timeout
Çalıştırılan sağlık komutunun en geç ne kadar süre içinde yanıt vermesi gerektiğini belirler. Süre aşılırsa kontrol otomatik olarak başarısız sayılır.
–no-healthcheck
Bu seçenek kullanıldığında konteyner için sağlık testi tamamen devre dışı bırakılmış olur.
Terminalde Sağlık Durumunu Kontrol Edelim
Konteyneri çalıştırdıktan sonra terminalde durumunu görebiliriz.
docker psSTATUS kısmında şöyle bir şey görebiliriz
healthy (2s ago)Daha detay görmek istersek eğer
docker inspect <container-id>Burada son healthcheck log’larını dakikası dakikasına görürsün. Uygulama nerede takılmış, komut ne cevap vermiş, prolemin sebebi timeout hatası mı hepsi burada gözükür.
Health Endpoint Bulunmuyorsa İzleme Nasıl Sağlanır?
Her projede /health endpoint’i olmayabilir. Bu tür durumlarda servisin portunu gerçekten dinleyip dinlemediğini basit bir komutla kontrol edebiliriz.
HEALTHCHECK CMD curl --fail http://localhost:8080 || exit 1Ya da port seviyesinde minimal bir kontrol yapmak istersek
HEALTHCHECK CMD nc -z localhost 8080 || exit 1Buradaki amaç, servisin yalnızca “ayakta durup durmadığını” değil, gerçekten erişilebilir olup olmadığını test etmektir.
Healthcheck testlerinin sağlıklı sonuç verebilmesi için container’ın doğru network üzerinde konumlandırılması da önemli.
Docker ağ sürücüleri ve özel ağ tanımlarıyla ilgili daha detaylı bir inceleme istersen, Docker Driver Çeşitleri Neler? Docker’da Özel Ağ Oluşturma yazısına da göz atabilirsin.
Healthcheck Yazarken Karşılaşılan Sorunlar
Healthcheck mantığı basit görünse de yanlış kurgulandığında sistemi gereksiz yere yorabilir. Mesela healthcheck içine büyük bir database sorgusu koyarsak, her 10 saniyede bir konteyneri kendi testinle boğmaya başlarız. Bunun yerine çok hafif bir kontrol mekanizması kullanılıyor olması gerekir. Küçük bir JSON dönen endpoint idealdir.
{"status": "ok"}Timeout değerinin gereğinden düşük olması, yoğun dönemlerde gereksiz başarısızlıklara yol açabilir. Ayrıca healthcheck’in sürekli hatalı görünmesine sebep olan yaygın durumlardan biri de container’ın yanlış Docker ağına bağlanmasıdır. Servis çalışsa bile curl hedefe erişemezse test otomatik olarak başarısız olur ve loglarda network not found hatası ortaya çıkar.
Bu sorunu çözmek için hazırladığımız Docker “network not found” Hatası Nasıl Giderilir? rehberinde ağın doğru şekilde yeniden oluşturulması için gereken adımları anlattık.
Gerçek Bir Health Endpoint Nasıl Olmalı?
Basit, hızlı ve gereksiz yük oluşturmayan bir kontrol noktası tanımlamak yeterlidir.
Node.js
app.get("/health", (req, res) => {
<br> res.status(200).json({ status: "ok", time: Date.now() });<br>
});Python Flask
@app.route('/health')<br>
def health():<br>
return {"status": "ok"}, 200PHP
<?php<br>
echo json_encode(["status" => "ok"]);Bu endpoint yalnızca uygulamanın canlı olduğunu doğrular.
Sık Sorulan Sorular
Aynı container içinde birden fazla healthcheck tanımlanabilir mi?
Dockerfile yalnızca tek bir HEALTHCHECK direktifi kabul eder. Ancak birden fazla bileşeni test etmek istersen tek bir script yazıp script içinde birden fazla kontrol yapabilirsin.
Healthcheck ile container yeniden başlamıyorsa sorun ne olabilir?
Docker’ın restart politikası aktif değilse healthcheck konteyneri sadece ‘unhealthy’ olarak işaretler, fakat yeniden başlatmaz. Otomatik restart için container şu şekilde çalıştırılmalıdır:
docker run --restart=on-failure ...Healthcheck içinde curl kullanmak yerine kendi binary’imi çalıştırabilir miyim?
Healthcheck özel scriptler, Go/Python binary’leri hatta kendi healthcheck tool’larınla da çalışabilir. Önemli olan testin hızlı çalışması ve sadece exit code üzerinden başarı durumunu iletmesidir.