一、前言
目前需求如下:
公司有10台带图形化的虚拟机供100名左右的用户使用,所有用户通过一个域名或者 IP 连接,平台随机分配一个机器给用户使用。
实现方式:
平台使用两台 haproxy 进行负载均衡分配机器,如果配置单 VIP ,两台haproxy 只有一台机器工作,压力有些大。 两台机器部署 keepalived 并且部署双 VIP,保证两台机器同时工作,使用 DNS 做双VIP 的轮询。一台机器宕机后,双 VIP 飘到一个机器上。
流程图如下(图中只花了5个后端server):
二、软件安装及相关配置文件
1 | yum install haproxy |
三、Haporxy 配置
- haproxy.cfg 主文件配置 ,两台机器的 haproxy (172.20.35.5 、172.20.35.11) 配置相同即可
1 | $ vim /etc/haproxy/haproxy.cfg |
haproxy 配置完成验证 ,从结果可看到 两台机器的 4000 端口都可以按照规则转发到后端的机器上。
这里要想看效果,需要提前在后端的 10 台机器配置 httpd 服务并配置index 页面,这里省略。
1
2
3
4
5
6
7
8
9
10curl 172.20.35.5:4000
this is nomachine5
curl 172.20.35.5:4000
this is nomachine6
curl 172.20.35.11:4000
this is nomachine22
curl 172.20.35.11:4000
this is nomachine23
三、单 VIP keepalived 部署
Master keepalived 配置
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$ vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
acassen@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id LVS_DEVEL
}
vrrp_script chk_haproxy {
script "/etc/keepalived/chk_haproxy.sh" ## 自定义服务检测脚本位置,脚本一定要有可执行权限
interval 4
weight -120 ## 当脚本返回值为复数时对 priority 做加法,如果 weight 是负数,priority 会越来与越小,小于 backup 的 priority 时 ,vip 会漂移过去。
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 55 ## 在同一网段下,master 和 backup 必须相同,且不和其他机器冲突。
priority 200 ## 决定谁拿 vip
advert_int 1
authentication {
auth_type PASS
auth_pass 8888
}
virtual_ipaddress {
172.20.22.230 ## 虚拟IP 地址
}
}Backup keepalived 配置
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$ vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
acassen@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id LVS_DEVEL
}
vrrp_script chk_haproxy {
script "/etc/keepalived/chk_haproxy.sh"
interval 4
weight -120
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 55 ## 必须和 master 的一致
priority 100 ## 如果这个值高于 200 会抢来vip,如果相等,master 持有vip
advert_int 1
authentication {
auth_type PASS
auth_pass 8888
}
track_script {
chk_haproxy
}
virtual_ipaddress {
172.20.22.230
}
}
四、双 VIP keepalived 部署
双 VIP 其实就是双主模式,这里没有谁是绝对的 master 或者 backup,两个机器互相都是 master 和 backup。
230 Master keepalived 配置
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$ vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
acassen@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id LVS_DEVEL
}
vrrp_script chk_haproxy {
script "/etc/keepalived/chk_haproxy.sh"
interval 4
weight -120
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 55 ## 这里和另一太机器的BACKUP 要一致
priority 200
nopreempt
advert_int 1
authentication {
auth_type PASS
auth_pass 8888
}
virtual_ipaddress {
172.20.22.230
}
}
vrrp_instance VI_2 {
state BACKUP
interface eth0
virtual_router_id 56 ## 这里同样和另一太机器的MASTER 要一致,并且和上面不同
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 8888
}
virtual_ipaddress {
172.20.22.231
}
}
231 Master keepalived 配置
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$ vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
acassen@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id LVS_DEVEL
}
vrrp_script chk_haproxy {
script "/etc/keepalived/chk_haproxy.sh"
interval 4
weight -120
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 55
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 8888
}
virtual_ipaddress {
172.20.22.231
}
}
vrrp_instance VI_2 {
state MASTER
interface eth0
virtual_router_id 56
priority 200
advert_int 1
nopreempt
authentication {
auth_type PASS
auth_pass 8888
}
virtual_ipaddress {
172.20.22.230
}
}
检验 vip 漂移情况
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19## 在 172.20.35.5 上执行
$ systemctl stop keepalived
## 在 172.20.35.11 上执行,可以看到 35.5 上的vip 已经漂移过来了
$ ip a
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:ba:cf:32 brd ff:ff:ff:ff:ff:ff
inet 172.20.35.11/24 brd 192.168.63.255 scope global eth0
inet6 fe80::20c:29ff:feba:cf32/64 scope link
valid_lft forever preferred_lft forever
inet 172.20.35.230/24 brd 192.168.63.255 scope global eth0
valid_lft forever preferred_lft forever
inet 172.20.35.231/24 brd 192.168.63.255 scope global eth0
valid_lft forever preferred_lft forever
五、keepalived 脚本案例
haproxy 服务不能启动就关闭keepalived 服务
1
2
3
4
5
6
7
8
9#!/bin/sh
if [ $(ps -ef |grep "haproxy" grep v 11 grep11 |grep v "chk" |wc -1) -eq 0 ] ; then
#/usr/bin/systemctl restart haproxy
echo 11/usr/bin/systemctl restart haproxy" > /etc/keepalived/123
fi
sleep 3
if [ $(ps ef|grep "haproxy" |grep v "grep" |grep v "chk"|wc -1) -eq 0 ]; then
/usr/bin/systemctl stop keepalived
fi上面直接关闭 keepalived 服务过于暴力,下面脚本根据 haproxy 服务情况返回 0/1,在 haproxy 恢复正常后,脚本执行返回0 会增加 priority 夺回 master 的 VIP
1
2
3
4
5
6
7#!/bin/bash
count = `ps aux | grep -v grep | grep haproxy | wc -l`
if [ $count > 0 ]; then
exit 0
else
exit 1
fi
六、keepalived 原理
Master 选举
keepalived 中优先级高的节点为MASTER。MASTER其中一个职责就是响应VIP的arp包,将VIP和mac地址映射关系告诉局域网内其他主机,同时,它还会以多播的形式(目的地址224.0.0.18)向局域网中发送VRRP通告,告知自己的优先级。
网络中的所有 BACKUP 节点只负责处理 MASTER 发出的多播包,当发现 MASTER 的优先级没自己高,或者没收到 MASTER 的 VRRP 通告时,BACKUP 将自己切换到 MASTER 状态,然后做MASTER该做的事:1.响应arp包,2.发送VRRP通告。
MASTER 和 BACKUP 节点的优先级如何调整?
首先,每个节点有一个初始优先级,由配置文件中的 priority 配置项指定,MASTER节点的 priority 应比 BAKCUP 高。运行过程中 keepalived 根据 vrrp_script 的weight设定,增加或减小节点优先级。规则如下:
- 当weight > 0时,vrrp_script script脚本执行返回0(成功)时优先级为priority + weight, 否则为priority。当BACKUP发现自己的优先级大于MASTER通告的优先级时,进行主从切换。
- 当weight < 0时,vrrp_script script脚本执行返回非0(失败)时优先级为priority + weight, 否则为priority。当BACKUP发现自己的优先级大于MASTER通告的优先级时,进行主从切换。 3. 当两个节点的优先级相同时,以节点发送VRRP通告的IP作为比较对象,IP较大者为MASTER。
七、抓包分析 VIP 浮动
原理我们分析完之后,我们通过 tcpdump 的抓包来看一下 vrrp 协议的包是怎么发出的。
1 | ## 首先我们在两台 master 正常工作的情况下,关闭 172.20.35.5 的 haproxy 服务。 |