Routing Table Mode

Ensure that all other modes are turned off. Have a look at Flags and Environment page.

Only vip_routingtable: "true" should be configured in your DaemonSet or Static Manifest.

Additionally to enable cleanup of unwanted routes in kube-vips table at startup, you can enable vip_cleanroutingtable: "true".

1C9l2i.e1n6t8.0.110.N0No.od0de.e112WWoorrkkllooaadd
Enabling svc_election: "true" kube-vip tries to do a leader election per service. This adds a higher possibility that not only one node gets all the traffic.
The leader election does not ensure, that traffic and services are distributed evenly to all nodes.
1C9l2i.e1n6t8.0.11100..N0N0o.o.d0d0e.e.1212WWoorrkkllooaadd

To enable multi-homing of an advertised Route you need to disable both leader elections:

  • vip_leaderelection: "false"
  • svc_election: "false".
1C9l2i.e1n6t8.0.11100..N0N0o.o.d0d0e.e.1112WWoorrkkllooaadd

To read the routes which were written into the routing-table of the kubernetes node by kube-vip. You need to install a routing-daemon on the node.

1apt install bird2

Configure the following files according to your setup. If you need more guidance on how bird should be configured have a look at the excellent guide.

This file configures the neighbors you want to peer with.

 1## /etc/bird.conf
 2# Change this into your BIRD router ID. It's a world-wide unique identification
 3# of your router, usually one of router's IPv4 addresses.
 4router id 127.0.0.1;
 5
 6# The Device protocol is not a real routing protocol. It doesn't generate any
 7# routes and it only serves as a module for getting information about network
 8# interfaces from the kernel.
 9protocol device {
10}
11
12include "/etc/bird.d/*.conf";
13
14protocol bgp {{neigh}}_v4 {
15    local as 65535;
16    neighbor {{neighbor-ipv4}} as 65535;
17    ipv4 {
18        export filter export_to_rr_v4;
19        import filter import_from_rr;
20    };
21}
22protocol bgp {{neigh}}_v6 {
23    local as 65535;
24    neighbor {{neighbor-ipv6}} as 65535;
25    ipv6 {
26        export filter export_to_rr_v6;
27        import filter import_from_rr;
28    };
29}
30### additional neighbors as above
31### ....

To only advertise the Routes to the different neighbors, you can add it to this separate file. The import and export filter are then used by the other file above.

 1## /etc/bird.d/kube-vip.conf
 2# The Kernel protocol is not a real routing protocol. Instead of communicating
 3# with other routers in the network, it performs synchronization of BIRD's
 4# routing tables with the OS kernel.
 5
 6filter anycast_nets_v4 {
 7    if (net ~ [10.0.0.0/27+]) then {
 8      bgp_community.add((65535, 16000));
 9      bgp_community.add((65535, 42));
10      accept;
11    }
12    reject;
13}
14
15
16filter anycast_nets_v6 {
17    if (net ~ [fd00::/64+]) then {
18      bgp_community.add((65535, 16000));
19      bgp_community.add((65535, 42));
20      accept;
21    }
22    reject;
23}
24
25
26ipv4 table lbv4;
27ipv6 table lbv6;
28
29protocol kernel lb_v4 {
30    learn;
31    kernel table 198;
32    scan time 1;
33    metric 64; # Use explicit kernel route metric to avoid collisions
34               # with non-BIRD routes in the kernel routing table
35    ipv4 {
36        table lbv4;
37        import filter anycast_nets_v4;
38        export where dest != RTD_UNREACHABLE; # Actually insert routes into the kernel routing table
39    };
40}
41
42protocol kernel lb_v6 {
43    learn;
44    kernel table 198;
45    scan time 1;
46    metric 64; # Use explicit kernel route metric to avoid collisions
47               # with non-BIRD routes in the kernel routing table
48    ipv6 {
49        table lbv6;
50        import filter anycast_nets_v6;
51        export where dest != RTD_UNREACHABLE; # Actually insert routes into the kernel routing table
52    };
53}
54
55protocol pipe lb_pipe_v4 {
56    table master4;
57    peer table lbv4;
58    import all;
59    export none;
60}
61protocol pipe lb_pipe_v6 {
62    table master6;
63    peer table lbv6;
64    import all;
65    export none;
66}
67
68filter import_from_rr {
69    if ( (65535, 42) ~ bgp_community ) then {
70        accept;
71    }
72    reject;
73}
74
75filter export_to_rr_v4 {
76    if ( proto = "lb_v4" ) then {
77        accept;
78    }
79    reject;
80}
81
82filter export_to_rr_v6 {
83    if ( proto = "lb_v6" ) then {
84        accept;
85    }
86    reject;
87}
bird> show protocols
Name         Proto      Table      State  Since         Info
device1      Device     ---        up     2025-06-20
lb_v4        Kernel     lbv4       up     2025-06-20
lb_v6        Kernel     lbv6       up     2025-06-20
lb_pipe_v4   Pipe       ---        up     2025-06-20    master4 <=> lbv4
lb_pipe_v6   Pipe       ---        up     2025-06-20    master6 <=> lbv6
{{neigh}}_v4 BGP        ---        up     2025-06-20    Established   
{{neigh}}_v6 BGP        ---        up     2025-06-20    Established   

Have a look at IPv4

bird> show route protocol lb_v4 stats
Table lbv4:
10.0.0.18/32     unicast [lb_v4 2025-07-13] * (10)
	dev lo
10.0.0.17/32     unicast [lb_v4 2025-07-05] * (10)
	dev lo
2 of 2 routes for 2 networks in table lbv4

Have a look at IPv6

bird> show route protocol lb_v6 stats
Table lbv6:
fd00::5/128 unicast [lb_v6 2025-07-13] * (10)
	dev lo
fd00::7/128 unicast [lb_v6 2025-06-20] * (10)
	dev lo
fd00::4/128 unicast [lb_v6 2025-07-05] * (10)
	dev lo
3 of 3 routes for 3 networks in table lbv6