Cloud Native 13 min read

Enable Cilium BGP Networking with Bird and FRR in a Vagrant Lab

This guide walks through setting up a simulated Kubernetes cluster with Cilium, configuring BGP using FRR on a router node and Bird on worker nodes, and enabling Cilium's built‑in BGP speaker to achieve cross‑node pod communication and LoadBalancer IP advertisement.

Liangxu Linux
Liangxu Linux
Liangxu Linux
Enable Cilium BGP Networking with Bird and FRR in a Vagrant Lab

Background

The official Cilium documentation provides several ways to integrate BGP. This article validates the following approaches: using BIRD, using kube‑router, native BGP, and the Cilium BGP control plane.

A simple network topology is created with Vagrant VMs: one router node with multiple NICs and two worker nodes (node1, node2) each with a single NIC. The workers’ default routes point to the router (node1 → 10.0.1.2, node2 → 10.0.2.2). All nodes run Kubernetes and Cilium.

Router Node System Settings

net.ipv4.ip_forward = 1
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
net.ipv6.conf.all.forwarding = 1

Deploying Cilium with BGP (Bird) Backend

Cilium supports two pod CIDR routing modes: encapsulation and native‑routing. Because the worker nodes are on different L2 subnets, autoDirectNodeRoutes cannot be used, so BGP is required.

1. Install and Configure FRR on the Router

Install FRR from the official repository and enable the BGP daemon:

FRRVER="frr-stable"
curl -O https://rpm.frrouting.org/repo/${FRRVER}-repo-1-0.el7.noarch.rpm
sudo yum install ./${FRRVER}*
sudo yum install frr frr-pythontools

Edit /etc/frr/daemons to set bgpd=yes, then create /etc/frr/frr.conf:

frr version 8.4.1
frr defaults traditional
hostname router
log syslog informational
!
router bgp 65100   # router ASN
  bgp router-id 192.168.121.16
  no bgp ebgp-requires-policy
  neighbor 10.0.1.10 remote-as 65010   # node1
  neighbor 10.0.2.10 remote-as 65020   # node2
!

Start the service:

systemctl restart frr

2. Deploy Cilium on the Workers

Apply the following Cilium configuration (as a cilium-config.yaml ConfigMap):

k8sServiceHost: "10.0.1.10"
k8sServicePort: 6443
kubeProxyReplacement: strict
device: eth1
ipam:
  operator:
    clusterPoolIPv4PodCIDR: "172.31.254.0/23"
    clusterPoolIPv4MaskSize: 26
loadBalancer:
  mode: dsr
 tunnel: disabled
autoDirectNodeRoutes: false
bpf:
  masquerade: true
ipv4NativeRoutingCIDR: "172.31.254.0/23"
socketLB:
  enabled: true
nodePort:
  enabled: true
externalIPs:
  enabled: true
hostPort:
  enabled: true

After the Cilium pods are ready, pods obtain IPs but cross‑node pod traffic does not work.

3. Install and Configure Bird2 on the Workers

Install Bird2: yum -y install bird2 Check the allocated PodCIDR ranges:

kubectl -n kube-system exec -it ds/cilium -- cilium node list

Create /etc/bird.conf on each worker:

router id 10.0.1.10;
protocol device {
    scan time 10;
}
protocol direct {
    disabled;
}
protocol kernel {
    ipv4 {
        import none;
        export none;
    };
}
protocol static {
    ipv4;
    route 172.31.254.0/26 via "cilium_host";
}
protocol bgp uplink0 {
    description "BGP uplink 0";
    local 10.0.1.10 as 65010;   # ASN of this node
    neighbor 10.0.1.2 as 65100; # router ASN
    ipv4 {
        import filter { reject; };
        export filter { accept; };
    };
}

Start Bird and verify BGP sessions from the router:

# On router
vtysh -c "show bgp summary"
vtysh -c "show bgp ipv4 all"

After these steps, node1 and node2 can communicate, and any server using the router as its default gateway can reach pod IPs.

Built‑in BGP Speaker (Cilium 1.10+)

From Cilium 1.10 onward, a native BGP speaker is included, eliminating the need for external Bird2. To enable it, create a ConfigMap named bgp-config in kube-system:

apiVersion: v1
kind: ConfigMap
metadata:
  name: bgp-config
  namespace: kube-system
data:
  config.yaml: |
    peers:
      - peer-address: 192.168.121.16
        peer-asn: 65100
        my-asn: 65000
    address-pools:
      - name: default
        protocol: bgp
        addresses:
          - 192.0.2.0/24

Then enable BGP in the Cilium configuration:

bgp:
  enabled: true
  announce:
    loadbalancerIP: true
    podCIDR: true
loadBalancer:
  mode: snat   # dsr mode may have issues

LoadBalancer Service Example

apiVersion: v1
kind: Service
metadata:
  name: whoami-lb
spec:
  type: LoadBalancer
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
      name: http
  selector:
    app: whoami

Cilium allocates an external IP from the 192.0.2.0/24 pool (e.g., 192.0.2.x) and announces it via BGP.

ECMP and Advanced BGP Configuration

For production scenarios, add ECMP‑related settings on the router and keep static neighbor definitions:

router bgp 65100
  bgp bestpath as-path multipath-relax
  bgp bestpath bandwidth skip-missing
  bgp router-id 192.168.121.16
  no bgp ebgp-requires-policy
  neighbor 10.0.1.10 remote-as 65000
  neighbor 10.0.2.10 remote-as 65000
!

Verify ECMP path selection:

vtysh -c "show bgp ipv4 unicast 192.0.2.0/32"

BGP Control Plane Controller

Cilium’s BGP control‑plane controller (available in newer releases) provides fine‑grained management of the built‑in BGP speaker, extending the ConfigMap shown earlier.

References

Using BIRD to run BGP – https://docs.cilium.io/en/stable/gettingstarted/bird/

Using kube‑router to run BGP – https://docs.cilium.io/en/stable/gettingstarted/kube-router/

BGP – https://docs.cilium.io/en/stable/gettingstarted/bgp/

Cilium BGP Control Plane – https://docs.cilium.io/en/stable/gettingstarted/bgp-control-plane/

LoadBalancer IP Address Management – https://docs.cilium.io/en/latest/network/lb-ipam/

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Cloud NativeKubernetesBGPCiliumFRRBird
Liangxu Linux
Written by

Liangxu Linux

Liangxu, a self‑taught IT professional now working as a Linux development engineer at a Fortune 500 multinational, shares extensive Linux knowledge—fundamentals, applications, tools, plus Git, databases, Raspberry Pi, etc. (Reply “Linux” to receive essential resources.)

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.