Zabbix Kubernetes Entegrasyonu ile Pod İzleme
Kubernetes ortamlarını izlemek, klasik sanal makine izlemekten epey farklı bir his. Podlar gelip gidiyor, namespace’ler büyüyor, servisler scale oluyor… Ve sen ortada Zabbix ile bu kaotik ortamı anlamlandırmaya çalışıyorsun. Birçok ekip bu noktada “Zabbix mi, yoksa Prometheus mu?” tartışmasına giriyor. Ama şunu söyleyeyim: eğer zaten kurumsal bir Zabbix altyapınız varsa ve tek bir pano üzerinden hem fiziksel sunucularınızı hem de Kubernetes cluster’ınızı izlemek istiyorsanız, bu entegrasyon düşündüğünüzden çok daha işe yarıyor.
Neden Zabbix ile Kubernetes?
Prometheus + Grafana kombinasyonu Kubernetes izleme için neredeyse standart haline geldi. Bunu biliyoruz. Ama gerçek dünyada işler her zaman o kadar temiz değil. Kurumda yıllardır çalışan bir Zabbix sunucusu var, on binlerce metrik buraya akıyor, alert mekanizmaları burada kurulu, nöbet sistemleri buraya entegre. Şimdi kalkıp “K8s için Prometheus kuralım” demek, operasyon ekibinin iki farklı sistemi takip etmesi anlamına geliyor.
Zabbix 6.0 ile birlikte gelen Kubernetes izleme template’leri bu sorunu ciddi ölçüde çözüyor. Native HTTP agent desteği ve Kubernetes API entegrasyonu ile pod durumları, container metrikleri, node sağlığı gibi kritik veriler doğrudan Zabbix’e akabiliyor.
Ortam Gereksinimleri
Başlamadan önce ortamınızın hazır olduğundan emin olun:
- Zabbix 6.0 veya üzeri (6.4 önerilir)
- Kubernetes 1.21+
- Zabbix Server’ın Kubernetes API’ye erişimi (doğrudan veya Zabbix Proxy üzerinden)
kubectlerişimi olan bir terminal
Küçük bir not: Zabbix Server’ı Kubernetes cluster’ının dışında tutmanızı öneririm. İzleme sisteminiz izlediği ortama bağımlı olmamalı. Cluster çöktüğünde sizi uyaracak sistem de cluster içindeyse, kim kimi uyaracak?
ServiceAccount ve RBAC Yapılandırması
Zabbix’in Kubernetes API’ye okuma yetkisiyle erişmesi gerekiyor. Bunun için özel bir ServiceAccount oluşturacağız. Minimum yetki prensibini uygulayalım, her şeye erişim vermeyelim.
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Namespace
metadata:
name: zabbix-monitoring
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: zabbix-service-account
namespace: zabbix-monitoring
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: zabbix-cluster-reader
rules:
- apiGroups: [""]
resources:
- nodes
- pods
- services
- endpoints
- namespaces
- persistentvolumes
- persistentvolumeclaims
- componentstatuses
verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
resources:
- deployments
- replicasets
- statefulsets
- daemonsets
verbs: ["get", "list", "watch"]
- apiGroups: ["batch"]
resources:
- jobs
- cronjobs
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: zabbix-cluster-reader-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: zabbix-cluster-reader
subjects:
- kind: ServiceAccount
name: zabbix-service-account
namespace: zabbix-monitoring
EOF
ServiceAccount token’ını almamız gerekiyor. Kubernetes 1.24 ve sonrasında token’lar artık otomatik oluşturulmuyor, elle talep etmeniz lazım:
# Token için Secret oluştur
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
name: zabbix-sa-token
namespace: zabbix-monitoring
annotations:
kubernetes.io/service-account.name: zabbix-service-account
type: kubernetes.io/service-account-token
EOF
# Token değerini al
kubectl get secret zabbix-sa-token -n zabbix-monitoring
-o jsonpath='{.data.token}' | base64 --decode
Bu token’ı güvenli bir yerde saklayın. Zabbix’te makro olarak kullanacağız.
Zabbix’te Host Tanımlaması
Kubernetes cluster’ını Zabbix’te bir host olarak tanımlayacağız. Configuration > Hosts > Create Host yolunu izleyin.
Host tanımlarken dikkat etmeniz gereken birkaç nokta var. Interface olarak “No interface” seçebilirsiniz çünkü metrikler HTTP agent üzerinden gelecek. Ya da cluster’ın API server adresini agent interface olarak tanımlayabilirsiniz, her iki yöntem de çalışıyor.
Asıl kritik kısım makro tanımlamaları. Host düzeyinde şu makroları tanımlayın:
- {$KUBE.API.URL}:
https://your-k8s-api-server:6443 - {$KUBE.API.TOKEN}: Az önce aldığınız ServiceAccount token’ı
- {$KUBE.HTTP.PROXY}: Eğer proxy kullanıyorsanız, kullanmıyorsanız boş bırakın
SSL sertifika doğrulaması için Zabbix’in cluster CA sertifikasına güvenmesi gerekiyor. Test ortamlarında bunu atlayabilirsiniz ama production’da mutlaka yapılandırın.
Resmi Template ile Hızlı Başlangıç
Zabbix, GitHub’da Kubernetes için hazır template’ler sunuyor. Bunları indirip import edelim:
# Template dosyalarını indir
wget https://raw.githubusercontent.com/zabbix/community-templates/main/
Kubernetes/template_kubernetes_cluster.yaml
# Ya da zbx_export_templates dizininden Zabbix arayüzü üzerinden import edebilirsiniz
Arayüzden import işlemi: Configuration > Templates > Import. YAML veya XML formatında template’i yükleyin.
Resmi template şunları kapsıyor:
- Node sayısı ve durumları
- Pod durumları (Running, Pending, Failed, Unknown)
- Deployment, ReplicaSet, DaemonSet metrikleri
- API Server sağlığı
- Persistent Volume kullanımı
- Namespace bazlı pod dağılımı
Özel Pod İzleme: HTTP Agent ile API Sorgulama
Resmi template’ler iyi bir başlangıç noktası ama çoğu zaman kendi ihtiyaçlarınıza göre özelleştirmeniz gerekiyor. Belirli bir namespace’deki podları izlemek istediğinizi varsayalım. Bunun için HTTP agent item oluşturacağız.
Zabbix arayüzünde Items > Create Item:
# Bu item'ın Type: HTTP agent olacak
# URL kısmına şunu girin:
{$KUBE.API.URL}/api/v1/namespaces/production/pods
# Headers kısmına:
Authorization: Bearer {$KUBE.API.TOKEN}
# Bu item'dan dönen JSON'u işlemek için
# preprocessing adımında JSONPath kullanacağız:
$.items[?(@.status.phase!="Running")].length()
Aynı mantıkla belirli bir deployment’ın pod sayısını izleyebilirsiniz:
# Deployment ready replica sayısı için URL:
{$KUBE.API.URL}/apis/apps/v1/namespaces/production/deployments/my-app
# JSONPath preprocessing:
$.status.readyReplicas
Low Level Discovery ile Dinamik Pod İzleme
Kubernetes’in dinamik yapısı düşünüldüğünde, elle her pod için item oluşturmak saçmalık olur. Low Level Discovery (LLD) burada devreye giriyor. Podlar otomatik olarak keşfedilecek ve her biri için Zabbix item’ları otomatik oluşturulacak.
Discovery rule için HTTP agent kullanan bir yapılandırma:
# Discovery Rule URL:
{$KUBE.API.URL}/api/v1/namespaces/{#NAMESPACE}/pods
# LLD Macro'lar için JSON preprocessing:
$.items[*].['metadata', 'status', 'spec']
# JSONPath ile macro tanımlamaları:
# {#POD.NAME} -> $.metadata.name
# {#POD.STATUS} -> $.status.phase
# {#POD.NODE} -> $.spec.nodeName
# {#NAMESPACE} -> $.metadata.namespace
Bunun ardından item prototype oluşturun:
# Item Prototype adı:
Pod [{#POD.NAME}] durumu
# URL:
{$KUBE.API.URL}/api/v1/namespaces/{#NAMESPACE}/pods/{#POD.NAME}
# JSONPath preprocessing:
$.status.phase
Bu yapı kurulduktan sonra Zabbix otomatik olarak her pod için ayrı bir item oluşturacak ve pod silindiğinde item da temizlenecek. Update interval’i fazla kısa tutmayın, 60-120 saniye Kubernetes için makul bir değer.
Alert Kuralları: Ne Zaman Alarm Verilmeli?
İzleme yapıyorsunuz ama alarm vermiyorsanız eksik. Birkaç kritik trigger senaryosu:
# Pod sürekli restart alıyorsa (CrashLoopBackOff tespiti)
# Trigger expression:
last(/Kubernetes Cluster/kube.pod.restart.count[{#POD.NAME}])>5
and
change(/Kubernetes Cluster/kube.pod.restart.count[{#POD.NAME}])>0
# Pending durumda kalan pod (5 dakikadan fazla)
# Trigger expression:
min(/Kubernetes Cluster/kube.pod.status[{#POD.NAME}],5m)="Pending"
# Deployment ready replica sayısı desired'dan az
# Trigger expression:
last(/Kubernetes Cluster/kube.deployment.ready[{#DEPLOY.NAME}])
<
last(/Kubernetes Cluster/kube.deployment.desired[{#DEPLOY.NAME}])
Severity seviyelendirmesi konusunda şunu söyleyeyim: production namespace’deki pod sorunlarını HIGH, diğerlerini AVERAGE olarak işaretleyin. Gece 03:00’te telefon açtıracak alarm sayısını minimum tutun, alarm yorgunluğu gerçek bir sorun.
Zabbix Proxy ile Uzak Cluster İzleme
Birden fazla Kubernetes cluster’ınız varsa veya Zabbix Server’ınızın cluster API’sine doğrudan erişimi yoksa, Zabbix Proxy kullanmak en temiz çözüm. Her cluster’ın bulunduğu network segment’ine bir Zabbix Proxy kurun.
# Zabbix Proxy'yi Kubernetes içinde çalıştırmak için
# Deployment örneği:
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: zabbix-proxy
namespace: zabbix-monitoring
spec:
replicas: 1
selector:
matchLabels:
app: zabbix-proxy
template:
metadata:
labels:
app: zabbix-proxy
spec:
containers:
- name: zabbix-proxy
image: zabbix/zabbix-proxy-sqlite3:ubuntu-6.4-latest
env:
- name: ZBX_HOSTNAME
value: "k8s-cluster-proxy"
- name: ZBX_SERVER_HOST
value: "zabbix-server.yourcompany.com"
- name: ZBX_SERVER_PORT
value: "10051"
- name: ZBX_PROXYMODE
value: "0"
ports:
- containerPort: 10051
EOF
Bu yapıda Zabbix Proxy, cluster içinden Kubernetes API’ye erişiyor ve metrikleri toplayıp Zabbix Server’a gönderiyor. Cluster dışarıdan erişilemez durumda olsa bile izleme çalışmaya devam ediyor.
Prometheus Metrics Endpoint’lerini Zabbix’e Entegre Etme
Çoğu Kubernetes uygulaması /metrics endpoint’i üzerinden Prometheus formatında metrik yayınlıyor. Bu metrikleri Zabbix’e almak mümkün, biraz daha fazla efor gerektiriyor ama çok işe yarıyor.
# Prometheus metrics endpoint'inden belirli bir metriği çeken item:
# Type: HTTP agent
# URL: http://{#POD.IP}:8080/metrics
# Bu endpoint düz text döndürüyor, preprocessing ile parse etmek gerekiyor
# Preprocessing step: Regular expression
# Pattern: http_requests_total{.*status="200".*}s+(d+)
# Output: 1
# Daha temiz bir yaklaşım için Zabbix'in
# Prometheus preprocessing destekini kullanın:
# Preprocessing type: Prometheus pattern
# Pattern: http_requests_total{status="200"}
Prometheus to Zabbix köprüsü için zabbix_exporter gibi araçlar da mevcut ama bence native HTTP agent + preprocessing kombinasyonu daha az bağımlılık oluşturuyor.
Gerçek Dünya Senaryosu: E-ticaret Platformu İzleme
Çalıştığım bir projeden somut örnek vereyim. Bir e-ticaret platformunun Kubernetes cluster’ını Zabbix’e entegre ettiğimizde şu yapıyı kurduk:
Namespace bazlı izleme stratejisi:
productionnamespace: Her pod için ayrı item, 60 saniyelik interval, HIGH severity alarmlarstagingnamespace: Namespace bazlı toplam metrikler, 5 dakikalık interval, WARNING severitymonitoringnamespace: Sadece ready/not-ready durumu, 10 dakikalık interval
Kritik metrikler:
- Ödeme servisi podlarının restart sayısı (sıfır tolerans)
- API gateway’in response time metrikleri (Prometheus endpoint’inden)
- Veritabanı bağlantı pool kullanımı
- Redis cluster pod sağlığı
Bu yapıyı kurduktan 2 hafta sonra, gece 02:15’te bir ödeme servisi podu CrashLoopBackOff’a girdi. Zabbix 3 dakika içinde alarm üretti, nöbetçi mühendis müdahale etti. Sorunun kaynağı bir OOM kill’di. Memory limit’i yetersiz kalmıştı. Sabaha kadar kimse fark etmeden 40-50 başarısız ödeme daha gerçekleşebilirdi.
Dashboard Yapılandırması
İzleme verisi var ama görselleştirmek de önemli. Zabbix’in native dashboard özellikleri Grafana kadar zengin değil ama temel ihtiyaçlar için yeterli.
Dashboard oluştururken şu widget kombinasyonunu öneriyorum:
- Gauge widget: Cluster genelinde Running/Total pod oranı
- Graph widget: Son 6 saatin pod restart grafiği
- Problems widget: Aktif K8s sorunlarının filtrelenmiş listesi
- Data overview: Namespace bazlı pod sayıları
Eğer organizasyonunuzda Grafana da varsa, Zabbix datasource plugin’i ile metrikleri Grafana’da görselleştirebilirsiniz. İki dünyanın en iyisini almanın güzel bir yolu.
Performans ve Ölçeklendirme Notları
Büyük cluster’larda (100+ node, 1000+ pod) dikkat etmeniz gereken birkaç şey var:
LLD discovery interval’ini en az 5 dakikaya ayarlayın. Her dakika binlerce pod için discovery çalıştırmak hem Zabbix’i hem de Kubernetes API server’ını gereksiz yere yoruyor.
Item history ve trends retention değerlerini dikkatli belirleyin. Pod metrikleri için 7-14 günlük history genellikle yeterli. Her şeyi 90 gün saklamak veritabanınızı şişirir.
# Zabbix Server konfigürasyonunda
# büyük K8s ortamları için önerilen değerler:
StartHTTPPollers=10
CacheSize=256M
ValueCacheSize=128M
HistoryCacheSize=256M
TrendCacheSize=64M
Bunları /etc/zabbix/zabbix_server.conf dosyanıza ekleyin ve servisi yeniden başlatın. Özellikle StartHTTPPollers değeri HTTP agent item sayısıyla orantılı olmalı.
Sık Karşılaşılan Sorunlar ve Çözümleri
SSL sertifika hatası: Kubernetes API’ye bağlanırken self-signed sertifika hatası alıyorsanız, item yapılandırmasında “Verify peer” seçeneğini devre dışı bırakabilirsiniz. Ama kalıcı çözüm, cluster CA sertifikasını Zabbix Server’ın güven deposuna eklemek.
# Cluster CA'yı al
kubectl config view --raw --minify
--flatten -o jsonpath='{.clusters[].cluster.certificate-authority-data}'
| base64 --decode > /etc/zabbix/k8s-ca.crt
# Zabbix item'larında TLS CA file olarak bu dosyayı kullan
Token expired hatası: ServiceAccount token’ı uzun ömürlü ama süresi dolabilir. Monitoring için oluşturduğunuz Secret’ın annotation’larını kontrol edin ve token rotation prosedürü oluşturun.
API rate limiting: Çok fazla item çok kısa interval ile çalışıyorsa Kubernetes API server throttling uygulayabilir. Bu durumda interval’leri artırın veya Zabbix Proxy’yi cluster içine alın, böylece API çağrıları cluster içi network’ten gelir ve daha az latency yaşanır.
Sonuç
Zabbix ile Kubernetes entegrasyonu “ya Zabbix ya Prometheus” ikilemine gerçek bir alternatif sunuyor. Kurumsal ortamlarda tek bir izleme platformu üzerinden hem geleneksel altyapıyı hem de container ortamını takip edebilmek, operasyon ekipleri için ciddi bir verimlilik kazanımı.
Burada anlattığım yapıyı adım adım uygularsanız, temel bir K8s izleme altyapısı birkaç saat içinde ayağa kalkar. Asıl zaman harcamanız gereken yer, hangi metriklerin gerçekten önemli olduğunu belirlemek ve alarm eşiklerini akıllıca yapılandırmak. Çok fazla alarm, hiç alarm yokmuş gibi davranmaya yol açar.
Kubernetes ortamınız büyüdükçe bu yapıyı GitOps yaklaşımıyla yönetmenizi öneririm. Template’leri, host tanımlarını ve makroları kod olarak saklayın, değişiklikleri versiyon kontrol altında tutun. Bir gün Zabbix veritabanınız bozulduğunda, her şeyi sıfırdan kurmak zorunda kalmamak için bu önlemi şimdiden alın.
