Install and configure Cilium CNI for Kubernetes with eBPF networking and security policies

Intermediate 25 min Apr 01, 2026 1,560 views
Ubuntu 24.04 Ubuntu 22.04 Debian 12 AlmaLinux 9 Rocky Linux 9 Fedora 41

Set up Cilium as your Kubernetes CNI plugin with advanced eBPF networking, load balancing, and network security policies. Includes Hubble observability for complete network visibility.

Prerequisites

  • Existing Kubernetes cluster with admin access
  • kubectl configured and working
  • Linux kernel 4.9+ with eBPF support
  • At least 2 CPU cores and 4GB RAM per node

What this solves

Cilium provides advanced networking, security, and observability for Kubernetes clusters using eBPF technology. It replaces traditional iptables-based networking with high-performance eBPF programs that run in the Linux kernel, offering better scalability and security than standard CNI plugins.

Step-by-step installation

Update system packages

Start by updating your system packages to ensure you have the latest security patches and dependencies.

sudo apt update && sudo apt upgrade -y
sudo apt install -y curl wget gnupg2 software-properties-common
sudo dnf update -y
sudo dnf install -y curl wget gnupg2 tar

Install Cilium CLI

Download and install the official Cilium CLI tool for managing Cilium installations and configurations.

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{,.sha256sum}
sha256sum --check cilium-linux-amd64.tar.gz.sha256sum
sudo tar xzvfC cilium-linux-amd64.tar.gz /usr/local/bin
rm cilium-linux-amd64.tar.gz{,.sha256sum}

Verify Kubernetes cluster prerequisites

Ensure your Kubernetes cluster is running and accessible, and that you have cluster-admin permissions.

kubectl cluster-info
kubectl get nodes
kubectl auth can-i '*' '*' --all-namespaces
Note: This tutorial assumes you have an existing Kubernetes cluster. If you need to set up a cluster first, check out our Kubernetes cluster installation guide.

Remove existing CNI plugin

If your cluster has an existing CNI plugin like Flannel or Calico, you need to remove it before installing Cilium.

# For Flannel
kubectl delete -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml

# For Calico
kubectl delete -f https://raw.githubusercontent.com/projectcalico/calico/master/manifests/calico.yaml

# Remove CNI configuration files from all nodes
sudo rm -rf /etc/cni/net.d/*
sudo rm -rf /opt/cni/bin/*
Warning: Removing the CNI plugin will cause existing pods to lose network connectivity. Plan this step during a maintenance window.

Install Cilium CNI

Deploy Cilium to your Kubernetes cluster with eBPF networking enabled and optimized configuration for production use.

cilium install \
  --version 1.15.1 \
  --set kubeProxyReplacement=true \
  --set k8sServiceHost=203.0.113.10 \
  --set k8sServicePort=6443 \
  --set hubble.relay.enabled=true \
  --set hubble.ui.enabled=true \
  --set operator.replicas=2
Note: Replace 203.0.113.10 with your actual Kubernetes API server IP address. Use kubectl cluster-info to find this address.

Wait for Cilium deployment

Monitor the Cilium installation progress and wait for all components to become ready.

cilium status --wait
kubectl get pods -n kube-system -l k8s-app=cilium
kubectl get pods -n kube-system -l name=cilium-operator

Enable Hubble observability

Configure Hubble for network flow visibility and monitoring across your cluster.

cilium hubble enable --ui
cilium hubble port-forward &

Install Hubble CLI

Install the Hubble CLI for command-line network observability and troubleshooting.

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{,.sha256sum}
sha256sum --check hubble-linux-amd64.tar.gz.sha256sum
sudo tar xzvfC hubble-linux-amd64.tar.gz /usr/local/bin
rm hubble-linux-amd64.tar.gz{,.sha256sum}

Configure eBPF networking and policies

Enable advanced eBPF features

Configure Cilium with advanced eBPF features including bandwidth management and socket-level load balancing.

apiVersion: v1
kind: ConfigMap
metadata:
  name: cilium-config
  namespace: kube-system
data:
  enable-bpf-masquerade: "true"
  enable-host-reachable-services: "true"
  enable-session-affinity: "true"
  enable-bandwidth-manager: "true"
  kube-proxy-replacement: "true"
  enable-health-check-nodeport: "true"
  node-port-bind-protection: "true"
  enable-auto-protect-node-port-range: "true"
  bpf-lb-algorithm: "maglev"
kubectl apply -f cilium-config.yaml
kubectl rollout restart ds/cilium -n kube-system

Create network security policies

Implement Layer 3 and Layer 4 network policies to secure pod-to-pod communication.

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: deny-all
  namespace: default
spec:
  endpointSelector: {}
  ingress: []
  egress: []
---
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: allow-frontend-to-backend
  namespace: default
spec:
  endpointSelector:
    matchLabels:
      app: backend
  ingress:
  - fromEndpoints:
    - matchLabels:
        app: frontend
    toPorts:
    - ports:
      - port: "8080"
        protocol: TCP
kubectl apply -f deny-all-policy.yaml

Configure Layer 7 HTTP policies

Set up application-layer security policies that can inspect and filter HTTP traffic.

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: http-policy
  namespace: default
spec:
  endpointSelector:
    matchLabels:
      app: api-server
  ingress:
  - fromEndpoints:
    - matchLabels:
        app: web-frontend
    toPorts:
    - ports:
      - port: "80"
        protocol: TCP
      rules:
        http:
        - method: "GET"
          path: "/api/.*"
        - method: "POST"
          path: "/api/users"
          headers:
          - "Content-Type: application/json"
kubectl apply -f http-policy.yaml

Enable cluster mesh for multi-cluster

Configure Cilium for multi-cluster networking if you have multiple Kubernetes clusters.

cilium clustermesh enable
cilium clustermesh status

Verify your setup

# Check Cilium status
cilium status

# Verify connectivity test
cilium connectivity test

# Check Hubble status
hubble status

# List network flows
hubble observe --follow

# Test policy enforcement
kubectl run test-pod --image=nginx --labels="app=test"
kubectl exec test-pod -- wget -qO- http://backend-service
Note: The connectivity test creates temporary test pods to verify networking functionality. This may take several minutes to complete.

Access Hubble UI

Open the Hubble UI for visual network observability and traffic analysis.

# Port forward to access Hubble UI
kubectl port-forward -n kube-system svc/hubble-ui 12000:80

</code><h2><code>Access the UI at http://localhost:12000</code></h2></pre>

# Common issues
<table>
<thead><tr><th>Symptom</th><th>Cause</th><th>Fix</th></tr></thead>
<tbody>
<tr><td>Pods stuck in ContainerCreating</td><td>CNI plugin not ready</td><td><code>cilium status</code> and restart cilium daemonset</td></tr>
<tr><td>Network policies not working</td><td>Missing policy labels</td><td>Verify pod labels match policy selectors</td></tr>
<tr><td>Hubble UI shows no flows</td><td>Hubble relay not enabled</td><td><code>cilium hubble enable</code> and restart pods</td></tr>
<tr><td>High CPU usage on nodes</td><td>eBPF program compilation</td><td>Wait for compilation or use pre-compiled images</td></tr>
<tr><td>LoadBalancer services not working</td><td>kube-proxy replacement not enabled</td><td>Add <code>--set kubeProxyReplacement=true</code> to install</td></tr>
<tr><td>DNS resolution failures</td><td>CoreDNS not accessible</td><td>Check CoreDNS pods and create DNS policy exceptions</td></tr>
</tbody>
</table>

# Performance optimization

<div class="step">
### Tune eBPF map sizes
<p>Optimize eBPF map sizes for large-scale deployments with many services and endpoints.</p>
<pre class="terminal"><code>apiVersion: v1
kind: ConfigMap
metadata:
  name: cilium-config
  namespace: kube-system
data:
  bpf-ct-global-tcp-max: "1000000"
  bpf-ct-global-any-max: "250000"
  bpf-nat-global-max: "524288"
  bpf-neigh-global-max: "524288"
  bpf-lb-map-max: "65536"

Enable direct server return

Configure direct server return for improved load balancing performance.

kubectl patch configmap cilium-config -n kube-system --patch='{"data":{"enable-dsr":"true"}}'
kubectl rollout restart ds/cilium -n kube-system

Next steps

Automated install script

Run this to automate the entire setup

Wil je dit niet zelf beheren?

Wij beheren infrastructuur voor bedrijven die afhankelijk zijn van uptime. Volledig beheerd, met één vast aanspreekpunt dat je omgeving kent.

U krijgt één vast aanspreekpunt dat uw omgeving kent

Op kantoor in Rotterdam 10:29 · bereikbaar in een bericht, geen ticketformulier