Skip to main content
In this lesson you will learn how to configure Cilium to either run alongside kube-proxy (default) or act as a complete replacement using Cilium’s eBPF-based datapath. The walkthrough uses a kind cluster, but the steps apply to other Kubernetes variants (Minikube, kubeadm) with minor adjustments.
A presentation slide with the word "Demo" on the left and "Kube Proxy" displayed on the right over a blue-green curved shape. A small "© Copyright KodeKloud" appears in the bottom-left.

Prerequisites

Create a kind cluster

Save the following as kind.config and create a cluster named my-cluster. This configuration disables the default CNI so we can install Cilium:
Create the cluster:
After creation, check node status (nodes will be NotReady until a CNI is installed):
Example output:
Verify kube-system pods — kube-proxy is present by default (one pod per node):
Example output highlighting kube-proxy:

Install Cilium (run alongside kube-proxy)

Install Cilium via the official Helm chart. By default, Cilium’s Helm chart sets kubeProxyReplacement to “false”, which means Cilium runs alongside kube-proxy and does not change service handling. Snippet example from values.yaml:
Install Cilium with Helm (adjust file paths as needed):
Verify Cilium pods are running:
Example output:
Verify the kube-proxy replacement setting from inside a Cilium agent pod using the Cilium debug tool: Get a Cilium agent pod name:
Exec into a Cilium agent pod and check status:
Expected output when running alongside kube-proxy:
This confirms Cilium is not replacing kube-proxy and leaves kube-proxy active.

Switching Cilium to replace kube-proxy

Cilium’s kube-proxy replacement (kubeProxyReplacement: “true”) hands over Kubernetes service handling from kube-proxy (iptables/ipvs) to Cilium’s eBPF-based datapath. High-level steps:
  1. Remove kube-proxy components (daemonset and configmap).
  2. Clean up kube-proxy-created iptables chains (environment-dependent).
  3. Update Cilium configuration to enable kube-proxy replacement and configure direct API server connectivity (k8sServiceHost/k8sServicePort).
  4. Upgrade the Cilium Helm release with new values.
  5. Verify replacement is active and confirm service connectivity.
Deleting kube-proxy and flushing iptables can disrupt cluster networking. Ensure you have console access to nodes and a recovery plan before making these changes on production clusters.
Important notes:
  • On kind clusters (Docker-in-Docker), iptables changes from inside containers may not affect the host. Proceed with caution and skip iptables cleanup on kind unless you understand the host context.
  • Ensure Cilium agents can reach the API server directly when kube-proxy is removed (set k8sServiceHost and k8sServicePort appropriately).

Remove kube-proxy daemonset and configmap

Delete the kube-proxy daemonset:
Delete the kube-proxy configmap:
You should see confirmation that resources were deleted.

iptables cleanup (environment-dependent)

kube-proxy typically creates Kubernetes-specific iptables chains. In production you would remove those so that Cilium’s eBPF datapath becomes authoritative for services. Do not run these commands on kind unless you know the correct host context. Example inspection and (cautious) commands:
On kind clusters running inside Docker containers, modifying host iptables from the container may not have the intended effect. Skip iptables cleanup on kind unless you know the correct host context.

Enable kube-proxy replacement in values.yaml

Edit your values.yaml to enable kube-proxy replacement and add API server connectivity settings. Example modifications:
Notes:
  • k8sServiceHost should be a hostname or IP reachable from worker nodes.
  • k8sServicePort is typically 6443 (API server port).
Table — kubeProxyReplacement options: Reference: Cilium kube-proxy replacement docs

Push updated configuration with Helm

Upgrade the Cilium release with the modified values:
After the upgrade, verify that Cilium reports kube-proxy replacement enabled. Get a Cilium agent pod and inspect status:
You should see a section similar to:
This confirms Cilium is now handling kube-proxy responsibilities.

Test service connectivity (NodePort example)

Create a simple nginx deployment and a NodePort service to verify service handling through Cilium’s replacement. deployment.yaml:
service.yaml:
Apply the manifests:
Confirm the service:
Example output:
Find node internal IPs:
Example excerpt:
From a host that can reach the node IP (here using worker node IP and nodePort 30007), confirm HTTP response:
Expected nginx response (truncated):
If you receive the nginx page, Cilium’s kube-proxy replacement is successfully servicing NodePort traffic via the eBPF datapath.

Summary

  • By default Cilium runs alongside kube-proxy (kubeProxyReplacement: “false”).
  • To let Cilium replace kube-proxy:
    • Remove kube-proxy components.
    • Clean iptables chains where required (environment-dependent).
    • Set kubeProxyReplacement: “true” and configure k8sServiceHost/k8sServicePort.
    • Upgrade the Cilium Helm release and verify with cilium-dbg status.
    • Validate service traffic with a test Deployment + Service.
  • Always test carefully and have recovery access when changing core networking components.
Links and references

Watch Video

Practice Lab