İçeriğe Atla
Mustafa Erbay
Rehberler · 11 dk okuma · görüntülenme Read in English
100%

Uygulamanız 'Up' Ama Çalışmıyor: Docker İç Sağlık Kontrolü

Docker konteynerleri 'up' görünse de uygulamanın çalışmadığı durumlar için sağlam sağlık kontrolleri (HEALTHCHECK) nasıl yazılır, adım adım anlatıyorum.

Docker konteynerinin 'Up' durumunda görünmesine rağmen içinde çalışan uygulamanın sağlıksız olduğunu gösteren bir illüstrasyon.

Geçtiğimiz kış, bir üretim ERP’sinde kritik bir entegrasyon servisimiz vardı. Gece 02:00 sularında, sistem monitörümde her şeyin yeşil olduğunu görüyordum; docker ps çıktısında servis “Up” durumundaydı. Ancak operatör ekranları boştaydı, üretim bandından veri gelmiyordu. Panik içinde loglara daldığımda, servisin dışarıdaki bir API’ye bağlanamadığını fark ettim.

İşte bu durum, “Up” görünen bir konteynerin aslında “sağlıklı” olmadığı anlamına gelir. Docker, sadece ana process’in çalışıp çalışmadığına bakar, uygulamanın gerçekten işlevsel olup olmadığını bilemez. Bu yazıda, bu tür yanıltıcı durumları aşmak ve Docker konteynerlerimizde sağlam iç sağlık kontrolleri (HEALTHCHECK) nasıl yazarız, adım adım anlatacağım.

Neden ‘Up’ Ama ‘Çalışmıyor’ Durumuna Düşüyoruz?

Bu, benim de sıkça karşılaştığım, genellikle kritik bir anda patlayan bir problem. Bir konteynerin ana process’i başarılı bir şekilde başlatıldığında Docker onu “Up” olarak işaretler. Ama bu, uygulamanın tüm bağımlılıklarının hazır olduğu veya iş mantığının doğru çalıştığı anlamına gelmez.

Bu tür durumlar genellikle birkaç farklı senaryodan kaynaklanır. Örneğin, uygulamanız ayağa kalkmış olabilir ama veritabanı bağlantısını henüz kuramamıştır veya dış bir API’den kritik konfigürasyonları çekememiştir. Kendi yan ürünümün backend’inde Redis bağlantısı koptuğunda, servis hala çalışıyor görünüyordu ama hiçbir istek cevap vermiyordu; bu da tipik bir “Up” ama “çalışmıyor” senaryosuydu.

Bu tür durumları tespit etmek ve otomatik olarak düzeltmek için Docker’ın HEALTHCHECK özelliğini kullanmak şart. Yoksa, ben de dahil, birçok sistem yöneticisi ve geliştirici, gece yarıları gelen uyarılarla uğraşmak zorunda kalırız.

Docker HEALTHCHECK Temelleri

Docker HEALTHCHECK, bir konteynerin içindeki uygulamanın gerçekten sağlıklı olup olmadığını periyodik olarak kontrol etmenizi sağlar. Eğer bir HEALTHCHECK başarısız olursa, Docker konteyneri “unhealthy” olarak işaretler ve bu bilgi orkestrasyon araçları (Docker Compose, Kubernetes) tarafından kullanılabilir.

Bir HEALTHCHECK talimatını Dockerfile’ınıza ekleyerek veya docker-compose.yml dosyanızda belirterek tanımlayabilirsiniz. En temel haliyle, uygulamanızın belirli bir HTTP endpoint’ine istek atıp başarılı bir yanıt almasını bekleriz.

# Dockerfile içinde HEALTHCHECK tanımlaması
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
  CMD curl --fail http://localhost:8080/health || exit 1

Burada kullandığım parametrelerin her birinin önemli bir anlamı var:

  • --interval=30s: Her 30 saniyede bir sağlık kontrolünü çalıştır. Çok sık kontrol, kaynak tüketimini artırabilir; çok seyrek kontrol, sorunları geç fark etmenize neden olabilir.
  • --timeout=10s: Sağlık kontrolü komutunun tamamlanması için maksimum 10 saniye bekle. Eğer bu süre içinde komut bitmezse, kontrol başarısız sayılır.
  • --start-period=5s: Konteyner başlatıldıktan sonra 5 saniye boyunca HEALTHCHECK sonuçlarını yok say. Bu süre, uygulamanın başlatma ve bağımlılıklarını yükleme süresini tanımak içindir. Bir üretim ERP’sinin boot süresi bazen 3 dakikayı buluyordu, start_period olmadan hep ‘unhealthy’ raporluyordu.
  • --retries=3: Bir HEALTHCHECK kaç kez başarısız olursa, konteyneri “unhealthy” olarak işaretle. Bu, geçici ağ sorunları gibi durumların yanlış alarm vermesini engeller.
  • CMD curl --fail http://localhost:8080/health || exit 1: Sağlık kontrolü için çalıştırılacak komut. curl --fail komutu, HTTP durum kodu 200 olmayan yanıtlar için sıfır olmayan bir çıkış kodu döndürür, bu da HEALTHCHECK’in başarısız olmasını sağlar.

Temel Bir HEALTHCHECK Tanımlaması

Basit bir web uygulamasını ele alalım, örneğin 8080 portunda çalışan bir FastAPI servisi. Bu servisin /health endpoint’inde 200 OK döndüğünü kontrol edebiliriz.

# Dockerfile
FROM python:3.9-slim-buster
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
EXPOSE 8080
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8080"]

HEALTHCHECK --interval=10s --timeout=5s --start-period=10s --retries=3 \
  CMD python -c "import socket; s = socket.create_connection(('localhost', 8080), timeout=1); s.close()" || exit 1

Burada curl yerine basit bir Python script’i kullandım. Neden mi? Çünkü curl veya wget gibi araçlar genellikle alpine tabanlı imajlarda varsayılan olarak gelmez ve bunları yüklemek imaj boyutunu artırır. Python’un dahili socket modülü ise çok daha hafif bir alternatiftir. Bu, benim de imaj boyutunu küçük tutmak istediğim projelerde sıkça başvurduğum bir yöntem.

Daha Akıllı HEALTHCHECK’ler Yazmak

Sadece bir portun dinleniyor olması veya bir /health endpoint’inin 200 OK dönmesi her zaman yeterli değildir. Uygulamanızın gerçek işlevselliğini yansıtan daha akıllı kontroller yazmamız gerekir.

Dış Bağımlılıkları Kontrol Etmek

Uygulamanızın veritabanı, Redis veya dış bir API gibi kritik bağımlılıkları varsa, HEALTHCHECK’in bunları da kontrol etmesi gerekir. Bir müşteri projesinde, ERP entegrasyon servisi, dışarıdaki bir iSCSI depolama birimine bağlanamadığında bile ‘Up’ kalıyordu. Buraya özel bir HEALTHCHECK eklememiz gerekti.

PostgreSQL Bağlantısı Kontrolü:

HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \
  CMD pg_isready -h localhost -p 5432 -U myuser || exit 1

Bu komut, PostgreSQL sunucusunun yerel makinede 5432 portunda myuser kullanıcısı ile bağlantı kurmaya hazır olup olmadığını kontrol eder. pg_isready aracı, PostgreSQL client paketleriyle birlikte gelir.

Redis Bağlantısı Kontrolü:

HEALTHCHECK --interval=15s --timeout=3s --start-period=10s --retries=5 \
  CMD redis-cli ping || exit 1

redis-cli ping komutu, Redis sunucusuna bir PING isteği gönderir ve yanıt alamazsa sıfır olmayan bir çıkış kodu döndürür. Bu da HEALTHCHECK’in başarısız olmasını sağlar.

Uygulama İçi Durum Kontrolü

Bazen uygulamanın kendi iç mantığını sorgulamak gerekir. Örneğin, bazı cache’ler dolu mu, belirli bir kuyrukta çok fazla mesaj mı var, yoksa bir iç servis hala görevlerini yerine getirebiliyor mu? Kendi geliştirdiğim Android spam blocker uygulamasının backend’inde, bazı cache’ler dolduğunda servis yavaşlıyordu. /health endpoint’ine cache durumunu da ekledim.

Bunu yapmak için uygulamanızda özel bir /healthz veya /readiness endpoint’i tanımlayabilirsiniz. Bu endpoint, sadece bir HTTP 200 OK döndürmekle kalmaz, aynı zamanda uygulamanın iç bağımlılıklarını ve kritik durum değişkenlerini de kontrol eder.

// Node.js Express uygulamasında /healthz endpoint örneği
app.get('/healthz', (req, res) => {
  const isDbConnected = checkDatabaseConnection(); // Veritabanı bağlantısını kontrol et
  const isRedisHealthy = checkRedisConnection();   // Redis bağlantısını kontrol et
  const isQueueProcessing = checkQueueStatus();     // Mesaj kuyruğu durumunu kontrol et

  if (isDbConnected && isRedisHealthy && isQueueProcessing) {
    res.status(200).send('Healthy');
  } else {
    res.status(503).send('Unhealthy');
  }
});

Ardından, Dockerfile içindeki HEALTHCHECK komutunu bu endpoint’i sorgulayacak şekilde güncelleyebiliriz:

HEALTHCHECK --interval=20s --timeout=5s --start-period=15s --retries=3 \
  CMD curl --fail http://localhost:8080/healthz || exit 1

Bu yaklaşım, uygulamanızın gerçek zamanlı durumunu çok daha doğru bir şekilde yansıtır ve yanıltıcı “Up” durumlarının önüne geçer.

HEALTHCHECK Parametrelerini Optimize Etmek

HEALTHCHECK parametreleri, uygulamanızın ve ortamınızın gereksinimlerine göre dikkatlice ayarlanmalıdır. Yanlış ayarlar, gereksiz yeniden başlatmalara veya sorunların geç fark edilmesine neden olabilir.

| Parametre | Açıklama | Optimizasyon İpuçları

Paylaş:

Bu yazı faydalı oldu mu?

Yükleniyor...

Bu yazı nasıldı?

ME

Mustafa Erbay

Sistem Mimarisi · Network Uzmanı · Altyapı, Güvenlik ve Yazılım

2006'dan bu yana sistem mimarisi, network, sunucu altyapıları, büyük yapıların kurulumu, yazılım ve sistem güvenliği ekseninde çalışıyorum. Bu blogda sahada karşılığı olan teknik deneyimlerimi paylaşıyorum.

Kişisel Notlar

Bu notlar sadece sizde saklanır. Tarayıcınızda yerel olarak tutulur.

Hazır 0 karakter

Yorumlar

Sunucu Taraflı AI Moderasyon

Yorumlar sunucuda yapay zeka ile denetlenir ve kalıcı olarak saklanır.

?
0/2000

Sunucu taraflı AI denetim

✉️ Ücretsiz · Spam yok · İstediğin an çık

Haftalık özet — AI değil, bizzat ben seçiyorum

Haftada bir mail: o haftanın en önemli yazısı, perde arkası notları, ve "bu hafta gerçekten kullandığım araç" bölümü. Az gürültü, çok sinyal.

  • 📌
    Haftanın en iyisi Sadece okumaya değer tek yazı
  • 🔧
    Alet çantası Bu hafta kullandığım araçlar
  • 🧠
    Perde arkası Blog'a girmeyen notlar

Spam yapmıyoruz. İstediğiniz zaman ayrılabilirsiniz. · Sadece Umami (self-hosted, Google yok) ile takip.

Okuma İstatistikleriniz

0

Yazı Okundu

0dk

Okuma Süresi

0

Gün Serisi

-

Favori Kategori

İlgili Yazılar