zl程序教程

您现在的位置是:首页 >  其它

当前栏目

openstack neutron L3 HA

Openstack HA neutron L3
2023-09-11 14:14:43 时间

作者:Liping Mao  发表于:2014-08-20
版权声明:能够随意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明



近期Assaf Muller写了一篇关于Neutron L3 HA的文章非常不错。

建议看原文。地址例如以下:

http://assafmuller.wordpress.com/category/ml2/



大致翻译例如以下:

L3 Agent Low Availability(L3 agent的低可用性)
眼下,在Openstack中。你仅仅能用多个网络节点达到负载分流,可是做不到HA。

如果我们有3个网络节点。创建的一些虚拟路由会被分配到这三个节点上。

然而,如果某一个节点down掉了。全部在这个节点上的虚拟路由器会中断服务。在Icehouse的neutron中还没有build-in的解决方式。




A Detour to the DHCP Agent(看看DHCP Agent是怎么做的)
DHCP是全然不同的情况。DHCP协议支持多个DHCP Server拥有同样的pool同一时候共存。

通过改动下面配置:
neutron.conf:
dhcp_agents_per_network = X

你就会将每一个network的DHCP分配到X个DHCP agents。所以。假设你部署了3个网络节点。而且设置了dhcp_agents_per_network=2,那么每一个neutron的network会被这3个网络节点中的2个DHCP agents服务。

那么这是怎样工作的呢?



首先我们看一下在实体机的情况下是怎么做的。当server连入到10.0.0.0/24子网时。它会广播出DHCP discover。两个DHCP Servers dnsmasq1和dnsmasq2(或者其它的DHCP Server实现)会收到广播包。之后回复一个offer ip是10.0.0.2。如果第一台dnsmasq1的response被server先收到。它就会广播request 10.0.0.2,而且指定dnsmasq1的ip 10.0.0.253 。两台DHCP server都会收到广播包,可是仅仅有dnsmasq1会回复ACK。由于全部的DHCP通信都是通过广播。那么dnsmasq2也会收到ACK,能够标记10.0.0.2被AA:BB:CC:11:22:33使用了,就不会将此IP分配给其它Server了。总的来说,由于clients和servers全部的通信都是通过广播。这样就仅仅须要简单的部署多个DHCP server就能达到HA的效果了。
在Neutron的情况下。MAC和IP的绑定关系是在创建port时设置好的。因此。全部的dnsmasq都会在收到请求前就知道MAC(AA:BB:CC:11:22:33)和IP(10.0.0.2)绑定了。能够看出DHCP HA是在协议层面就支持的。



Back to the Lowly Available L3 Agent(回到L3 Agent的低可用性)
L3 agent眼下和DHCP的情况不同,那么假设须要做HA是怎么做的呢?

使用外部的Cluster技术(Pacemaker / Corosync)指定一个Standby网络节点,当active网络节点发生故障时,L3agent会起到standby节点上。两个节点拥有同样的hostname。

还有一个方案是写一个脚本作为cron job。它会调用api获得哪些L3 agents死了,然后将属于这些L3 agents的虚拟路由reschedule到其它L3 agents。

在Juno里面Kevin Benton写了一个neutron内置的reschedule,代码是:https://review.openstack.org/#/c/110893/


Rescheduling Routers Takes a Long, Long Time(rescheduling虚拟路由会花非常长时间。。。

)

全部的这些都须要非常长的时间将虚拟路由reschedule到新的L3 agent。

假设有上千个虚拟路由的话那failover可能须要以小时计的down time。




Distributed Virtual Router(分布式虚拟路由)
这里有些文档说明它是怎样工作的:


它主要是将路由移至计算节点:
DVR仅仅处理Floating IPs。 默认网关的SNAT还是在网络节点的L3 agent上做。

DVR眼下不支持VLAN模式,仅仅能同tunnels和L2pop启用时工作。

在每个计算节点上都须要连接到外部网络。
总的来说。假设你的部署是基于havana或者icehouse,那DVR会须要对你的部署有比較大的修改。而L3 HA会更贴近你当前的部署。


理想情况下,你应该使用DVR+L3 HA 。

Floating IP将被你计算节点直接路由。网关SNAT的traffic将会走网络节点带HA的L3 agent。




Layer 3 High Availability(L3的高可用性)
在Juno里,我们使用keepalived做L3的HA。 Keepalived内部使用的是VRRP,那么首先我们看一下VRRP。



What is VRRP, how does it work in the physical world?

(什么是VRRP,它是怎样工作的)

VRRP是为了解决网络默认网关的HA的问题。那么是怎么做的呢?当我们在有两台路由的网络拓扑中,你能够指定一半的server是第一个路由的IP地址,另外一半server指定到第二个路由的IP地址。


这样能够提供负载分流,可是假设一个路由器down了就有问题了。自然的就会想到使用一个虚拟IP作为server的默认网关。当Master的路由down了之后,standby的路由器不会收到从Master发出的VRRP hello包,这样就会导致standbys的路由器的一次选举。获胜者将作为新的Master。

新的Master将使用VIP。并须要发出gratuitous ARP用于刷新servers的ARP cache。交换机也会知道此虚拟MAC从旧的port移动至了新的port。




通过这样做了之后,默认路由会改为新的Active的路由,可是没有实现负载分流。那么怎样同一时候做到负载分流呢?能够通过VRRP groups,一半的servers使用第一个VIP,还有一半的servers使用第二个VIP。

这种话随意的路由 down掉之后就会移至还有一台路由。



细心的读者可能会想到一个问题,假设路由的external网络连接断了会怎么样呢?他还会是active的路由吗?事实上VRRP是有能力监控external网络,这样就能够把external网络断掉的路由器标示为failure。



Note:对于IP地址。有以下两种可行的方案:
1. 每一个路由器都拥有自己的IP地址,VIP在master作为additional或者secondary IP。

2. 仅仅有VIP一个地址。仅仅有master有IP地址。slaves没有IP地址。


VRRP – The Dry Facts(VRRP基本知识)

1. 直接通过IP协议封装。
2. master使用组播地址224.0.0.18 MAC地址为01-00-5E-00-00-12发送给standby节点Hello消息。
3. 虚拟MAC的地址是00-00-5E-00-01-{VRID}。 因此在同一个广播域中有256个VRIDs(0到255)。
4. 选举的过程使用的是用户设定的priority值,范围是1-255, 数值越大优先级越高。

5. 抢占式(preemptive)选举,这和其它的网络协议一样,当优先级高的路由器增加或者从错误状态中恢复时,会抢占成为master。
6. 非抢占式(non-preemptive)选举。当优先级高的路由器增加或者从错误状态中恢复时,不会抢占成为master,还是维持slave的状态。
7. hello消息的周期是可配置的,假设standby在3倍周期内没有收到hello消息就会发起选举。



Back to Neutron-land(回来看neutron的情况)

L3 HA会在每个router的namespace中启动一个keepalived。不同的router通过专用的HA网络通信。每个tenant一个有一个专用的HA网络。HA网络和一般的网络没什么不同,仅仅是它本身没有属于某个tenant,所以在CLI和GUI中是看不到的。

HA routers在namespace中,有一个'HA' device:当一个HA router被创建时,它会被schedule到多个网络节点。每个namespace都会通过HA device连接到HA网络。

Keepalived的控制流就是通过HA device转发的。下面是router namespace的"ip addr"输出:

[stack@vpn-6-88 ~]$ sudo ip netns exec qrouter-b30064f9-414e-4c98-ab42-646197c74020 ip address
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 
    ...
2794: ha-45249562-ec: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default 
    link/ether 12:34:56:78:2b:5d brd ff:ff:ff:ff:ff:ff
    inet 169.254.0.2/24 brd 169.254.0.255 scope global ha-54b92d86-4f
       valid_lft forever preferred_lft forever
    inet6 fe80::1034:56ff:fe78:2b5d/64 scope link 
       valid_lft forever preferred_lft forever
2795: qr-dc9d93c6-e2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default 
    link/ether ca:fe:de:ad:be:ef brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.1/24 scope global qr-0d51eced-0f
       valid_lft forever preferred_lft forever
    inet6 fe80::c8fe:deff:fead:beef/64 scope link 
       valid_lft forever preferred_lft forever
2796: qg-843de7e6-8f: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default 
    link/ether ca:fe:de:ad:be:ef brd ff:ff:ff:ff:ff:ff
    inet 19.4.4.4/24 scope global qg-75688938-8d
       valid_lft forever preferred_lft forever
    inet6 fe80::c8fe:deff:fead:beef/64 scope link 
       valid_lft forever preferred_lft forever

这是master的输出。在还有一个网络节点上会有相同的ha, qr 和qg。可是他们没有IP。同一时候也没有floating ip而且路由表为空。

他们是作为配置项写在keepalived的配置文件里的。当keepalived检測到master down掉时,这些地址将会被配置上去。这里是keepalived.conf的样例:

vrrp_sync_group VG_1 {
    group {
        VR_1
    }
    notify_backup "/path/to/notify_backup.sh"
    notify_master "/path/to/notify_master.sh"
    notify_fault "/path/to/notify_fault.sh"
}
vrrp_instance VR_1 {
    state BACKUP
    interface ha-45249562-ec
    virtual_router_id 1
    priority 50
    nopreempt
    advert_int 2
    track_interface {
        ha-45249562-ec
    }
    virtual_ipaddress {
        19.4.4.4/24 dev qg-843de7e6-8f
    }
    virtual_ipaddress_excluded {
        10.0.0.1/24 dev qr-dc9d93c6-e2
    }
    virtual_routes {
        0.0.0.0/0 via 19.4.4.1 dev qg-843de7e6-8f
    }
}


这里的notify脚本是什么呢?这些脚本是keepalived在状态转换为master、backup或者fault时运行的。这里是转换为master的脚本样例:
#!/usr/bin/env bash
neutron-ns-metadata-proxy --pid_file=/tmp/tmpp_6Lcx/tmpllLzNs/external/pids/b30064f9-414e-4c98-ab42-646197c74020/pid --metadata_proxy_socket=/tmp/tmpp_6Lcx/tmpllLzNs/metadata_proxy --router_id=b30064f9-414e-4c98-ab42-646197c74020 --state_path=/opt/openstack/neutron --metadata_port=9697 --debug --verbose
echo -n master > /tmp/tmpp_6Lcx/tmpllLzNs/ha_confs/b30064f9-414e-4c98-ab42-646197c74020/state

这个脚本不过启动了neutron-ns-metadata-proxy,再将状态写到了状态文件里(状态文件之后会被L3读取)。

backup和fault脚本会kill neutron-ns-metadata-proxy进程,并记录相应状态。这意味着neutron-ns-metadata-proxy只会在master上存在。



* Aren’t We Forgetting the Metadata Agent?(我们忘了Metadata agent了吗?)

你仅仅须要将其(neutron-metadata-agent)在每一个网络节点上跑着就能够了。


Future Work & Limitations(将来的工作和眼下的限制)
1. TCP连接 -- 眼下的实现中。TCP sessions会在failover的时候中断。理想情况下,使用conntrackd应该能够做到sessions在failover时不中断。

2. Master Router在哪里? 眼下管理员不知道master在哪个网络节点中,计划是agents上报这个信息。然后通过API暴露出去。
3. 当须要维护一个网络节点时,我们全部Master可以放弃Master状态。这样可以加快failover。
4. 通知l2pop VIP的移动。Master节点会拥有VIP,可是Standby会存在相同的neutron port和MAC地址。这会对L2pop产生不利影响。由于它觉得MAC地址是仅仅存在于网络的某一位置的。

解决问题的计划是:当agent检測到VRRP状态发生变化时,发送RPC消息。也就是说当一个路由变为Master时。Controller会收到消息并通知L2pop更新。

5. FW, VPN和LB,与DVR和L3 HA集成时都有问题。在Kilo版本号中会深入去看。
6. 每一个tenant有1个HA网络,这就限制了每一个tenant有255个HA Router,由于VRID在同一广播域中有255个的限制。

Usage & Configuration(使用和配置)
neutron.conf:
l3_ha = True
max_l3_agents_per_router = 2
min_l3_agents_per_router = 2

l3_ha=Ture表示全部的虚拟路由都是HA模式的,默觉得false
你能够设置HA Router被schedule到max和min数目的网络节点数。比方你有4个网络节点。你设置了max和min为2,那么每一个HA router会被schedule到两个L3 agent上。

当你的网络节点个数小于min时,HA路由会创建失败。


CLI能够覆盖l3_ha的配置(必须拥有admin权限):
neutron router-create --ha=<True | False> router1

References
BP: 
spec: 
How to test: 
Code: 
https://review.openstack.org/#/q/topic:bp/l3-high-availability,n,z
Wiki:
Section in Neutron L3 sub team wiki (Including overview of patch dependencies and future work):
https://wiki.openstack.org/wiki/Meetings/Neutron-L3-Subteam#Blueprint:_l3-high-availability_.28safchain.2C_amuller.29