πŸ“šBook Signing at KubeCon EU 2026Meet us at Booking.com HQ (Mon 18:30-21:00) & vCluster booth #521 (Tue 24 Mar, 12:30-1:30pm) β€” free book giveaway!RSVP Booking.com Event
Observability intermediate ⏱ 20 minutes K8s 1.28+

Network Observability with Cilium Hubble

Monitor Kubernetes network traffic with Cilium Hubble. Service maps, DNS visibility, HTTP flow logs, network policy auditing, and Hubble UI dashboards.

By Luca Berton β€’ β€’ πŸ“– 5 min read

πŸ’‘ Quick Answer: Hubble is the observability layer built into Cilium. Enable it with cilium hubble enable --ui to get real-time network flow logs, DNS query visibility, HTTP request tracing, and a service dependency map. Use hubble observe CLI to filter flows by namespace, pod, verdict (FORWARDED/DROPPED), and protocol.

The Problem

Kubernetes NetworkPolicies are β€œfire and forget” β€” you apply them but can’t see what’s actually happening. When a pod can’t connect, is it DNS? NetworkPolicy? Wrong service port? Hubble gives eBPF-level visibility into every packet, DNS query, and HTTP request flowing through the cluster β€” without sidecars or application changes.

flowchart TB
    subgraph CLUSTER["Kubernetes Cluster"]
        POD_A["Pod A"] -->|"HTTP GET /api"| POD_B["Pod B"]
        POD_A -->|"DNS query"| COREDNS["CoreDNS"]
        POD_A -->|"DROPPED"| POD_C["Pod C<br/>(blocked by policy)"]
    end
    
    subgraph HUBBLE["Hubble (eBPF)"]
        FLOWS["Flow Logs<br/>(every packet)"]
        DNS["DNS Visibility<br/>(every query)"]
        HTTP["HTTP Tracing<br/>(L7 flows)"]
        MAP["Service Map<br/>(dependency graph)"]
    end
    
    CLUSTER --> HUBBLE

The Solution

Enable Hubble

# If Cilium is installed via CLI
cilium hubble enable --ui

# If Cilium is installed via Helm
helm upgrade cilium cilium/cilium \
  --namespace kube-system \
  --set hubble.relay.enabled=true \
  --set hubble.ui.enabled=true \
  --set hubble.metrics.enabled="{dns,drop,tcp,flow,icmp,http}"

# Port-forward Hubble UI
cilium hubble ui
# Opens browser at http://localhost:12000

Hubble CLI: Observe Flows

# Install Hubble CLI
export HUBBLE_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/hubble/master/stable.txt)
curl -LO "https://github.com/cilium/hubble/releases/download/$HUBBLE_VERSION/hubble-linux-amd64.tar.gz"
tar xzf hubble-linux-amd64.tar.gz && sudo mv hubble /usr/local/bin/

# Port-forward Hubble Relay
kubectl port-forward -n kube-system deploy/hubble-relay 4245:4245 &

# Observe all traffic in a namespace
hubble observe --namespace my-app

# Filter dropped traffic (NetworkPolicy violations)
hubble observe --verdict DROPPED

# DNS queries from a specific pod
hubble observe --pod my-app/web-abc123 --protocol DNS

# HTTP flows with status codes
hubble observe --namespace my-app --protocol HTTP \
  -o json | jq '.flow.l7.http'

# Traffic between two services
hubble observe \
  --from-pod my-app/frontend \
  --to-pod my-app/backend

Hubble Prometheus Metrics

# Expose Hubble metrics to Prometheus
hubble:
  metrics:
    enabled:
      - dns:query;ignoreAAAA
      - drop
      - tcp
      - flow
      - icmp
      - http
    serviceMonitor:
      enabled: true

# Key metrics:
# hubble_dns_queries_total β€” DNS query count by rcode
# hubble_drop_total β€” dropped packets by reason
# hubble_flows_processed_total β€” total flows
# hubble_http_requests_total β€” HTTP requests by method/status

Network Policy Audit with Hubble

# Find all dropped traffic (potential policy gaps)
hubble observe --verdict DROPPED --since 1h -o compact

# Example output:
# DROPPED  my-app/frontend -> my-app/cache:6379 TCP
# DROPPED  my-app/backend  -> kube-system/coredns:53 UDP
# β†’ Missing NetworkPolicy: backend needs DNS egress

# Find all traffic from a pod (to write policies)
hubble observe --from-pod my-app/frontend --since 24h \
  -o json | jq -r '.flow | "\(.source.namespace)/\(.source.labels) -> \(.destination.namespace)/\(.destination.labels) \(.l4.TCP.destination_port // .l4.UDP.destination_port)"' | sort -u

Common Issues

IssueCauseFix
hubble observe no outputHubble Relay not runningCheck kubectl get pods -n kube-system -l app.kubernetes.io/name=hubble-relay
No HTTP flowsL7 visibility not enabledAdd hubble.http to Cilium CiliumNetworkPolicy
High CPU on HubbleToo many flow eventsIncrease sampling rate or filter namespaces
UI shows no service mapNot enough traffic observedGenerate traffic or wait for organic flows
DNS queries not visibleDNS metrics not enabledAdd dns to hubble.metrics.enabled

Best Practices

  • Enable Hubble in all clusters β€” zero performance impact for basic flow logs
  • Use DROPPED filter first β€” fastest way to find NetworkPolicy issues
  • Export metrics to Prometheus β€” long-term visibility beyond Hubble’s buffer
  • Enable L7 selectively β€” HTTP tracing adds overhead; enable per-namespace
  • Audit before enforcing β€” observe flows first, then write NetworkPolicies from real traffic
  • Use service map for architecture docs β€” auto-generated dependency graph

Key Takeaways

  • Hubble provides eBPF-level network observability without sidecars
  • See every flow: source, destination, port, protocol, verdict (FORWARDED/DROPPED)
  • DNS visibility catches resolution failures and slow queries
  • HTTP tracing shows request methods, paths, and status codes
  • Service map auto-generates architecture dependency graphs from live traffic
  • Essential for writing and debugging Kubernetes NetworkPolicies
#cilium #hubble #network-observability #ebpf #service-map
Luca Berton
Written by Luca Berton

Principal Solutions Architect specializing in Kubernetes, AI/GPU infrastructure, and cloud-native platforms. Author of Kubernetes Recipes and creator of CopyPasteLearn courses.

Kubernetes Recipes book cover

Want More Kubernetes Recipes?

This recipe is from Kubernetes Recipes, our 750-page practical guide with hundreds of production-ready patterns.

Luca Berton Ansible Pilot Ansible by Example Open Empower K8s Recipes Terraform Pilot CopyPasteLearn ProteinLens