Zabbix ile AWS ve Azure Bulut Kaynaklarını İzleme

Bulut altyapısı izleme meselesine gelince, çoğu ekip ya tamamen cloud-native araçlara (CloudWatch, Azure Monitor) yaslanıyor ya da bunları tamamen görmezden gelip sadece Zabbix’e bakıyor. İkisi de yanlış. Biz birkaç yıl önce karma bir ortamı yönetirken bu ikisini birleştirmenin ne kadar değerli olduğunu acı tecrübelerle öğrendik. Bu yazıda, Zabbix’i AWS ve Azure ile nasıl konuşturacağınızı, hangi metriklerin kritik olduğunu ve gerçek senaryolarda nasıl çalıştığını anlatacağım.

Neden Zabbix ve Bulut Araçları Birlikte?

CloudWatch veya Azure Monitor kullanıyorsunuz, her şey güzel. Peki on-premise sunucularınız, bare-metal makineleriniz, kendi veri merkezinizdeki ağ ekipmanlarınız var ise? Her şeyi tek ekrandan görmek istiyorsanız Zabbix’i merkeze almak mantıklı. Ama Zabbix’in kendi başına bulut kaynaklarını izleyebilmesi için doğru yapılandırılması gerekiyor.

Zabbix 6.0 ve sonrasında AWS ve Azure için hazır template’ler geldi. Bu template’ler CloudWatch ve Azure Monitor API’lerini çekerek metrikleri Zabbix’e taşıyor. Yani siz hem bulut hem de on-premise izlemeyi tek konsoldan yapabiliyorsunuz. Alarm yönetimi, eskalasyon kuralları, dashboard her yerde tek.

Mimari Genel Bakış

Kuruluma geçmeden önce kafanızda netleşmesi gereken şey şu: Zabbix doğrudan AWS veya Azure API’lerine bağlanıyor. Bu bağlantıyı kuran Zabbix server (veya proxy) olduğu için özel bir agent kurmuyorsunuz. Yani EC2 instance’larınızın içine dokunmadan, sadece API kimlik bilgileriyle izleme yapabiliyorsunuz.

Kurulum şeması şöyle işliyor:

  • Zabbix Server veya Proxy, AWS CloudWatch API veya Azure Monitor REST API’yi sorguluyor
  • Script tabanlı item’lar veya HTTP item’lar bu sorguları yapıyor
  • Dönen metrikler Zabbix’e işleniyor, trigger’lar tetikleniyor
  • Tek dashboard’dan hem fiziksel hem sanal hem de bulut kaynakları görünüyor

Bant genişliği açısından düşünüldüğünde, Zabbix proxy kullanmak API sorgularını dağıtmak için çok daha sağlıklı bir seçenek. Özellikle yüzlerce bulut kaynağı izlediğinizde proxy’leri bölgesel olarak konuşlandırmak her şeyi sadeleştiriyor.

AWS İzleme Kurulumu

IAM Kullanıcısı ve Politika Tanımlaması

Önce AWS tarafında bir IAM kullanıcısı açıp sadece okuma yetkisi vermeniz gerekiyor. Güvenlik açısından en az yetki prensibini burada kesinlikle uygulamanızı tavsiye ederim. Production ortamında tam yetkili bir IAM key’i Zabbix’e vermek ciddi bir risk.

# AWS CLI ile IAM policy oluşturma
aws iam create-policy 
  --policy-name ZabbixCloudWatchReadOnly 
  --policy-document '{
    "Version": "2012-10-17",
    "Statement": [
      {
        "Effect": "Allow",
        "Action": [
          "cloudwatch:GetMetricData",
          "cloudwatch:GetMetricStatistics",
          "cloudwatch:ListMetrics",
          "ec2:DescribeInstances",
          "ec2:DescribeInstanceStatus",
          "rds:DescribeDBInstances",
          "elasticloadbalancing:DescribeLoadBalancers",
          "s3:ListAllMyBuckets",
          "lambda:ListFunctions"
        ],
        "Resource": "*"
      }
    ]
  }'

IAM kullanıcısını oluşturup bu policy’i attach edin, ardından access key üretin. Bu key’i Zabbix macro’larına gömeceğiz.

Zabbix Makro Tanımlaması

Zabbix arayüzünde Administration > General > Macros kısmına gidip aşağıdaki macro’ları tanımlayın. Bu macro’ları global düzeyde değil, host düzeyinde tanımlamak daha güvenli çünkü farklı AWS account’larınız varsa her host grubu için ayrı key kullanabilirsiniz.

# Host macro'ları (Zabbix arayüzünden girilecek)
{$AWS.ACCESS.KEY.ID} = AKIAIOSFODNN7EXAMPLE
{$AWS.SECRET.ACCESS.KEY} = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
{$AWS.REGION} = eu-west-1

Secret key’i Zabbix’te secret tipinde saklayın, plain text olarak değil. Zabbix 5.4 ve sonrasında macro türü olarak “secret text” seçeneği var, bunu kullanın.

AWS Template’ini Import Etme

Zabbix’in resmi GitHub reposundan veya Zabbix Share’den AWS template’lerini indirip import edebilirsiniz. Zabbix 6.2 ve sonrasında bazı template’ler out-of-the-box geliyor ama güncel olanları şuradan almak daha iyi:

# Template'i indirme
wget https://raw.githubusercontent.com/zabbix/zabbix/trunk/templates/cloud/AWS/aws_ec2/template_aws_ec2.yaml

# Zabbix API ile import (token almanız gerekiyor)
curl -s -X POST 
  -H "Content-Type: application/json" 
  -d '{
    "jsonrpc": "2.0",
    "method": "user.login",
    "params": {
      "user": "Admin",
      "password": "zabbix"
    },
    "id": 1
  }' 
  http://your-zabbix-server/zabbix/api_jsonrpc.php

Template’i aldıktan sonra arayüzden Configuration > Templates > Import diyerek yükleyin.

EC2 Instance Keşfi

AWS template’lerinde otomatik keşif (discovery) var. Zabbix, CloudWatch API üzerinden tüm running instance’larınızı keşfedip otomatik olarak host olarak ekleyebiliyor. Bunun için discovery rule’u yapılandırmanız gerekiyor:

# Discovery için Python betiği örneği (Zabbix external script)
#!/usr/bin/env python3
import boto3
import json
import sys

def discover_ec2_instances(region, access_key, secret_key):
    ec2 = boto3.client(
        'ec2',
        region_name=region,
        aws_access_key_id=access_key,
        aws_secret_access_key=secret_key
    )
    
    response = ec2.describe_instances(
        Filters=[{'Name': 'instance-state-name', 'Values': ['running']}]
    )
    
    instances = []
    for reservation in response['Reservations']:
        for instance in reservation['Instances']:
            name = ''
            for tag in instance.get('Tags', []):
                if tag['Key'] == 'Name':
                    name = tag['Value']
            
            instances.append({
                '{#INSTANCE.ID}': instance['InstanceId'],
                '{#INSTANCE.NAME}': name,
                '{#INSTANCE.TYPE}': instance['InstanceType'],
                '{#REGION}': region
            })
    
    return json.dumps({'data': instances})

if __name__ == '__main__':
    region = sys.argv[1]
    access_key = sys.argv[2]
    secret_key = sys.argv[3]
    print(discover_ec2_instances(region, access_key, secret_key))

Bu betiği /usr/lib/zabbix/externalscripts/ altına koyun ve çalıştırma izni verin:

chmod +x /usr/lib/zabbix/externalscripts/aws_ec2_discovery.py
chown zabbix:zabbix /usr/lib/zabbix/externalscripts/aws_ec2_discovery.py

Azure İzleme Kurulumu

Service Principal Oluşturma

Azure tarafında Zabbix’in API’ye erişmesi için bir Service Principal tanımlamanız gerekiyor. Bu, AWS’deki IAM kullanıcısının Azure karşılığı sayılır.

# Azure CLI ile Service Principal oluşturma
az ad sp create-for-rbac 
  --name "ZabbixMonitoring" 
  --role "Monitoring Reader" 
  --scopes /subscriptions/YOUR_SUBSCRIPTION_ID

# Çıktı şöyle görünür:
# {
#   "appId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
#   "displayName": "ZabbixMonitoring",
#   "password": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
#   "tenant": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
# }

Monitoring Reader rolü yeterli ama eğer resource discovery da yapacaksanız Reader rolü de lazım. İkisini birlikte verin ama daha geniş yetkiler vermeyin.

Azure Macro Tanımlamaları

# Azure host macro'ları
{$AZURE.APP.ID} = xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
{$AZURE.PASSWORD} = your-service-principal-password
{$AZURE.TENANT.ID} = xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
{$AZURE.SUBSCRIPTION.ID} = xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

Azure Metrik Sorgulama

Azure Monitor REST API’yi Zabbix HTTP item’ları üzerinden sorgulayabilirsiniz. Önce token almanız, sonra metrik çekmeniz gerekiyor. Bunu bir wrapper script ile basitleştirebilirsiniz:

#!/usr/bin/env python3
import requests
import sys
import json

def get_azure_token(tenant_id, client_id, client_secret):
    url = f"https://login.microsoftonline.com/{tenant_id}/oauth2/token"
    data = {
        'grant_type': 'client_credentials',
        'client_id': client_id,
        'client_secret': client_secret,
        'resource': 'https://management.azure.com/'
    }
    response = requests.post(url, data=data)
    return response.json()['access_token']

def get_vm_metric(subscription_id, resource_group, vm_name, metric_name, token):
    url = (
        f"https://management.azure.com/subscriptions/{subscription_id}"
        f"/resourceGroups/{resource_group}/providers/Microsoft.Compute"
        f"/virtualMachines/{vm_name}/providers/microsoft.insights"
        f"/metrics?api-version=2018-01-01"
        f"&metricnames={metric_name}"
        f"&timespan=PT1H&interval=PT5M&aggregation=Average"
    )
    headers = {'Authorization': f'Bearer {token}'}
    response = requests.get(url, headers=headers)
    data = response.json()
    
    timeseries = data['value'][0]['timeseries'][0]['data']
    last_value = [x for x in timeseries if 'average' in x][-1]['average']
    return last_value

if __name__ == '__main__':
    tenant_id = sys.argv[1]
    client_id = sys.argv[2]
    client_secret = sys.argv[3]
    subscription_id = sys.argv[4]
    resource_group = sys.argv[5]
    vm_name = sys.argv[6]
    metric_name = sys.argv[7]
    
    token = get_azure_token(tenant_id, client_id, client_secret)
    value = get_vm_metric(subscription_id, resource_group, vm_name, metric_name, token)
    print(value)

Kritik Metrikler ve Trigger Örnekleri

AWS EC2 için İzlenmesi Gereken Metrikler

  • CPUUtilization: Instance’ın CPU kullanımı, yüzde olarak
  • NetworkIn / NetworkOut: Gelen ve giden ağ trafiği, bayt olarak
  • DiskReadOps / DiskWriteOps: Disk okuma/yazma operasyonları, EBS için kritik
  • StatusCheckFailed: Instance veya sistem status check başarısızlığı, 0 veya 1
  • CPUCreditBalance: T serisi instance’larda burst kredi bakiyesi, tükenmeden önce uyar
  • EBSWriteLatency: EBS yazma gecikmesi, milisaniye olarak

Azure VM için İzlenmesi Gereken Metrikler

  • Percentage CPU: VM CPU kullanımı
  • Network In / Network Out: Ağ trafiği byte cinsinden
  • Disk Read Bytes / Disk Write Bytes: Disk I/O
  • OS Disk IOPS Consumed Percentage: OS disk IOPS tüketim oranı
  • Available Memory Bytes: Kullanılabilir bellek
  • VM Availability Metric: VM’in erişilebilirlik durumu

Trigger Örnekleri

Zabbix trigger ifadelerini doğru kurmak, alarm yorgunluğunu önlemek açısından kritik. Özellikle bulut kaynaklarında flapping (titreşen) alarmlar gerçek bir sorun:

# EC2 CPU Trigger - 5 dakika boyunca %80 üzerinde kaldıysa alarm
{aws:aws.ec2.cpu.utilization["{$INSTANCE.ID}"].avg(5m)} > 80

# T serisi CPU Credit düşük uyarı - 100 kredinin altına düştüğünde
{aws:aws.ec2.cpu.credit.balance["{$INSTANCE.ID}"].last()} < 100

# StatusCheck başarısız - hemen alarm ver
{aws:aws.ec2.status.check.failed["{$INSTANCE.ID}"].last()} > 0

# Azure VM CPU - 10 dakika ortalama %90 üzeri
{azure:azure.vm.cpu.utilization["{$VM.NAME}"].avg(10m)} > 90

Gerçek Dünya Senaryosu: Karma Ortam İzleme

Geçen yıl bir e-ticaret projesinde şöyle bir yapı vardı: Core veritabanları on-premise’de, uygulama sunucuları AWS EC2’de, CDN ve static dosyalar Azure Blob’da, bir de hibrit bağlantı üzerinden konuşan legacy sistemler. CloudWatch ve Azure Monitor ayrı ayrı çalışıyor, on-premise için başka bir araç, legacy için başkası. Alarm yönetimi kabus gibiydi.

Çözüm olarak Zabbix’i merkeze aldık. On-premise için Zabbix agent, AWS için CloudWatch entegrasyonu, Azure için Monitor API entegrasyonu. Hepsini tek Zabbix instance’ında topladık. Zabbix proxy’leri bölgesel olarak konuşlandırdık; AWS eu-west-1 için bir proxy, Azure westeurope için başka bir proxy.

Sonuç: Alarm aldığımızda tek yere bakıyoruz. Korelasyon çok daha kolay. “EC2’de CPU spike oldu, aynı anda Azure CDN latency arttı, on-premise DB connection count düştü” gibi bir tabloyu tek ekrandan görmek olayın kök nedenini bulmayı çok hızlandırdı.

Performans ve Ölçeklendirme İpuçları

Yüzlerce bulut kaynağı izlediğinizde Zabbix performansı kritik hale geliyor. Birkaç pratik öneri:

  • Polling interval’larını akıllıca ayarlayın: Her metriği 1 dakikada bir sorgulamak hem CloudWatch API maliyetinizi artırır hem de Zabbix’i yorar. Kritik metrikler 1-2 dakika, genel metrikler 5 dakika yeterli
  • Zabbix proxy kullanın: Her bölge veya hesap için ayrı proxy, yük dağılımı için şart
  • History ve trend retention’ı optimize edin: Bulut verisi çok fazla. History için 7-14 gün, trend için 90 gün genellikle yeterli
  • Valuecache boyutunu artırın: zabbix_server.conf içinde ValueCacheSize=256M gibi bir değer büyük ortamlarda performansı ciddi artırıyor
# /etc/zabbix/zabbix_server.conf optimizasyonları
StartPollers=50
StartHTTPPollers=10
StartPreprocessors=15
CacheSize=512M
ValueCacheSize=256M
HistoryCacheSize=128M
TrendCacheSize=64M

API Rate Limiting ile Başa Çıkma

CloudWatch API’nin rate limiti var. Çok fazla concurrent sorgu yaptığınızda throttling yiyorsunuz. Bunu aşmak için:

# Zabbix'te item timeout ve retry ayarları
# zabbix_server.conf
Timeout=30

# External script'lerde exponential backoff örneği
import time
import boto3
from botocore.exceptions import ClientError

def get_metric_with_retry(cw_client, **kwargs):
    max_retries = 5
    for attempt in range(max_retries):
        try:
            return cw_client.get_metric_statistics(**kwargs)
        except ClientError as e:
            if e.response['Error']['Code'] == 'Throttling':
                wait = (2 ** attempt) + 0.1
                time.sleep(wait)
            else:
                raise
    raise Exception("Max retries exceeded")

Maliyet İzleme Entegrasyonu

Zabbix’te AWS ve Azure maliyetlerini de izleyebilirsiniz. Bu çoğu ekibin aklına gelmiyor ama çok değerli.

AWS Cost Explorer API üzerinden günlük maliyet verisi çekip Zabbix’e item olarak yazabilirsiniz. Aylık bütçenizin belirli bir yüzdesini aştığında alarm üretebilirsiniz:

#!/usr/bin/env python3
import boto3
from datetime import datetime, timedelta
import sys

def get_daily_cost(access_key, secret_key):
    client = boto3.client(
        'ce',
        region_name='us-east-1',
        aws_access_key_id=access_key,
        aws_secret_access_key=secret_key
    )
    
    today = datetime.now().strftime('%Y-%m-%d')
    yesterday = (datetime.now() - timedelta(days=1)).strftime('%Y-%m-%d')
    
    response = client.get_cost_and_usage(
        TimePeriod={'Start': yesterday, 'End': today},
        Granularity='DAILY',
        Metrics=['UnblendedCost']
    )
    
    cost = float(response['ResultsByTime'][0]['Total']['UnblendedCost']['Amount'])
    return round(cost, 2)

if __name__ == '__main__':
    access_key = sys.argv[1]
    secret_key = sys.argv[2]
    print(get_daily_cost(access_key, secret_key))

Bu veriye dayanarak “günlük maliyet 500 doları aştı” gibi bir trigger kurabilirsiniz. Birisi yanlışlıkla büyük bir instance tipi başlatırsa veya bir loop hatalı şekilde kaynak üretmeye başlarsa anında haberdar olursunuz.

Güvenlik Notları

Birkaç şeyi atlamamak lazım:

  • IAM ve Service Principal credentials’larını Zabbix macro’larında secret tipinde saklayın
  • Zabbix server’ın ağ erişimini kısıtlayın, API çağrıları için belirli IP veya VPC endpoint kullanın
  • Access key’leri düzenli rotate edin, Zabbix’teki macro’ları da buna göre güncelleyin
  • Audit loglarını tutun, hangi Zabbix kullanıcısının hangi host’a baktığını kayıt altına alın
  • AWS’de Zabbix için ayrı bir IAM role veya cross-account role kullanmayı düşünün, özellikle çok hesaplı ortamlarda

Sonuç

Zabbix’i sadece “sunuculara agent kur, izle” şeklinde görmek artık yeterli değil. Bulut kaynaklarını da aynı çatı altında izlemek, özellikle karma ortamlar için operasyonel görünürlüğü inanılmaz artırıyor. AWS ve Azure entegrasyonu başlangıçta biraz kurulum gerektiriyor ama oturduktan sonra gerçekten değiyor.

En önemli şey şu: template’leri kurup her şeyi default bırakmayın. Kendi ortamınıza göre trigger threshold’larını ayarlayın, gereksiz metrikleri devre dışı bırakın, polling interval’larını optimize edin. Yoksa alarm gürültüsü ve API maliyetleri hızla artıyor.

Maliyet izlemeyi de es geçmeyin. Bulut faturası sürpriz yapmasın diye Zabbix’e birkaç cost item eklemek saatler sürmüyor ama ayda belki binlerce dolarlık tasarruf sağlayabiliyor. Özellikle ekibinizde developer’lar da console erişimine sahipse bu tip bir izleme hayat kurtarıcı.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir