本文主要讲解使用quagga、Docker和quagga搭建简单的BGP网络。
使用OVS+Docker+quagga搭建BUG网络
首先对本次使用的技术进行一个简单的介绍,接着说明一下本次试验的环境,最后进行BGP简单网络的搭建。
1. 简单介绍
1.1 BGP网络介绍
BGP网络介绍
BGP(边界网关协议)主要用于互联网AS(自治系统)之间的互联,BGP的最主要功能在于控制路由的传播和选择最好的路由。
中国联通 、中国电信、中国移动、教育网和一些大的民营IDC运营商都具有AS号,全国各大网络运营商多数都是通过BGP协议与自身的AS号来实现多线互联的。使用BGP协议互联后,网络运营商的所有骨干路由设备将会判断到IDC机房IP段的最佳路由,以保证不同网络运营商用户的高速访问。
1.2 Docker介绍
Docker介绍
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。
1.3 quagga介绍
quagga介绍
quagga软件原名是Zebra是由一个日本开发团队编写的一个以GNU版权方式发布的软件。它将linux机器打造成一台功能完备的路由器。
Quagga支持的路由协议
Quagga能够同时支持RIPv1、RIPv2、RIPng、OSPFv2、OSPFv3、BGP-4和 BGP-4+等诸多TCP/IP协议。其中:
RIPv1、RIPv2、OSPFv2适用于Ipv4的自治域系统内部网络路由协议。
BGP-4是用于Ipv4的自治域系统之间的外部网络路由协议。
RIPng、OSPFv3、BGP-4+主要扩展对Ipv6的支持。
Quagga的特性
模块化设计:Quagga基于模块化方案的设计,即对每一个路由协议使用单独的守护进程。
运行速度快:因为使用了模块化的设计,使得Quagga的运行速度比一般的路由选择程序要快。
可靠性高:在所有软件模块都失败的情况下,路由器可以继续保持连接并且daemons也会继续运行。故障诊断不必离线的状态下被诊断和更正
支持Ipv6:Quagga不仅支持Ipv4,还支持Ipv6。
Quagga的运行机制
由于Quagga采用模块化的设计,因此Quagga运行时要运行多个守护进程,包括ripd ripngd ospfd ospf6d bgpd 和Zebra。
其中,Zebra守护进程用来更新内核的路由表,而其他的守护进程负责进行相应路由选择协议的路由更新。
Quagga的好处
1.4 OpenVSwitch介绍
OpenVSwitch介绍
OpenvSwitch,简称OVS是一个虚拟交换软件,主要用于虚拟机VM环境,作为一个虚拟交换机,支持Xen/XenServer, KVM, and VirtualBox多种虚拟化技术。虽然是虚拟交换机,但是其工作原理与物理交换机类似。在虚拟交换机的实现中,其两端分别连接着物理网卡和多块虚拟网卡,同时虚拟交换机内部会维护一张映射表,根据MAC地址寻找对应的虚拟机链路进而完成数据转发。
OpenvSwitch是实现虚拟化网络的重要基础组件,在OpenStack中利用OpenvSwitch作为底层部件来完成虚拟网络提供和租户网络管理。OpenvSwitch可以实现访问控制功能,通过转发规则,可以实现简单的安全行为,包括通过、禁止等。
2. 本次运行的环境
2.1 系统环境
- Centos 7.6.1810
2.2 软件环境
- Docker 17.06【docker镜像为centos7】
- OpenVSwitch 2.5.8版本
3. BGP网络搭建
3.1为首先准备BGP的一些基础环境,
3.1 BGP环境准备
准备Docker和OVS
3.1.1 安装Docker和OVS
[root@localhost ~]#yum install docker-ce.x86_64 openvswitch.x86_64 -y
#安装docker和OVS
[root@localhost ~]#systemctl start docker
[root@localhost ~]#systemctl start openvswitch
#启动docker和OVS
3.1.2 Docker下载centos镜像
[root@localhost ~]#docker pull centos:latest
#下载centos镜像
[root@localhost ~]#docker run -itd --privileged=true --name temp centos:latest /bin/bash
#运行centos镜像
[root@localhost ~]#docker exec -i temp yum update -y
#更新docker镜像系统
[root@localhost ~]#docker exec -i temp yum install quagga net-tools vim screen -y
#在docker镜像里安装quagga等基础环境
[root@localhost ~]#docker commit temp quagga
#保存为quagga镜像
3.1.3 部署OVS
增加OVS网桥
[root@localhost ~]#ovs-vsctl add-br br1
#增加OVS网桥
[root@localhost ~]#ovs-vsctl show
15f3e9bd-93d4-44d5-aba9-752bea391fce
Bridge "br1"
Port "br1"
Interface "br1"
type: internal
ovs_version: "2.5.8"
#查看是否添加成功
3.1.4 部署BGP网络
网络拓扑图如下所示:

- 运行Docker
[root@localhost ~]# docker run -itd --privileged=true --network none --name BGP1 quagga:latest /bin/bash
#运行docker A
[root@localhost ~]# ovs-docker add-port br1 eth1 BGP1 --ipaddress=192.168.2.1/24
[root@localhost ~]# ovs-docker add-port br1 eth2 BGP1 --ipaddress=100.100.0.1/30
#添加容器A网络
[root@localhost ~]# docker run -itd --privileged=true --network none --name BGP2 quagga:latest /bin/bash
#运行docker B
[root@localhost ~]# ovs-docker add-port br1 eth1 BGP2 --ipaddress=10.10.2.1/24
[root@localhost ~]# ovs-docker add-port br1 eth2 BGP2 --ipaddress=100.100.0.2/30
#添加容器B网络
- 容器BGP1-运行quagga程序
这里使用screen放在后台运行
[root@localhost ~]# docker attach BGP1
[root@a6a0fd30b609 ~]# echo 'hostname 55dea2659df3'>/etc/quagga/zebra.conf
#写入zebra配置文件
[root@a6a0fd30b609 ~]# nohup zebra &
#放后台
[root@a6a0fd30b609 ~]# echo '! -*- bgp -*-
!
! BGPd sample configuratin file
!
! $Id: bgpd.conf.sample,v 1.1 2002/12/13 20:15:29 paul Exp $
!
hostname bgpd
password zebra
!enable password please-set-at-here
!
!bgp mulitple-instance
!
router bgp 7675
! bgp router-id 10.0.0.1
! network 10.0.0.0/8
! neighbor 10.0.0.2 remote-as 7675
! neighbor 10.0.0.2 route-map set-nexthop out
! neighbor 10.0.0.2 ebgp-multihop
! neighbor 10.0.0.2 next-hop-self
!
! access-list all permit any
!
!route-map set-nexthop permit 10
! match ip address all
! set ip next-hop 10.0.0.1
!
!log file bgpd.log
!
log stdout'> /etc/quagga/bgpd.conf
# 写入BGP配置文件
[root@a6a0fd30b609 ~]# nohup bgpd &
# 放入后台
[root@a6a0fd30b609 ~]# echo '! -*- ospf -*-
!
! OSPFd sample configuration file
!
!
hostname ospfd
password zebra
!enable password please-set-at-here
!
!router ospf
! network 192.168.1.0/24 area 0
!
log stdout'>/etc/quagga/ospfd.conf
#写入ospf配置文件
[root@a6a0fd30b609 ~]# nohup ospfd &
[root@a6a0fd30b609 ~]# netstat -tunlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:2601 0.0.0.0:* LISTEN 61/zebra
tcp 0 0 0.0.0.0:2604 0.0.0.0:* LISTEN 101/ospfd
tcp 0 0 0.0.0.0:2605 0.0.0.0:* LISTEN 95/bgpd
tcp 0 0 0.0.0.0:179 0.0.0.0:* LISTEN 95/bgpd
tcp6 0 0 :::2601 :::* LISTEN 61/zebra
tcp6 0 0 :::2604 :::* LISTEN 101/ospfd
tcp6 0 0 :::2605 :::* LISTEN 95/bgpd
tcp6 0 0 :::179 :::* LISTEN 95/bgpd
#检测端口
- 容器BGP2-运行quagga程序配置内容同上
- 配置BGP网络
对容器BGP1进行配置
我们要确认当前没有已经配置的BGP会话。在一些版本,我们可能会发现一个AS号为7675的BGP会话。由于我们不需要这个会话,所以把它移除。
[root@a6a0fd30b609 ~]# vtysh
#进入quagga路由器
bgpd# configure terminal
bgpd(config)# no router bgp 7675
bgpd(config)# router bgp 100
bgpd(config-router)# no auto-summary
bgpd(config-router)# no synchronization
bgpd(config-router)# neighbor 100.100.0.2 remote-as 200
bgpd(config-router)# neighbor 100.100.0.2 description "provider B"
bgpd(config-router)# exit
bgpd(config)# exit
bgpd# write
# 对BGP进行设置
对容器BGP2进行配置
[root@ea07e44ee83b ~]# vtysh
Router-B# configure terminal
Router-B(config)#no router bgp 7675
Router-B(config)# router bgp 200
Router-B(config)#no auto-summary
Router-B(config)#no synchronizaiton
Router-B(config-router)# neighbor 100.100.0.1 remote-as 100
Router-B(config-router)# neighbor 100.100.0.1 description "provider A"
Router-B(config-router)#exit
Router-B(config)#exit
Router-B# write
检测此步骤是否搭建成功,如果显示如下,说明此步骤没问题。
ea07e44ee83b# show ip bgp summary
BGP router identifier 100.100.0.2, local AS number 200
RIB entries 0, using 0 bytes of memory
Peers 1, using 4560 bytes of memory
Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd
100.100.0.1 4 100 3 4 0 0 0 00:01:12 0
Total number of neighbors 1
- 配置BGP前缀通告
AS 100将以192.168.2.1/24作为通告,在我们的例子中AS 200将同样以10.10.2.1/24作为通告。这些前缀需要被添加到BGP配置如下。
#在路由器-A中:
bgpd# configure terminal
bgpd(config)# router bgp 100
bgpd(config-router)# network 192.168.2.1/24
bgpd(config-router)# exit
bgpd(config)# exit
bgpd# write
#在路由器-B中:
ea07e44ee83b# configure terminal
ea07e44ee83b(config)# router bgp 200
ea07e44ee83b(config-router)# network 10.10.2.1/24
ea07e44ee83b(config-router)# exit
ea07e44ee83b(config)# exit
ea07e44ee83b# write
#两个路由器会根据需要开始通告前缀。
- 测试前缀通告
首先,确认前缀的数量是否被改变了,输入“show ip bgp summary”查看:
ea07e44ee83b# show ip bgp summary
BGP router identifier 100.100.0.2, local AS number 200
RIB entries 3, using 336 bytes of memory
Peers 1, using 4560 bytes of memory
Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd
100.100.0.1 4 100 11 12 0 0 0 00:08:15 1
Total number of neighbors 1
查看所接收的更多前缀细节,我们可以使用以下命令,
“show ip bgp neighbors 邻居IP advertised-routes”
这个命令用于显示邻居所接收到的前缀总数。
ea07e44ee83b# show ip bgp neighbors 100.100.0.1 advertised-routes
BGP table version is 0, local router ID is 100.100.0.2
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
r RIB-failure, S Stale, R Removed
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 10.10.2.0/24 100.100.0.2 0 32768 i
Total number of prefixes 1
查看哪一个前缀是我们从邻居接收到的,可以使用如下命令:“show ip bgp neighbors 邻居IP routes”
ea07e44ee83b# show ip bgp neighbors 100.100.0.1 routes
BGP table version is 0, local router ID is 100.100.0.2
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
r RIB-failure, S Stale, R Removed
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 192.168.2.0 100.100.0.1 0 0 100 i
Total number of prefixes 1
也可以查看所有的BGP路由器:“show ip bgp”
ea07e44ee83b# show ip bgp
BGP table version is 0, local router ID is 100.100.0.2
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
r RIB-failure, S Stale, R Removed
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 10.10.2.0/24 0.0.0.0 0 32768 i
*> 192.168.2.0 100.100.0.1 0 0 100 i
Total number of prefixes 2
3.1.5 测试BGP网络
在BGP1中ping BGP2中的192.168.2.1和10.10.2.1都可以ping通
- 测试方法1
ea07e44ee83b# ping 192.168.2.1
PING 192.168.2.1 (192.168.2.1) 56(84) bytes of data.
64 bytes from 192.168.2.1: icmp_seq=1 ttl=64 time=0.947 ms
64 bytes from 192.168.2.1: icmp_seq=2 ttl=64 time=0.095 ms
64 bytes from 192.168.2.1: icmp_seq=3 ttl=64 time=0.101 ms
64 bytes from 192.168.2.1: icmp_seq=4 ttl=64 time=0.120 ms
^C
--- 192.168.2.1 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3001ms
rtt min/avg/max/mdev = 0.095/0.315/0.947/0.365 ms
ea07e44ee83b# ping 10.10.2.1
PING 10.10.2.1 (10.10.2.1) 56(84) bytes of data.
64 bytes from 10.10.2.1: icmp_seq=1 ttl=64 time=0.240 ms
64 bytes from 10.10.2.1: icmp_seq=2 ttl=64 time=0.072 ms
64 bytes from 10.10.2.1: icmp_seq=3 ttl=64 time=0.080 ms
64 bytes from 10.10.2.1: icmp_seq=4 ttl=64 time=0.092 ms
^C
--- 10.10.2.1 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 2999ms
rtt min/avg/max/mdev = 0.072/0.121/0.240/0.069 ms
#ping测试
- 测试方法2
[root@localhost ~]# docker run -itd --privileged=true --network none --name test quagga:latest /bin/bash
[root@localhost ~]# ovs-docker add-port br1 eth1 test --ipaddress=192.168.2.100/24
[root@localhost ~]# docker exec -i test ip route add default via 192.168.2.1
[root@localhost ~]# docker exec -i test ping 10.10.2.1 -c 4
PING 10.10.2.1 (10.10.2.1) 56(84) bytes of data.
64 bytes from 10.10.2.1: icmp_seq=1 ttl=63 time=1.07 ms
64 bytes from 10.10.2.1: icmp_seq=2 ttl=63 time=0.228 ms
64 bytes from 10.10.2.1: icmp_seq=3 ttl=63 time=0.235 ms
64 bytes from 10.10.2.1: icmp_seq=4 ttl=63 time=0.117 ms
--- 10.10.2.1 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3001ms
rtt min/avg/max/mdev = 0.117/0.414/1.078/0.386 ms
# 如果可以通,说明配置成功