
- Programs the Linux kernel datapath with eBPF for most routing and load-balancing work, avoiding the need for a separate Ingress-controller pod for L3/L4.
- Uses Envoy only where required: L7 processing, TLS termination (if configured), and policy enforcement.
- Supports both traditional Kubernetes Ingress and the Gateway API for modern traffic routing.
When you enable Cilium’s ingress controller (ingressController.enabled = true), Cilium automatically configures Envoy where needed. eBPF handles most routing and load-balancing tasks for better performance and lower resource usage.
Enabling Cilium Ingress (Helm values)
To enable Cilium Ingress in a Helm-managed installation, set up the NodePort service implementation and enable the ingress controller in your values.yaml. You can also make Cilium the default Ingress controller and choose a load balancer mode (dedicated or shared). values.yaml (example)Load balancer modes: dedicated vs shared
Cilium supports two modes for provisioning external cloud load balancers for Ingress resources. Choose the mode that fits your isolation, cost, and routing needs.| Mode | Description | When to use |
|---|---|---|
| dedicated | Each Ingress resource provisions its own external Load Balancer (e.g., AWS ELB/ALB per Ingress). | Use when you need strict isolation per Ingress or separate public endpoints. |
| shared | Multiple Ingress resources share a single external Load Balancer. Cilium programs forwarding rules so a single LB routes traffic to many Ingresses. | Use to minimize cloud LB count and cost; centralize routing and certificates. |
Using dedicated mode increases the number of cloud load balancers (and cost). Use shared mode to consolidate LB resources, and prefer dedicated only when endpoint isolation or separate LB features are required.
- ingress.cilium.io/loadbalancer-mode: shared
- ingress.cilium.io/loadbalancer-mode: dedicated
Example: Minimal Ingress manifest
If you setingressController.default: true, Cilium will claim Ingresses without an ingressClassName. Otherwise, you can explicitly set the Cilium ingress class.
Behavior examples
Dedicated mode- Each Ingress provisions an external LB, so
kubectl get ingresswill show unique addresses per Ingress:
- All Ingress resources present the same external address because a single shared LB is used and Cilium programs routing rules to direct traffic to the correct Ingress backend.
Verification and troubleshooting tips
- Check Cilium pods and operator in the kube-system namespace to confirm the ingress controller is enabled:
- kubectl -n kube-system get pods | grep cilium
- kubectl -n kube-system get deployment cilium-operator
- Validate default controller behavior:
- Create an Ingress without ingressClassName if
ingressController.default: trueand confirm Cilium has claimed it.
- Create an Ingress without ingressClassName if
- Change mode per-Ingress via annotation:
ingress.cilium.io/loadbalancer-mode: sharedordedicated. - Inspect the Envoy configuration (when used) in the Cilium-managed Envoy instances for L7 policy issues.
- Consult logs for cilium-agent and cilium-operator when troubleshooting provisioning or LB interactions.
References
- Kubernetes Ingress Concepts
- Cilium Documentation — Ingress and Load Balancing
- Gateway API (overview)