CCA — Cilium Certified Associate
BGP Control Plane and Egress Gateway — The Road Beyond the Cluster
In one line
BGP Control Plane advertises a node's Pod CIDR and Service VIPs to neighboring routers with BGP to create a way in from outside into the cluster, and Egress Gateway makes particular Pods pass through a designated node and IP when going outside. The one that does not program the datapath is the BGP Control Plane. Egress Gateway forwards selected outbound packets to the gateway node and SNATs the source address, so it does change actual datapath behavior. You must distinguish advertising routes from processing packets.
Why this was needed
If an outside router does not know the route to the Pod CIDR, knowing only the Pod IP is not enough to reach it. That does not mean, however, that a Pod IP is inherently for cluster-internal use only, or that external access necessarily requires NAT. With a proper return path and datapath and policy, you can route directly. In an environment that uses BGP, Cilium advertises routes so that external routers can learn the next hop. For a Service VIP as well, being assigned an address and being reachable at that address from outside are separate matters.
There is also a problem in the opposite direction. Pod IPs keep changing and node IPs change too, but old firewalls work on the basis of "allow only what comes from this IP." The documentation describes the use of Egress Gateway with exactly this case: making Pods in a particular namespace go out to legacy infrastructure with a predictable IP. The BGP & External Networking domain of the CCA (6%) asks about the roles and constraints of these two features.
How it works
What the BGP Control Plane does and does not do
The first sentence of the documentation sets the scope. The BGP Control Plane advertises routes to BGP-connected routers so that the Pod network and Services are reachable from outside the cluster. It also states explicitly, "it does not program the datapath, so do not use it for reachability inside the cluster." You turn it on with bgpControlPlane.enabled=true, and the agent advertises only the address families that are configured. An agent configured to use only IPv4 cannot advertise IPv6 routes.
Four resources
| Resource | Role |
|---|---|
| CiliumBGPClusterConfig | The BGP instances (localASN) and peers (peerASN, peerAddress, peerConfigRef) to apply to the nodes chosen by nodeSelector |
| CiliumBGPPeerConfig | Session settings shared by multiple peers — timers, MD5 authentication, eBGP multihop, graceful restart, transport, address families, and advertisement selectors |
| CiliumBGPAdvertisement | The kinds of prefixes to put in the routing table and their attributes (community, localPreference) |
| CiliumBGPNodeConfigOverride | Values that differ from node to node |
apiVersion: cilium.io/v2
kind: CiliumBGPClusterConfig
metadata: {name: cilium-bgp}
spec:
nodeSelector: {matchLabels: {rack: rack0}}
bgpInstances:
- name: instance-65000
localASN: 65000
peers:
- name: peer-65000-tor1
peerASN: 65000
peerAddress: fd00:10:0:0::1
peerConfigRef: {name: cilium-peer}
---
apiVersion: cilium.io/v2
kind: CiliumBGPAdvertisement
metadata: {name: bgp-advertisements, labels: {advertise: bgp}}
spec:
advertisements:
- advertisementType: PodCIDR
- advertisementType: Service
service: {addresses: [LoadBalancerIP]}
selector: {matchExpressions: [{key: bgp, operator: In, values: [blue]}]}
The families[].advertisements of a PeerConfig is a label selector. The advertise: bgp label in the example above must match that selector for the advertisement to actually go out. If you created all the resources but nothing is advertised, look at this label first.
What often goes wrong with the default behavior
Here are three points carried over from the documentation as they are. First, a BGP instance comes up by default with no listening port. The design lets another BGP router such as Bird run on the same node, so Cilium only initiates connections and does not accept them. If it has to accept them, you give a localPort, and port 179 requires CAP_NET_BIND_SERVICE. Second, the default timers are connectRetry 120 seconds, hold 90 seconds, and keepalive 30 seconds, and in a data center it recommends lowering them to something like hold 9 seconds and keepalive 3 seconds. Third, if you turn on graceful restart, the peer does not withdraw the routes right away even when the agent restarts, so the datapath keeps forwarding. The default RestartTime is 120 seconds.
What gets advertised
PodCIDR advertisement advertises the Pod CIDR allocated to that node, not the whole range. This works only with Kubernetes or ClusterPool IPAM, and with MultiPool IPAM you advertise by choosing pools with a selector of the CiliumPodIPPool type. With other IPAMs, the PodCIDR type has no effect. Service advertisement puts LoadBalancerIP, ClusterIP, and ExternalIP in service.addresses as you choose, and the VIP goes out as an exact /32 or /128 route. When several nodes advertise the same VIP, the upstream router splits the load with ECMP, and there is a warning to check with the network team first because this can exceed the router's upper limit on the number of ECMP paths. You view session state with cilium bgp peers.
Egress Gateway — pinning the way out
Egress Gateway sends IPv4 and IPv6 connections from Pods to specific destination CIDRs outside the cluster to a designated gateway node, and masquerades them with that node's predictable IP. To turn it on, together with egressGateway.enabled=true, both BPF masquerading and kube-proxy replacement must be on. The policy resource is the cluster-scoped CiliumEgressGatewayPolicy, in which you state the source Pods with selectors[].podSelector (the namespace via the io.kubernetes.pod.namespace label), the destinations with destinationCIDRs, and the exceptions with excludedCIDRs. Internal cluster IPs (Pods, nodes, the API server) are excluded from SNAT even if they fall within the destination range.
The constraints are clear as well. There is a delay before the policy is applied to a new Pod, during which it can go out with the Pod IP or the node IP, it cannot be used together with Cluster Mesh, and it is not compatible with the mode that keeps identity storage in a kvstore or with CiliumEndpointSlice.
What it looks like in the field
A BGP session being Established does not prove that Services are reachable. First check the peer's address, AS, and connection state, and then see whether the destination prefix is in the receive routing table (RIB). If the route exists, check the selected next hop and the kernel forwarding path (FIB) and follow through with a real request. If there is no route, start with the advertisement selector and the address allocation; if the route exists but the request fails, investigate the Service backends, the datapath, the policy, and the return path. Do not conclude from a single timeout that it is an authentication failure or a policy block.
With Egress Gateway, right after you turn it on there are reports that "some requests still go out with the node IP," and often the cause is the delay before the policy attaches to a newly started Pod. If the firewall side allowed only the gateway IP, requests in that short window are rejected.
Five states separated by measurement
LabHub's personal-VM probe of 2026-09-12 connected Cilium 1.20.1 and FRR 8.4.4 and compared the following states. FRR was placed in a network namespace acting as an external router, and no default route was added. Here, "no route" means there is no route to the experiment's destination, not that the router has no routes at all for its connected networks.
| State | Peer | Destination RIB | Destination FIB | Actual Pod HTTP |
|---|---|---|---|---|
| Before peer configuration | Idle | None | None | Connection failed |
| Peer connected only | Established | None | None | Connection failed |
| PodCIDR advertised, FRR's bgp no-rib kept | Established | Present | None | Connection failed |
| FRR's no bgp no-rib applied | Established | Present | Present | 200 |
| After the PodCIDR advertisement is withdrawn | Established | None | None | Connection failed |
bgp no-rib is an FRR setting that deliberately separates BGP learning from kernel route installation in this probe. It does not mean that turning on Cilium's advertisement automatically resolves FRR's forwarding setup. The allocated node PodCIDR was 10.42.0.0/24, not the whole configured pool 10.42.0.0/16. On failure, the curl exit code was 7 and the output was 000. 000 is not an HTTP status code given by a server, and you must not explain this result by rewriting it as a NetworkPolicy timeout block. You have to leave the observation point and even the command's exit code to be able to tell it apart from other failures.
In a later separate comparison, only the /32 of the selected Service VIP was advertised, and it was checked whether other VIPs that were not advertised and direct Pod access failed. The router namespace created on the same VM, unlike an independent external machine, could be affected by socket-LB. When a Pod route was temporarily added, even the VIP that was not advertised succeeded, which blurred the comparison. Finally, after confirming that socketLB.hostNamespaceOnly=true had been applied to the running agent, it was confirmed that with no Pod route and no default route, only the selected VIP returned 200. This setting should be read not as a cure-all for every production outage but as a case of checking that the experimental environment does not change what is being measured.
This table is the result of a development probe and is not evidence that a learner completed a new BGP lab on the platform. The follow-up lab is organized so that the comparison states are separated and full re-grading remains possible even after the last step. You can check the official behavior at FRR 8.4 BGP and Cilium socket-LB bypass.
What to check in the next quiz
It asks about the role of the Gateway API resources and the traffic split field, where Cilium differs from other controllers (eBPF interception, the ingress identity), the per-node Envoy structure, WireGuard's key distribution and port, the roles of the four BGP resources, the PodCIDR advertisement scope and VIP route length, the default for the listening port, and the prerequisites for Egress Gateway. References: Cilium BGP Control Plane, BGP Control Plane Resources, Egress Gateway.