Kube-OVN is an enterprise-grade Kubernetes networking solution built on Open Virtual Network (OVN). It provides advanced features like subnets, VPCs, QoS, and network policies implemented at the OVN layer. But OVN's complexity means more components that can fail silently — and when the networking layer breaks, your pods are unreachable while kubectl get pods still shows them as Running.
In this tutorial you'll set up comprehensive uptime monitoring for your Kube-OVN-based Kubernetes cluster using Vigilmon — free tier, no credit card required.
Why Kube-OVN clusters need external monitoring
Kube-OVN adds a sophisticated networking layer between your pods and the outside world. Failures here create a class of issues that Kubernetes doesn't detect:
- OVN northbound/southbound DB goes down — OVN control plane is lost; existing flows still work but no new network policy or routing changes are applied; new pods get no network
- kube-ovn-controller crashes — subnet allocation, IP address management, and load balancer provisioning all stop; pods start without network interfaces
- ovs-vswitchd or ovsdb-server fails on a node — that node's pods lose network connectivity while Kubernetes still reports them as
Running - Gateway node becomes unavailable — pods on non-gateway nodes lose external connectivity; internal pod-to-pod traffic may work but external requests time out
- VPC routing table corruption — inter-namespace or inter-VPC traffic is silently dropped while internal cluster DNS and pod status look healthy
These failures are particularly tricky because Kubernetes liveness probes check that the application process is alive, not that it can receive network traffic from outside the cluster.
What you'll need
- A running Kubernetes cluster with Kube-OVN as the CNI
- At least one service exposed via LoadBalancer or Ingress
- A free Vigilmon account (sign up takes 30 seconds)
Step 1: Expose a health endpoint for monitoring
Kube-OVN itself exposes metrics and health endpoints. Check that your application services are reachable and add health routes:
# Check Kube-OVN pods
kubectl get pods -n kube-system -l app=kube-ovn-controller
kubectl get pods -n kube-system -l app=kube-ovn-cni
# Check the Kube-OVN pinger component — it actively tests connectivity
kubectl get pods -n kube-system -l app=kube-ovn-pinger
The kube-ovn-pinger already monitors per-node connectivity. You want external monitoring on top of that.
Deploy a test application with a health endpoint to verify end-to-end connectivity through the Kube-OVN network stack:
# connectivity-test.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: network-health
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: network-health
template:
metadata:
labels:
app: network-health
spec:
containers:
- name: health
image: nginx:alpine
ports:
- containerPort: 80
volumeMounts:
- name: config
mountPath: /etc/nginx/conf.d
readinessProbe:
httpGet:
path: /health
port: 80
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /health
port: 80
initialDelaySeconds: 10
periodSeconds: 30
volumes:
- name: config
configMap:
name: health-nginx
---
apiVersion: v1
kind: ConfigMap
metadata:
name: health-nginx
namespace: default
data:
default.conf: |
server {
listen 80;
location /health {
return 200 '{"status":"ok","net":"kube-ovn"}';
add_header Content-Type application/json;
}
}
---
apiVersion: v1
kind: Service
metadata:
name: network-health
namespace: default
spec:
type: LoadBalancer
selector:
app: network-health
ports:
- port: 80
targetPort: 80
protocol: TCP
kubectl apply -f connectivity-test.yaml
# Get the LoadBalancer IP
kubectl get svc network-health
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
# network-health LoadBalancer 10.96.200.5 203.0.113.110 80/TCP 1m
# Verify it responds
curl http://203.0.113.110/health
# {"status":"ok","net":"kube-ovn"}
Kube-OVN also exposes its own metrics endpoint. You can optionally expose that for monitoring:
# Kube-OVN metrics (Prometheus format)
kubectl port-forward -n kube-system svc/kube-ovn-controller 10660:10660
curl http://localhost:10660/metrics | grep kube_ovn_ovs_up
Step 2: Set up HTTP monitoring in Vigilmon
With your health endpoint exposed, add it to Vigilmon:
- Log in to vigilmon.online and go to Monitors → New Monitor
- Choose HTTP / HTTPS as the type
- Set the URL to your LoadBalancer health endpoint:
http://203.0.113.110/health - Set the check interval to 1 minute
- Under Expected response, set:
- Status code:
200 - Response body contains:
"status":"ok"
- Status code:
- Save the monitor
This single monitor validates the entire Kube-OVN data path: pod network interface assignment, OVS flow programming, gateway routing, and LoadBalancer IP binding all have to be working for a 200 response to reach Vigilmon.
Why external monitoring catches what kube-ovn-pinger misses
The kube-ovn-pinger probes connectivity between nodes on the provisioning VLAN — it catches internal OVN fabric failures. But it doesn't validate that traffic from the public internet can reach your services through your LoadBalancer. Vigilmon's multi-region consensus model probes from multiple independent geographic locations and requires agreement before firing, eliminating false positives from single-path transient failures while still catching real external connectivity losses within seconds.
Step 3: Monitor TCP ports and per-node connectivity
OVN/OVS failures are often node-specific. Add TCP monitors for individual node ports to detect per-node networking failures:
LoadBalancer TCP port:
- Go to Monitors → New Monitor
- Choose TCP Port
- Enter: Host
203.0.113.110, Port80 - Save the monitor
Node-level TCP check (NodePort):
Expose the health service as a NodePort to verify that individual nodes can route traffic:
# nodeport-health.yaml
apiVersion: v1
kind: Service
metadata:
name: network-health-nodeport
namespace: default
spec:
type: NodePort
selector:
app: network-health
ports:
- port: 80
targetPort: 80
nodePort: 30180
protocol: TCP
kubectl apply -f nodeport-health.yaml
# Get node IPs
kubectl get nodes -o wide
# NAME STATUS ROLES AGE INTERNAL-IP EXTERNAL-IP
# node-1 Ready worker 5d 192.168.1.10 203.0.113.11
# node-2 Ready worker 5d 192.168.1.11 203.0.113.12
Add a TCP monitor for each node's NodePort:
Host: 203.0.113.11 Port: 30180 (node-1)
Host: 203.0.113.12 Port: 30180 (node-2)
This catches the case where a specific node's OVS instance is broken — a failure mode that is completely invisible to LoadBalancer-level monitoring.
Step 4: Configure alert channels
A Kube-OVN networking failure is one of the most disruptive Kubernetes incidents: pods appear healthy but are unreachable, and diagnosing OVN/OVS issues requires deep expertise. Early detection is critical.
Email alerts
- In Vigilmon, go to Alert Channels → Add Channel → Email
- Enter your network/platform team's on-call email
- Assign the channel to all Kube-OVN monitors
Webhook alerts (Slack, PagerDuty, etc.)
- Go to Alert Channels → Add Channel → Webhook
- Enter your webhook URL
- Assign the channel to your monitors
Example payload when the network health endpoint goes down:
{
"monitor_name": "Kube-OVN Network Health",
"status": "down",
"url": "http://203.0.113.110/health",
"started_at": "2024-01-15T10:23:00Z",
"duration_seconds": 90
}
Use this to trigger OVN diagnostics immediately:
# Check OVN/OVS component health
kubectl get pods -n kube-system | grep -E "ovn|ovs|kube-ovn"
# Check kube-ovn-controller logs
kubectl logs -n kube-system -l app=kube-ovn-controller --tail=100
# Check OVN NB/SB database status
kubectl exec -n kube-system -it ovn-central-<pod-id> -- ovn-nbctl show | head -50
# Check per-node OVS status
kubectl exec -n kube-system -it kube-ovn-cni-<pod-id> -- ovs-vsctl show
# Check kube-ovn-pinger results
kubectl logs -n kube-system -l app=kube-ovn-pinger --tail=50
Step 5: Create a public status page
Network-level failures affect every application running in the cluster. A status page lets all teams track the incident without needing kubectl access.
- In Vigilmon, go to Status Pages → New Status Page
- Give it a name: "Cluster Network Status"
- Add your monitors: Network Health HTTP, LoadBalancer TCP, per-node NodePort checks
- Group them: External Connectivity, Load Balancer, Per-Node Health
- Publish the page
Share this URL with:
- All development teams running services in the cluster
- Your NOC or on-call rotation
- Stakeholders who need SLA visibility during incidents
Putting it all together
Here's a summary of the monitors to create for a Kube-OVN cluster:
| Monitor | Type | What it catches |
|---------|------|-----------------|
| http://203.0.113.110/health | HTTP | Full data-path connectivity (pod → gateway → LB → internet) |
| 203.0.113.110:80 | TCP | LoadBalancer port binding |
| 203.0.113.11:30180 | TCP | Node-1 OVS/OVN data path |
| 203.0.113.12:30180 | TCP | Node-2 OVS/OVN data path |
| https://api.your-cluster.com/healthz | HTTP | Kubernetes API server (control plane) |
And the OVN/OVS diagnostics to run when an alert fires:
# Quick triage: is it control plane or data plane?
kubectl get nodes
kubectl get pods -n kube-system | grep -E "ovn|kube-ovn"
# Data plane: check OVS flows on the affected node
kubectl debug node/node-1 -it --image=docker.io/kubeovn/kube-ovn:v1.12.0 -- \
ovs-ofctl dump-flows br-int | head -30
# Control plane: check OVN logical topology
ovn-nbctl logical-switch-list
ovn-nbctl acl-list <switch-name>
# Check subnet allocation
kubectl get subnet -A
kubectl describe subnet default
What's next
- SSL certificate monitoring — add Vigilmon SSL monitors for any HTTPS services using Kube-OVN's LoadBalancer with TLS termination
- Heartbeat monitoring — use Vigilmon heartbeats to verify that your Kube-OVN controller reconciliation and pinger jobs are running as expected
- Multi-cluster coverage — if you run multiple Kube-OVN clusters, create a status page group per cluster to isolate failures and track SLAs independently
Get started free at vigilmon.online — no credit card, monitors start running in under a minute.