目录
[1.1 什么是keepalived](#1.1 什么是keepalived)
[1.2 什么是VRRP协议](#1.2 什么是VRRP协议)
[二、Keepalived 部署](#二、Keepalived 部署)
[2.1 keepalived 简介](#2.1 keepalived 简介)
[2.2 keepalived 框架](#2.2 keepalived 框架)
[2.3 实验环境搭建](#2.3 实验环境搭建)
[2.4 Keepalived 安装](#2.4 Keepalived 安装)
[2.5 Keepalived 配置](#2.5 Keepalived 配置)
[2.5.1 虚拟路由配置](#2.5.1 虚拟路由配置)
[2.5.2 独立日志](#2.5.2 独立日志)
[2.5.3 独立子配置文件](#2.5.3 独立子配置文件)
[三、Keepalived 的应用示例](#三、Keepalived 的应用示例)
[3.1 VIP单播配置](#3.1 VIP单播配置)
[3.2 邮件配置](#3.2 邮件配置)
[3.3 通知脚本](#3.3 通知脚本)
[3.4 master/master 的 Keepalived 双主架构](#3.4 master/master 的 Keepalived 双主架构)
[3.5 实现IPVS的高可用性](#3.5 实现IPVS的高可用性)
一、高可用集群
1.1 什么是keepalived
keepalived是集群管理中保证集群高可用的一个服务软件,用来防止单点故障。基于VRRP(冗余协议)基础之上提高系统高用性、降低平均故障时间,减少资源耗费的高可用集群。
通常情况下是将两台服务器组成一个热备组,同一时间热备组内只有一台主服务器(master)提供服务,同时master会虚拟出一个共用IP地址(VIP),这个VIP只存在master上并对外提供服务。
如果keepalived检测到master宕机或服务故障,备服务器会自动接管VIP成为master,keepalived并将master从热备组移除,当master恢复后,会自动加入到热备组,默认再抢占成为master,起到故障转移功能。减少资源损耗。
1.2 什么是VRRP协议
VRRP全称 Virtual Router Redundancy Protocol,即虚拟路由冗余协议。对于VRRP,需要清楚知道的是:
1)VRRP是用来实现路由器冗余的协议。
2)VRRP协议是为了消除在静态缺省路由环境下路由器单点故障引起的网络失效而设计的主备模式的协议,使得发生故障而进行设计设备功能切换时可以不影响内外数据通信,不需要再修改内部网络的网络参数。
3)VRRP协议需要具有IP备份,优先路由选择,减少不必要的路由器通信等功能。
4)VRRP协议将两台或多台路由器设备虚拟成一个设备,对外提供虚拟路由器IP(一个或多个)。然而,在路由器组内部,如果实际拥有这个对外IP的路由器如果工作正常的话,就是master,或者是通过算法选举产生的,MASTER实现针对虚拟路由器IP的各种网络功能,如ARP请求,ICMP,以及数据的转发等,其他设备不具有该IP,状态是BACKUP。除了接收MASTER的VRRP状态通告信息外,不执行对外的网络功能,当主级失效时,BACKUP将接管原先MASTER的网络功能。
5)VRRP协议配置时,需要配置每个路由器的虚拟路由ID(VRID)和优先权值,使用VRID将路由器进行分组,具有相同VRID值的路由器为同一个组,VRID是一个0-255的整整数,;同一个组中的路由器通过使用优先权值来选举MASTER。,优先权大者为MASTER,优先权也是一个0-255的正整数。
二、Keepalived 部署
2.1 keepalived 简介
是VRRP的软件实现,为了实现高可用ipvs服务
功能:
- 基于vrrp协议完成地址流动
- 为vip地址所在的节点生成ipvs规则(在配置文件中预先定义)
- 为ipvs集群的各RS做健康状态检测
- 基于脚本调用接口完成脚本中定义的功能,进而影响集群事务,以此支持nginx、haproxy等服务
2.2 keepalived 框架

|-------------------|------------------------|
| 参数 | 作用 |
| vrrp stack | VIP消息通告 |
| checkers | 监测real server |
| system call | 实现 vrrp 协议状态转换时调用脚本的功能 |
| SMTP | 邮件组件 |
| IPVS wrapper | 生成IPVS规则 |
| Netlink Reflector | 网络接口 |
| WatchDog | 监控进程 |
[用户核心组件]
|------|--------------------------------------|
| 名称 | 作用 |
| 控制组件 | 提供keepalived.conf的解析器,完成Keepalived配置 |
|--------|-----------------------------------|
| 名称 | 作用 |
| 内存管理组件 | 为某些通用的内存管理功能(例如分配,重新分配,发布等)提供访问权限 |
|-------|-------------------|
| 名称 | 作用 |
| I0复用器 | 针对网络目的而优化的自己的线程抽象 |
2.3 实验环境搭建

注意事项:
- 防火墙和selinux必须关闭
- 各节点时间必须同步
根据上图将IP配置好,在rs1和rs2上安装httpd,并启动,到此为止,基本环境我们就搭建好了
[root@rs1 ~]# yum install httpd -y
[root@rs1 ~]# systemctl enable --now httpd
Created symlink from /etc/systemd/system/multi-user.target.wants/httpd.service to /usr/lib/systemd/system/httpd.service.
[root@rs2 ~]# yum install httpd -y
[root@rs2 ~]# systemctl enable --now httpd
Created symlink from /etc/systemd/system/multi-user.target.wants/httpd.service to /usr/lib/systemd/system/httpd.service.
2.4 Keepalived 安装
-
安装Keepalived(在 ka1 和 ka2上)
[root@k1 ~]# yum install keepalived -y
[root@k2 ~]# yum install keepalived -y

2.5 Keepalived 配置
2.5.1 虚拟路由配置
全局预览

|-----------------------|---------------------------------------------------------|
| 参数 | 解释 |
| uth_pass 1111 | 共享密钥,前八位有效,建议六位 |
| priority 100/80 | 优先级,范围:1-254;值越大优先级越高 |
| virtual_router_id 100 | 同属一个虚拟机的多个keepalived结点必须相同,我设定了100 |
| advert_int 1 | vrrp 通告的时间间隔,默认 1s |
| virtual_ipaddress | 虚拟IP,自己设定。指定 VIP ,不指定网卡,默认为 eth0, 注意:不指定 /prefix, 默认 32 |
1、查看依赖文件
[root@k1 ~]# rpm -ql keepalived

2、打开主配置文件 /etc/keepalived/keepalived.conf 进行编辑
[root@k1 ~]# vim /etc/keepalived/keepalived.conf

3、修改完成后,启动服务
[root@k1 ~]# systemctl enable --now keepalived.service
Created symlink from /etc/systemd/system/multi-user.target.wants/keepalived.service to /usr/lib/systemd/system/keepalived.service.

4、在主配置文件中设置vrrp

5、重启k1中的keepalived服务
[root@k1 ~]# systemctl restart keepalived.service
6、这里偷个懒,直接将k1配置好的文件复制到k2
[root@k1 ~]# scp /etc/keepalived/keepalived.conf [email protected]:/etc/keepalived/keepalived.conf

7、在k2中修改一下优先级(priority)
[root@k2 ~]# vim /etc/keepalived/keepalived.conf

8、在k2启动keepalived服务
[root@k2 ~]# systemctl enable --now keepalived.service

9、现在进行测试,在k1中抓包,看能否获取到组播。因为在前面的配置文件中,我给k1设置的优先级为100,k2优先级为80,在主机k1没有出现故障的情况下,抓包获取到的组播应该是k1的包
[root@k1 ~]# tcpdump -i eth0 -nn host 224.0.0.18

10、现在我将k1的keepalived服务停止,模拟k1出现故障的状态,再次进行抓包操作,可以看到获取到的是k2的包
[root@k1 ~]# systemctl stop keepalived.service
[root@k1 ~]# tcpdump -i eth0 -nn host 224.0.0.18

11、再次打开k1的keepalived服务,就可以看到抓取的包恢复成k1了

2.5.2 独立日志
1、在 k1 和 k2 中,进入主配置文件,并做以下修改
[root@k1 ~]# vim /etc/keepalived/keepalived.conf
[root@k2 ~]# vim /etc/keepalived/keepalived.conf

2、进入 k1和 k1 的 /etc/sysconfig/keepalived 编写日志级别,这里注意日志级别范围是0~7
[root@k1 ~]# vim /etc/sysconfig/keepalived
[root@k1 ~]# cat /etc/sysconfig/keepalived
KEEPALIVED_OPTIONS="-D -S 6"
[root@k2 ~]# vim /etc/sysconfig/keepalived
[root@k2 ~]# cat /etc/sysconfig/keepalived
KEEPALIVED_OPTIONS="-D -S 6"

3、重启keepalived服务
[root@k1 ~]# systemctl restart keepalived
[root@k2 ~]# systemctl restart keepalived

4、修改配置文件内容,设定采集方法
[root@k1 ~]# vim /etc/rsyslog.conf
[root@k2 ~]# vim /etc/rsyslog.conf

5、重启rsyslog.conf
[root@k1 ~]# systemctl restart rsyslog.service
[root@k2 ~]# systemctl restart rsyslog.service

6、查看日志
[root@k1 ~]# ll /var/log/keepalived.log
-rw------- 1 root root 4766 8月 12 13:38 /var/log/keepalived.log

2.5.3 独立子配置文件
建立文件,并在/etc/keepalived/conf.d/172.25.254.100.conf中添加以下内容
k1和k2一样的操作


三、Keepalived 的应用示例
3.1 VIP单播配置
- Keepalived 的 VRRP(Virtual Router Redundancy Protocol)实现支持两种模式:组播和单播。
- 组播模式:这是 VRRP 的标准模式,也是 Keepalived 的默认模式。在组播模式中,VRRP 实例将其通告(Advertisement)消息发送到一个特定的组播地址(通常是 224.0.0.18)。所有的 VRRP 实例都监听这个地址,因此它们都可以接收到这些通告消息。这种模式的优点是它不需要知道其他 VRRP 实例的 IP 地址,但是它需要网络设备支持组播。
- 单播模式:在单播模式中,VRRP 实例将其通告消息直接发送到其他 VRRP 实例的 IP 地址。这种模式的优点是它不需要网络设备支持组播,但是它需要在配置中指定其他 VRRP 实例的 IP 地址。
-
默认keepalived主机之间利用多播相互通告消息,会造成网络拥塞,可以替换成单播,减少网络流量
#注意:
#启用vrrp_strict时,不能启用单播,否则服务无法启动
#在所有节点vrrp_instance语句块中设置对方主机的IP,建议设置为专用于对应心跳线网络的地址,而非使
用业务网络
unicast_src_ip <IPADDR> #指定发送单播的源IP
unicast_peer {
<IPADDR> #指定接收单播的对方目标主机IP
1、在主机master k1中对主配置文件做以下修改

2、在k1中进行单播处理,指向172.25.254.20

3、在k2中进行单播处理,指向172.25.254.10

4、抓包查看单播效果
[root@k1 ~]# tcpdump -i eth0 -nn src host 172.25.254.10 and dst 172.25.254.20

[root@k2 ~]# tcpdump -i eth0 -nn src host 172.25.254.20 and dst 172.25.254.10

3.2 邮件配置
1、首先在浏览器登录自己的qq邮箱,并获取授权码
2、在k1和k2中安装mail
[root@k1 ~]# yum install mailx -y
[root@k2 ~]# yum install mailx -y
3、进入配置文件添加以下内容


4、发送测试邮件
root@k1 ~]# echo hello world | mail -s test [email protected]
[root@k2 ~]# echo test | mail -s test [email protected]
5、查看qq邮箱,收到邮件

3.3 通知脚本
1、在k1/k2中的keepalived结点配置如下
[root@k1 ~]# vim /etc/keepalived/mail.sh
[root@k1 ~]# cat /etc/keepalived/mail.sh
#!/bin/bash
mail_dst="[email protected]"
send_message()
{
mail_sub="$HOSTNAME to be $1 vip move"
mail_msg="`date +%F\ %T`:vrrp move $HOSTNAME chage $1"
echo $mail_msg | mail -s "$mail_sub" $mail_dst
}
case $1 in
master)
send_message master
;;
backup)
send_message backup
;;
fault)
send_message fault
;;
*)
;;
esac
[root@k2 ~]# vim /etc/keepalived/mail.sh
[root@k2 ~]# cat /etc/keepalived/mail.sh
mail_dst="[email protected]"
send_message()
{
mail_sub="$HOSTNAME to be $1 vip move"
mail_msg="`date +%F\ %T`:vrrp move $HOSTNAME chage $1"
echo $mail_msg | mail -s "$mail_sub" $mail_dst
}
case $1 in
master)
send_message master
;;
backup)
send_message backup
;;
fault)
send_message fault
;;
*)
;;
esac
2、赋权限
[root@k1 ~]# chmod +x /etc/keepalived/mail.sh
[root@k2 ~]# chmod +x /etc/keepalived/mail.sh
3、在主配置文件中添加以下内容

4、重启keepalived服务
[root@k1 ~]# systemctl restart keepalived.service
[root@k2 ~]# systemctl restart keepalived.service
5、在qq邮箱中查看邮件

6、关闭k1的 keepalived服务,在浏览器中查看邮件,可以发现发送主机变成了k2

3.4 master/master 的 Keepalived 双主架构
- master/slave的单主架构,同一时间只有一个Keepalived对外提供服务,此主机繁忙,而另一台主机却 很空闲,利用率低下,可以使用master/master的双主架构,解决此问题。
- master/master 的双主架构: 即将两个或以上VIP分别运行在不同的keepalived服务器,以实现服务器并行提供web访问的目的,提高服务器资源利用率。
1、在master k1中配置


2、在master k2中配置


3、分别重启keepalived服务
[root@k1 ~]# systemctl restart keepalived.service
[root@k2 ~]# systemctl restart keepalived.service
4、在两个master主机中分别查看ip


5、停用master k1的 keepalived 服务,查看master k1的ip

3.5 实现IPVS的高可用性
3.5.1 IPVS相关配置
- 配置结构
virtual_server IP port {
...
real_server {
...
}
real_server {
...
}
...
}
- 定义格式
- virtual_server IP port 定义虚拟主机IP地址及其端口
- virtual_server fwmark int ipvs的防火墙打标,实现基于防火墙的负载均衡集群
- virtual_server group string 使用虚拟服务器组
- 应用层检测
status_code 200 判断上述检测机制为健康状态的响应码,一般为 200
nb_get_retry 3 重试次数
connect_ip 172.25.24.10 向当前RS哪个IP地址发起健康状态检测请求
connect_port 80 向当前RS的哪个PORT发起健康状态检测请求
bindto 172.25.254.10 向当前RS发出健康状态检测请求时使用的源地址
bind_port 80 向当前RS发出健康状态检测请求时使用的源端口
- TCP检测
- connect_ip 172.25.254.10 向当前RS的哪个IP地址发起健康状态检测请求
- connect_port 80 向当前RS的哪个PORT发起健康状态检测请求
- bindto 172.25.254.10 发出健康状态检测请求时使用的源地址
- bind_port 80 发出健康状态检测请求时使用的源端口
- connect_timeout 1 客户端请求的超时时长(等于haproxy的timeout server)
3.5.2 案例
给rs1/rs2配置VIP,我配置的临时ip
[root@rs1 ~]# ip a a 172.24.254.100 dev lo
[root@rs2 ~]# ip a a 172.24.254.100 dev lo
查看


进入rs1和rs2的脚本,修改ARP响应规则
[root@rs1 ~]# vim /etc/sysctl.d/arp.conf
[root@rs1 ~]# cat /etc/sysctl.d/arp.conf
net.ipv4.conf.all.arp_ignore=1
net.ipv4.conf.all.arp_announce=2
net.ipv4.conf.lo.arp_ignore=1
net.ipv4.conf.lo.arp_announce=2
[root@rs2 ~]# vim /etc/sysctl.d/arp.conf
[root@rs2 ~]# cat /etc/sysctl.d/arp.conf
net.ipv4.conf.all.arp_ignore=1
net.ipv4.conf.all.arp_announce=2
net.ipv4.conf.lo.arp_ignore=1
net.ipv4.conf.lo.arp_announce=2
启动脚本


在k1和k2中下载ipvsadm,并修改主配置文件



重启
[root@k1 ~]# systemctl restart keepalived.service
[root@k2 ~]# systemctl restart keepalived.service
测试
[root@k1 ~]# curl 172.25.254.100
RS1 - 172.25.254.110
[root@k1 ~]# curl 172.25.254.100
RS2 - 172.25.254.120
[root@k1 ~]# curl 172.25.254.100
RS1 - 172.25.254.110


3.6 VRRP脚本控制VIP
3.6.1 怎么实现
- vrrp_script:自定义资源监控脚本,vrrp实例根据脚本返回值,公共定义,可被多个实例调用,定义在vrrp实例之外的独立配置块,一般放在global_defs设置块之后。
- 通常此脚本用于监控指定应用的状态。一旦发现应用的状态异常,则触发对MASTER节点的权重减至低于SLAVE节点,从而实现 VIP 切换到 SLAVE 节点。
- track_script :调用 vrrp_script 定义的脚本去监控资源,定义在 VRRP 实例之内,调用事先定义的 vrrp_script
3.6.2 定义 VRRP
vrrp_script <SCRIPT_NAME> 定义一个检测脚本,在 global_defs 之外配置
script <STRING>|<QUOTED-STRING> shell命令或脚本路径
interval <INTEGER> 间隔时间,单位为秒,默认1 秒
timeout <INTEGER> 超时时间
weight <INTEGER:-254..254> 默认为 0, 如果设置此值为负数,当上面脚本返回值为非0 时会将此值与本节点权重相加可以降低本节点权重,即表示fall, 如果是正数,当脚本返回值为0,会将此值与本节点权重相加可以提高本节点权重 即表示 rise, 通常使用负值
fall <INTEGER> 执行脚本连续几次都失败 , 则转换为失败,建议设为 2 以上
rise <INTEGER> 执行脚本连续几次都成功,把服务器从失败标记为成功
user USERNAME [GROUPNAME] 执行监测脚本的用户或组
init_fail 设置默认标记为失败状态,监测成功之后再转换为成功状态
3.6.3 调用VRRP
vrrp_instance test {
... ...
track_script {
check_down
}
}
3.6.4 案例:利用脚本实现主从角色切换
[root@k1 ~]# vim /mnt/check_yee.sh
[root@k1 ~]# cat /mnt/check_yee.sh
#!/bin/bash
[ ! -f "/mnt/yee" ]
[root@k1 ~]# chmod +x /mnt/check_yee.sh #赋权限


3.7 实现HAProxy高可用
在k1和k2中安装 haproxy,并启动
[root@k1 ~]# yum install haproxy -y
[root@k1 ~]# systemctl enable --now haproxy
Created symlink from /etc/systemd/system/multi-user.target.wants/haproxy.service to /usr/lib/systemd/system/haproxy.service.
[root@k2 ~]# yum install haproxy -y
[root@k2 ~]# systemctl enable --now haproxy
Created symlink from /etc/systemd/system/multi-user.target.wants/haproxy.service to /usr/lib/systemd/system/haproxy.service.
在k1和k2的主配置文件/etc/haproxy/haproxy.cfg中做修改
[root@k1 ~]# vim /etc/haproxy/haproxy.cfg
#
listen webserver
mode http
balance roundrobin
bind 172.25.254.100:80
server web1 172.25.254.110:80 check
server web2 172.25.254.120:80 check
[root@k1 ~]# systemctl restart haproxy.service
[root@k2 ~]# vim /etc/haproxy/haproxy.cfg
#
listen webserver
mode http
balance roundrobin
bind 172.25.254.100:80
server web1 172.25.254.110:80 check
server web2 172.25.254.120:80 check
[root@k2 ~]# systemctl restart haproxy.service
检测端口是否打开


在k1和k2的两个节点启用内核参数


在k1中编写检测脚本

修改主配置文件,k1与k2相同

测试
[root@k1 ~]# curl 172.25.254.100
RS1 - 172.25.254.110
[root@k1 ~]# curl 172.25.254.100
RS2 - 172.25.254.120
关闭k1的haproxy,假设出现故障,先进行检测


将ARP响应规则全部改为0

k1和k2做相同操作

再次重启haproxy和keepaliver服务,k1vip丢失,k2拥有两个


测试
[root@k2~]# for i in {1..10}; do curl 172.25.254.100; done
172.25.254.110
172.25.254.120
172.25.254.110
172.25.254.120
172.25.254.110
172.25.254.120
172.25.254.110
172.25.254.120
172.25.254.110
172.25.254.120