Skip to main content
In this lesson you’ll enable and configure BGP on a Cilium-based Kubernetes cluster so the cluster can advertise Pod CIDRs and Service IPs to an external router. This allows your physical network to route directly to nodes and enables ECMP when multiple nodes advertise the same service IP. Topology overview:
A network diagram showing a control-plane and two worker nodes, each with an ens33 interface and pod CIDRs (10.0.1.0/24 and 10.0.2.0/24) connected to a central router (5.5.5.5). The worker nodes establish BGP peering with the router to advertise their networks.
  • 3-node cluster: control-plane, worker1, worker2.
  • Each node sits on a different L2 network; all are reachable via a central router (the “outside world”).
  • Router loopback: 5.5.5.5 — worker1 and worker2 will peer to that IP and advertise their Pod CIDRs and service IPs.
Overview of steps
  1. Enable Cilium’s BGP control plane via Helm values.
  2. Restart Cilium operator and agents to pick up the change.
  3. Label nodes to select where BGP instances should run.
  4. Create three Cilium CRDs in order:
    • CiliumBGPAdvertisement — defines what to advertise (PodCIDR, Service types, attributes).
    • CiliumBGPPeerConfig — peer-level settings (timers, multihop, address families).
    • CiliumBGPClusterConfig — cluster-level config (which nodes, BGP instances & peers).
  5. Apply resources and validate peers, sessions and routes.
  6. Inspect Cilium logs on the agent if troubleshooting is required.
Prerequisites
  • A running Kubernetes cluster with Cilium installed.
  • Helm access to upgrade Cilium (if needed).
  • Network reachability between nodes and the external router (ensure any firewall/NAT allows BGP TCP/179 or multihop TTL as configured).
Enable the BGP control plane in Cilium Edit your Cilium Helm values (values.yaml) and enable the BGP control plane:
Upgrade the Cilium release and restart relevant components so the changes take effect:
Label the nodes where BGP should run In this demo BGP runs only on worker1 and worker2. Add a label that the cluster config will match on (e.g. bgp=true):
Cilium BGP CRDs — what to create and why You will create three Cilium CRD resources. Create files for each and apply them in the order shown below. Summary table of the CRDs:
  1. bgp-advertisement.yaml — which prefixes and attributes to advertise
Notes:
  • The first entry advertises each node’s PodCIDR and attaches route attributes (communities, local preference).
  • The second entry advertises service addresses for services matched by the selector. The example selector intentionally matches nothing; to advertise all services omit the selector or use an empty selector. In production prefer a controlled selector to avoid leaking internal service IPs.
  1. bgp-peer-config.yaml — peer-level timers, multihop and address families
Notes:
  • keepAlive (3s) and holdTime (9s) must match the external router configuration.
  • ebgpMultihop permits a TTL > 1 for eBGP sessions when peers are not directly connected.
  • This demo uses only IPv4 unicast.
  1. bgp-config.yaml — cluster-level config enabling BGP instances on selected nodes
Notes:
  • nodeSelector chooses nodes labeled with bgp=true.
  • localASN is the ASN used by the node’s BGP instance (here 64000). For eBGP your peer ASN should differ (here 65000).
  • peerConfigRef binds this peer to the peer settings defined earlier.
Apply the resources Apply the three manifests in the following order:
Validate BGP peering and routes Use the Cilium CLI and other tools to validate peers, sessions, and routes. List BGP peers (shows session state and route counts):
Example output:
  • Session State “established” means the BGP neighborship is up.
  • Received & Advertised columns show route counts from/to the peer.
Show routes advertised by the cluster (IPv4 unicast):
Example output (truncated):
Router-side verification (example using Bird) On your external router, confirm it has learned the Pod and service routes. Example Bird command and sample result:
Example relevant lines:
  • When the router learns the same service IP from multiple nodes, it can use ECMP (equal-cost multipath) for load distribution.
Troubleshooting — inspect Cilium agent logs If peers aren’t establishing, inspect the cilium-agent logs on the node running the BGP control plane and filter for bgp-control-plane entries:
Sample log snippets indicating BGP initialization and peer events:
Best practices and tips
  • Choose ASNs, BGP timers and ebgp-multihop values consistent with your physical network and external router configuration.
  • Use selectors in CiliumBGPAdvertisement to control which services are announced; avoid advertising all service IPs in production unless intentionally required.
  • Monitor route advertisements and BGP session health with the Cilium CLI and your router tooling (e.g., Bird, FRR).
Wrap-up
  • You enabled Cilium’s BGP control plane, configured node-level BGP instances, established a peer to an external router, and advertised Pod CIDRs and service IPs.
  • With these announcements your physical network can natively route traffic to nodes and support ECMP for service IPs advertised by multiple nodes.
Links and references

Watch Video