Docker Healthcheck Komutları ile Servis Durumu Nasıl İzlenir?

Bir Docker konteyneri “çalışıyor” durumunda görünse bile uygulama içerde hiçbir yanıt üretmiyor olabilir. Port kapanabilir, işlem kilitlenebilir veya veritabanı bağlantısı başarısız olabilir. Healthcheck, bu sessiz şekilde oluşan hataları otomatik olarak fark etmek için kullanılır. Sağlıklı bir kontrol mekanizması ise uygulama içinde oluşturulan hafif bir health endpoint’e bağlıdır. Çünkü sistemdeki gerçek durumu en açık biçimde bu küçük kontrol noktası gösterir.

Konteynerlerde HEALTHCHECK Tanımlama

Dockerfile’a healthcheck eklemek için ilk olarak temel yapının oluşturulması gerekir. Örneğin bir Node.js uygulaması geliştirdiğimizi varsayalım. İlk adım olarak Dockerfile dosyasını açıp gerekli alanları düzenleyelim.

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 1

Bu tanımla uygulamanın /health endpoint’ine her 20 saniyede bir sorgu gönderilir. Cevap 5 saniyelik zaman diliminde gelmezse kontrol başarısız sayılır. Bu başarısızlık üç defa arka arkaya gerçekleşirse Docker konteyneri unhealthy olarak işaretlenir.

Healthcheck İçindeki Parametreleri Anlama

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 ps

STATUS 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.

Endpoint Olmadan Healthcheck Nasıl Yapılı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 1

Ya da port seviyesinde minimal bir kontrol yapmak istersek

HEALTHCHECK CMD nc -z localhost 8080 || exit 1

Buradaki 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 Network Driver Çeşitleri Nelerdir? 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 çok düşük ayarlanırsa, yüksek yük altında gereksiz hata sonuçları üretebilir. Bunun yanında healthcheck’in sürekli başarısız görünmesinin en sık nedenlerinden biri container’ın hatalı Docker ağına bağlı olmasıdır. Servis aktif olsa bile curl endpoint’e ulaşamazsa test başarısız sayılır ve loglarda network not found uyarısı görülür.

Sorunun çözümü için hazırladığımız Docker Ağ Bulamıyor ‘network not found’ Hatası Pratik Çözümü rehberinde, ağı yeniden doğru şekilde oluşturmak için gereken tüm adımları paylaştı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"}, 200

PHP

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

Yorum yapın