Mart 7 2025

Zabbix LLD (Low-Level Discovery) ile Dinamik Monitoring Otomasyonu

Altyapınız büyüdükçe, her yeni mikroservis, disk, network arayüzü veya veritabanı instance’ı için manuel konfigürasyon yapmak tam bir kabusa dönüşür. Eğer her yeni deployment’ta Zabbix API’sine koşup item oluşturmaya çalışıyorsanız ya da daha kötüsü, arayüzden tek tek elle ekleme yapıyorsanız, geçmiş olsun; race condition’ların ve kilitlenen Zabbix veritabanlarının dünyasına hoş geldiniz. Altyapınızda gerçek anlamda bir otomasyon ve modern bir monitoring kurgulamak istiyorsanız, başvuracağınız yegane mekanizma zabbix lld (Low-Level discovery) mimarisidir.

Bu yazıda, teorik gevezelikleri bir kenara bırakıp, 5+ yıl deneyimli bir SRE’nin production ortamında doğrudan kullanabileceği, custom bir LLD mekanizmasını sıfırdan nasıl inşa edeceğimizi adım adım ele alacağız. Hedefimiz: Sunucu üzerinde koşan dinamik Docker container portlarını otomatik keşfeden, bunlara dinamik item’lar atayan ve port kapandığında alarm üreten bir kurgu oluşturmak.

Neden Standart Agent Keşfi Değil de LLD?

Zabbix’in standart active agent auto-registration mekanizması yeni bir host’u sisteme dahil etmek için harikadır. Ancak host sisteme dahil olduktan sonra, o host’un “içindeki” değişken kaynakları (örneğin dinamik ayağa kalkan PostgreSQL container’ları, değişen disk partition’ları veya ephemeral portlar kullanan mikroservisler) izlemek standart şablonlarla mümkün değildir.

LLD bize şunu sağlar: Host üzerinde bir script çalışır, bize standart bir JSON çıktısı üretir ve Zabbix bu JSON’ı parse ederek her bir değişken için dinamik olarak Item, Trigger ve Graph prototiplerinden gerçek metrikler türetir. Sistemde artık olmayan kaynaklar ise “Keep lost resources period” süresi sonunda otomatik olarak silinir. Veritabanınız çöplerden temizlenmiş olur.

Adım 1: Custom LLD Scripti ve JSON Formatı

Zabbix LLD motorunun tek bir kutsal kuralı vardır: Scriptiniz her ne yapıyorsa yapsın, günün sonunda Zabbix’e geçerli bir JSON array’i döndürmek zorundadır. Modern Zabbix versiyonlarında (Zabbix 4.4+) artık klasikleşmiş {"data": [...]} sarmalayıcısına ihtiyacımız yok; doğrudan flat JSON array döndürebiliyoruz.

Öncelikle hedef sunucumuzda dinlenen aktif uygulama portlarını ve servis isimlerini bulan bir bash script yazalım. Bu scripti /usr/local/bin/discover_apps.sh yoluna kaydedeceğiz:

#!/bin/bash
# /usr/local/bin/discover_apps.sh

# Sunucuda koşan belirli servisleri ve portlarını dinle (Örn: java, node, python)
raw_ports=$(ss -tulpn | grep -E 'node|java|python|docker' | awk '{print $5}' | grep -oE '[0-9]+$' | sort -u)

first=1
echo "["

for port in $raw_ports; do
    # Port üzerinde koşan process adını bulalım
    app_name=$(ss -tulpn | grep -E ":$port " | awk '{print $7}' | cut -d'"' -f2 | head -n 1)
    
    if [ -z "$app_name" ]; then
        app_name="unknown-service"
    fi

    if [ [ $first -eq 0 ] ]; then
        echo ","
    fi
    
    echo "  {"
    echo "    \"{#APP_PORT}\": \"$port\","
    echo "    \"{#APP_NAME}\": \"$app_name\""
    echo "  }"
    first=0
done

echo "]"

Burada dikkat etmeniz gereken en kritik nokta macro isimlendirmeleridir. LLD makroları her zaman {#MACRO_NAME} formatında, süslü parantez ve diyez işaretiyle başlamalı ve büyük harfle yazılmalıdır. Bu scriptin çıktısı şu şekilde olacaktır:

[
  {
    "{#APP_PORT}": "8081",
    "{#APP_NAME}": "payment-api"
  },
  {
    "{#APP_PORT}": "9000",
    "{#APP_NAME}": "auth-service"
  }
]

Adım 2: Zabbix Agent Konfigürasyonu (UserParameter)

Zabbix sunucusunun bu scripti tetikleyebilmesi için hedef sunucudaki Zabbix Agent konfigürasyonuna (veya Agent 2) bir UserParameter eklememiz gerekiyor. Scripti çalıştırılabilir yapmayı ve Agent’a yetki vermeyi unutmayın.

chmod +x /usr/local/bin/discover_apps.sh

Şimdi /etc/zabbix/zabbix_agentd.d/userparameter_apps.conf dosyası oluşturup içerisine şu satırı ekleyelim:

UserParameter=custom.apps.discovery,/usr/local/bin/discover_apps.sh

Değişikliğin devreye girmesi için Zabbix Agent servisini restart ediyoruz:

systemctl restart zabbix-agent

SRE refleksi olarak, arayüze geçmeden önce bu parametrenin çalışıp çalışmadığını Zabbix Server veya Proxy üzerinden zabbix_get ile simüle edelim. Bu adımı atlamayın; permission hatalarını debug etmenin en hızlı yolu budur:

zabbix_get -s 10.0.1.50 -p 10050 -k custom.apps.discovery

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

Şimdi Zabbix UI tarafında bu yapıyı karşılayacak şablonu (Template) hazırlayalım. Doğrudan host üzerinde değil, her zaman bir template üzerinde çalışın ki bu yapıyı yüzlerce sunucuya ölçekleyebilesiniz.

1. Discovery Rule Oluşturma

Oluşturduğunuz template içinde Discovery Rules sekmesine gelin ve Create discovery rule butonuna tıklayın:

  • Name: Custom Application Discovery
  • Type: Zabbix agent (veya aktif mimari kullanıyorsanız Zabbix agent (active))
  • Key: custom.apps.discovery
  • Update interval: 1h (Üretim ortamında bu keşif sürecini 1 saatten daha sık çalıştırmayın. Disk veya port keşifleri sunucuya gereksiz yük bindirebilir. Test aşamasında 1m yapabilirsiniz.)
  • Keep lost resources period: 3d (Eğer bir servis kapanırsa, ona ait geçmiş metrikler ve item’lar 3 gün boyunca saklanır, ardından silinir. Flapping durumları için bu süreyi sıfır yapmayın.)

2. LLD Macro Paths (Opsiyonel ama Profesyonel Yöntem)

Eğer scriptinizden standart dışı veya nested (iç içe geçmiş) bir JSON dönüyorsa, LLD rule içerisindeki LLD Macros sekmesinde JSONPath kullanarak makrolarınızı elle eşleyebilirsiniz. Biz flat JSON kullandığımız için Zabbix bunu otomatik eşleştirecektir, ancak nested yapılarda şu şekilde tanımlama yapmanız gerekir:

  • LLD Macro: {#APP_PORT} -> JSONPath: $.port

Adım 4: Item Prototipleri (Item Prototypes) ile Dinamik Metrik Üretimi

Keşif kuralımız hazır. Şimdi bu kuralın keşfettiği her bir port için dinamik olarak metrik toplayacak Item Prototype’ı tanımlayalım. Discovery rule içerisindeki Item prototypes sekmesine tıklayın ve Create item prototype deyin:

  • Name: Application {#APP_NAME} Status on Port {#APP_PORT}
  • Key: net.tcp.listen[{#APP_PORT}]
  • Type: Zabbix agent
  • Type of information: Numeric (unsigned)

Neden bu key? net.tcp.listen, Zabbix’in gömülü (built-in) fonksiyonudur ve belirtilen portun dinlenip dinlenmediğini kontrol edip geriye 1 (açık) veya 0 (kapalı) döner. LLD burada devreye girerek her bir host için keşfettiği port sayısı kadar dinamik item oluşturacaktır. Örneğin sunucuda 3 port varsa, arkada 3 farklı item otomatik ayağa kalkacaktır.

Adım 5: Dinamik Trigger Prototipleri ile Alert Altyapısı

Dinamik item’larımız varsa, bunlara bağlı dinamik alarm mekanizmalarımız da olmalı. Item prototipi oluşturduktan sonra, aynı menü altındaki Trigger prototypes sekmesine geçip yeni bir prototip tanımlıyoruz:

  • Name: Application {#APP_NAME} on port {#APP_PORT} is down
  • Severity: High
  • Expression:
    last(/Template Custom Apps/net.tcp.listen[{#APP_PORT}])=0

Bu ifade sayesinde, hangi servis çökerse çöksün, alarm başlığında dinamik olarak o servisin adı ve portu yazacaktır (Örn: “Application payment-api on port 8081 is down”). Tek bir trigger prototipi ile binlerce farklı servisin alarm kurgusunu tek seferde yönetmiş oluyoruz.

Ölçeklenebilir LLD İçin SRE Pratikleri (Best Practices)

Production ortamında yüzlerce LLD kuralı çalıştırırken sisteminizin darboğaza girmemesi için şu kurallara riayet edin:

  1. Preprocessing Kullanın: LLD ile gelen ham JSON datası üzerinde değişiklik yapmak veya bazı gereksiz keşifleri filtrelemek için LLD Preprocessing adımlarını (JSONPath, Regular Expression) kullanın. Keşif scriptini sunucu tarafında her seferinde modifiye etmek yerine Zabbix tarafında filtrelemek daha yönetilebilirdir.
  2. Discard Unchanged Limitini Ayarlayın: Keşif JSON’ınız saatlerce değişmeyebilir. Zabbix Server’ın veritabanına sürekli aynı keşif verisini yazıp yük oluşturmasını engellemek için LLD kuralının preprocessing kısmına Discard unchanged with heartbeat (örn: 12h) ekleyin.
  3. Zabbix Trapper Alternatifi: Eğer host sayınız çok fazlaysa ve agent’ların aktif olarak query edilmesi Zabbix Poller’larını yoruyorsa, LLD tipini Zabbix trapper yapın. Sunuculardaki scriptleri crontab ile çalıştırıp çıktıyı zabbix_sender ile push edin. Bu yöntem, Zabbix Server üzerindeki poller yükünü neredeyse sıfıra indirir.

Zabbix LLD, altyapınızı kod olarak yönettiğiniz (Infrastructure as Code) modern dünyada monitoringinizi dinamik kılmanın en güçlü yoludur. Bir kez doğru kurgulandığında, operasyonel yükünüzü ciddi oranda azaltır ve insan hatasını ortadan kaldırır.

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

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