Temmuz 26 2024

Zabbix’te LLD (Low-Level Discovery) ile Dinamik Host Keşfi

DevOps dünyasında “bunu elle hallederiz ya” dediğiniz her an, arkadan sinsice yaklaşan teknik borç (technical debt) canavarının nefesini ensenizde hissedersiniz. Konu sistem izleme ve monitoring olduğunda da durum farklı değil. Dinamik olarak ölçeklenen, sürekli yeni servislerin ayağa kalktığı modern altyapılarda, her yeni disk partition, ağ arayüzü veya çalışan custom servis için Zabbix’e manuel host veya item eklemek tam bir işkencedir. İşte bu noktada, zabbix dünyasının can kurtaran simidi olan lld (low-level discovery) devreye giriyor. Bu yazıda, modern altyapıların vazgeçilmezi olan otomasyon felsefesine sadık kalarak, LLD ile dinamik keşif süreçlerini, kendi custom template’lerimizi yazmayı ve trigger tanımlamayı pratik örneklerle ele alacağız.

LLD (Low-Level Discovery) Nedir ve Neden Hayat Kurtarır?

Geleneksel monitoring yaklaşımlarında, bir sunucunun üzerindeki diskleri izlemek istediğinizde /dev/sda1, /dev/sdb1 gibi diskleri tek tek elle tanımlamanız gerekirdi. Peki ya yarın sisteme yeni bir NVMe disk eklenirse? Ya da Kubernetes worker node’u üzerinde dinamik olarak yüzlerce ephemeral disk mount edilirse? Hepsini manuel olarak takip edip sisteme girmek imkansızdır.

LLD, hedef makinede belirli bir script veya agent modülü çalıştırarak mevcut kaynakları tarar, bunları bir JSON array yapısı haline getirir ve Zabbix Server’a raporlar. Zabbix Server bu JSON’ı okuyarak dinamik olarak item’lar, trigger’lar ve hatta grafikler oluşturur (bunlara prototype denir). Kaynak ortadan kalktığında ise (örneğin bir disk unmount edildiğinde) belirlediğiniz koruma süresi (keep lost resources period) sonunda bu item’ları otomatik olarak temizler. İşte gerçek otomasyon budur!

Adım 1: LLD’nin Kalbi – JSON Çıktısı ve custom LLD Makroları

Zabbix’in bir kaynağı dinamik olarak keşfedebilmesi için tek bir şartı vardır: Çıktının belirli bir JSON formatında olması. Zabbix 5.0 öncesinde katı bir {"data": [...]} formatı zorunluyken, modern Zabbix versiyonlarında (5.0 ve sonrası) düz bir JSON array de kabul edilmektedir.

LLD süreçlerinde en kritik bileşen, iki süslü parantez ve diyez işaretiyle başlayan LLD Makrolarıdır (örneğin: {#SERVICE_NAME}). Bu makrolar, keşfedilen her bir bileşenin benzersiz kimliğini temsil eder.

Gelin, sunucumuzda koşan aktif TCP portlarını otomatik keşfedecek basit bir bash script yazalım. Bu scripti hedef sunucuya yerleştireceğiz.

#!/bin/bash
# discover_ports.sh
# Sunucuda dinlenen TCP portlarını listeleyen ve JSON üreten script

ports=$(netstat -tuln | awk 'NR>2 {print $4}' | awk -F':' '{print $NF}' | sort -u | grep -E '^[0-9]+$')

echo "["
first=1
for port in $ports; do
    # JSON yapısını bozmamak için virgül kontrolü
    if [ $first -eq 0 ]; then
        echo ","
    fi
    # Servis adını bulmaya çalışalım (opsiyonel)
    service_name=$(lsof -i :$port -t | xargs ps -p -o comm= 2>/dev/null | head -n1)
    if [ -z "$service_name" ]; then
        service_name="unknown"
    fi
    printf '  { "{#TCP_PORT}": "%s", "{#PORT_SERVICE}": "%s" }' "$port" "$service_name"
    first=0
done
echo ""
echo "]"

Bu scripti çalıştırdığınızda aşağıdaki gibi temiz bir JSON çıktısı almalısınız:

[
  { "{#TCP_PORT}": "22", "{#PORT_SERVICE}": "sshd" },
  { "{#TCP_PORT}": "80", "{#PORT_SERVICE}": "nginx" },
  { "{#TCP_PORT}": "5432", "{#PORT_SERVICE}": "postgres" }
]

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

Yazdığımız bu scripti Zabbix Agent’ın çalıştırabilmesi için bir UserParameter tanımlamamız gerekiyor. Hedef sunucudaki Zabbix Agent konfigürasyon dosyasına (/etc/zabbix/zabbix_agentd.d/custom_lld.conf) şu satırı ekliyoruz:

UserParameter=custom.ports.discovery,/etc/zabbix/scripts/discover_ports.sh

Script dosyasının izinlerini ayarlamayı ve Zabbix kullanıcısının çalıştırabileceğinden emin olmayı unutmayın:

chmod +x /etc/zabbix/scripts/discover_ports.sh
systemctl restart zabbix-agent

Şimdi Zabbix Server veya Proxy üzerinden bu anahtarın çalışıp çalışmadığını zabbix_get yardımıyla test edelim. Bu adım debug süreçleri için hayati önem taşır:

zabbix_get -s 192.168.1.50 -k custom.ports.discovery

JSON çıktısını terminalde gördüyseniz, tebrikler! Altyapı hazır, şimdi Zabbix arayüzüne geçebiliriz.

Adım 3: Template, Discovery Rule ve Item Prototype Tanımlama

Zabbix Web UI üzerinde yeni bir template (örneğin: Template App Custom Port Discovery) oluşturun veya var olan bir template içerisine girin.

1. Discovery Rule Oluşturma

  • Template içinden Discovery rules sekmesine gelin ve Create discovery rule butonuna tıklayın.
  • Name: Active TCP Ports Discovery
  • Type: Zabbix agent (veya active agent kullanıyorsanız active seçin)
  • Key: custom.ports.discovery
  • Update interval: 1h (Sık sık port değişmiyorsa 1 saat idealdir, sistemi yormaya gerek yok)
  • Keep lost resources period: 7d (Sönen portlar 7 gün sonra sistemden silinsin)

2. Item Prototype Oluşturma

Keşfedilen her bir portun ayakta olup olmadığını kontrol edecek asıl izleme bileşenini (item) burada tanımlayacağız. Oluşturduğumuz Discovery rule içindeki Item prototypes sekmesine gidin ve Create item prototype deyin.

  • Name: Port {#TCP_PORT} ({#PORT_SERVICE}) Status
  • Type: Simple check (veya Zabbix Agent net.tcp.service kontrolü)
  • Key: net.tcp.service[tcp,,{#TCP_PORT}]
  • Type of information: Numeric (unsigned)

Burada dikkat ettiyseniz Key alanında doğrudan {#TCP_PORT} makrosunu kullandık. Zabbix LLD motoru, JSON’dan gelen her satır için bu item şablonunu çoğaltacak ve dinamik olarak net.tcp.service[tcp,,22], net.tcp.service[tcp,,80] gibi gerçek izleme item’ları üretecektir.

Adım 4: Akıllı Alarmlar İçin Trigger Prototype Yazmak

Item’ları oluşturduk ancak port kapandığında alarm almamız gerekiyor. Bunun için yine aynı Discovery rule altındaki Trigger prototypes sekmesini kullanıyoruz.

  • Name: Port {#TCP_PORT} ({#PORT_SERVICE}) is DOWN on {HOST.NAME}
  • Severity: Average veya High
  • Expression: last(/Template App Custom Port Discovery/net.tcp.service[tcp,,{#TCP_PORT}])=0

Bu trigger prototype sayesinde, yeni bir port sisteme dahil olduğunda hem izleme kalemi (item) hem de alarm mekanizması (trigger) sıfır manuel müdahale ile anında aktif hale gelecektir. Nginx’i mi restart ettiniz? Port kapandığı an alarmınız hazır!

Pro-Tip: Filtreleri Kullanarak Gürültüyü Engellemek (Noise Reduction)

LLD çok güçlüdür ancak bazen “gürültüye” sebep olabilir. Örneğin dinamik ephemeral portları (örneğin 32768-60999 arasını) veya her ayağa kalkan anlamsız portu izlemek istemeyebilirsiniz. LLD içerisindeki Filters sekmesi bu iş için biçilmiş kaftandır.

Keşif kuralınızın (Discovery Rule) altındaki Filters sekmesine gelin:

  • Label A: Macro: {#TCP_PORT} – Regular expression: ^(80|443|22|5432|3306)$

Bu kuralı eklediğinizde, Zabbix script çıktısındaki tüm portları değil, sadece sizin regex filtrenize uyan kritik portları (HTTP, HTTPS, SSH, PostgreSQL, MySQL) izlemeye alacaktır.

Özet ve Kapanış

Zabbix’te dinamik keşif (LLD) mimarisini kurmak, DevOps mühendislerinin altyapı büyürken geceleri rahat uyumasını sağlayan en kritik adımlardan biridir. Bu makalede ele aldığımız mantığı sadece port keşfi için değil; docker container’ları, SSL sertifika süreleri, log dosyaları, hatta AWS üzerindeki dinamik kaynaklar için bile uygulayabilirsiniz. Tek yapmanız gereken, hedefi tarayan ve standart bir JSON çıktısı üreten ufak bir script yazıp bunu Zabbix makroları ile eşleştirmek.

Otomasyonun olmadığı yerde monitoring sadece bir yükten ibarettir. LLD ile kalın, sistemlerinizi kendi kendine keşfeden akıllı yapılara dönüştürün!

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

Posted 26 Temmuz 2024 by Kerem Danış in category "Genel