Luckylau's Blog

Openstack 负载均衡 LoadBalancerv2

​ 最近研究了一下Openstack负载均衡,yum源和源码级别的安装都尝试成功了。网上有很多文章都是LoadBalancerv1,这个已经被放弃了。所以写一下自己是如何使用LoadBalancerv2。当然在介绍之前还是从负载均衡基础知识开始吧。(Mitaka版本的LoadBalancerv2)

负载均衡的概念和分类?

​ 负载均衡(Load Balancing)是将来访的网络流量在运行相同应用的多个服务器之间进行分发的一种核心网络服务。它的功能由负载均衡器(load balancer)提供。负载均衡器可以是一个硬件设备,也可以由软件实现。它充当反向代理,在多个服务器之间分发网络或者应用流量。它常用来增加应用的访问容量(并发用户数)和可靠性,它也会通过降低服务器的负载来提高应用的总体性能。

负载均衡器的分类

负载均衡器一般可以分为两类:第4层负载均衡器和第7层负载均衡器。

第 4 层负载平衡器:基于网络和传输层协议(IP,TCP,FTP,UDP等)来均衡负载。

第7层的负载均衡器:基于应用层协议比如 HTTP, SMTP, SNMP, FTP, Telnet 等均衡负载。比如对 HTTP 来说,第七层的负载均衡器能根据应用的特定数据比如 HTTP 头,cookies 或者应用消息中的数据来做进一步的请求分发。

负载分发算法

​ 两种类型的负载均衡器都能接收请求,然后根据特定的算法将请求分发到特定的服务器。一些行业标准的算法是:

​ 轮询 (Round robin):轮流分发到各个(活动)服务器
​ 加权轮循 (Weighted round robin):每个服务器有一定的加权(weight),轮询时考虑加权。
​ 最少连接 (Least connections):转发到有最少连接数的服务器
​ 最少响应时间 (Least response time):转发到响应时间最短的服务器

可靠性和可用性

​ 负载均衡器通过监控应用的健康状态来确保可靠性和可用性,并且只转发请求到能及时做出响应的服务和应用。

Session persistence (会话保持)

​ 用户(浏览器)在和服务端交互的时候,通常会在本地保存一些信息,而整个过程叫做一个会话(Session)并用唯一的Session ID进行标识。会话的概念不仅用于购物车这种常见情况,因为HTTP协议是无状态的,所以任何需要逻辑上下文的情形都必须使用会话机制,此外HTTP客户端也会额外缓存一些数据在本地,这样就可以减少请求提高性能了。如果负载均衡可能将这个会话的请求分配到不同的后台服务端上,这肯定是不合适的,必须通过多个backend共享这些数据,效率肯定会很低下,最简单的情况是保证会话一致性——相同的会话每次请求都会被分配到同一个backend上去。

​ 会话保持表示在一个会话期间,转发一个用户的请求到同一个后端服务器。这对购物车或者付款类的请求非常重要。 常用的方法包括:

​ Source IP:相同来源的请求转发到同一个服务器
​ HTTP Cookie:该模式下,loadbalancer 为客户端的第一次连接生成 cookie,后续携带该 cookie 的请求会被某个 member 处理
​ APP Cookie:该模式下,依靠后端应用服务器生成的 cookie 决定被某个 member 处理

负载均衡的实现方式?

http重定向

​ 当http代理(比如浏览器)向web服务器请求某个URL后,web服务器可以通过http响应头信息中的Location标记来返回一个新的URL。这意味着HTTP代理需要继续请求这个新的URL,完成自动跳转。

缺陷:
1、吞吐率限制
​ 主站点服务器的吞吐率平均分配到了被转移的服务器。现假设使用RR(Round Robin)调度策略,子服务器的最大吞吐率为1000reqs/s,那么主服务器的吞吐率要达到3000reqs/s才能完全发挥三台子服务器的作用,那么如果有100台子服务器,那么主服务器的吞吐率可想而知得有大?相反,如果主服务的最大吞吐率为6000reqs/s,那么平均分配到子服务器的吞吐率为2000reqs/s,而现子服务器的最大吞吐率为1000reqs/s,因此就得增加子服务器的数量,增加到6个才能满足。

2、重定向访问深度不同
​ 有的重定向一个静态页面,有的重定向相比复杂的动态页面,那么实际服务器的负载差异是不可预料的,而主站服务器却一无所知。因此整站使用重定向方法做负载均衡不太好。

​ 我们需要权衡转移请求的开销和处理实际请求的开销,前者相对于后者越小,那么重定向的意义就越大,例如下载。你可以去很多镜像下载网站试下,会发现基本下载都使用了Location做了重定向。

DNS负载均衡

​ DNS负责提供域名解析服务,当访问某个站点时,实际上首先需要通过该站点域名的DNS服务器来获取域名指向的IP地址,在这一过程中,DNS服务器完成了域名到IP地址的映射,同样,这样映射也可以是一对多的,这时候,DNS服务器便充当了负载均衡调度器,它就像http重定向转换策略一样,将用户的请求分散到多台服务器上,但是它的实现机制完全不同。

​ 相比http重定向,基于DNS的负载均衡完全节省了所谓的主站点,或者说DNS服务器已经充当了主站点的职能。但不同的是,作为调度器,DNS服务器本身的性能几乎不用担心。因为DNS记录可以被用户浏览器或者互联网接入服务商的各级DNS服务器缓存,只有当缓存过期后才会重新向域名的DNS服务器请求解析。也说是DNS不存在http的吞吐率限制,理论上可以无限增加实际服务器的数量。

缺陷:
1、没有用户能直接看到DNS解析到了哪一台实际服务器,加服务器运维人员的调试带来了不便。
2、策略的局限性。例如你无法将HTTP请求的上下文引入到调度策略中,而在前面介绍的基于HTTP重定向的负载均衡系统中,调度器工作在HTTP层面,它可以充分理解HTTP请求后根据站点的应用逻辑来设计调度策略,比如根据请求不同的URL来进行合理的过滤和转移。
3、如果要根据实际服务器的实时负载差异来调整调度策略,这需要DNS服务器在每次解析操作时分析各服务器的健康状态,对于DNS服务器来说,这种自定义开发存在较高的门槛,更何况大多数站点只是使用第三方DNS服务。
4、DNS记录缓存,各级节点的DNS服务器不同程序的缓存会让你晕头转向。
5、基于以上几点,DNS服务器并不能很好地完成工作量均衡分配,最后,是否选择基于DNS的负载均衡方式完全取决于你的需要。

反向代理负载均衡

​ 几乎所有主流的Web服务器都热衷于支持基于反向代理的负载均衡。它的核心工作就是转发HTTP请求。
相比前面的HTTP重定向和DNS解析,反向代理的调度器扮演的是用户和实际服务器中间人的角色:
1、任何对于实际服务器的HTTP请求都必须经过调度器
2、调度器必须等待实际服务器的HTTP响应,并将它反馈给用户(前两种方式不需要经过调度反馈,是实际服务器直接发送给用户)

特性:
1、调度策略丰富。例如可以为不同的实际服务器设置不同的权重,以达到能者多劳的效果。
2、对反向代理服务器的并发处理能力要求高,因为它工作在HTTP层面。
3、反向代理服务器进行转发操作本身是需要一定开销的,比如创建线程、与后端服务器建立TCP连接、接收后端服务器返回的处理结果、分析HTTP头部信息、用户空间和内核空间的频繁切换等,虽然这部分时间并不长,但是当后端服务器处理请求的时间非常短时,转发的开销就显得尤为突出。例如请求静态文件,更适合使用前面介绍的基于DNS的负载均衡方式。
4、反向代理服务器可以监控后端服务器,比如系统负载、响应时间、是否可用、TCP连接数、流量等,从而根据这些数据调整负载均衡的策略。
5、反射代理服务器可以让用户在一次会话周期内的所有请求始终转发到一台特定的后端服务器上(粘滞会话),这样的好处一是保持session的本地访问,二是防止后端服务器的动态内存缓存的资源浪费。

IP层负载均衡LVS-NAT

​ 我们需要在HTTP层面以下实现负载均衡,这些负载均衡调度器的工作必须由Linux内核来完成,因为我们希望网络数据包在从内核缓冲区进入进程用户地址空间之前,尽早地被转发到其他实际服务器上。而且正因为可以将调度器工作在应用层之下,这些负载均衡系统可以支持更多的网络服务协议,比如ftp,smtp,dns,以及流媒体和VoIP等应用。

​ DNAT: 反向NAT,将实际服务器放置在内部网络,而作为网关的NAT服务器将来自用户端的数据包转发给内部网络的实际服务器(需要修改的是数据包的目标地址和端口)。比较著名的例子是LVS。NAT调度器的吞吐率很高是因为其在内核中进行请求转发的较低开销。

但是NAT服务器的带宽却成为了瓶颈。幸运的是,LVS提供了另一种负载均衡的方式,那就是直接路由。

直接路由LVS-DR

​ 不同于NAT机制,直接路由的负载均衡调度器工作在数据链路层上,简单地说,它通过修改数据包的目标mac地址,将数据包转发到实际服务器上,并且重要的是,实际服务器的响应数据包将直接发送给客户端,不经过调度器。适用于视频网站(响应的数据包远远超过请求的数据包)。对于LVS-DR,一旦调度器失效,你可以马上将LVS-DR切换到DNS-RR模式

常见的开源软件负载均衡器?

​ 负载均衡器 目前有2种,一种是通过硬件来进行进行,常见的硬件有比较昂贵的NetScaler、F5、Radware和Array等商用的负载均衡器,它的优点就是有专业的维护团队来对这些服务进行维护、缺点就是花销太大,所以对于规模较小的网络服务来说暂时还没有需要使用;另外一种就是类似于LVS/HAProxy、Nginx的基于Linux的开源免费的负载均衡软件策略,这些都是通过软件级别来实现,所以费用非常低廉。

Nginx、LVS及HAProxy是目前最常用的开源软件负载均衡器。

LVS

LVS:使用集群技术和Linux操作系统实现一个高性能、高可用的服务器,它具有很好的可伸缩性(Scalability)、可靠性(Reliability)和可管理性(Manageability)。

LVS的特点是:

1、抗负载能力强、是工作在网络4层之上仅作分发之用,没有流量的产生,这个特点也决定了它在负载均衡软件里的性能最强的;

2、配置性比较低,这是一个缺点也是一个优点,因为没有可太多配置的东西,所以并不需要太多接触,大大减少了人为出错的几率;

3、工作稳定,自身有完整的双机热备方案,如LVS+Keepalived和LVS+Heartbeat,不过我们在项目实施中用得最多的还是LVS/DR+Keepalived;

4、无流量,保证了均衡器IO的性能不会收到大流量的影响;

5、应用范围比较广,可以对所有应用做负载均衡;

6、软件本身不支持正则处理,不能做动静分离,这个就比较遗憾了;其实现在许多网站在这方面都有较强的需求,这个是Nginx/HAProxy+Keepalived的优势所在。

7、如果是网站应用比较庞大的话,实施LVS/DR+Keepalived起来就比较复杂了,特别后面有Windows Server应用的机器的话,如果实施及配置还有维护过程就比较复杂了,相对而言,Nginx/HAProxy+Keepalived就简单多了。

Nginx

Nginx的特点是:

1、工作在网络的7层之上,可以针对http应用做一些分流的策略,比如针对域名、目录结构,它的正则规则比HAProxy更为强大和灵活,这也是许多朋友喜欢它的原因之一;

2、Nginx对网络的依赖非常小,理论上能ping通就就能进行负载功能,这个也是它的优势所在;

3、Nginx安装和配置比较简单,测试起来比较方便;

4、也可以承担高的负载压力且稳定,一般能支撑超过几万次的并发量;

5、Nginx可以通过端口检测到服务器内部的故障,比如根据服务器处理网页返回的状态码、超时等等,并且会把返回错误的请求重新提交到另一个节点,不过其中缺点就是不支持url来检测;

6、Nginx仅能支持http和Email,这样就在适用范围上面小很多,这个它的弱势;

7、Nginx不仅仅是一款优秀的负载均衡器/反向代理软件,它同时也是功能强大的Web应用服务器。LNMP现在也是非常流行的web架构,大有和以前最流行的LAMP架构分庭抗争之势,在高流量的环境中也有很好的效果。

8、Nginx现在作为Web反向加速缓存越来越成熟了,很多朋友都已在生产环境下投入生产了,而且反映效果不错,速度比传统的Squid服务器更快,有兴趣的朋友可以考虑用其作为反向代理加速器。

HAProxy

HAProxy的特点是:

1、HAProxy是支持虚拟主机的,以前有朋友说这个不支持虚拟主机,我这里特此更正一下。

2、能够补充Nginx的一些缺点比如Session的保持,Cookie的引导等工作

3、支持url检测后端的服务器出问题的检测会有很好的帮助。

4、它跟LVS一样,本身仅仅就只是一款负载均衡软件;单纯从效率上来讲HAProxy更会比Nginx有更出色的负载均衡速度,在并发处理上也是优于Nginx的。

5、HAProxy可以对Mysql读进行负载均衡,对后端的MySQL节点进行检测和负载均衡,不过在后端的MySQL slaves数量超过10台时性能不如LVS,所以我向大家推荐LVS+Keepalived。

6、HAProxy的算法现在也越来越多了,具体有如下8种:

roundrobin,表示简单的轮询,这个不多说,这个是负载均衡基本都具备的;

static-rr,表示根据权重,建议关注;

leastconn,表示最少连接者先处理,建议关注;

source,表示根据请求源IP,这个跟Nginx的IP_hash机制类似,我们用其作为解决session问题的一种方法,建议关注;

ri,表示根据请求的URI;

rl_param,表示根据请求的URl参数’balance url_param’ requires an URL parameter name;

hdr(name),表示根据HTTP请求头来锁定每一次HTTP请求;

rdp-cookie(name),表示根据据cookie(name)来锁定并哈希每一次TCP请求。

负载均衡部署模式?

基本的负载均衡场景有3种:

Two-Arm (or sometimes called In-Line)(双臂)模式
One-Arm(单臂)模式
Direct Server Response模式

Two-Arm (or sometimes called In-Line)(双臂)模式

双臂模式有 switched mode(“bridge mode” or “transparent mode”) 和routed mode两种,routed mode要优于switched mode,实际生产环境也没有switched mode方式。

​ 对于routed mode模式来说,As you can agree, the Load-Balancer is also a router between the “Front End” and “Back End” networks. As such, he can simply do destination IP NAT in client request coming to the load-balanced virtual IP and forward the packet to one of the servers in server farm. During this proces, the destination physical server is chosen by the load-balancing algorithm.Return traffic is going back via the Load-Balancer and the source IP is again changed to the virtual load-balanced IP in the response to the Client.

One-Arm(单臂)模式

​ the Load-Balancer is using only one interface and this interface is on the same L2 network with all the servers.

​ The traffic that the client initializes will get to the Load-Balancer that has the virtual load-balanced IP. The load-sharing algorithm will pick a physical server to which the Load-Balancer will forward the traffic with destination IP NATed to the physical IP of the server and forward it out the same interface towards the physical server.BUT the Load-balancer also needs to do source IP nat so that the server reply will go back from the server to the Load-Balancer and not directly back to the Client, who is not expecting a reply directly from physical server IP. From the physical servers perspective, all the traffic is coming from Load-Balancer

Direct Server Response (or sometimes called Direct Server Return)

​ As we hopefully all know, switches learn about MAC addresses as they see frames coming on ports with source MACs. Also imagine that we have a router that has to know the MAC address of the Load-Balanced IP on the last L3 hop. With the picture below, you can already spot the “trick” this scenario tries to present here once you notice the disabled ARP on physical servers

​ In this scenario, Load-balancer only sees the incoming part of client-server traffic and all the returning traffic from physical servers is coming directly back to the client IP. The biggest advantages of this solution is that there is no NAT and the Load-Balancer throughput is only used in one way, so less performance impact for the Load-Balancer system. Disabling ARP on a physical server is not a difficult task.

​ Disadvantages however are that you have to manually configure the Load-Balancer with all the server MAC addresses and might be more difficult to troubleshoot with only one way traffic seen by the Load-Balancer on the whole L2 segment.

LoadBalancerv2初体验?

1.部署

我们假设LoadBalancerv2服务在网络节点启动,以yum源的方式安装。源码是:

https://github.com/openstack/neutron-lbaas/tree/stable/mitaka

在控制节点(neutron-server)操作如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
yum install openstack-neutron-lbaas
cd /etc/neutron/
#1.3编辑neutron.conf文件
service_plugins =router, neutron_lbaas.services.loadbalancer.plugin.LoadBalancerPluginv2
#1.4 编辑lbaas_agent.ini 文件
[DEFAULT]
interface_driver =neutron.agent.linux.interface.OVSInterfaceDriver
ovs_use_veth = True
device_driver = neutron_lbaas.drivers.haproxy.namespace_driver.HaproxyNSDriver
[haproxy]
user_group =haproxy
#1.5 编辑neutron_lbaas.conf文件
service_provider =LOADBALANCERV2:Haproxy:neutron_lbaas.drivers.haproxy.plugin_driver.HaproxyOnHostPluginDriver:default
#然后执行
neutron-db-manage --subproject neutron-lbaas upgrade head
systemctl restart neutron-server

在网络节点操作如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
yum install haproxy
yum install openstack-neutron-lbaas
cd /etc/neutron/
#1.4 编辑neutron.conf文件
service_plugins =router, neutron_lbaas.services.loadbalancer.plugin.LoadBalancerPluginv2
#1.5 编辑lbaas_agent.ini 文件
[DEFAULT]
interface_driver =neutron.agent.linux.interface.OVSInterfaceDriver
ovs_use_veth = True
device_driver = neutron_lbaas.drivers.haproxy.namespace_driver.HaproxyNSDriver
[haproxy]
user_group =haproxy
#1.6 编辑neutron_lbaas.conf文件
service_provider =LOADBALANCERV2:Haproxy:neutron_lbaas.drivers.haproxy.plugin_driver.HaproxyOnHostPluginDriver:default
#1.7启动服务
systemctl start neutron-lbaasv2-agent.service

另外可以安装前端界面

1.8安装neutron-lbaas-dashboard
这个是在openstack_dashboard安装的节点,一般是controller节点

1
2
3
4
5
6
7
8
9
git clone https://git.openstack.org/openstack/neutron-lbaas-dashboard
cd neutron-lbaas-dashboard
python setup.py install
cp neutron_lbaas_dashboard/enabled/1480project_loadbalancersv2_panel.py /usr/share/openstack-dashboard/openstack_dashboard/local/enabled/
systemctl restart httpd.service memcached.service

2.创建负载均衡

Load balancer
The load balancer occupies a neutron network port and has an IP address assigned from a subnet.
Listener
Load balancers can listen for requests on multiple ports. Each one of those ports is specified by a listener.
Pool
A pool holds a list of members that serve content through the load balancer.
Member
Members are servers that serve traffic behind a load balancer. Each member is specified by the IP address and port that it uses to serve traffic.
Health monitor
Members may go offline from time to time and health monitors divert traffic away from members that are not responding properly. Health monitors are associated with pools.
由于lbaas dashboard有些问题,所以在后台用命令行创建, dashboard可显示,但不能任何操作

[root@controller ~]# source admin-openrc.sh

[root@controller ~]# neutron subnet-list

创建loadbalancer
[root@controller ~]# neutron lbaas-loadbalancer-create –name lb1 96f0db98-45fb-48ef-afae-808425fbb2bc
添加lbaas-listener
[root@controller ~]# neutron lbaas-listener-create –loadbalancer lb1 –protocol HTTP –protocol-port 80 –name listener1
创建pool
[root@controller ~]# neutron lbaas-pool-create –lb-algorithm ROUND_ROBIN –listener listener1 –protocol HTTP –name pool1
添加member
[root@controller ~]# neutron lbaas-member-create –subnet 96f0db98-45fb-48ef-afae-808425fbb2bc –address 172.16.1.4 –protocol-port 80 pool1
[root@controller ~]# neutron lbaas-member-create –subnet 96f0db98-45fb-48ef-afae-808425fbb2bc –address 172.16.1.5 –protocol-port 80 pool1
[root@controller ~]# neutron lbaas-member-create –subnet 96f0db98-45fb-48ef-afae-808425fbb2bc –address 172.16.1.6 –protocol-port 80 pool1
添加监控
[root@controller ~]# neutron lbaas-healthmonitor-create –delay 3 –type HTTP –max-retries 3 –timeout 3 –pool pool1

[root@controller ~]# neutron lbaas-loadbalancer-show lb1

3.简单验证:

我们对member成员进行模拟http服务,即172.16.1.4,172.16.1.5,172.16.1.6分别运行

172.16.1.4
while true; do echo -e ‘HTTP/1.0 200 OK\r\nContent-Length: 8\r\n\r\nserver1’ | sudo nc -l -p 80 ; done
172.16.1.5
while true; do echo -e ‘HTTP/1.0 200 OK\r\nContent-Length: 8\r\n\r\nserver2’ | sudo nc -l -p 80 ; done
172.16.1.6
while true; do echo -e ‘HTTP/1.0 200 OK\r\nContent-Length: 8\r\n\r\nserver3’ | sudo nc -l -p 80 ; done

然后创建一个客户端访问负载均衡的vip 172.16.1.9 ,多次执行,如下图
wget -O - http:// 172.16.1.9 (第一次)
wget -O - http:// 172.16.1.9 (第二次)
wget -O - http:// 172.16.1.9 (第三次)
wget -O - http:// 172.16.1.9(第四次)

我们发现第一次是server1响应

第二次是server2响应

第三次是server3响应

第四次是server1响应

参考:

http://networkgeekstuff.com/networking/basic-load-balancer-scenarios-explained/

https://docs.openstack.org/mitaka/networking-guide/config-lbaas.html

http://www.cnblogs.com/sammyliu/p/4656176.html

http://blog.csdn.net/u013628152/article/details/51318414

Luckylau wechat
如果对您有价值,看官可以打赏的!