Skip to main content
This article explains how Cilium implements Ingress in Kubernetes, comparing its approach with traditional controllers and showing how to enable and configure Cilium’s Ingress features via Helm. Cilium combines eBPF-based kernel integration for high-performance L3/L4 routing with Envoy for selective L7 and policy enforcement. It also supports the Kubernetes Gateway API (overview only; Gateway API specifics are out of scope here).
A slide titled "Cilium Ingress" showing a multicolored hexagon cluster on the left funneling to two Kubernetes icons on the right labeled "gateway api" and "Ingress." It illustrates Cilium routing or integration with the Gateway API and Ingress.
Key advantages of Cilium Ingress
  • 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)
Apply and reload Cilium components

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.
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.
You can also control the LB mode per-Ingress with an annotation:
  • ingress.cilium.io/loadbalancer-mode: shared
  • ingress.cilium.io/loadbalancer-mode: dedicated

Example: Minimal Ingress manifest

If you set ingressController.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 ingress will show unique addresses per Ingress:
Shared mode
  • 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: true and confirm Cilium has claimed it.
  • Change mode per-Ingress via annotation: ingress.cilium.io/loadbalancer-mode: shared or dedicated.
  • 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

This concludes the Cilium Ingress overview. Gateway API integration and advanced Envoy configuration are covered in separate Cilium documentation and guides.

Watch Video