Kubernetes networking is berucht complex. CNI plugins, kube-proxy, iptables chains, service meshes — laag op laag van abstractie die uiteindelijk kapotgaat op manieren die niemand begrijpt.

Cilium verandert dit. Het gebruikt eBPF om networking logica in de Linux kernel te plaatsen, waarbij iptables volledig wordt overgeslagen. Het resultaat: betere performance, meer zichtbaarheid, en network policies die daadwerkelijk logisch zijn.

Dit draai ik in mijn clusters. Laat me je tonen waarom.

Wat is eBPF?

eBPF (extended Berkeley Packet Filter) laat je sandboxed programma’s draaien in de Linux kernel zonder kernel source code te wijzigen of kernel modules te laden.

flowchart TD
    subgraph userspace["User Space"]
        APP["Applicatie"]
        CILIUM["Cilium Agent"]
    end

    subgraph kernel["Kernel Space"]
        EBPF["eBPF Programma's"]
        NET["Network Stack"]
        HOOKS["Kernel Hooks<br/>(XDP, TC, Socket)"]
    end

    APP --> NET
    CILIUM -->|"laadt"| EBPF
    EBPF --> HOOKS
    HOOKS --> NET

Traditionele networking gebruikt iptables — een keten van regels die sequentieel worden geëvalueerd. eBPF programma’s worden gecompileerd en direct in de kernel uitgevoerd, met map-based lookups in plaats van lineaire regel scanning.

Het verschil op schaal is dramatisch. Iptables met 10.000 services? Performance nachtmerrie. Cilium met 10.000 services? Constant-time lookups.

Cilium Installeren

Vervang je bestaande CNI met Cilium:

# Installeer Cilium CLI
CILIUM_CLI_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/cilium-cli/main/stable.txt)
curl -L --fail --remote-name-all https://github.com/cilium/cilium-cli/releases/download/${CILIUM_CLI_VERSION}/cilium-linux-amd64.tar.gz
sudo tar xzvfC cilium-linux-amd64.tar.gz /usr/local/bin
rm cilium-linux-amd64.tar.gz

# Installeer Cilium in cluster
cilium install --version 1.15.0

# Verifieer installatie
cilium status --wait

Voor Helm-based GitOps deployment:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: cilium
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://helm.cilium.io/
    chart: cilium
    targetRevision: 1.15.0
    helm:
      values: |
        kubeProxyReplacement: true
        k8sServiceHost: "10.0.0.1"
        k8sServicePort: "6443"

        hubble:
          enabled: true
          relay:
            enabled: true
          ui:
            enabled: true

        operator:
          replicas: 2

        ipam:
          mode: kubernetes

  destination:
    server: https://kubernetes.default.svc
    namespace: kube-system

kube-proxy Vervanging

Cilium kan kube-proxy volledig vervangen door Kubernetes Services in eBPF te implementeren:

# Cilium values
kubeProxyReplacement: true
k8sServiceHost: "10.0.0.1"  # API server IP
k8sServicePort: "6443"

Voordelen:

  • Geen iptables regels voor services
  • Direct server return voor betere performance
  • Socket-level load balancing — beslissingen bij connect(), niet per-packet
  • Maglev hashing voor consistente backend selectie

Verifieer dat het werkt:

kubectl -n kube-system exec ds/cilium -- cilium status | grep KubeProxyReplacement
# KubeProxyReplacement: True [eth0 10.0.0.10 (Direct Routing)]

Network Policies

Cilium implementeert standaard Kubernetes NetworkPolicy plus uitgebreide CiliumNetworkPolicy:

Kubernetes NetworkPolicy

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: api-ingress
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: api
  policyTypes:
    - Ingress
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: frontend
      ports:
        - protocol: TCP
          port: 8080

CiliumNetworkPolicy (Uitgebreid)

Cilium’s native policies bieden meer kracht:

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: api-policy
  namespace: production
spec:
  endpointSelector:
    matchLabels:
      app: api
  ingress:
    - fromEndpoints:
        - matchLabels:
            app: frontend
      toPorts:
        - ports:
            - port: "8080"
              protocol: TCP
          rules:
            http:
              - method: "GET"
                path: "/api/v1/.*"
              - method: "POST"
                path: "/api/v1/orders"

Let op de rules.http — Cilium kan L7 policies afdwingen, waarbij specifieke HTTP methods en paths worden toegestaan. Geen service mesh nodig.

DNS-Based Policies

Sta verkeer naar externe services toe op DNS naam:

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: allow-external-api
spec:
  endpointSelector:
    matchLabels:
      app: backend
  egress:
    - toFQDNs:
        - matchName: "api.stripe.com"
        - matchPattern: "*.amazonaws.com"
      toPorts:
        - ports:
            - port: "443"

Cilium onderschept DNS queries en update policies dynamisch wanneer IPs veranderen.

Cluster-Wide Policies

Pas policies toe over alle namespaces:

apiVersion: cilium.io/v2
kind: CiliumClusterwideNetworkPolicy
metadata:
  name: deny-external-by-default
spec:
  endpointSelector: {}
  egress:
    - toEntities:
        - cluster
        - host
    - toFQDNs:
        - matchPattern: "*.internal.company.com"
  egressDeny:
    - toEntities:
        - world

Dit weigert internet toegang standaard, en staat alleen intern verkeer toe tenzij expliciet toegestaan.

Hubble: Network Observability

Hubble is Cilium’s observability laag. Het toont je wat er daadwerkelijk gebeurt op je netwerk.

# Enable Hubble
hubble:
  enabled: true
  relay:
    enabled: true
  ui:
    enabled: true
  metrics:
    enabled:
      - dns
      - drop
      - tcp
      - flow
      - icmp
      - http

Hubble CLI

# Installeer Hubble CLI
export HUBBLE_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/hubble/master/stable.txt)
curl -L --fail --remote-name-all https://github.com/cilium/hubble/releases/download/$HUBBLE_VERSION/hubble-linux-amd64.tar.gz
sudo tar xzvfC hubble-linux-amd64.tar.gz /usr/local/bin

# Port-forward naar Hubble Relay
cilium hubble port-forward &

# Observeer flows
hubble observe --namespace production

# Filter op pod
hubble observe --pod production/api-xyz123

# Filter op verdict
hubble observe --verdict DROPPED

# Filter op HTTP
hubble observe --protocol http --http-status 500

Hubble UI

Toegang tot de visuele network flow map:

cilium hubble ui
# Opent browser naar http://localhost:12000

De UI toont:

  • Service dependency graph
  • Real-time traffic flows
  • Policy verdicts (allowed/dropped)
  • HTTP request/response details

Hubble Metrics

Exporteer naar Prometheus:

hubble:
  metrics:
    serviceMonitor:
      enabled: true
    enabled:
      - dns:query;ignoreAAAA
      - drop
      - tcp
      - flow
      - icmp
      - http

Nuttige metrics:

  • hubble_flows_processed_total — Totaal geobserveerde flows
  • hubble_drop_total — Gedropte packets per reden
  • hubble_http_requests_total — HTTP requests per method, status
  • hubble_dns_queries_total — DNS queries per type, response

Service Mesh (Zonder Sidecars)

Cilium kan service mesh features leveren zonder sidecar proxies:

# Enable L7 proxy
l7Proxy: true

# Enable mutual TLS
authentication:
  mutual:
    spiffe:
      enabled: true
      trustDomain: cluster.local

Beschikbare features:

  • mTLS tussen services (met SPIFFE identities)
  • L7 load balancing met retries
  • Traffic management (canary, header-based routing)
  • Observability (L7 metrics, distributed tracing)

Het belangrijke verschil: geen sidecar containers. De eBPF dataplane regelt alles, wat resource overhead en latency vermindert.

BGP voor Bare Metal

Draai je op bare metal zonder cloud load balancer? Cilium spreekt BGP:

# Enable BGP
bgpControlPlane:
  enabled: true
apiVersion: cilium.io/v2alpha1
kind: CiliumBGPPeeringPolicy
metadata:
  name: rack-bgp
spec:
  nodeSelector:
    matchLabels:
      rack: rack-1
  virtualRouters:
    - localASN: 65001
      exportPodCIDR: true
      neighbors:
        - peerAddress: "10.0.0.1/32"
          peerASN: 65000

Je pods krijgen routeerbare IPs, geadverteerd via BGP naar je netwerk infrastructuur.

Bandbreedte Management

Cilium kan bandbreedte limieten afdwingen:

apiVersion: v1
kind: Pod
metadata:
  annotations:
    kubernetes.io/ingress-bandwidth: "10M"
    kubernetes.io/egress-bandwidth: "10M"
spec:
  containers:
    - name: app
      image: my-app:latest

Geïmplementeerd in eBPF, niet tc rules. Efficiënter, voorspelbaarder.

Encryptie

Versleutel alle pod-to-pod verkeer:

# WireGuard encryptie (aanbevolen)
encryption:
  enabled: true
  type: wireguard

# Of IPsec
encryption:
  enabled: true
  type: ipsec

WireGuard is sneller en simpeler. IPsec als je compliance certificeringen nodig hebt die het specifiek vereisen.

Verifieer encryptie:

kubectl -n kube-system exec ds/cilium -- cilium status | grep Encryption
# Encryption: Wireguard [NodeEncryption: Disabled, cilium_wg0 (Pubkey: xxx, Port: 51871, Peers: 2)]

Multi-Cluster met Cluster Mesh

Verbind meerdere Cilium clusters:

# Enable Cluster Mesh op elk cluster
cilium clustermesh enable

# Verbind clusters
cilium clustermesh connect --destination-context cluster2

Features:

  • Global services — Dezelfde service toegankelijk vanaf elk cluster
  • Cross-cluster network policies — Sta verkeer toe van cluster1 naar cluster2 pods
  • Gedeelde identities — Consistente security policies over clusters
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: allow-from-cluster1
spec:
  endpointSelector:
    matchLabels:
      app: api
  ingress:
    - fromEndpoints:
        - matchLabels:
            io.cilium.k8s.policy.cluster: cluster1
            app: frontend

Troubleshooting

Check Endpoint Status

kubectl -n kube-system exec ds/cilium -- cilium endpoint list

Check Policy Verdicts

kubectl -n kube-system exec ds/cilium -- cilium policy get

Debug Gedropte Traffic

hubble observe --verdict DROPPED

Check BPF Maps

kubectl -n kube-system exec ds/cilium -- cilium bpf lb list
kubectl -n kube-system exec ds/cilium -- cilium bpf endpoint list

Mijn Productie Configuratie

cilium:
  kubeProxyReplacement: true
  k8sServiceHost: "10.0.0.1"
  k8sServicePort: "6443"

  ipam:
    mode: kubernetes

  # Enable Hubble observability
  hubble:
    enabled: true
    relay:
      enabled: true
    ui:
      enabled: true
    metrics:
      enabled:
        - dns:query
        - drop
        - tcp
        - flow
        - http

  # WireGuard encryptie
  encryption:
    enabled: true
    type: wireguard

  # L7 policies
  l7Proxy: true

  # Operator HA
  operator:
    replicas: 2

  # Resource limits
  resources:
    limits:
      cpu: 1000m
      memory: 1Gi
    requests:
      cpu: 100m
      memory: 256Mi

Belangrijke keuzes:

  • kube-proxy vervanging — Simpeler, sneller
  • WireGuard encryptie — Zero-config versleuteling
  • Hubble metrics — Exporteer naar Prometheus voor alerting
  • L7 proxy — HTTP-aware policies zonder service mesh

Waarom Cilium?

Traditionele CNI plugins werken. Calico, Flannel, Weave — ze routen allemaal packets. Maar ze bouwen op iptables, een technologie uit 1998.

Cilium representeert de toekomst:

  • eBPF — Programmeerbare dataplane in de kernel
  • Identity-based — Policies gebaseerd op wat, niet waar
  • Observable — Zie daadwerkelijk verkeer, niet alleen regels
  • Uitbreidbaar — Service mesh, BGP, encryptie in één tool

Voor het begrijpen van je netwerk geeft Cilium zichtbaarheid die iptables-gebaseerde oplossingen niet kunnen matchen. Voor security vangen L7-aware policies wat L3/L4 niet kan. Voor performance verslaat eBPF lineaire regel evaluatie.

Dit is hoe moderne Kubernetes networking eruitziet.


iptables heeft ons decennia goed gediend. Maar Kubernetes vraagt iets dynamischer, meer observable, krachtiger. eBPF is dat iets, en Cilium is hoe je het gebruikt.