择要
上一篇文章中我们学习了calico的原理,kubernetes中的node节点,利用 calico 的 bird 程序相互学习路由,为了加深对 bird 程序的认识,本文我们将利用bird举行实验,实验中实现了BGP FULL MESH模式让宿主相互学习到对方的容器网段,从而到达容器网段能相互通信的目标。
bird 实验
bird简介
- BIRD 实际上是 BIRD Internet Routing Daemon 的缩写,是一款可运行在 Linux 和其他类 Unix 系统上的路由软件,它实现了多种路由协议,比如 BGP、OSPF、RIP 等。
- BIRD 会在内存中维护许多路由表,路由表根据不同的协议,通过与各种“其他事物”互换路由信息,来更新路由规则。这里说的“其他事物”可能是其他的路由表,也可能是外部的路由器,还可以是内核的某些 API。
- 根本概念
路由表
路由表(Routing tables)是 BIRD 的核心,一个路由表是内存中一组路由规则的聚集,BIRD 根据网络类型的不同会有多种路由表。默认情况下,BIRD 有master默认的路由表。除此外,你也可以创建其他的路由表。
协议与通道
协议(Protocols)将路由表和“其他事物”毗连起来。“其他事物”可以是一个 Socket 对象,毗连了外部的路由器,比方 BGP 路由协议;也可以是修改 FIB 的内核 API,比方kernel协议;也可以是空,比如静态路由static协议。一个协议可以实例化为多个对象,比方创建多个 BGP 协议的实例,以表现多个 BGP 邻居。协议也会提供一些路由属性,根据协议的不同路由属性也不同,比如利用 BGP 协议时,会有bgp_path属性。
本文的目标不是先容bird的底子概念,重点在于bgp的实操,如果需要详细相识干系概念可以查阅文档:https://soha.moe/post/bird-bgp-kickstart.html
目标
- 学习bird程序的安装方法
- 学习bird.conf配置文件的语法
- 学习利用bird实现三台宿主bgp full mesh 模式
- 三台宿主的各个容器网段能相互通信
实验环境
系统版本bird版本宿主IP容器网段ubuntu16.04BIRD 1.5.010.226.11.27192.168.227.0/24ubuntu16.04BIRD 1.5.010.226.11.22192.168.222.0/24ubuntu16.04BIRD 1.5.010.226.11.21192.168.221.0/24 实验拓扑
三台宿主在同一网段内,每个宿主各自下挂一个容器网段,下面实现三台服务器两两相互建立bgp peer,相互学习路由,终极目标是实现各个容器网段能相互通信。
创建模仿的容器网段
我们知道容器是通过linux 的 namespace 机制实现的一个隔离空间, 这里我们同样借助 namespace 机制 实现一个隔离空间,并为隔离出的命名空间配置网络,模仿一个宿主"挂了"一个容器网段。
- # 创建命名空间 netns1
- ip netns add netns1
- # 创建 veth peer
- ip link add veth1 type veth peer name veth2
- # 将 veth1 放入 netns1
- ip link set veth1 netns netns1
- # 查看 veth
- ip link show | grep veth
- # 为 netns1 中的
- ip netns exec netns1 ifconfig veth1 192.168.222.102/24 up
- # 为 netns1 指定默认网关,网关是宿主1的网络协议栈
- ip netns exec netns1 route add -net 0.0.0.0/0 gw 192.168.222.101
- # 为宿主中的 veth2 配置IP地址,这样就实现了宿主与netns1 通过 veth2 与 veth1 的互联
- ifconfig veth2 192.168.222.101/24 up
复制代码
- ip netns add netns1
- ip link add veth1 type veth peer name veth2
- ip link set veth1 netns netns1
- ip link show | grep veth
- ip netns exec netns1 ifconfig veth1 192.168.221.102/24 up
- ip netns exec netns1 route add -net 0.0.0.0/0 gw 192.168.221.101
- ifconfig veth2 192.168.221.101/24 up
复制代码
- ip netns add netns1
- ip link add veth1 type veth peer name veth2
- ip link set veth1 netns netns1
- ip link show | grep veth
- ip netns exec netns1 ifconfig veth1 192.168.227.102/24 up
- ip netns exec netns1 route add -net 0.0.0.0/0 gw 192.168.227.101
- ifconfig veth2 192.168.227.101/24 up
复制代码 bird的安装
- apt-get update
- apt-get install bird
- /etc/init.d/bird start
复制代码
- /etc/init.d/bird status
- birdc show status
复制代码 输出如下表现表现安装正常
- root@10_226_11_21:/etc/bird# birdc show status
- BIRD 1.5.0 ready.
- BIRD 1.5.0
- Router ID is 10.226.11.21
- Current server time is 2024-09-23 15:03:28
- Last reboot on 2024-09-22 20:22:36
- Last reconfiguration on 2024-09-23 13:01:00
- Daemon is up and running
复制代码 bgp full-mesh模式的实现
宿主10.226.11.27上的/etc/bird/bird.conf配置
- # This is a minimal configuration file, which allows the bird daemon to start
- # but will not cause anything else to happen.
- #
- # Please refer to the documentation in the bird-doc package or BIRD User's
- # Guide on http://bird.network.cz/ for more information on configuring BIRD and
- # adding routing protocols.
- #log syslog all;
- log "/var/log/bird.log" all;
- # Change this into your BIRD router ID. It's a world-wide unique identification
- # of your router, usually one of router's IPv4 addresses.
- router id 10.226.11.27;
- filter export_filter_v4 {
- if net ~ [ 192.168.227.0/24 ] then accept; # 如果为默认路由则拒绝
- reject;
- #accept; # 接收所有其他路由
- }
- # The Kernel protocol is not a real routing protocol. Instead of communicating
- # with other routers in the network, it performs synchronization of BIRD's
- # routing tables with the OS kernel.
- protocol kernel {
- debug { states };
- scan time 10;
- learn;
- persist;
- import none; # kernel to bird map
- export all; # Actually insert routes into the kernel routing table
- }
- # The Device protocol is not a real routing protocol. It doesn't generate any
- # routes and it only serves as a module for getting information about network
- # interfaces from the kernel.
- protocol direct {
- interface "veth2";
- }
- protocol device {
- }
- # 与10.226.11.21建立bgp peer的配置
- protocol bgp peer_10_226_11_21 {
- debug { states };
- local as 64512;
- neighbor 10.226.11.21 as 64512;
- source address 10.226.11.27;
- #multihop;
- password "passwd";
- direct;
- export filter export_filter_v4; # 使用过滤表 export_filter_v4 控制哪些路由可以发布给bgp peer
- import all; # 从 direct, device, static, kernel 等所有protocol的路由都导入bird 的 bgp 路由
- }
- # 与10.226.11.22建立bgp peer的配置
- protocol bgp peer_10_226_11_22 {
- debug { states };
- # 配置 BGP 的 graceful restart
- # 如果对端因为网络抖动或暂时崩溃而暂时下线,会导致所有传入路由瞬间消失
- # 为了避免这种情况下数据转发中断,才有 graceful restart
- # 建议打开
- graceful restart on;
- # 指定自己的 ASN 为 65550
- local as 64512;
- # 指定对端的 ASN 为 64512,IP 为 10.226.11.22
- # 如果 ASN 和 local as 相同,那么 BIRD 会自动认为这是一个 iBGP,否则是 eBGP
- # i 表示 internal(内部),e 表示 external(外部)
- neighbor 10.226.11.22 as 64512;
- # source: 定义本地地址作为BGP会话的源地址。Default:邻居所连接接口的本端地址。
- source address 10.226.11.27;
- #multihop;
- # password: 如果和对端约定了密码,在这里配置约定好的密码,否则不用写
- password "passwd";
- # direct: eBGP 默认启用可以不写
- # direct: iBGP 如果是直接连接的可以写这个来避免 multihop 被指定
- # 指定邻居为直连。邻居的IP地址必须在直接可达的IP范围内(即与路由器的接口有关联),
- # 否则BGP会话不会启动,而是等待这样的接口出现。另一种选择是多跳选项。默认值:使能eBGP。
- direct;
- #export all; # 将所有 bird 路由表中的路由都通过bgp发布给peer
- #export: 控制哪些路由可以发布给bgp peer
- export filter {
- # net 匹配的则被filter放行
- if net ~ [ 192.168.227.0/24 ] then accept;
- # 其他的路由全部被filter挡住,从而不会被发布给bgp peer
- reject;
- };
- import all;
- }
复制代码 由于配置文件较长,我们展开详细讲解。
Bird.conf配置详细说明
关于bird.conf配置文件的详细说明可以参考文档 https://soha.moe/post/bird-bgp-kickstart.html
- log "/var/log/bird.log" all;
复制代码 log的配置,表现bird日志单独记录的文件/var/log/bird.log; 如果你希望log记录到系统默认日志,可以利用
#log syslog all;
定义bgp节点的 router-id , bgp 协议中要求每个节点必须定义一个router-id,而且是全局唯一不能重复。
Protocol 表现
对 kernel 路由表的控制
- protocol kernel {
- # 开启debug模式,日志输出更详细
- debug { states };
- # 参与安全重启恢复。如果启用了该选项,并且激活了优雅重启恢复,那么内核协议将推迟路由表的同步,直到恢复结束。注意,内核路由导入到BIRD不受影响。
- graceful restart on;
- # 每 10 秒扫描一次kernel路由表。这个路由表就是用户在宿主上执行ip route show 看到的表
- scan time 10;
- # 允许学习由其他路由守护进程或系统管理员添加到内核路由表中的路由。这只能在支持路由作者识别的系统上实现。
- # 缺省情况下,不引入由kernel(标记为“proto kernel”)创建的路由。使用learn all选项来导入这些路由。
- learn;
- # 告诉BIRD在退出时将所有路由留在路由表中(而不是清理它们)
- persist;
- # import 控制哪些路由被导入到 bird
- import none; # kernel to bird map
- # export 控制哪些路由从 bird 插入到 kernel 路由表
- export all; # Actually insert routes into the kernel routing table
- }
复制代码 对直连路由的控制
- protocol direct {
- # interface 指定哪个接口的路由将被导入到bird路由表
- interface "veth2";
- }
复制代码 控制对bgp peer 10.226.11.22 的路由发布
- protocol bgp peer_10_226_11_22 {
- debug { states };
- # 配置 BGP 的 graceful restart
- # 如果对端因为网络抖动或暂时崩溃而暂时下线,会导致所有传入路由瞬间消失
- # 为了避免这种情况下数据转发中断,才有 graceful restart
- # 建议打开
- graceful restart on;
- # 指定自己的 ASN 为 65550
- local as 64512;
- # 指定对端的 ASN 为 64512,IP 为 10.226.11.22
- # 如果 ASN 和 local as 相同,那么 BIRD 会自动认为这是一个 iBGP,否则是 eBGP
- # i 表示 internal(内部),e 表示 external(外部)
- neighbor 10.226.11.22 as 64512;
- # source: 定义本地地址作为BGP会话的源地址。Default:邻居所连接接口的本端地址。
- source address 10.226.11.27;
- #multihop;
- # password: 如果和对端约定了密码,在这里配置约定好的密码,否则不用写
- password "passwd";
- # direct: eBGP 默认启用可以不写
- # direct: iBGP 如果是直接连接的可以写这个来避免 multihop 被指定
- # 指定邻居为直连。邻居的IP地址必须在直接可达的IP范围内(即与路由器的接口有关联),
- # 否则BGP会话不会启动,而是等待这样的接口出现。另一种选择是多跳选项。默认值:使能eBGP。
- direct;
- #export all; # 将所有 bird 路由表中的路由都通过bgp发布给peer
- #export: 控制哪些路由可以发布给bgp peer
- export filter {
- # net 匹配的则被filter放行
- if net ~ [ 192.168.227.0/24 ] then accept;
- # 其他的路由全部被filter挡住,从而不会被发布给bgp peer
- reject;
- };
- # import 控制对方bgp peer 发个我的路由,哪些会被我接收
- import all;
- }
复制代码 控制对bgp peer 10.226.11.21 的路由发布
- protocol bgp peer_10_226_11_21 {
- debug { states };
- local as 64512;
- neighbor 10.226.11.21 as 64512;
- source address 10.226.11.27;
- #multihop;
- password "passwd";
- direct;
- export filter export_filter_v4; # 使用过滤表 export_filter_v4 控制哪些路由可以发布给bgp peer
- import all; # 从 direct, device, static, kernel 等所有protocol的路由都导入bird 的 bgp 路由
- }
复制代码 示意图
宿主10.226.11.22上的/etc/bird/bird.conf配置
- # This is a minimal configuration file, which allows the bird daemon to start# but will not cause anything else to happen.## Please refer to the documentation in the bird-doc package or BIRD User's# Guide on http://bird.network.cz/ for more information on configuring BIRD and# adding routing protocols.#log syslog all;log "/var/log/bird.log" all;
- # Change this into your BIRD router ID. It's a world-wide unique identification# of your router, usually one of router's IPv4 addresses.router id 10.226.11.22;filter export_filter_v4 { if net ~ [ 192.168.222.0/24 ] then accept; # 如果为默认路由则拒绝 reject; #accept; # 接收全部其他路由};# The Kernel protocol is not a real routing protocol. Instead of communicating# with other routers in the network, it performs synchronization of BIRD's# routing tables with the OS kernel.protocol kernel { debug { states }; scan time 10; learn; persist; import none; # kernel to bird map export all; # Actually insert routes into the kernel routing table}# The Device protocol is not a real routing protocol. It doesn't generate any# routes and it only serves as a module for getting information about network# interfaces from the kernel.protocol direct { interface "veth2";}protocol device {}protocol bgp peer_10_226_11_21 { debug { states }; local as 64512; neighbor 10.226.11.21 as 64512; source address 10.226.11.22; #multihop; # multihop 用于source address 不是直连的情况,比如利用loopback地点互联 direct; password "passwd"; export all; import all;}protocol bgp peer_10_226_11_27 { debug { states }; local as 64512; neighbor 10.226.11.27 as 64512; source address 10.226.11.22; direct; password "passwd"; export all; import all;}
复制代码 宿主10.226.11.21上的/etc/bird/bird.conf配置
- # This is a minimal configuration file, which allows the bird daemon to start# but will not cause anything else to happen.## Please refer to the documentation in the bird-doc package or BIRD User's# Guide on http://bird.network.cz/ for more information on configuring BIRD and# adding routing protocols.log "/var/log/bird.log" all;
- # Change this into your BIRD router ID. It's a world-wide unique identification# of your router, usually one of router's IPv4 addresses.router id 10.226.11.21;filter filter_export_v4 { if net ~ [ 192.168.21.0/24 ] then accept; if net ~ [ 192.168.221.0/24 ] then accept; reject;}# The Kernel protocol is not a real routing protocol. Instead of communicating# with other routers in the network, it performs synchronization of BIRD's# routing tables with the OS kernel.protocol kernel { learn; persist; scan time 10; import none; export all; # Actually insert routes into the kernel routing table}# The Device protocol is not a real routing protocol. It doesn't generate any# routes and it only serves as a module for getting information about network# interfaces from the kernel.protocol device {}protocol direct { interface "veth2";}protocol bgp peer_10_226_11_22 { debug { states }; local as 64512; neighbor 10.226.11.22 as 64512; source address 10.226.11.21; #multihop; direct; password "passwd"; export all; import all;}protocol bgp peer_10_226_11_27 { debug { states }; local as 64512; neighbor 10.226.11.27 as 64512; source address 10.226.11.21; direct; password "passwd"; export all; import all;}
复制代码 查看状态
登录宿主10.226.11.27查看其干系网络的状态
Established表现与bgp peer邻接关系已经建立,而且已经相互完成了路由学习
- root@10_226_11_27:/work/code# birdc show protocol
- BIRD 1.5.0 ready.
- name proto table state since info
- kernel1 Kernel master up 16:06:17
- direct1 Direct master up 16:06:17
- device1 Device master up 16:06:17
- peer_10_226_11_21 BGP master up 16:06:21 Established
- peer_10_226_11_22 BGP master up 16:06:22 Established
复制代码
- root@10_226_11_27:/work/code# birdc show route
- BIRD 1.5.0 ready.
- # 从 protocol direct 导入的路由
- 192.168.227.0/24 dev veth2 [direct1 16:06:17] * (240)
- # 从 bgp peer_10_226_11_21 学习的路由
- 192.168.221.0/24 via 10.226.11.21 on eth0 [peer_10_226_11_21 16:06:21] * (100) [i]
- # 从 bgp peer_10_226_11_22 学习的路由
- 192.168.222.0/24 via 10.226.11.22 on eth0 [peer_10_226_11_22 16:18:14] * (100) [i]
复制代码
- root@10_226_11_27:/work/code# birdc show route all
- BIRD 1.5.0 ready.
- 192.168.227.0/24 dev veth2 [direct1 16:06:17] * (240)
- Type: device unicast univ
- 192.168.221.0/24 via 10.226.11.21 on eth0 [peer_10_226_11_21 16:06:21] * (100) [i]
- Type: BGP unicast univ
- BGP.origin: IGP
- BGP.as_path:
- BGP.next_hop: 10.226.11.21
- BGP.local_pref: 100
- 192.168.222.0/24 via 10.226.11.22 on eth0 [peer_10_226_11_22 16:18:14] * (100) [i]
- Type: BGP unicast univ
- BGP.origin: IGP
- BGP.as_path:
- BGP.next_hop: 10.226.11.22
- BGP.local_pref: 100
复制代码
- root@10_226_11_27:/work/code# ip route show
- default via 10.226.8.1 dev eth0
- # 宿主 eth0接口 的直连路由
- 10.226.8.0/22 dev eth0 proto kernel scope link src 10.226.11.27
- # 从bird 学习来的路由
- 192.168.221.0/24 via 10.226.11.21 dev eth0 proto bird
- 192.168.222.0/24 via 10.226.11.22 dev eth0 proto bird
- # 宿主 veth2接口 直接的路由(模拟的容器网段)
- 192.168.227.0/24 dev veth2 proto kernel scope link src 192.168.227.101
复制代码 网络测试验证
- 从容器192.168.227.101 ping 容器192.168.222.101
- root@10_226_11_27:/work/code# ip netns exec netns1 ping 192.168.222.101 -c 2
- PING 192.168.222.101 (192.168.222.101) 56(84) bytes of data.
- 64 bytes from 192.168.222.101: icmp_seq=1 ttl=63 time=0.925 ms
- 64 bytes from 192.168.222.101: icmp_seq=2 ttl=63 time=0.252 ms
- --- 192.168.222.101 ping statistics ---
- 2 packets transmitted, 2 received, 0% packet loss, time 1001ms
- rtt min/avg/max/mdev = 0.252/0.588/0.925/0.337 ms
复制代码
- 从容器192.168.227.101 ping 容器192.168.221.101
- root@10_226_11_27:/work/code# ip netns exec netns1 ping 192.168.221.101 -c 2
- PING 192.168.221.101 (192.168.221.101) 56(84) bytes of data.
- 64 bytes from 192.168.221.101: icmp_seq=1 ttl=63 time=0.221 ms
- 64 bytes from 192.168.221.101: icmp_seq=2 ttl=63 time=0.251 ms
- --- 192.168.221.101 ping statistics ---
- 2 packets transmitted, 2 received, 0% packet loss, time 1011ms
- rtt min/avg/max/mdev = 0.221/0.236/0.251/0.015 ms
复制代码
- 宿主10.226.11.27 ping 192.168.221.101
- root@10_226_11_27:/work/code# ping 192.168.221.101 -c 2
- PING 192.168.221.101 (192.168.221.101) 56(84) bytes of data.
- 64 bytes from 192.168.221.101: icmp_seq=1 ttl=64 time=0.886 ms
- 64 bytes from 192.168.221.101: icmp_seq=2 ttl=64 time=0.268 ms
- --- 192.168.221.101 ping statistics ---
- 2 packets transmitted, 2 received, 0% packet loss, time 1015ms
- rtt min/avg/max/mdev = 0.268/0.577/0.886/0.309 ms
- root@10_226_11_27:/work/code# traceroute -d 192.168.221.101
- traceroute to 192.168.221.101 (192.168.221.101), 30 hops max, 60 byte packets
- 1 192.168.221.101 (192.168.221.101) 0.261 ms 0.231 ms 0.225 ms
复制代码
- root@10_226_11_27:/work/code# ip netns exec netns1 ip route
- default via 192.168.227.101 dev veth1
- 192.168.227.0/24 dev veth1 proto kernel scope link src 192.168.227.102
- root@10_226_11_27:/work/code# ip netns exec netns1 ip route get 192.168.221.101
- 192.168.221.101 via 192.168.227.101 dev veth1 src 192.168.227.102
- cache
复制代码 实验结论
- 实现了三台宿主的bird的bgp full mesh 模式
- 三台宿主通过bgp相互完成了路由学习
- 通过实验我们对calico中的bird程序有了更深入的认知
参考文档
bird官网
BGP_example_1
Intro-to-BGP-with-BIRD
bird-bgp-kickstart
https://wiki.skywolf.cloud/quickstart/player.html
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |