Zabbix’te Maintenance Periyodu Tanımlama
Gece yarısı telefon çalıyor, NOC ekibinden biri arıyor: “Abla, şu sunuculara güncelleme atacağız, Zabbix’ten alarm yağmasın diye ne yapacağız?” İşte tam bu noktada maintenance periyotları devreye giriyor. Zabbix’in en kullanışlı özelliklerinden biri olan bu mekanizma, planlı bakım pencerelerinde gereksiz alarm kirliliğini önler ve hem siz hem de ekibiniz sabaha kadar gereksiz stres yaşamaz.
Maintenance Periyodu Nedir ve Neden Önemlidir
Zabbix’teki maintenance periyodu, belirli bir zaman aralığında host veya host gruplarına yönelik bildirim mekanizmasını askıya almanızı sağlar. Ama burada ince bir nokta var: maintenance aktifken veri toplanmaya devam eder, sadece tetiklenen problemler için bildirim gitmez. Bu ayrımı çok iyi anlamak gerekiyor çünkü bazı ekipler “maintenance açtık, veri de toplanmıyor” yanılgısına düşüyor.
İki temel maintenance türü var:
- With data collection: İzleme devam eder, trigger’lar ateşlenir ama bildirim gitmez. Problem log’u tutulmaya devam eder.
- No data collection: Host’a hiçbir istek gönderilmez, veri toplanmaz. Gerçek anlamda “sessiz mod” budur.
Çoğu senaryo için birinci tip yeterli. Özellikle ağ cihazlarını yeniden başlatıyorsanız ya da kernel güncelleme sonrası reboot yapıyorsanız, No data collection daha temiz bir deneyim sunar.
Zabbix API ile Maintenance Oluşturma
Arayüzden tıklayarak da maintenance açabilirsiniz ama bu yaklaşım ölçeklenmiyor. Onlarca sunucuya aynı anda bakım penceresi açmanız gerektiğinde, Zabbix API’si hayat kurtarır. Önce bir authentication token alalım:
curl -s -X POST
-H "Content-Type: application/json"
-d '{
"jsonrpc": "2.0",
"method": "user.login",
"params": {
"username": "Admin",
"password": "zabbix"
},
"id": 1
}'
http://zabbix.sirket.local/zabbix/api_jsonrpc.php
Bu isteğin döndürdüğü result alanındaki string bizim auth token’ımız. Bunu bir değişkene atalım ve maintenance oluşturalım:
TOKEN="abc123def456"
SIMDI=$(date +%s)
BITIS=$((SIMDI + 7200)) # 2 saatlik pencere
curl -s -X POST
-H "Content-Type: application/json"
-d "{
"jsonrpc": "2.0",
"method": "maintenance.create",
"params": {
"name": "Patch Tuesday - Web Sunucular",
"active_since": ${SIMDI},
"active_till": ${BITIS},
"hostids": ["10084", "10085", "10086"],
"timeperiods": [
{
"timeperiod_type": 0,
"start_date": ${SIMDI},
"period": 7200
}
],
"maintenance_type": 0
},
"auth": "${TOKEN}",
"id": 2
}"
http://zabbix.sirket.local/zabbix/api_jsonrpc.php
Burada maintenance_type: 0 veri toplamaya devam eden türü, maintenance_type: 1 ise veri toplamayan türü temsil ediyor. timeperiod_type: 0 ise tek seferlik (one time only) periyot anlamına geliyor.
Shell Script ile Toplu Maintenance Yönetimi
Gerçek ortamda tek bir sunucu için değil, bir host grubunun tamamı için maintenance açmak daha mantıklı. Şu script’i production’da kullanıyoruz:
#!/bin/bash
# zabbix_maintenance.sh
# Kullanim: ./zabbix_maintenance.sh <group_adi> <sure_dakika> <aciklama>
ZABBIX_URL="http://zabbix.sirket.local/zabbix/api_jsonrpc.php"
ZABBIX_USER="automation_user"
ZABBIX_PASS="guclu_sifre_buraya"
GROUP_ADI="${1:-'Linux Servers'}"
SURE_DK="${2:-60}"
ACIKLAMA="${3:-'Otomatik bakım penceresi'}"
# Token al
TOKEN=$(curl -s -X POST
-H "Content-Type: application/json"
-d "{
"jsonrpc": "2.0",
"method": "user.login",
"params": {
"username": "${ZABBIX_USER}",
"password": "${ZABBIX_PASS}"
},
"id": 1
}" "${ZABBIX_URL}" | python3 -c "import sys,json; print(json.load(sys.stdin)['result'])")
echo "Token alindi: ${TOKEN:0:8}..."
# Host group ID bul
GROUP_ID=$(curl -s -X POST
-H "Content-Type: application/json"
-d "{
"jsonrpc": "2.0",
"method": "hostgroup.get",
"params": {
"filter": {"name": ["${GROUP_ADI}"]}
},
"auth": "${TOKEN}",
"id": 2
}" "${ZABBIX_URL}" | python3 -c "import sys,json; data=json.load(sys.stdin); print(data['result'][0]['groupid'])")
echo "Group ID: ${GROUP_ID}"
SIMDI=$(date +%s)
BITIS=$((SIMDI + SURE_DK * 60))
MAINTENANCE_ADI="${ACIKLAMA} - $(date '+%Y-%m-%d %H:%M')"
# Maintenance olustur
RESULT=$(curl -s -X POST
-H "Content-Type: application/json"
-d "{
"jsonrpc": "2.0",
"method": "maintenance.create",
"params": {
"name": "${MAINTENANCE_ADI}",
"active_since": ${SIMDI},
"active_till": ${BITIS},
"groupids": ["${GROUP_ID}"],
"timeperiods": [
{
"timeperiod_type": 0,
"start_date": ${SIMDI},
"period": $((SURE_DK * 60))
}
],
"maintenance_type": 0,
"description": "${ACIKLAMA}"
},
"auth": "${TOKEN}",
"id": 3
}" "${ZABBIX_URL}")
echo "Sonuc: ${RESULT}"
Bu script’i çalıştırmadan önce automation için ayrı bir Zabbix kullanıcısı oluşturmanızı öneririm. Admin hesabıyla API çağrısı yapmak güvenlik açısından kötü pratik.
Tekrarlayan Maintenance Periyotları
Her Salı gece saat 02:00’de güncelleme yapıyorsanız, her seferinde elle maintenance açmak yerine tekrarlayan periyot tanımlayabilirsiniz. Zabbix arayüzünde bunu yapmak için Configuration > Maintenance yolunu izleyip yeni bir maintenance oluştururken timeperiod bölümünde “Every week” seçeneğini kullanabilirsiniz. API üzerinden ise şöyle görünüyor:
curl -s -X POST
-H "Content-Type: application/json"
-d "{
"jsonrpc": "2.0",
"method": "maintenance.create",
"params": {
"name": "Haftalik Patch Penceresi - Veritabani",
"active_since": 1700000000,
"active_till": 1800000000,
"groupids": ["15"],
"timeperiods": [
{
"timeperiod_type": 2,
"dayofweek": 2,
"start_time": 7200,
"period": 3600
}
],
"maintenance_type": 0
},
"auth": "${TOKEN}",
"id": 3
}"
http://zabbix.sirket.local/zabbix/api_jsonrpc.php
Buradaki parametreleri açayım:
- timeperiod_type: 2: Haftalık tekrar
- dayofweek: 2: Salı günü (1=Pazartesi, 2=Salı, …, 7=Pazar)
- start_time: 7200: Gece 02:00 (saniye cinsinden, 7200 saniye = 2 saat)
- period: 3600: 1 saatlik pencere
- active_since / active_till: Bu maintenance tanımının geçerli olduğu tarih aralığı
active_since ve active_till alanları, tekrarlayan maintenance’ın hangi tarihler arasında aktif olacağını belirler. Örneğin bir projenin beta dönemi boyunca her hafta maintenance açmak istiyorsanız bu alanlar çok işe yarıyor.
Maintenance Sırasında Problem Davranışı
Bir şey önemli: Maintenance başlamadan önce zaten açık olan bir problem, maintenance boyunca bildirim almaya devam eder mi? Hayır. Zabbix, maintenance aktifken mevcut problemleri de susturur. Maintenance bittiğinde ise hala aktif olan problemler için bildirim tetiklenip tetiklenmeyeceği trigger’ın kendisine bağlı. Generate multiple ALARMS seçeneği açıksa bildirim gelir, kapalıysa gelmez.
Bu davranışı test etmek için şu Python betiğini kullanabilirsiniz:
#!/usr/bin/env python3
"""
Zabbix aktif maintenance durumunu kontrol eder
"""
import requests
import json
from datetime import datetime
ZABBIX_URL = "http://zabbix.sirket.local/zabbix/api_jsonrpc.php"
def get_token(user, password):
payload = {
"jsonrpc": "2.0",
"method": "user.login",
"params": {"username": user, "password": password},
"id": 1
}
r = requests.post(ZABBIX_URL, json=payload)
return r.json()["result"]
def get_active_maintenances(token):
simdi = int(datetime.now().timestamp())
payload = {
"jsonrpc": "2.0",
"method": "maintenance.get",
"params": {
"output": "extend",
"selectHosts": ["host", "name"],
"selectGroups": ["name"],
"filter": {}
},
"auth": token,
"id": 2
}
r = requests.post(ZABBIX_URL, json=payload)
maintenances = r.json()["result"]
aktif = []
for m in maintenances:
bitis = int(m["active_till"])
if bitis > simdi:
aktif.append({
"id": m["maintenanceid"],
"name": m["name"],
"bitis": datetime.fromtimestamp(bitis).strftime("%Y-%m-%d %H:%M"),
"hosts": [h["name"] for h in m.get("hosts", [])],
"gruplar": [g["name"] for g in m.get("groups", [])]
})
return aktif
token = get_token("Admin", "zabbix")
aktif_maintenanceler = get_active_maintenances(token)
for m in aktif_maintenanceler:
print(f"[{m['id']}] {m['name']}")
print(f" Bitis: {m['bitis']}")
print(f" Hostlar: {', '.join(m['hosts']) if m['hosts'] else '-'}")
print(f" Gruplar: {', '.join(m['gruplar']) if m['gruplar'] else '-'}")
print()
Ansible ile Zabbix Maintenance Entegrasyonu
DevOps ekipleri için daha ilginç bir senaryo: Ansible playbook çalışmadan önce otomatik maintenance aç, playbook bitince kapat. Ansible’ın community.zabbix koleksiyonu bunu çok kolaylaştırıyor:
---
- name: Web Sunucu Guncelleme Playbook
hosts: web_sunuculari
gather_facts: false
pre_tasks:
- name: Zabbix maintenance baslat
community.zabbix.zabbix_maintenance:
server_url: "http://zabbix.sirket.local/zabbix"
login_user: "automation_user"
login_password: "{{ vault_zabbix_pass }}"
name: "Ansible - {{ inventory_hostname }} guncelleme"
host_names:
- "{{ inventory_hostname }}"
state: present
collect_data: true
minutes: 30
desc: "Otomatik Ansible guncelleme maintenance"
delegate_to: localhost
tasks:
- name: Paketleri guncelle
ansible.builtin.apt:
upgrade: dist
update_cache: true
become: true
- name: Gerekirse yeniden baslat
ansible.builtin.reboot:
reboot_timeout: 300
become: true
when: ansible_os_family == "Debian"
post_tasks:
- name: Zabbix maintenance kapat
community.zabbix.zabbix_maintenance:
server_url: "http://zabbix.sirket.local/zabbix"
login_user: "automation_user"
login_password: "{{ vault_zabbix_pass }}"
name: "Ansible - {{ inventory_hostname }} guncelleme"
state: absent
delegate_to: localhost
Bu yapıda pre_tasks ve post_tasks bloklarını kullanmak kritik. Eğer playbook bir sebepten başarısız olursa, post_tasks hala çalışır ve maintenance’ı kapatır. Tabii bunun için --force-handlers bayrağını da playbook’a eklemek iyi bir pratik.
Eski Maintenance Kayıtlarını Temizleme
Zaman içinde Zabbix veritabanında onlarca, bazen yüzlerce eski maintenance kaydı birikir. Bunları temizlemek hem veritabanı performansı açısından hem de arayüz karmaşıklığını azaltmak açısından önemli. API ile süresi geçmiş maintenance’ları bulup silelim:
#!/bin/bash
# Suresi gecmis maintenance kayitlarini temizle
ZABBIX_URL="http://zabbix.sirket.local/zabbix/api_jsonrpc.php"
TOKEN=$(./get_token.sh) # Token'i ayri bir scriptten al
SIMDI=$(date +%s)
# Suresi gecmis kayitlari bul
ESKI_IDS=$(curl -s -X POST
-H "Content-Type: application/json"
-d "{
"jsonrpc": "2.0",
"method": "maintenance.get",
"params": {
"output": ["maintenanceid", "name", "active_till"]
},
"auth": "${TOKEN}",
"id": 1
}" "${ZABBIX_URL}" | python3 -c "
import sys, json
data = json.load(sys.stdin)
simdi = ${SIMDI}
eski = [m['maintenanceid'] for m in data['result']
if int(m['active_till']) < simdi - 86400] # 1 gunden eski
print(json.dumps(eski))
")
echo "Silinecek maintenance sayisi: $(echo $ESKI_IDS | python3 -c 'import sys,json; print(len(json.load(sys.stdin)))')"
# Sil
if [ "$(echo $ESKI_IDS | python3 -c 'import sys,json; print(len(json.load(sys.stdin)))')" -gt "0" ]; then
curl -s -X POST
-H "Content-Type: application/json"
-d "{
"jsonrpc": "2.0",
"method": "maintenance.delete",
"params": ${ESKI_IDS},
"auth": "${TOKEN}",
"id": 2
}" "${ZABBIX_URL}"
echo "Temizlik tamamlandi."
else
echo "Silinecek kayit yok."
fi
Bu script’i cron’a ekleyip her Pazar gece çalıştırabilirsiniz. 30 gün geçmiş tüm maintenance kayıtlarını temizlemek için eşiği 86400 * 30 olarak değiştirin.
Gözden Kaçan Detaylar ve Pratik Öneriler
Yıllarca Zabbix kullananların sıklıkla düştüğü birkaç tuzak var:
- Saat dilimi sorunları: Zabbix sunucusu UTC’de çalışıyorken siz Türkiye saatiyle maintenance açmaya çalışırsanız 3 saatlik kayma yaşarsınız. API’ye gönderdiğiniz timestamp’lerin her zaman UTC tabanlı olduğunu unutmayın.
date -u +%skullanın,date +%sdeğil.
- Host vs Host Group önceliği: Bir host hem bir grup maintenance’ında hem de bireysel host maintenance’ında yer alıyorsa, ikisi de aynı anda aktif olabilir. Bu çakışma sorun yaratmaz ama yönetimi zorlaştırır. Mümkünse ya group bazlı ya da host bazlı tutun, ikisini karıştırmayın.
- Zabbix Proxy ortamları: Eğer proxy kullanıyorsanız, maintenance bilgisi proxy’e iletilmesi biraz zaman alabilir. Özellikle passive proxy’lerde bu gecikme fark edilebilir oluyor. Maintenance’ı bakım başlamadan 5-10 dakika önce açmak bu sorunu pratik olarak çözer.
- Tags ile maintenance: Zabbix 6.0 ve sonrasında maintenance’ları host tag’leri ile ilişkilendirebilirsiniz. Örneğin
env:productiontagine sahip tüm hostlara maintenance açmak mümkün. Bu özelliği kullanmak, bakım süreçlerini çok daha granüler hale getirir.
- Maintenance sırasında eskalasyon: Normal şartlarda Zabbix problemler için eskalasyon action’ları tetikler. Maintenance aktifken bu eskalasyonlar da durur. Maintenance bittiğinde hala açık olan problemler için eskalasyon sıfırdan başlar, kaldığı yerden devam etmez.
Sonuç
Zabbix maintenance periyotları, görünürde basit bir özellik gibi dursa da doğru kullanıldığında operasyonel olgunluğun önemli bir göstergesi haline gelir. Ham alarm sayısını düşürür, NOC ekibinin güvenini artırır ve “bu alarm önemli mi değil mi” yorgunluğunu azaltır.
Şu üç noktayı akılda tutmak yeterli: maintenance açmayı manuel bir işlem olmaktan çıkarın ve CI/CD ya da Ansible pipeline’ınıza entegre edin; timestamp’lerde UTC dikkatini asla elden bırakmayın; ve periyodik temizlik yapmazsanız birkaç ay içinde yüzlerce atıl kayıtla karşı karşıya kalırsınız. Bunların üçü de öğrenilmesi kolay ama öğrenilmediğinde ciddi operasyonel acılara yol açan detaylar. Ekibinize bu alışkanlıkları kazandırdığınızda, gece yarısı telefon çalmayı büyük ölçüde azaltmış olursunuz.
