Cilium Network Policies

by Afanasy Barbarov

Cilium 1.19 with Hubble on Talos Linux.

Cilium on Talos Linux

Cilium is a CNI using eBPF for high-performance networking. I use it for:

  • Pod networking with VXLAN tunneling
  • Kube-proxy replacement
  • Hubble for network flow observability
  • Future: CiliumNetworkPolicy for L7 policies

Helm Configuration

Config stored in k8s/cilium-values.yaml:

# devices: ens3 required for Cilium 1.19+ (explicit device detection)
devices: ens3
bpf:
  hostLegacyRouting: true  # Required for DNS on Talos
cgroup:
  autoMount:
    enabled: false
  hostRoot: /sys/fs/cgroup
cluster:
  name: echo
k8sServiceHost: localhost
k8sServicePort: 7445  # KubePrism endpoint
kubeProxyReplacement: true
operator:
  replicas: 1
routingMode: tunnel
tunnelProtocol: vxlan
securityContext:
  capabilities:
    ciliumAgent: [CHOWN, KILL, NET_ADMIN, NET_RAW, IPC_LOCK, SYS_ADMIN, SYS_RESOURCE, DAC_OVERRIDE, FOWNER, SETGID, SETUID]
    cleanCiliumState: [NET_ADMIN, SYS_ADMIN, SYS_RESOURCE]
hubble:
  enabled: true
  relay:
    enabled: true
  ui:
    enabled: true

Install/upgrade:

helm upgrade --install cilium cilium/cilium -n kube-system -f k8s/cilium-values.yaml --version 1.19.0

Key Settings

  • devices: ens3 - Required for Cilium 1.19+. Without this, Cilium fails with "unable to determine direct routing device"
  • bpf.hostLegacyRouting: true - Required for DNS on Talos (eBPF Host-Routing conflicts with Talos DNS forwarding)
  • k8sServiceHost/Port: localhost:7445 - KubePrism endpoint for kube-proxy replacement

Hubble

Access the Hubble UI:

cilium hubble ui

Or port-forward:

kubectl port-forward -n kube-system svc/hubble-ui 12000:80

Watch network flows:

hubble observe
hubble observe --verdict DROPPED  # Only denied traffic

Network Policies

CiliumNetworkPolicies implemented for namespace isolation:

data namespace (k8s/network-policy-data.yaml)

  • Ingress: within namespace, observability (metrics ports only), kube-system
  • Egress: DNS, within namespace, kube-apiserver

observability namespace (k8s/network-policy-observability.yaml)

  • Ingress: within namespace, webhooks from API server, telemetry from data/kube-system/cnpg-system
  • Egress: DNS, within namespace, scrape data namespace metrics, kube-apiserver/host/remote-node
  • Blocked: external internet (no phoning home)

cnpg-system namespace (k8s/network-policy-cnpg-system.yaml)

  • Ingress: within namespace, webhooks from API server
  • Egress: DNS, within namespace, data namespace (manages Postgres), kube-apiserver/host/remote-node

Useful commands

# Watch dropped traffic
kubectl exec -n kube-system -it ds/cilium -- hubble observe --verdict DROPPED

# Check specific namespace
kubectl exec -n kube-system -it ds/cilium -- hubble observe --namespace data --verdict DROPPED

Written by Afanasy Barbarov — Tech Lead with 15+ years shipping production systems in Rust, Go, and TypeScript. Facing a similar challenge? Reach out on LinkedIn. Support my work.

More articles

Previous post

Setting up Talos Linux + Kubernetes + Cilium on Bare Metal.

Read more

Next post

ClickStack + HyperDX Observability with Kubernetes Operators.

Read more