Cilium Series Part 5: Replacing KubeProxy with Cilium
This article was last updated on: May 17, 2026 am
Series Articles
Introduction
Switching the Kubernetes CNI from other components to Cilium already provides a noticeable boost in network performance. However, by toggling different Cilium modes and enabling additional features, you can further improve Cilium’s network performance. Tuning options include but are not limited to:
- Enable Native Routing
- Fully replace KubeProxy
- Switch IP Address Masquerading to eBPF-based mode
- Run Kubernetes NodePort in DSR (Direct Server Return) mode
- Bypass iptables Connection Tracking
- Switch Host Routing to BPF-based mode (requires Linux Kernel >= 5.10)
- Enable IPv6 BIG TCP (requires Linux Kernel >= 5.19)
- Disable Hubble (not recommended — observability is more important than a marginal performance gain)
- Change MTU to jumbo frames (requires network conditions to allow it)
- Enable Bandwidth Manager (requires Kernel >= 5.1)
- Enable BBR congestion control for Pods (requires Kernel >= 5.18)
- Enable XDP Acceleration (requires native XDP driver support)
- (Optional for advanced users) Adjust eBPF Map Size
- Linux Kernel optimization and upgrade
- CONFIG_PREEMPT_NONE=y
- Other:
- tuned network-* profiles, e.g.: tuned-adm profile network-latency or network-throughput
- Set CPU to performance mode
- Stop irqbalance and pin NIC interrupts to specific CPUs
When network/NIC/OS conditions permit, we enable as many of these tuning options as possible. Related optimizations will be covered one by one in subsequent articles. Stay tuned.
In the previous article, we enabled Cilium Native Routing, which resulted in a significant improvement in network throughput.
Today, we will use Cilium to fully replace KubeProxy, creating a Kubernetes cluster without KubeProxy, thereby drastically reducing iptables rule chains (and netfilter) for comprehensive network performance improvements.
Test Environment
- Cilium 1.13.4
- K3s v1.26.6+k3s1
- OS
- 3 Ubuntu 23.04 VMs, Kernel 6.2, x86
Background
In Kubernetes clusters, Kube Proxy makes heavy use of iptables. At larger cluster scales, thousands or even tens of thousands of iptables rules can severely degrade Kubernetes network performance, leading to slow network request responses.
An example of a large number of iptables rule chains:

What Kube Proxy Does
Kube Proxy is responsible for traffic routing in the following areas:
- ClusterIP: In-cluster access via ClusterIP
- NodePort: Access from inside and outside the cluster via NodePort
- ExternalIP: External access via external IPs
- LoadBalancer: External access via LoadBalancer
Cilium fully implements all of these features with significant performance improvements. The official Cilium benchmark results are as follows:

Performance is even better with DSR enabled:

Implementation Steps
Let’s proceed with the replacement. Cilium’s eBPF kube-proxy replacement works in both direct routing and tunnel modes.
Reinstall K3s
1 | |
Notes:
- –disable=servicelb K3s servicelb is not a standard Kubernetes component. To reduce interference, we remove it first.
- –disable-kube-proxy Disables Kube Proxy
Reinstall Cilium
Depending on the situation, you may need to uninstall Cilium first:
1 | |
Reinstall with the kubeProxyReplacement parameter:
1 | |
Notes:
- kubeProxyReplacement=strict Sets kube-proxy replacement to strict mode. By default, Helm sets kubeProxyReplacement=disabled, which only enables in-cluster load balancing for ClusterIP services.
Basic Verification
Verify after installation:
1 | |
Use --verbose to view full details:
1 | |
Hands-on Verification
Next, we can create an Nginx deployment, then create a new NodePort service and verify that Cilium has correctly installed the service.
Create the Nginx Deployment:
1 | |
Next, create a NodePort service for these two instances:
1 | |
Check the NodePort service port and other details:
1 | |
Using the cilium service list command, we can verify that Cilium’s eBPF kube-proxy replacement has created the new NodePort service. In this example, a service with port 32727 was created (on NIC device eth0):
1 | |
Additionally, we can use iptables in the host namespace to verify that there are no iptables rules for this service:
1 | |
The empty result above confirms that there are no KUBE-SVC related iptables rules.
We can test using curl against NodePort, ClusterIP, PodIP, etc.:
1 | |
│ 📝Note
│
│ The last two commands work because we previously enabled Native Routing.
All requests succeed:
1 | |
🎉🎉🎉
Summary
Kube Proxy’s heavy use of iptables negatively impacts network performance in large-scale Kubernetes clusters. By fully replacing Kube Proxy with Cilium, you can significantly improve Kubernetes network performance for ClusterIP, NodePort, LoadBalancer, externalIPs, and more.
So far, the following performance tuning items have been completed:
- ✔️ Enable Native Routing
- ✔️ Fully replace KubeProxy
- Switch IP Address Masquerading to eBPF-based mode
- Run Kubernetes NodePort in DSR (Direct Server Return) mode
- Bypass iptables Connection Tracking
- Switch Host Routing to BPF-based mode (requires Linux Kernel >= 5.10)
- Enable IPv6 BIG TCP (requires Linux Kernel >= 5.19)
- Change MTU to jumbo frames (requires network conditions to allow it)
- Enable Bandwidth Manager (requires Kernel >= 5.1)
- Enable BBR congestion control for Pods (requires Kernel >= 5.18)
- Enable XDP Acceleration (requires native XDP driver support)