Zabbix has been a mainstay of infrastructure monitoring for over two decades, and while Kubernetes-native tooling like Prometheus tends to dominate the conversation, plenty of teams already run Zabbix across their entire infrastructure estate and want Kubernetes folded into that same system rather than run in parallel. In this guide, I’ll cover how to set up Kubernetes monitoring with Zabbix, using its official Helm charts and native Kubernetes monitoring template.
Why Zabbix for Kubernetes
Zabbix gives you a single, mature monitoring platform across bare metal, VMs, network devices, and now Kubernetes — with built-in alerting, escalation policies, and a long history of enterprise reliability. If your infrastructure team already has Zabbix triggers, templates, and dashboards built out, extending that same system into Kubernetes avoids maintaining two separate alerting stacks with two separate on-call workflows.
Kubernetes Architecture Context
Zabbix’s Kubernetes integration works differently from the typical Prometheus pull model. It uses:
- Zabbix Agent 2, deployed as a DaemonSet, collecting node and container-level metrics.
- Zabbix Java Gateway or the newer native Kubernetes monitoring feature, which polls the Kubernetes API server directly for cluster-level object state (Pods, Deployments, Nodes) — conceptually similar to what kube-state-metrics does for Prometheus.
- Zabbix Server, the central component that stores collected data, evaluates triggers, and fires alerts.
- Zabbix Proxy (optional), useful in multi-cluster setups to reduce load on the central server and handle network segmentation.
Step 1: Deploy Zabbix Components via Helm
helm repo add zabbix-community https://zabbix-community.github.io/helm-zabbix
helm repo update
Install the Zabbix server, web frontend, and database:
helm install zabbix zabbix-community/zabbix -n zabbix --create-namespace \
--set zabbixServer.enabled=true \
--set zabbixWeb.enabled=true \
--set mysql.enabled=true
Check the deployment:
kubectl get pods -n zabbix
Step 2: Deploy the Zabbix Agent as a DaemonSet
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: zabbix-agent
namespace: zabbix
spec:
selector:
matchLabels:
app: zabbix-agent
template:
metadata:
labels:
app: zabbix-agent
spec:
hostNetwork: true
hostPID: true
containers:
- name: zabbix-agent2
image: zabbix/zabbix-agent2:6.4-alpine-latest
env:
- name: ZBX_SERVER_HOST
value: "zabbix-server.zabbix.svc.cluster.local"
- name: ZBX_HOSTNAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
volumeMounts:
- name: proc
mountPath: /host/proc
readOnly: true
- name: sys
mountPath: /host/sys
readOnly: true
volumes:
- name: proc
hostPath:
path: /proc
- name: sys
hostPath:
path: /sys
kubectl apply -f zabbix-agent-daemonset.yaml
Step 3: Configure Native Kubernetes Monitoring
Modern Zabbix (6.4+) includes a native Kubernetes monitoring data collection feature that polls the API server directly, rather than requiring a separate exporter. Configure it through the Zabbix frontend:
- Data collection → Kubernetes → Create Kubernetes cluster
- Provide the API server URL and a ServiceAccount token with read-only access (see RBAC below).
- Zabbix auto-discovers Nodes, Pods, and Deployments and creates corresponding hosts and items automatically.
Create the ServiceAccount and token Zabbix will authenticate with:
apiVersion: v1
kind: ServiceAccount
metadata:
name: zabbix-monitoring
namespace: zabbix
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: zabbix-monitoring-role
rules:
- apiGroups: [""]
resources: ["pods", "nodes", "namespaces", "events", "services"]
verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
resources: ["deployments", "statefulsets", "daemonsets", "replicasets"]
verbs: ["get", "list", "watch"]
- apiGroups: ["metrics.k8s.io"]
resources: ["pods", "nodes"]
verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: zabbix-monitoring-binding
subjects:
- kind: ServiceAccount
name: zabbix-monitoring
namespace: zabbix
roleRef:
kind: ClusterRole
name: zabbix-monitoring-role
apiGroup: rbac.authorization.k8s.io
---
apiVersion: v1
kind: Secret
metadata:
name: zabbix-monitoring-token
namespace: zabbix
annotations:
kubernetes.io/service-account.name: zabbix-monitoring
type: kubernetes.io/service-account-token
Retrieve the token to paste into the Zabbix frontend:
kubectl get secret zabbix-monitoring-token -n zabbix -o jsonpath='{.data.token}' | base64 -d
Note this uses read-only verbs (get, list, watch) exclusively — Zabbix never needs write access to your cluster to monitor it.
Step 4: Install the Kubernetes Metrics Server (Required for Resource Metrics)
Zabbix’s metrics.k8s.io polling depends on the standard Kubernetes metrics-server being present in the cluster:
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
kubectl get deployment metrics-server -n kube-system
Without this, Zabbix can still see object state (Pod phase, restart counts) but won’t get live CPU/memory utilization numbers.
Step 5: Import the Kubernetes Nodes/Pods Template
Zabbix ships official templates (“Kubernetes nodes by HTTP”, “Kubernetes cluster state”) that map directly onto the discovered objects. Import via Data collection → Templates → Import, then link them to the auto-discovered host group for your cluster.
Step 6: Build Triggers and Alerts
Common triggers worth configuring immediately:
- Node
NotReadycondition sustained for more than 2 minutes. - Pod
CrashLoopBackOffstate detected. - Deployment’s available replicas below desired replicas for more than 5 minutes.
- PersistentVolumeClaim usage above 85%.
Example trigger expression (Zabbix trigger syntax) for a Pod restart spike:
last(/Kubernetes cluster state/kube.pod.restarts.rate[production,api-server])>5
Set escalation actions in Alerts → Actions → Trigger actions to route these into whatever notification channel your team already uses in Zabbix (email, Slack integration, PagerDuty via webhook).
Dashboards
Zabbix’s built-in dashboard widgets (Graph, Problems, Top hosts) can be composed into a Kubernetes overview dashboard without needing a separate tool like Grafana, though Zabbix also supports a Grafana data source plugin if your team prefers that visualization layer while keeping Zabbix as the collection/alerting backend.
Security Considerations
- Scope the monitoring ServiceAccount strictly to read-only verbs, as shown above — never grant
create/update/delete. - Run the Zabbix Agent DaemonSet with only the host mounts it actually needs (
/proc,/sysread-only); avoid unnecessaryhostPID/hostNetworkif your monitoring needs don’t require them. - Store the Kubernetes API token as a Kubernetes Secret and restrict who can read it via RBAC on the
zabbixnamespace itself. - If exposing the Zabbix web frontend externally, put it behind proper authentication (LDAP/SAML integration, which Zabbix supports natively) and TLS.
Performance and Scaling
- For large clusters (500+ nodes), consider a Zabbix Proxy per cluster or region to offload polling and reduce load on the central Zabbix Server, syncing data asynchronously.
- Tune the discovery interval for Kubernetes objects — very frequent polling on large clusters can generate significant load on both the API server and Zabbix’s own database.
- Archive/trend older historical data according to your retention needs; Zabbix’s housekeeping settings control this independently of Kubernetes.
Common Mistakes
- Forgetting to deploy metrics-server, then wondering why CPU/memory graphs are empty even though Pod state monitoring works fine.
- Granting the monitoring ServiceAccount write permissions “just in case” — unnecessary and a real security risk if the Zabbix server itself is ever compromised.
- Not setting resource limits on the Zabbix Agent DaemonSet, letting it compete with actual workloads for node resources.
- Over-polling large clusters without a Proxy tier, causing API server load spikes that show up as false “Node NotReady” alerts.
Summary
Zabbix can serve as a genuine, capable Kubernetes monitoring solution — not just a bolt-on — by combining its DaemonSet-based agent for node/container metrics with its native Kubernetes API polling for cluster object state. The setup takes a bit more manual RBAC and template work than a Prometheus stack, but it pays off if you’re consolidating Kubernetes into an observability platform your team already trusts and knows how to operate at scale.