高可用性演练

本文档将引导您完成两台VyOS机器的完整HA设置。本设计以虚拟机为主路由器,物理机为备份,采用VRRP、BGP、OSPF和conntrack共享。

本文档的目的是指导您完成所有设置,以便您和您能够重新启动任何计算机,并且不会丢失超过几秒的连接。

设计

这是基于现实生活,在生产设计。其中一个复杂的问题是确保网络中有冗余数据。我们使用一对Cisco Nexus交换机,并使用跨它们的虚拟端口通道来实现这一点。这是一个额外的好处,还允许完全开关故障而不停机。如何实现这一点留给读者练习,但我们的设置在这里有记录。

演练建议

commit 命令隐含在每个节之后。如果你犯了一个错误,commit 会警告你,你可以在做太多事情之前纠正它。请确保你早承诺,多承诺。

如果您正在阅读本文档,强烈建议您完成整个文档,只执行virtual router1步骤,然后回来在备份硬件路由器上再次阅读。

这样可以确保你不会跑得太快,或者错过一步。不过,现在在硬件路由器上配置固定IP地址和默认路由将使您的生活更轻松。

示例网络

在本文档中,我们的上游提供商为我们分配了203.0.113.0/24,我们正在VLAN100上发布。

他们想让我们从路由器192.0.2.21和192.0.2.22在192.0.2.11和192.0.2.12上建立一个BGP会话。他们是AS 65550,我们是AS65551。

我们的路由器将有一个203.0.113.1的浮动IP地址,并使用.2和.3作为它们的固定IP。

我们将使用10.200.201.0/24作为VLAN201上的“内部”网络。

当流量来自10.200.201.0/24网络时,它将被伪装成203.0.113.1

对于站点之间的连接,我们正在运行一个到两个远程路由器的WireGuard链接,并在这些链接上使用OSPF来分发路由。该远程站点预计将从10.201.0.0/16中的任何内容发送流量

VLANs

我们将使用以下VLAN:

  • 50:上游,使用他们分配的192.0.2.0/24网络。

  • 100:“公共”网络,使用我们的203.0.113.0/24网络。

  • 201:“内部”网络,使用10.200.201.0/24

硬件

  • 交换机1(Nexus 10gb交换机)

  • 交换机2(Nexus 10gb交换机)

  • compute1 (VMware ESXi 6.5)

  • compute2 (VMware ESXi 6.5)

  • compute3 (VMware ESXi 6.5)

  • 路由器2(随机1RU机器,带4个NIC)

请注意,router1是一个在其中一个计算节点上运行的VM。

网络布线

  • 从数据中心-这连接到两个交换机上的端口1,并标记为VLAN 50

  • Cisco VPC交叉连接-端口39和40连接在每个交换机之间

  • 硬件路由器-每个交换机的端口8

  • compute1 - 交换机的端口9

  • compute2 - 交换机的端口10

  • compute3 - 交换机的端口11

这就忽略了额外的带外管理网络,它应该在完全不同的交换机上,并且在机架中有不同的馈送,超出了这个范围。

注解

Our implementation uses VMware’s Distributed Port Groups, which allows VMware to use LACP. This is a part of the ENTERPRISE licence, and is not available on a Free licence. If you are implementing this and do not have access to DPGs, you should not use VMware, and use some other virtualization platform instead.

基本设置(通过控制台)

创建router1虚拟机,使其能够承受虚拟机主机故障或网络链接故障。使用VMware,这是通过启用vSphere DRS、vSphere可用性和创建使用LACP的分布式端口组来实现的。

许多其他虚拟机监控程序都会这样做,我希望本文档能够扩展到文档中,说明如何为其他人执行此操作。

创建一个“所有VLAN”网络组,将所有集群流量传递到VM。将此网络组作为eth0附加到路由器1。

注解

VMware:必须禁用此端口组的安全性。确保启用了``Promiscuous Mode``、MAC address changes``和``Forged transmits。所有这些都将作为故障转移的一部分来完成。

硬件路由器上的键合

在硬件路由器上创建LACP绑定。我们假设eth0和eth1连接到两个交换机上的端口8,并且这些端口配置为端口通道。

set interfaces bonding bond0 description 'Switch Port-Channel'
set interfaces bonding bond0 hash-policy 'layer2'
set interfaces bonding bond0 member interface 'eth0'
set interfaces bonding bond0 member interface 'eth1'
set interfaces bonding bond0 mode '802.3ad'

分配外部IP地址

VLAN 100和201将具有浮动IP地址,但是VLAN50没有,因为这是直接与上游通信。在vlan50上创建我们的IP地址。

对于硬件路由器,将``eth0``替换为``bond0``。由于(几乎)每个命令都是相同的,除非需要在不同的主机上执行不同的操作,否则不会指定此命令。

set interfaces ethernet eth0 vif 50 address '192.0.2.21/24'

在这种情况下,硬件路由器具有不同的IP,因此

set interfaces ethernet bond0 vif 50 address '192.0.2.22/24'

添加(临时)默认路由

假设上游提供的路由器能够充当默认路由器,并将其作为静态路由添加。

set protocols static route 0.0.0.0/0 next-hop 192.0.2.11
commit
save

启用SSH

启用SSH,这样您现在就可以SSH到路由器,而不是使用控制台。

set service ssh
commit
save

此时,您应该能够通过SSH连接到这两个控制台,并且不再需要访问控制台(除非您破坏了某些东西!)

VRRP配置

我们正在设置VRRP,这样当一台机器返回服务时它就不会发生故障,并且它优先考虑router1而不是router2。

内部网络

它的浮动IP地址为10.200.201.1/24,使用虚拟路由器ID 201。它们之间的区别是接口名、hello源地址和对等地址。

路由器1

set interfaces ethernet eth0 vif 201 address 10.200.201.2/24
set high-availability vrrp group int hello-source-address '10.200.201.2'
set high-availability vrrp group int interface 'eth0.201'
set high-availability vrrp group int peer-address '10.200.201.3'
set high-availability vrrp group int no-preempt
set high-availability vrrp group int priority '200'
set high-availability vrrp group int virtual-address '10.200.201.1/24'
set high-availability vrrp group int vrid '201'

路由器2

set interfaces ethernet bond0 vif 201 address 10.200.201.3/24
set high-availability vrrp group int hello-source-address '10.200.201.3'
set high-availability vrrp group int interface 'bond0.201'
set high-availability vrrp group int peer-address '10.200.201.2'
set high-availability vrrp group int no-preempt
set high-availability vrrp group int priority '100'
set high-availability vrrp group int virtual-address '10.200.201.1/24'
set high-availability vrrp group int vrid '201'

公共网络

它的浮动IP地址为203.0.113.1/24,使用虚拟路由器ID 113。虚拟路由器ID只是一个介于1和254之间的随机数,可以设置为您想要的任何值。最佳实践建议您在整个企业范围内保持它们的独特性。

路由器1

set interfaces ethernet eth0 vif 100 address 203.0.113.2/24
set high-availability vrrp group public hello-source-address '203.0.113.2'
set high-availability vrrp group public interface 'eth0.100'
set high-availability vrrp group public peer-address '203.0.113.3'
set high-availability vrrp group public no-preempt
set high-availability vrrp group public priority '200'
set high-availability vrrp group public virtual-address '203.0.113.1/24'
set high-availability vrrp group public vrid '113'

路由器2

set interfaces ethernet bond0 vif 100 address 203.0.113.3/24
set high-availability vrrp group public hello-source-address '203.0.113.3'
set high-availability vrrp group public interface 'bond0.100'
set high-availability vrrp group public peer-address '203.0.113.2'
set high-availability vrrp group public no-preempt
set high-availability vrrp group public priority '100'
set high-availability vrrp group public virtual-address '203.0.113.1/24'
set high-availability vrrp group public vrid '113'

创建VRRP同步组

同步组用于复制连接跟踪。它需要分配给一个随机的VRRP组,我们正在使用VRRP组``int``创建一个名为``sync``的同步组``

set high-availability vrrp sync-group sync member 'int'

测试

此时,当运行``show interfaces``时,您应该能够看到这两个IP地址,并且``show vrrp``应该在主状态下显示这两个接口(在router2上显示从状态)。

vyos@router1:~$ show vrrp
Name      Interface      VRID  State    Last Transition
--------  -----------  ------  -------  -----------------
int       eth0.201        201  MASTER   100s
public    eth0.100        113  MASTER   200s
vyos@router1:~$

您应该能够ping到和从您分配的所有ip。

NAT和conntrack同步

来自10.200.201.0/24的伪装流量,该流量指向公共接口。

注解

我们明确排除了主要的上游网络,这样BGP或OSPF流量就不会意外地被NAT。

set nat source rule 10 destination address '!192.0.2.0/24'
set nat source rule 10 outbound-interface 'eth0.50'
set nat source rule 10 source address '10.200.201.0/24'
set nat source rule 10 translation address '203.0.113.1'

配置conntrack同步并禁用帮助程序

大多数conntrack模块会导致更多的问题,尤其是在复杂的网络中。默认情况下关闭它们,如果以后需要打开它们,可以这样做。

set system conntrack modules ftp disable
set system conntrack modules gre disable
set system conntrack modules nfs disable
set system conntrack modules pptp disable
set system conntrack modules sip disable
set system conntrack modules tftp disable

现在启用节点之间的复制。将硬件路由器上的eth0.201替换为bond0.201。

set service conntrack-sync accept-protocol 'tcp,udp,icmp'
set service conntrack-sync event-listen-queue-size '8'
set service conntrack-sync failover-mechanism vrrp sync-group 'sync'
set service conntrack-sync interface eth0.201
set service conntrack-sync mcast-group '224.0.0.50'
set service conntrack-sync sync-queue-size '8'

测试

最简单的测试方法是使用命令show conntrack sync statistics查看备用硬件路由器上的连接跟踪统计数据。数字应该非常接近主路由器上的数字。

当两个路由器都启动时,您应该能够建立一个从NAT’ed机器到internet的连接,重新启动活动机器,并且该连接应该被保留,并且不会退出。

基于Wireguard的OSPF

由于其设计,Wireguard没有向上或向下链接的概念。这使得在网络传输中使用它变得复杂和简单,而对于可靠的状态检测,您需要在链路中断时使用一些东西来检测。

如果您使用路由协议本身,您可以同时解决两个问题。这只是一个基本的例子,是作为一个起点提供的。

配置Wireguard

有很多关于设置Wireguard的说明和文档。您需要记住的唯一重要的一点是,每个OSPF连接只能使用一个WireGuard接口。

对于点到点链接,我们使用10.254.60/24中的小/30。

路由器1

用其他路由器的IP地址替换203.0.113.3。

set interfaces wireguard wg01 address '10.254.60.1/30'
set interfaces wireguard wg01 description 'router1-to-offsite1'
set interfaces wireguard wg01 ip ospf authentication md5 key-id 1 md5-key 'i360KoCwUGZvPq7e'
set interfaces wireguard wg01 ip ospf cost '11'
set interfaces wireguard wg01 ip ospf dead-interval '5'
set interfaces wireguard wg01 ip ospf hello-interval '1'
set interfaces wireguard wg01 ip ospf network 'point-to-point'
set interfaces wireguard wg01 ip ospf priority '1'
set interfaces wireguard wg01 ip ospf retransmit-interval '5'
set interfaces wireguard wg01 ip ospf transmit-delay '1'
set interfaces wireguard wg01 peer OFFSITE1 allowed-ips '0.0.0.0/0'
set interfaces wireguard wg01 peer OFFSITE1 endpoint '203.0.113.3:50001'
set interfaces wireguard wg01 peer OFFSITE1 persistent-keepalive '15'
set interfaces wireguard wg01 peer OFFSITE1 pubkey 'GEFMOWzAyau42/HwdwfXnrfHdIISQF8YHj35rOgSZ0o='
set interfaces wireguard wg01 port '50001'

场外1

这是连接回router1的静态IP,而不是浮动IP。

set interfaces wireguard wg01 address '10.254.60.2/30'
set interfaces wireguard wg01 description 'offsite1-to-router1'
set interfaces wireguard wg01 ip ospf authentication md5 key-id 1 md5-key 'i360KoCwUGZvPq7e'
set interfaces wireguard wg01 ip ospf cost '11'
set interfaces wireguard wg01 ip ospf dead-interval '5'
set interfaces wireguard wg01 ip ospf hello-interval '1'
set interfaces wireguard wg01 ip ospf network 'point-to-point'
set interfaces wireguard wg01 ip ospf priority '1'
set interfaces wireguard wg01 ip ospf retransmit-interval '5'
set interfaces wireguard wg01 ip ospf transmit-delay '1'
set interfaces wireguard wg01 peer ROUTER1 allowed-ips '0.0.0.0/0'
set interfaces wireguard wg01 peer ROUTER1 endpoint '192.0.2.21:50001'
set interfaces wireguard wg01 peer ROUTER1 persistent-keepalive '15'
set interfaces wireguard wg01 peer ROUTER1 pubkey 'CKwMV3ZaLntMule2Kd3G7UyVBR7zE8/qoZgLb82EE2Q='
set interfaces wireguard wg01 port '50001'

测试WireGuard

确保可以从两个路由器ping 10.254.60.1和.2。

Create Export Filter

我们只想出口我们知道我们应该出口的网络。始终将路由筛选器(导入和导出)白名单。一个好的经验法则是**“如果您不是网络的默认路由器,不要将其发布为”**。这意味着我们明确不想发布192.0.2.0/24网络(但确实要宣传10.200.201.0和203.0.113.0,这是我们的默认路由)。此筛选器应用于``redistribute connected``中。如果我们要宣传它,远程机器将通过默认路由看到192.0.2.21可用,建立连接,然后OSPF会说“192.0.2.0/24通过此隧道可用”,此时隧道将中断,OSPF将丢弃路由,然后192.0.2.0/24将通过默认情况再次访问。这叫“拍打”。

set policy access-list 150 description 'Outbound OSPF Redistribution'
set policy access-list 150 rule 10 action 'permit'
set policy access-list 150 rule 10 destination any
set policy access-list 150 rule 10 source inverse-mask '0.0.0.255'
set policy access-list 150 rule 10 source network '10.200.201.0'
set policy access-list 150 rule 20 action 'permit'
set policy access-list 150 rule 20 destination any
set policy access-list 150 rule 20 source inverse-mask '0.0.0.255'
set policy access-list 150 rule 20 source network '203.0.113.0'
set policy access-list 150 rule 100 action 'deny'
set policy access-list 150 rule 100 destination any
set policy access-list 150 rule 100 source any

创建导入筛选器

我们只想导入我们知道的网络。我们的OSPF对等机应该只在10.201.0.0/16范围内的广告网络。请注意,这是反向匹配。您在访问列表100中拒绝接受路由。

set policy access-list 100 description 'Inbound OSPF Routes from Peers'
set policy access-list 100 rule 10 action 'deny'
set policy access-list 100 rule 10 destination any
set policy access-list 100 rule 10 source inverse-mask '0.0.255.255'
set policy access-list 100 rule 10 source network '10.201.0.0'
set policy access-list 100 rule 100 action 'permit'
set policy access-list 100 rule 100 destination any
set policy access-list 100 rule 100 source any
set policy route-map PUBOSPF rule 100 action 'deny'
set policy route-map PUBOSPF rule 100 match ip address access-list '100'
set policy route-map PUBOSPF rule 500 action 'permit'

启用OSPF

每个路由器**都必须**有一个唯一的路由器id。之所以使用“参考带宽”,是因为在最初设计OSPF时,链路速度超过1gbit的想法是闻所未闻的,而且它不能正确扩展。

set protocols ospf area 0.0.0.0 authentication 'md5'
set protocols ospf area 0.0.0.0 network '10.254.60.0/24'
set protocols ospf auto-cost reference-bandwidth '10000'
set protocols ospf log-adjacency-changes
set protocols ospf parameters abr-type 'cisco'
set protocols ospf parameters router-id '10.254.60.2'
set protocols ospf route-map PUBOSPF

测试OSPF

当您在两个路由器上都启用了OSPF时,您应该可以通过命令``show ip OSPF neighbor``看到对方。状态必须为“Full”或“2-Way”,如果不是,则表示主机之间存在网络连接问题。这通常是由NAT或MTU问题引起的。在``show ip route``的输出中不应该看到任何新路由(除非这是第二遍)

BGP

BGP是一种极其复杂的网络协议。这里提供了一个示例。

注解

路由器id必须是唯一的。

路由器1

``redistribute ospf``命令纯粹是作为如何扩展的一个例子。在本演练中,它将被BGPOUT规则10000过滤,因为它不是203.0.113.0/24。

set policy prefix-list BGPOUT description 'BGP Export List'
set policy prefix-list BGPOUT rule 10 action 'deny'
set policy prefix-list BGPOUT rule 10 description 'Do not advertise short masks'
set policy prefix-list BGPOUT rule 10 ge '25'
set policy prefix-list BGPOUT rule 10 prefix '0.0.0.0/0'
set policy prefix-list BGPOUT rule 100 action 'permit'
set policy prefix-list BGPOUT rule 100 description 'Our network'
set policy prefix-list BGPOUT rule 100 prefix '203.0.113.0/24'
set policy prefix-list BGPOUT rule 10000 action 'deny'
set policy prefix-list BGPOUT rule 10000 prefix '0.0.0.0/0'
set policy route-map BGPOUT description 'BGP Export Filter'
set policy route-map BGPOUT rule 10 action 'permit'
set policy route-map BGPOUT rule 10 match ip address prefix-list 'BGPOUT'
set policy route-map BGPOUT rule 10000 action 'deny'
set policy route-map BGPPREPENDOUT description 'BGP Export Filter'
set policy route-map BGPPREPENDOUT rule 10 action 'permit'
set policy route-map BGPPREPENDOUT rule 10 set as-path-prepend '65551 65551 65551'
set policy route-map BGPPREPENDOUT rule 10 match ip address prefix-list 'BGPOUT'
set policy route-map BGPPREPENDOUT rule 10000 action 'deny'
set protocols bgp 65551 address-family ipv4-unicast network 192.0.2.0/24
set protocols bgp 65551 address-family ipv4-unicast redistribute connected metric '50'
set protocols bgp 65551 address-family ipv4-unicast redistribute ospf metric '50'
set protocols bgp 65551 neighbor 192.0.2.11 address-family ipv4-unicast route-map export 'BGPOUT'
set protocols bgp 65551 neighbor 192.0.2.11 address-family ipv4-unicast soft-reconfiguration inbound
set protocols bgp 65551 neighbor 192.0.2.11 remote-as '65550'
set protocols bgp 65551 neighbor 192.0.2.11 update-source '192.0.2.21'
set protocols bgp 65551 parameters router-id '192.0.2.21'

路由器2

这是相同的,但是使用BGPPREPENDOUT route-map来发布更长的路径。