Mart 7 2025

Zabbix LLD ve Host Prototipleri ile Dinamik Altyapı Monitoring Otomasyonu

Altyapıyı “kod olarak” (Infrastructure as Code) yönettiğimiz, Kubernetes cluster’larının havada uçuştuğu modern dünyada, izleme sistemine manuel olarak host eklemek kabul edilebilir bir durum değil. SRE ekipleri olarak her yeni servis deploy edildiğinde Zabbix arayüzüne girip elle template bağlamakla zaman kaybedemeyiz. İşte tam bu noktada, ölçeklenebilir ve sıfır dokunuşlu (zero-touch) bir monitoring mimarisi kurmak için zabbix altyapısının sunduğu Low-Level Discovery (lld) ve otomatik discovery mekanizmalarını devreye almamız gerekiyor.

Bu makalede, teorik tanımları bir kenara bırakıp doğrudan üretim ortamında (production) çalışan, dinamik Docker container’larını otomatik olarak keşfeden ve bunları izleyen uçtan uca bir LLD senaryosu kurgulayacağız. Amacımız, yeni bir container ayağa kalktığında Zabbix’in bunu otomatik olarak algılaması, item’ları ve trigger’ları dinamik olarak oluşturması ve hatta gerekirse host prototipleri üzerinden yeni host’lar yaratmasıdır. Bu sayede izleme süreçlerinde tam bir otomasyon sağlayacağız.

Neden Yerleşik Şablonlar Yetmiyor? (Neden LLD?)

Zabbix standart disk, network interface veya CPU çekirdeklerini keşfetmek için zaten hazır LLD kuralları sunar. Ancak iş kendi yazdığınız mikroservislere, dinamik portlarda çalışan API’lere veya sistemdeki Docker container’larına geldiğinde standart şablonlar çaresiz kalır. Kendi LLD yapımızı kurmak zorundayız çünkü:

  • Her mikroservisin kaynak tüketim limiti ve threshold değerleri farklıdır.
  • Dinamik olarak ölçeklenen (auto-scale olan) ortamlarda statik tanımlar çöker.
  • İzleme yükünü (monitoring overhead) minimize etmek için sadece “aktif” olan kaynakları dinlememiz gerekir.

LLD’nin çalışma mantığı basittir: Zabbix Agent veya bir external script, Zabbix Server’a JSON formatında bir veri döndürür. Bu JSON verisi içinde yer alan özel makrolar (örneğin {#CONTAINERNAME}), Zabbix tarafından işlenerek prototiplerden gerçek Item ve Trigger’lar türetilmesini sağlar.

Adım 1: Dinamik JSON Payload Üreten Keşif Scripti

İlk olarak, hedef sunucuda çalışan Docker container’larını keşfedecek ve Zabbix’in anlayacağı LLD JSON formatını üretecek bir Bash script yazalım. Scriptimizin jq bağımlılığı olacak, bu yüzden hedef sunucuda kurulu olduğundan emin olun.

#!/usr/bin/env bash
# /etc/zabbix/scripts/docker_discovery.sh
# Amacımız çalışan container adlarını ve ID'lerini JSON dizisi olarak dönmek.

set -e

# Docker daemon'a erişim kontrolü
if ! docker ps --format '{{.Names}}' > /dev/null 2>&1; then
    echo '{"error": "Docker daemon not reachable or permission denied"}'
    exit 1
fi

# Zabbix 5.0+ için uyumlu modern LLD JSON formatı
docker ps --format '{{.Names}}' | jq -R -s -c '
  split("\n") | 
  map(select(length > 0)) | 
  map({"{#CONTAINERNAME}": ., "{#CONTAINERID}": .[:12]})
'

Neden bu scripti yazdık? Zabbix, LLD kurallarında veri beklerken anahtar-değer çiftlerinden oluşan bir liste ister. Yukarıdaki script çalıştığında bize tam olarak şu çıktıyı verir:

[{"{#CONTAINERNAME}":"web-api-prod","{#CONTAINERID}":"a3f89e12bcd3"},{"{#CONTAINERNAME}":"postgres-db","{#CONTAINERID}":"f8d72110ebd2"}]

Adım 2: Zabbix Agent Entegrasyonu (UserParameter)

Hazırladığımız scripti Zabbix Agent’a bir anahtar (key) olarak tanıtmalıyız. Ancak burada kritik bir production detayı var: Zabbix Agent varsayılan olarak zabbix kullanıcısıyla çalışır ve bu kullanıcının Docker socket’ine (/var/run/docker.sock) erişim yetkisi yoktur. Bu yetki sorununu çözmezsek script boş dönecektir.

Öncelikle zabbix kullanıcısını docker grubuna ekleyin:

sudo usermod -aG docker zabbix
# Değişikliklerin geçerli olması için agent'ı restart edin
sudo systemctl restart zabbix-agent2 # veya zabbix-agent

Şimdi agent konfigürasyon dizininde yeni bir dosya oluşturalım ve UserParameter tanımımızı yapalım. Aynı zamanda container’ların CPU tüketimini de çekeceğimiz dinamik bir item anahtarı tanımlıyoruz:

# /etc/zabbix/zabbix_agentd.d/docker_monitoring.conf

# Keşif kuralı için UserParameter
UserParameter=custom.docker.discovery,/etc/zabbix/scripts/docker_discovery.sh

# Keşfedilen her container için veri toplayacak dinamik parametre
# $1 parametresi container adını temsil eder ({#CONTAINERNAME})
UserParameter=custom.docker.cpu[*],docker stats --no-stream --format "{{.CPUPerc}}" "$1" | tr -d '%'

Konfigürasyonu yüklemek için agent’ı reload edin:

sudo zabbix_agentd -R config_cache_reload

Zabbix Server veya Proxy üzerinden bu anahtarın çalışıp çalışmadığını zabbix_get ile test edin (SRE altın kuralı: Test etmediğin şey çalışmıyordur):

zabbix_get -s 127.0.0.1 -k custom.docker.discovery
zabbix_get -s 127.0.0.1 -k custom.docker.cpu[web-api-prod]

Adım 3: Zabbix Arayüzünde LLD Rule Tanımlama

Zabbix UI üzerinden bir Template oluşturun (örneğin: Template App Custom Docker LLD). Bu template içine gidip Discovery Rules sekmesini açın ve “Create discovery rule” butonuna tıklayın.

  • Name: Docker Container Discovery
  • Type: Zabbix agent (veya aktif agent kullanıyorsanız active)
  • Key: custom.docker.discovery
  • Update interval: 1h (Üretim ortamında docker container listesi sürekli değişmiyorsa bu süreyi uzun tutun. Dakika başı keşif yapmak veritabanına yük bindirir.)
  • Keep lost resources period: 7d (Kapanan container’ların verilerinin hemen silinmemesi, trend analizi için önemlidir.)

Item Prototypes Oluşturma

Oluşturduğumuz Discovery Rule içerisine girip Item Prototypes sekmesine tıklıyoruz. Burada dinamik olarak üretilecek item’ı tanımlayacağız.

  • Name: Container {#CONTAINERNAME} CPU Usage
  • Key: custom.docker.cpu[{#CONTAINERNAME}]
  • Type of information: Numeric (float)
  • Units: %

Buradaki sihir {#CONTAINERNAME} makrosundadır. Zabbix scriptten dönen JSON’daki her bir obje için otomatik olarak bu item’ı türetecektir.

Adım 4: Akıllı Trigger Prototipleri ve Bağlam (Context) Makroları

Her container aynı hassasiyete sahip değildir. Örneğin, bir kuyruk işleyici (worker) container’ı sürekli %95 CPU ile çalışabilir ve bu normaldir. Ancak ana veritabanı container’ının %90 CPU tüketmesi kriz demektir. Statik trigger limitleri yazarsanız, gecenin üçünde gereksiz alert’ler (alert fatigue) ile uyanırsınız.

Bunu çözmek için Zabbix’in “User macros with context” özelliğini trigger prototipinde kullanacağız.

Bir Trigger Prototype oluşturun:

  • Name: Container {#CONTAINERNAME} high CPU utilization
  • Expression:
    last(/Template App Custom Docker LLD/custom.docker.cpu[{#CONTAINERNAME}]) > {$DOCKER_CPU_LIMIT:"{#CONTAINERNAME}"}
  • Severity: Average

Neden böyle yaptık? Şablon seviyesinde genel bir makro tanımlayacağız: {$DOCKER_CPU_LIMIT} = 85. Ancak belirli bir container (örneğin postgres-db) için bu limiti düşürmek veya yükseltmek istersek, o host’un makrolarına gidip sadece {$DOCKER_CPU_LIMIT:postgres-db} = 70 yazmamız yeterli olacaktır. Zabbix, LLD çalışırken spesifik makroyu bulamazsa global varsayılana geri döner.

Adım 5: Host Prototipleri ile Tam Otomasyon

Senaryoyu bir adım öteye taşıyalım. Sadece item ve trigger değil, keşfedilen her dinamik yapı için Zabbix üzerinde bağımsız birer Host oluşturmak istiyorsak ne yapacağız? Örneğin, her bir Kubernetes Namespace’ini veya dinamik AWS VPC’lerindeki hypervisor’leri kendi şablonlarıyla ayrı birer host olarak izlemek istiyoruz.

Oluşturduğumuz Discovery Rule içinde Host Prototypes sekmesine gelin:

  • Host name: Docker_Host_{#CONTAINERNAME}
  • Visible name: Docker Container {#CONTAINERNAME}
  • Templates: İzlemek istediğiniz diğer alt şablonları buraya bağlayın (örneğin işletim sistemi bazlı veya uygulama bazlı standart şablonlar).
  • Host groups: Dinamik host’ların hangi grupta toplanacağını seçin (örneğin Discovered Containers).
  • Interfaces: Eğer container’lara doğrudan IP üzerinden erişilecekse, JSON payload’dan gelen {#CONTAINER_IP} makrosunu buraya gömebilirsiniz.

Bu yöntemle, Zabbix altyapınızda hiçbir manuel müdahale olmadan, sadece arka planda çalışan container veya servislerin durumuna göre yüzlerce host’un otomatik olarak yaratılıp, sistemden kaldırıldıklarında ise (belirttiğiniz retention süresi sonunda) otomatik temizlendiğini göreceksiniz.

SRE İçin Performans ve İnce Ayarlar

LLD büyük bir güçtür ancak yanlış yapılandırıldığında Zabbix Server ve veritabanı üzerinde ciddi bir darboğaza (bottleneck) yol açar. Production ortamlarında şu kurallara mutlaka uyun:

  1. Preprocessing Kullanın: JSON payload çok büyükse, Zabbix Agent tarafında bunu filtrelemek için Preprocessing adımlarında JSONPath veya Discard unchanged with heartbeat kullanın. Değişmeyen veriyi sürekli veritabanına yazarak I/O tüketmeyin.
  2. Timeout Değerlerini Artırın: Docker veya bulut API’lerine sorgu atan scriptler bazen 3 saniyeden uzun sürebilir. zabbix_server.conf ve zabbix_agentd.conf dosyalarındaki varsayılan Timeout=3 değerini Timeout=30 olarak güncelleyin.
  3. LLD Kuyruk Takibi: Zabbix Administration -> Queue altından LLD kurallarının birikip birikmediğini periyodik olarak kontrol edin. Eğer birikme varsa, StartDiscoverers parametresini server konfigürasyonunda artırın.

Sonuç olarak, LLD kullanarak izleme altyapınızı statik bir yapıdan, kendi kendini yöneten (self-healing / self-discovering) dinamik bir organizmaya dönüştürmüş oldunuz. Artık yeni servislerin monitör edilmesi işini tamamen otomasyona bırakıp kahvenizi yudumlayabilirsiniz.

Etiketler: , , , ,
Copyright 20254541. All rights reserved.

Posted 7 Mart 2025 by Kerem Danış in category "Genel