第十三章:Keepalived高可用
第一节:keepalived介绍
1.简介
高可用HA(High Availability)是分布式系统架构设计中必须考虑的因素之一,它通常是指,通过设计减少系统不能提供服务的时间。
2.keepalived工作原理
keepalived高可用功能实现的基本原理为:
两台主机同时安装好keepalived软件并启动服务,开始正常工作时
角色为Master的主机获得所有资源并对用户提供服务
角色为Backup的主机作为Master主机的热备;
当角色为Master的主机失效或出现故障时
角色为Backup的主机将自动接管Master主机的所有工作,包括接管VIP资源及相应资源服务
而当角色为Master的主机故障修复后,又会自动接管回他原来处理的工作
角色为Backup的主机则同时释放Master主机失效时他接管的工作
此时,两台主机将恢复到启动时各自的原始角色及工作状态
keepalived.png
3.VRRP协议
VRRP通过竞选机制来实现虚拟路由器的功能
所有的协议报文都是通过IP组播(Multicast)包
默认的多播地址224.0.0.18
VIP前提条件:
1.虚拟公网IP必须是真实可用的
2.虚拟公网IP不能重复
3.虚拟公网IP必须和相同网段的物理网卡绑定
4.组播地址必须是可以通讯的
第二节:keepalived安装配置
1.安装keepalived
yum install keepalived -y
2.配置文件解释
global_defs {
router_id lb01 #设置路由ID,每个主机不一样
}
vrrp_instance VI_1 { #设置VRRP组名,同一组组名相同
state MASTER #设置角色状态,分为MASTER BACKUP
interface eth0 #VIP绑定的网卡
virtual_router_id 50 #虚拟路由id,同一组一样
priority 150 #权重,权重越高,优先级越高
advert_int 1 #发送组播间隔
authentication { #设置验证,密码为明文
auth_type PASS
auth_pass 1111
}
virtual_ipaddress { #设定的虚拟IP,这个虚拟IP必须是存在且合法且没有被使用的。
10.0.0.3
}
}
3.lb01配置
global_defs {
router_id lb01
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 50
priority 150
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.0.3
}
}
4.lb02配置
global_defs {
router_id lb02
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 50
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.0.3
}
}
5.启动
systemctl start keepalived
6.测试(以上为抢占式:默认)
关掉任意一台,观察VIP是否会漂移
恢复MASTER观察BACKUP的VIP是否会消失
7.非抢占式高可用配置
1.LB01服务器的配置
global_defs {
router_id lb01
}
vrrp_instance VI_1 {
state BACKUP
nopreempt
interface eth0
virtual_router_id 50
priority 150
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.0.3
}
}
2.LB02服务器的配置
global_defs {
router_id lb01
}
vrrp_instance VI_1 {
state BACKUP
nopreempt
interface eth0
virtual_router_id 50
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.0.3
}
}
重点:
1、两个节点的state都必须配置为BACKUP
2、两个节点都必须加上配置 nopreempt
引用官方文档对nopreempt字段的说明:
"nopreempt" allows the lower priority machine to maintain the master role, even when a higher priority machine comes back online.
译:“nopreempt”允许较低优先级的机器维护主角色,即使在较高优先级的机器重新联机时也是如此。
NOTE: For this to work, the initial state of this entry must be BACKUP.
根据上述描述,第一点提到的state必须配置为BACKUP就明白了。
3、其中一个节点的优先级必须要高于另外一个节点的优先级。
第三节:脑裂现象
1.安装抓包工具(查看实验现象)
yum install tcpdump -y
2.lb02抓包查看
tcpdump -nn -i any host 224.0.0.18
3.lb02新开一个终端,然后开启防火墙
systemctl start firewalld.service
4.lb02观察抓包现象
观察是否两边都有VIP
5.添加放行规则
firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 --in-interface eth0 --destination 224.0.0.18 --protocol vrrp -j ACCEPT
firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 --in-interface eth1 --destination 224.0.0.18 --protocol vrrp -j ACCEPT
systemctl reload firewalld
6.lb02观察抓包现象
观察是否两边都有VIP
第四节:keepalived双主实验
1.lb01配置文件
[root@lb01 ~]# cat /etc/keepalived/keepalived.conf
global_defs {
router_id lb01
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 50
priority 150
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.0.3
}
}
vrrp_instance VI_2 {
state BACKUP
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 2222
}
virtual_ipaddress {
10.0.0.4
}
}
2.lb02配置文件
[root@lb02 ~]# cat /etc/keepalived/keepalived.conf
global_defs {
router_id lb02
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 50
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.0.3
}
}
vrrp_instance VI_2 {
state MASTER
interface eth0
virtual_router_id 51
priority 150
advert_int 1
authentication {
auth_type PASS
auth_pass 2222
}
virtual_ipaddress {
10.0.0.4
}
}
3.重启keepalived并观察现象
systemctl restart keepalived
第五节:keepalived结合nginx反向代理负载均衡
lb服务器的Nginx配置:
注意!两台lb服务器的Nginx配置一模一样
1.备份原有配置
mkdir /backup
cd /etc/nginx/conf.d
mv * /backup
2.编写负载均衡Nginx配置文件
[root@lb01 /etc/nginx/conf.d]# cat proxy.conf
upstream web_pools {
server 172.16.1.7;
server 172.16.1.8;
}
server {
listen 80;
server_name (www|bbs).mysun.com ;
location / {
proxy_pass http://web_pools;
include proxy_params;
}
}
3.测试并重启nginx
nginx -t
systemctl restart nginx
4.lb01的keepalived配置
[root@lb01 ~]# cat /etc/keepalived/keepalived.conf
global_defs {
router_id lb01
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 50
priority 150
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.0.3
}
}
5.lb02的keepalived配置
[root@lb02 ~]# cat /etc/keepalived/keepalived.conf
global_defs {
router_id lb02
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 50
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.0.3
}
}
6.nginx配置(WEB服务器)
1.web服务器配置:注意!两台web服务器配置一模一样
[root@web01 ~]# cat /etc/nginx/conf.d/www.conf
server {
listen 80;
server_name www.mysun.com;
location / {
root /code;
index www.html;
}
}
2.写入测试文件
echo "$(hostname)" >/code/index.html
第六节: 防脑裂脚本
1.问题现象一:后端Nginx挂了
1.nginx挂了,但是keep还活着
2.问题解决思路:
1.编写一个脚本解决nginx挂了问题:
- 启动nginx
- 如果启动2次都失败了,停掉自己的keepalived
2.keepalived定时去调用这个脚本
3.实现:
1.命令如何实现
systemctl start nginx
2.检查nginx进程
[root@lb01 ~]# ps -C nginx --no-header|wc -l #开启了nginx服务
2
[root@lb01 ~]#ps -C nginx --no-header|wc -l #关闭了nginx服务
0
脚本内容:
[root@lb01 ~]# cat check_web.sh
#!/bin/bash
nginx_status=$(ps -C nginx --no-header|wc -l)
if [[ ${nginx_status} == 0 ]]
then
systemctl start nginx &> /dev/null
sleep 1
nginx_status=$(ps -C nginx --no-header|wc -l)
if [[ ${nginx_status} == 0 ]]
then
systemctl stop keepalived
fi
fi
keepalived调用脚本:
[root@lb01 ~]# cat /etc/keepalived/keepalived.conf
global_defs {
router_id lb01
}
vrrp_script check_web {
script "/server/scripts/check_web.sh"
interval 5
weight 50
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 50
priority 150
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.0.3
}
track_script {
check_web
}
}
1.问题现象二:脑裂问题
- lb01和lb02上面都有Vip
2.问题解决思路
1.对面的MASTER的Nginx还活着
curl -I -s -w "%{http_code}\n" -o /dev/null 10.0.0.5
返回状态码:200
2.但是我又有了VIP
ip a |grep "10.0.0.3"|wc -l
3.停掉自己的nginx和keepalived(我就把自己干掉)
systemctl stop nginx
systemctl stop keepalived
脚本内容:
[root@lb02 /server/scripts]# cat check_vip.sh
#!/bin/bash
master_status=$(curl -I -s -w "%{http_code}\n" -o /dev/null 10.0.0.5)
my_vip=$(ip a |grep "10.0.0.3"|wc -l)
if [ ${master_status} == 200 -a ${my_vip} == 1 ]
then
systemctl stop nginx
systemctl stop keepalived
fi
keepalived配置:
[root@lb02 ~]# cat /etc/keepalived/keepalived.conf
global_defs {
router_id lb02
}
vrrp_script check_web {
script "/server/scripts/check_web.sh"
interval 5
weight 50
}
vrrp_script check_vip {
script "/server/scripts/check_vip.sh"
interval 5
weight 50
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 50
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.0.3
}
track_script {
check_web
check_vip
}
}