一、实验目的
软件负载均衡一般通过两种方式来实现:基于操作系统的软负载实现和基于第三方应用的软负载实现。LVS是基于Linux操作系统实现的一种软负载,而HAProxy则是基于第三方应用实现的软负载。HAProxy相比LVS的使用要简单很多,但跟LVS一样,HAProxy自己并不能实现高可用,一旦HAProxy节点故障,将会影响整个站点。本文带来的是HAProxy基于KeepAlived实现Web高可用及动静分离。
二、实验环境介绍是准备
1、实验拓扑图
2、环境介绍
3、同步时间
1
2
3
4
5
|
[root@proxy ~]# ntpdate 202.120.2.101
[root@node1 ~]# ntpdate 202.120.2.101
[root@node2 ~]# ntpdate 202.120.2.101
[root@hpf-linux ~]# ntpdate 202.120.2.101
root@Slave ~]# ntpdate 202.120.2.101
|
4、node1、node2节点安装启动httpd及提供测试页
1
2
3
4
5
6
7
8
9
10
|
[root@node1 ~]# rpm -q httpd
httpd-2.2.15-45.el6.centos.x86_64
[root@node1 ~]# cat /www/a.com/htdoc/index.html
<h1>This is node1 !</h1>
[root@node1 ~]# service httpd start
[root@node2 ~]# rpm -q httpd
httpd-2.2.15-45.el6.centos.x86_64
[root@node2 ~]# cat /www/a.com/htdoc/index.html
<h1>This is node2 !</h1>
[root@node2 ~]# service httpd start
|
5、安装LNMP动态站点并提供测试页
如何安装LNMP这里就不列举说明了,下面提供测试页:
1
2
3
4
5
|
[root@hpf-linux ~]# cat /www/a.com/index.php
<h1>This is LNMP:node3 !</h1>
<?php
phpinfo();
?>
|
6、查看各节点的服务是否启动
1
2
3
4
5
6
7
8
9
|
[root@proxy htdoc]# curl http://192.168.1.9
<h1>This is node1 !</h1>
[root@proxy htdoc]# curl http://192.168.1.10
<h1>This is node2 !</h1>
[root@proxy htdoc]# curl http://192.168.1.6 |head
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 75128 0 75128 0 0 1044k 0 --:--:-- --:--:-- --:--:-- 1063k
<h1>This is LNMP:node3 !</h1>
|
三、安装并配置Haproxy
1、在HA1节点安装haproxy并提供配置文件
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
|
[root@proxy ~]# rpm -q haproxy
haproxy-1.5.4-2.el6_7.1.x86_64
[root@proxy ~]# cat /etc/haproxy/haproxy.cfg
global
log 127.0.0.1 local0 #日志配置,所有日志都记录在本地,通过local0输出
log 127.0.0.1 local1 notice
maxconn 25600 #最大连接数
chroot /usr/share/haproxy #改变Haproxy的工作目录
uid 99 #用户的UID
gid 99 #用户的GID
nbproc 1 #进程数据(可以设置多个)
daemon #以后台守护进程方式运行Haproxy
#debug #是否开启调试
defaults
log global
mode http #默认使用协议,可以为{http|tcp|health} http:是七层协议 tcp:是四层 health:只返回OK
option httplog #详细记录http日志
option dontlognull #不记录健康检查的日志信息
retries 3 #3次连接失败则认为服务不可用
option redispatch #ServerID对应的服务器宕机后,强制定向到其他运行正常的服务器
maxconn 30000 #默认的最大连接数
# contimeout 5000 #连接超时
# clitimeout 5000 #客户端超时
# srvtimeout 5000 #服务器超时
timeout check 1s #心跳检测超时
timeout http-request 10s #默认http请求超时时间
timeout queue 1m #默认队列超时时间
timeout connect 10s #默认连接超时时间
timeout client 1m #默认客户端超时时间
timeout server 1m #默认服务器超时时间
timeout http-keep-alive 10s #默认持久连接超时时间
listen stats
mode http
bind 0.0.0.0:8090 #指定IP地址与Port
stats enable #开启Haproxy统计状态
stats refresh 3s #统计页面自动刷新时间间隔
stats hide-version #状态页面不显示版本号
stats uri /haproxyadmin?stats #统计页面的uri为"/haproxyadmin?stats"
stats realm Haproxy\ Statistics #统计页面认证时提示内容信息
stats auth admin:admin #统计页面的用户名与密码
stats admin if TRUE #启用或禁用状态页面
frontend allen #定义前端服务器
bind *:80
mode http
option httpclose #每次请求完成主动关闭http连接
option forwardfor #后端服务器获取客户端的IP地址,可以从http header中获取
acl url_static path_end -i .html .jpg .gif #定义ACL规则以如".html"结尾的文件;-i:忽略大小写
acl url_dynamic path_end -i .php
default_backend webservers #客户端访问时默认调用后端服务器地址池
use_backend lamp if url_dynamic #调用后端服务器并检查ACL规则是否被匹配
backend webservers #定义后端服务器
balance roundrobin #定义算法;基于权重进行轮询
server node1 192.168.1.9:80 check rise 2 fall 1 weight 2
server node2 192.168.1.10:80 check rise 2 fall 1 weight 2
backend lamp
balance source #定义算法;源地址hash运算;类似于Nginx的ip_hash
server lamp 192.168.1.6:80 check rise 2 fall 1
#####注释:check:启动对后端server的健康状态检测;rise:离线的server转换到正常状态成功检查的次数;fall:确认server从正常状态转换为不可用状态需要检查的次数;weight:权重,数量越大,超重越高
|
从新载入文件:
1
|
[root@proxy ~]# service haproxy restart
|
浏览器测试:
2、在HA2服务器上安装Haproxy;这里就不在介绍了,安装与配置方法与在HA1服务器上安装相同。
四、安装配置keepalived
1、安装
1
2
3
4
|
[root@proxy ~]# rpm -q keepalived
keepalived-1.2.13-5.el6_6.x86_64
[root@Slave ~]# rpm -q keepalived
keepalived-1.2.13-5.el6_6.i686
|
2、修改HA1服务器的主配置文件
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
|
[root@proxy ~]# cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
}
notification_email_from Master
smtp_connect_timeout 3
smtp_server 127.0.0.1
router_id LVS_DEVEL
}
vrrp_script chk_haproxy {
script "killall -0 haproxy"
interval 1
weight 2
}
vrrp_instance VI_1 {
interface eth0
state MASTER
priority 201
virtual_router_id 109
garp_master_delay 1
authentication {
auth_type PASS
auth_pass password
}
track_interface {
eth0
}
virtual_ipaddress {
192.168.1.88/16 dev eth0 label eth0:0
}
track_script {
chk_haproxy
}
notify_master "/etc/keepalived/notify.sh master"
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"
}
vrrp_instance VI_2 {
interface eth0
state BACKUP
priority 99
virtual_router_id 52
garp_master_delay 1
authentication {
auth_type PASS
auth_pass password
}
track_interface {
eth0
}
virtual_ipaddress {
192.168.1.89/16 dev eth0 label eth0:1
}
track_script {
chk_haproxy
}
}
|
配置HA1服务器notify.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
|
[root@proxy ~]# cat /etc/keepalived/notify.sh
#!/bin/bash
# description: An example of notify script
#
vip=192.168.1.88
contact='[email protected]'
notify() {
mailsubject="`hostname` to be $1: $vip floating"
mailbody="`date '+%F\ %T'`: vrrp transition, `hostname` changed to be $1"
echo $mailbody | mail -s "$mailsubject" $contact
}
case "$1" in
master)
notify master
/etc/rc.d/init.d/haproxy start
exit 0
;;
backup)
notify backup
/etc/rc.d/init.d/haproxy stop
exit 0
;;
fault)
notify fault
/etc/rc.d/init.d/haproxy stop
exit 0
;;
*)
echo 'Usage: `basename $0` {master|backup|fault}'
exit 1
;;
esac
|
3、修改HA2服务器的主配置文件
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
|
[root@Slave ~]# cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
}
notification_email_from Slave
smtp_connect_timeout 3
smtp_server 127.0.0.1
router_id LVS_DEVEL
}
vrrp_script chk_haproxy {
script "killall -0 haproxy"
interval 1
weight 2
}
vrrp_instance VI_1 {
interface eth0
state BACKUP
priority 200
virtual_router_id 109
garp_master_delay 1
authentication {
auth_type PASS
auth_pass password
}
track_interface {
eth0
}
virtual_ipaddress {
192.168.1.88/16 dev eth0 label eth0:0
}
track_script {
chk_haproxy
}
}
vrrp_instance VI_2 {
interface eth0
state MASTER
priority 100
virtual_router_id 52
garp_master_delay 1
authentication {
auth_type PASS
auth_pass password
}
track_interface {
eth0
}
virtual_ipaddress {
192.168.1.89 dev eth0 label eth0:1
}
track_script {
chk_haproxy
}
notify_master "/etc/keepalived/notify.sh master"
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"
}
|
配置notify.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
|
[root@Slave ~]# cat /etc/keepalived/notify.sh
#!/bin/bash
# description: An example of notify script
#
vip=192.168.1.89
contact='[email protected]'
notify() {
mailsubject="`hostname` to be $1: $vip floating"
mailbody="`date '+%F\ %T'`: vrrp transition, `hostname` changed to be $1"
echo $mailbody | mail -s "$mailsubject" $contact
}
case "$1" in
master)
notify master
/etc/rc.d/init.d/haproxy start
exit 0
;;
backup)
notify backup
/etc/rc.d/init.d/haproxy stop
exit 0
;;
fault)
notify fault
/etc/rc.d/init.d/haproxy stop
exit 0
;;
*)
echo 'Usage: `basename $0` {master|backup|fault}'
exit 1
;;
esac
|
启动keepalived并查看VIP:
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
|
[root@proxy ~]# service keepalived start
[root@Slave ~]# service keepalived start
[root@proxy ~]# ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 100
0
link/ether 00:0c:29:b0:04:27 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.8/24 brd 192.168.1.255 scope global eth0
inet 192.168.1.88/16 scope global eth0:0
inet6 fe80::20c:29ff:feb0:427/64 scope link
valid_lft forever preferred_lft forever
[root@Slave ~]# ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000
link/ether 00:0c:29:df:1e:04 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.22/24 brd 192.168.1.255 scope global eth0
inet 192.168.1.89/32 scope global eth0:1
inet6 fe80::20c:29ff:fedf:1e04/64 scope link
valid_lft forever preferred_lft forever
|
4、测试:
5、模拟haproxy机器故障
1
2
|
[root@proxy
~]# service haproxy stop
|
查看VIP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
[root@proxy ~]# ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:b0:04:27 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.8/24 brd 192.168.1.255 scope global eth0
inet6 fe80::20c:29ff:feb0:427/64 scope link
valid_lft forever preferred_lft forever
[root@Slave ~]# ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000
link/ether 00:0c:29:df:1e:04 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.22/24 brd 192.168.1.255 scope global eth0
inet 192.168.1.89/32 scope global eth0:1
inet 192.168.1.88/16 scope global eth0:0
inet6 fe80::20c:29ff:fedf:1e04/64 scope link
valid_lft forever preferred_lft forever
|
查看邮件: