Skip to content

Cilium & Network Policies

Cilium is the CNI (Container Network Interface) plugin. It handles all pod-to-pod networking and enforces NetworkPolicies using eBPF — a Linux kernel technology that allows high-performance, programmable packet processing.

What eBPF Means for You

Traditional CNIs use iptables rules. Cilium uses eBPF programs loaded directly into the kernel:

  • Faster — no iptables chain traversal
  • More observable — every packet can be logged (Hubble)
  • L7-aware — can enforce policies based on HTTP path, method, gRPC service name

Hubble UI

Hubble is Cilium's observability layer. It shows real-time network flows between pods as a visual graph.

cilium hubble ui   # opens browser automatically

The UI shows: - Which pods are talking to which - Whether traffic is allowed (green) or dropped (red) by a NetworkPolicy - Protocols, ports, and response codes

This is invaluable for understanding and debugging NetworkPolicies.

Network Policies

NetworkPolicies live in infrastructure/network-policies/ and are managed by Flux.

Default Deny Ingress

default-deny-ingress.yaml — blocks all inbound traffic to pods in default namespace:

spec:
  podSelector: {}   # all pods
  policyTypes:
    - Ingress
  # no ingress rules = deny everything

Zero-trust baseline

Apply default-deny first, then add explicit allow rules. This forces you to think about every traffic path.

Allow DNS Egress

allow-dns-egress.yaml — allows pods to resolve DNS names (required for any service communication):

egress:
  - to:
      - namespaceSelector:
          matchLabels:
            kubernetes.io/metadata.name: kube-system
    ports:
      - protocol: UDP
        port: 53

Allow Monitoring Scrape

allow-monitoring-scrape.yaml — allows Prometheus to scrape metrics from pods in default namespace.

Cilium-Specific Policies (L7)

Standard NetworkPolicy operates at L3/L4 (IP + port). Cilium extends this with CiliumNetworkPolicy for L7:

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: allow-get-only
spec:
  endpointSelector:
    matchLabels:
      app: my-api
  ingress:
    - toPorts:
        - ports:
            - port: "8080"
              protocol: TCP
          rules:
            http:
              - method: GET   # only allow GET, block POST/DELETE etc.

This level of policy is not possible with standard K8s NetworkPolicy.

Useful Commands

# Check Cilium health
cilium status

# Run full connectivity test
cilium connectivity test

# Open Hubble network flow UI
cilium hubble ui

# Observe live flows in terminal (requires hubble CLI)
hubble observe --follow

# List NetworkPolicies
kubectl get networkpolicies -A

# Check Cilium endpoints (per-pod policy status)
kubectl exec -n kube-system ds/cilium -- cilium endpoint list

See ADR-008 for the full decision record.