BGP control plane in Cilium doesn’t actually do BGP routing; it’s a sophisticated mechanism for distributing network policies to external BGP speakers.

Let’s see it in action. Imagine you have an external router (like a Cisco, Juniper, or even another Linux box running FRR) that you want to advertise routes to, but only specific routes that Cilium manages. Here’s a simplified setup.

First, your Cilium agent needs to be configured to expose BGP information. This is done via the bgpPeering section in your Cilium configuration (often in a cilium-config ConfigMap or directly in the Cilium Operator deployment).

apiVersion: cilium.io/v2alpha1
kind: CiliumConfig
metadata:
  name: cilium-config
spec:
  bgpPeering:
    # Enable BGP peering
    enabled: true
    # Listen address for BGP announcements (e.g., IPv4, IPv6)
    listenAddresses:
      - 0.0.0.0
      - ::
    # Optional: specify a specific router ID if needed
    # routerID: 192.168.1.1

Now, on your external BGP router, you’d configure a BGP neighbor pointing to your Cilium agent’s IP address. If Cilium is running on Kubernetes nodes, you’d typically point to the node’s IP. Let’s assume your Cilium node has IP 10.0.0.5 and your external router has IP 10.0.0.6.

On the external router (using FRR syntax for example):

router bgp 65001
  neighbor 10.0.0.5 remote-as 65001
  neighbor 10.0.0.5 update-source 10.0.0.6
  !
  address-family ipv4 unicast
    network 192.168.100.0/24 # A route this router *already* knows about
    neighbor 10.0.0.5 activate
  exit-address-family

The magic happens when Cilium receives network policy updates. For example, if you create a CiliumNetworkPolicy that selects pods with a specific label and defines egress rules, Cilium can then advertise the CIDRs of those pods to its BGP neighbors.

Consider this policy:

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: allow-external-access
spec:
  endpointSelector:
    matchLabels:
      app: frontend
  egress:
  - toCIDR:
    - 10.0.1.0/24 # This is the CIDR Cilium will advertise

When this policy is applied, Cilium’s BGP component will advertise the 10.0.1.0/24 prefix to the configured BGP neighbor (10.0.0.5). The external router will then install this route, directing traffic destined for 10.0.1.0/24 towards the Cilium node.

The problem this solves is enabling external network devices to dynamically learn about and route traffic to specific Kubernetes workloads managed by Cilium, without requiring manual route injection or complex overlay network configurations. Cilium acts as a BGP speaker, announcing the IP addresses of pods that are part of certain network policies.

Internally, Cilium leverages a BGP daemon (often a Go-based library like gobgp or its own implementation) to manage peering sessions and exchange BGP Update messages. When a Cilium agent starts, it initializes its BGP component, establishes peering with configured neighbors, and then subscribes to events from the Cilium datapath and policy enforcement components. When a network policy is applied or modified, Cilium translates the relevant pod CIDRs or IP prefixes into BGP NLRI (Network Layer Reachability Information) and advertises them to its neighbors. Conversely, it can also receive routes from external peers and use them to inform its own policy enforcement, although the primary use case here is outbound advertisement.

The key levers you control are:

  • bgpPeering.enabled: Toggles the BGP control plane on/off.
  • bgpPeering.listenAddresses: Specifies which interfaces Cilium listens on for BGP peering requests.
  • bgpPeering.neighbors: (Not shown in the basic config, but crucial for production) This section defines remote BGP peers, including their IP addresses, AS numbers, and potentially authentication details.
  • CiliumNetworkPolicy and CiliumIPAM configurations: The existence and definition of policies, and how IP addresses are allocated to pods, directly determine what CIDRs Cilium will advertise.

One aspect often overlooked is the interaction with Cilium’s IP Address Management (IPAM). Cilium typically allocates CIDRs to nodes for pod IPs. When these CIDRs are part of a CiliumNetworkPolicy that is configured to be advertised via BGP, Cilium will announce these node-local pod CIDRs. This means external routers learn about the node’s IP block that contains pods, and traffic is then routed to the node, where Cilium’s CNI handles the final destination based on pod IPs.

The next logical step is to configure route redistribution and filtering on your external BGP router to selectively accept or reject routes advertised by Cilium, based on AS path attributes or prefix lists.

Want structured learning?

Take the full Cilium course →