多读书多实践,勤思考善领悟

LVS+Keepalived高性能业务架构解决方案

本文于2063天之前发表,文中内容可能已经过时。

一、概况

1.1 应用场景

Nginx/LVS/HAProxy的基于Linux的开源免费的负载均衡软件。对于大型的,需要进行高并发的网站或者对网络不太严格的场景,可以使用Nginx;对于大型的Web服务器的时候可以使用Haproxy;对性能有严格要求的时候可以使用LVS,就单纯从负载均衡的角度来说,LVS也许会成为主流,更适合现在大型的互联网公司。本文采用LVS+keepalived方案来解决业务架构高可用。

1.2 LVS/Nginx/HAProxy特点

名称 特点
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 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 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的算法现在也越来越多了,算法特别灵活

二、相关理论

2.1 Keepalived工作原理

keepalived:顾名思义是保持存活,常用来搭建设备的高可用,防止业务核心设备出现单点故障。keepalived基于VRRP协议来实现高可用,主要用作realserver的健康检查以及负载均衡主机和backup主机之间的故障漂移。如果将TCP/IP划分为5层,则Keepalived就是一个类似于3~5层交换机制的软件,具有3~5层交换功能,其主要作用是检测web服务器的状态,如果某台web服务器故障,Keepalived将检测到并将其从系统中剔除,当该web服务器工作正常后Keepalived自动将其加入到服务器群中,这些工作全部自动完成,而不需要人工干预,只需要人工修复故障的web服务器即可。

三层机理是发送ICMP数据包即PING给某台服务器,如果不通,则认为其故障,并从服务器群中剔除;四层机理是检测TCP端口号状态来判断某台服务器是否故障,如果检测端口存在异常,则从服务器群中剔除;五层机理是根据用户的设定检查某个服务器应用程序是否正常运行,如果不正常,则从服务器群中剔除。

2.2 LVS工作原理

LVS工作在网络层。通过控制IP来实现负载均衡。IPVS是其具体的实现模块。IPVS的主要作用:安装在Director Server上面,在Director Server虚拟一个对外访问的IP(VIP)。用户访问VIP,到达Director Server,Director Server根据一定的规则选择一个Real Server,处理完成后然后返回给客户端数据。这些步骤产生了一些具体的问题,比如如何选择具体的Real Server,Real Server如果返回给客户端数据等等。IPVS为此有三种机制:

n VS/NAT(Virtual Server via Network Address Translation),即网络地址翻转技术实现虚拟服务器。当请求来到时,Diretor server上处理的程序将数据报文中的目标地址(即虚拟IP地址)改成具体的某台Real Server,端口也改成Real Server的端口,然后把报文发给Real Server。Real Server处理完数据后,需要返回给Diretor Server,然后Diretor server将数据包中的源地址和源端口改成VIP的地址和端口,最后把数据发送出去。由此可以看出,用户的请求和返回都要经过Diretor Server,如果数据过多,Diretor Server肯定会不堪重负。

n VS/TUN(Virtual Server via IP Tunneling),即IP隧道技术实现虚拟服务器。它跟VS/NAT基本一样,但是Real server是直接返回数据给客户端,不需要经过Diretor server,这大大降低了Diretor server的压力。

n VS/DR(Virtual Server via Direct Routing),即用直接路由技术实现虚拟服务器。跟前面两种方式,它的报文转发方法有所不同,VS/DR通过改写请求报文的MAC地址,将请求发送到Real Server,而Real Server将响应直接返回给客户,免去了VS/TUN中的IP隧道开销。这种方式是三种负载调度机制中性能最高最好的,但是必须要求Director Server与Real Server都有一块网卡连在同一物理网段上。

三、架构拓扑

img

四、资源规划

主机名称 内网IP 操作系统
LVS-Master 10.10.10.2 Centos 6.5 64位
LVS-Backup 10.10.10.3 Centos 6.5 64位
WEB01 10.10.10.11 Centos 6.5 64位
WEB02 10.10.10.12 Centos 6.5 64位
WEB03 10.10.10.13 Centos 6.5 64位
NFS-server 10.10.10.20 Centos 6.5 64位
VIP 10.10.10.100 \

五、实施部署

5.1 初始化配置

l getenforce 0关闭SeLinux

l 修改主机名

l 防火墙开放22/80端口

l 测试网络连通性

l 更新YUM源

1
2
3
4
5
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup

wget -O /etc/yum.repos.d/CentOS-Base.repo <http://mirrors.aliyun.com/repo/Centos-6.repo>

yum makecache #生成缓存

5.2 LVS配置

在master与backup上面同时配置

安装可采用yum直接安装,或下载tar包编译安装。

1
2
3
4
5
yum install ipvsadm

/etc/init.d/ipvsadm save

/etc/init.d/ipvsadm start

查看ipvsadm状态

1
/etc/init.d/ipvsadm -ln

# 开启icmp包重定向

1
2
3
4
5
echo "1" > /proc/sys/net/ipv4/conf/all/send_redirects

echo "1" > /proc/sys/net/ipv4/conf/default/send_redirects

echo "1" > /proc/sys/net/ipv4/conf/eth0/send_redirects

#添加路由

1
route add -host 10.10.10.100 dev eth1

#清除LVS规则

1
ipvsadm -C

# 添加一条虚拟服务器记录

# -p指定一定的时间内将相同的客户端分配到同一台后端服务器解决session问题

1
ipvsadm -A -t 10.10.10.100:80 -s wlc -p

# 添加真实服务器记录

1
2
3
4
5
ipvsadm -a -t 10.10.10.100:80 -r 10.10.10.11:80 -g -w 1

ipvsadm -a -t 10.10.10.100:80 -r 10.10.10.12:80 -g -w 1

ipvsadm -a -t 10.10.10.100:80 -r 10.10.10.13:80 -g -w 1

#设置tcp tcpfin udp超市连接值

1
2
3
ipvsadm --set 30 120 300

Ipvsadm

配置完成后,查看ipvsadm状态与主机路由

wKiom1if6QGxmGLvAAJAoSW8TjY908.png
wKioL1if6VPQswrgAADfbd18iPA107.png
wKiom1if6YaykMuFAAEnqxb0DZ0588.png
wKioL1if6bLwOe-kAAImyjyDCZE115.png

5.3 Keepalived部署

5.3.1 Keepalived的安装

在master与backup上面均需要配置

安装开发组环境工具

1
yum groupinstall "Development tools" -y

安装相应软件包

1
2
3
yum install openssl-devel popt-devel -y

ln -s /usr/src/kernels/2.6.32-642.1.1.el6.x86_64 /usr/src/linux #此处要根据实际操作系统最高版本的kernel 为准

如果/usr/src/kernels/下面没文件使用yum 安装 kernel-devel

#下载keepalive

1
2
3
4
5
6
7
wget [http://www.keepalived.org/software/keepalived-1.2.24.tar.gz](http://www.keepalived.org/software/keepalived-1.2.1.tar.gz)

tar zxvf keepalived-1.2.24.tar.gz

cd keepalived-1.2.24

./configure --with-kernel-dir=/usr/src/kernels/2.6.32-642.1.1.el6.x86_64

(注意这个步骤要看到以下字样才是正常的)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Use IPVS Framework : Yes

IPVS sync daemon support : Yes



make && make install

cp /usr/local/etc/rc.d/init.d/keepalived /etc/rc.d/init.d/

cp /usr/local/etc/sysconfig/keepalived /etc/sysconfig/

mkdir /etc/keepalived

cp /usr/local/etc/keepalived/keepalived.conf /etc/keepalived/

cp /usr/local/sbin/keepalived /usr/sbin/

chkconfig --add keepalived

chkconfig --level 2345 keepalived on

/etc/init.d/keepalived start

至此keepalive就已经安装完毕。

注意:主要backup服务器之上修改两点即可

1、state MASTER backup服务器需要更改为BACKUP

2、priority 100小于master的优先级

5.3.2 配置keepalived

编辑keepalived.conf

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
! Configuration File for keepalived



global_defs {

notification_email {

xuel@51idc.com

}

notification_email_from Alexandre.Cassen@firewall.loc

smtp_server 127.0.0.1

smtp_connect_timeout 30

router_id LVS_DEVEL

}



vrrp_instance VI_1 {

state MASTER #backup主机配置为BACKUP

​ interface eth0 #实例绑定的网卡

​ virtual_router_id 51 # VRID 标记( 0...255

​ priority 100#backup主机配置优先级小于100,如配置90

​ advert_int 1#检查间隔,默认 1s

​ authentication {

​ auth_type PASS

​ auth_pass 1111

​ }

​ virtual_ipaddress {

10.10.10.100#VIP地址,如果有多个 VIP ,继续换行填写

​ }

}



virtual_server 10.10.10.100 80 { #设置 VIP及监听后端服务端口

​ delay_loop 6

​ lb_algo wrr#LVS调度算法 rr|wrr|lc|wlc|sh|dh|lblc

​ lb_kind DR#LVS实现负载均衡的机制 NAT|DR|TUN

​ nat_mask 255.255.255.0

​ persistence_timeout 50# 会话保持时间

​ protocol TCP



​ real_server 10.10.10.11 80 {

weight 3

​ TCP_CHECK {#tcp健康检查

​ connect_timeout 10#连接超时时间

​ nb_get_retry 3#重连次数

​ delay_before_retry 3#重连间隔时间

​ connect_port 80#健康检查端口

​ }

​ }

​ real_server 10.10.10.12 80 {

​ weight 3

​ TCP_CHECK {

​ connect_timeout 10

​ nb_get_retry 3

​ delay_before_retry 3

​ connect_port 80

​ }

​ }

​ real_server 10.10.10.13 80 {

​ weight 3

​ TCP_CHECK {

​ connect_timeout 10

​ nb_get_retry 3

​ delay_before_retry 3

​ connect_port 80

​ }

​ }

}

5.4 后端WEB服务器

安装httpd,并写测试页

1
2
3
yum install httpd

chkconfig httpd on

wKioL1if6hOgTnaUAAA14do87X8155.png
wKiom1if6mTCmxTeAABzu9GlOA8284.png

WEB01与WEB02同时配置

1
2
3
4
5
6
7
echo "1">/proc/sys/net/ipv4/conf/default/arp_ignore

echo "2">/proc/sys/net/ipv4/conf/default/arp_announce

echo "1">/proc/sys/net/ipv4/conf/all/arp_ignore

echo "2">/proc/sys/net/ipv4/conf/all/arp_announce

arp_ignore:定义对目标地址为本地IP的ARP询问不同的应答模式0

0 - (默认值): 回应任何网络接口上对任何本地IP地址的arp查询请求

1 - 只回答目标IP地址是来访网络接口本地地址的ARP查询请求

2 -只回答目标IP地址是来访网络接口本地地址的ARP查询请求,且来访IP必须在该网络接口的子网段内

3 - 不回应该网络界面的arp请求,而只对设置的唯一和连接地址做出回应

4-7 - 保留未使用

8 -不回应所有(本地地址)的arp查询

arp_announce:对网络接口上,本地IP地址的发出的,ARP回应,作出相应级别的限制: 确定不同程度的限制,宣布对来自本地源IP地址发出Arp请求的接口

0 - (默认) 在任意网络接口(eth0,eth1,lo)上的任何本地地址

1 -尽量避免不在该网络接口子网段的本地地址做出arp回应. 当发起ARP请求的源IP地址是被设置应该经由路由达到此网络接口的时候很有用.此时会检查来访IP是否为所有接口上的子网段内ip之一.如果改来访IP不属于各个网络接口上的子网段内,那么将采用级别2的方式来进行处理.

2 - 对查询目标使用最适当的本地地址.在此模式下将忽略这个IP数据包的源地址并尝试选择与能与该地址通信的本地地址.首要是选择所有的网络接口的子网中外出访问子网中包含该目标IP地址的本地地址. 如果没有合适的地址被发现,将选择当前的发送网络接口或其他的有可能接受到该ARP回应的网络接口来进行发送.

关于对arp_announce 理解的一点补充

1
sysctl -p

添加VIP地址与路由

1
2
3
ifconfig lo:0 10.10.10.100 broadcast 10.10.10.100 netmask 255.255.255.255 up

route add -host 10.10.10.100 dev lo:0

5.5 共享存储

1
2
3
4
5
6
7
yum -y install nfs-utils rpcbind

service nfs start

chkconfig nfs on

vim /etc/exprots
wKiom1if6qiBJQh4AABDp2VqjGM206.png

1
echo “This is NFS-share test page!”>/NFSshare


后端WEB挂载共享存储
1
mount 10.10.10.20:/NFSshare /var/www/html/


wKioL1if6tuRnMn4AAEYNFouaD0726.png

测试访问VIP

wKiom1if6waS_9QGAAAyLVZWCU8532.png

5.6 测试

为测试方便,在后端WEB服务器上,写入对用文件

wKioL1if60fAmnhmAAA2peFH7B0192.png
wKioL1if61rCmuIxAAKtIzaYWOQ697.png

5.6.1 负载均衡测试

停止WEB02 httpd

wKioL1if67KQUYykAADS39rt5hc180.png
wKiom1if66KzbGrzAABynwQ5chI847.png

再停止WEB03 httpd

wKioL1if6-vxpC1RAAC9ZTyh8ek008.png
wKiom1if7Aeh8qXzAACoj0W5QRw404.png
wKioL1if7AmzXbdKAAFYuq_Xt44291.png

5.6.2 高可用测试

wKioL1if7FqiuKkZAAKvfwCB384054.png

停止LVS-Master 的keepalived服务

wKioL1if7Gzz7BTbAAJjS9kzdV0853.png

此时VIP已经漂移到LVS-Backup上面

wKioL1if7LzThHlPAAKIj16SSis197.png

后端web已经正常对外提供服务。

启动Master之上的Keepalived,VIP成功漂移会MASTER之上

wKiom1if7OqDuBW9AAMgGtlFCSc452.png
wKioL1if7TORLscJAACuY5-iUrM257.png

恢复邮件

wKiom1if7UehEMi2AAERxay89WA080.png

六、注意事项

6.1 LVS安装注意事项

ln -s /usr/src/kernels/2.6.32-642.1.1.el6.x86_64 /usr/src/linux #此处要根据实际操作系统最高版本的kernel 为准

./configure –with-kernel-dir=/usr/src/kernels/2.6.32-642.1.1.el6.x86_64

(注意这个步骤要看到以下字样才是正常的)

Use IPVS Framework : Yes

IPVS sync daemon support : Yes

6.2 将相关开机自启服务

开机自启服务

wKioL1if7dTAbuqLAABcL-VSYHI957.png

开机自启脚本

wKiom1if7f6gzvMtAADjQfxemwM899.png

开机NFS自动挂载

wKioL1if7lbhJAykAAGEoEz5BRU670.png

6.3 脚本

为方便配置,目前已经写了两个脚本,方便运行安装。

在Master与Backup之上配置

LVS-MB-ipvsadm.sh

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
\#!/bin/bash

VIP=10.10.10.100

RIPS1=10.10.10.11

RIPS2=10.10.10.12

RIPS3=10.10.10.13

SERVICE=80

. /etc/rc.d/init.d/functions

case "$1" in

start)

echo "Start LVS of DR Mode"

echo "1" > /proc/sys/net/ipv4/conf/all/send_redirects

echo "1" > /proc/sys/net/ipv4/conf/default/send_redirects

echo "1" > /proc/sys/net/ipv4/conf/eth0/send_redirects

route add -host $VIP dev eth0

ipvsadm -C

ipvsadm -A -t $VIP:$SERVICE -s wlc -p

ipvsadm -a -t $VIP:$SERVICE -r $RIPS1:$SERVICE -g -w 1

ipvsadm -a -t $VIP:$SERVICE -r $RIPS2:$SERVICE -g -w 1

ipvsadm -a -t $VIP:$SERVICE -r $RIPS3:$SERVICE -g -w 1

ipvsadm --set 30 120 300

ipvsadm

;;

stop)

echo "Stop LVS DR"

ifconfig eth1 down

ipvsadm -C

;;

*)

echo "Usage:$0 {start ? stop}"

exit 1

esac

在后端WEB01、WEB02之上配置

LVS-RS-WEB.sh

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
\#!/bin/bash

VIP=172.16.16.100

. /etc/init.d/functions

case "$1" in

start)

echo "Start LVS of RS"

/sbin/ifconfig lo:0 $VIP broadcast $VIP netmask 255.255.255.255 up

/sbin/route add -host $VIP dev lo:0

echo "1">/proc/sys/net/ipv4/conf/default/arp_ignore

echo "2">/proc/sys/net/ipv4/conf/default/arp_announce

echo "1">/proc/sys/net/ipv4/conf/all/arp_ignore

echo "2">/proc/sys/net/ipv4/conf/all/arp_announce

sysctl -p

;;

stop)

/sbin/ifconfig lo:0 down

echo "Close LVS of RS"

echo "0">/proc/sys/net/ipv4/conf/lo/arp_ignore

echo "0">/proc/sys/net/ipv4/conf/lo/arp_announce

echo "0">/proc/sys/net/ipv4/conf/all/arp_ignore

echo "0">/proc/sys/net/ipv4/conf/all/arp_announce

sysctl -p

;;

*)

echo "Usage:$0{start|stop}"

exit 1

esac