一、高可用集群
1.1集群类型
-
LB(Load Balance) 负载均衡:将网络流量分配到多个服务器的技术,旨在优化资源使用、最大化吞吐量、减少响应时间,并避免单个服务器过载
- LVS (Linux Virtual Server): 基于 Linux 内核的负载均衡器,工作在四层(传输层,TCP/UDP),非常适合处理大量流量,常用于高性能场景。
- HAProxy: 一个强大的开源负载均衡器,支持四层(TCP)和七层(HTTP)负载均衡,广泛用于 HTTP 和 TCP 协议的高性能环境。
- Nginx: 作为 Web 服务器、反向代理服务器以及负载均衡器,Nginx 可以在七层(HTTP)进行负载均衡,尤其适合处理静态内容和高并发连接。
-
HA(High Availability )高可用集群:高可用集群通过消除单点故障(SPoF),确保系统在任何组件出现故障时仍能提供服务
- 数据库高可用: 使用数据库复制和故障切换机制(如 MySQL 的主从复制、Galera Cluster),确保数据库服务的高可用性。
- Redis 高可用: 使用 Redis Sentinel 或者 Redis Cluster 来实现高可用性,确保数据的持续可用。
-
SPoF( Single Point of Failure)解决单点故障:在系统设计中,SPoF 指的是任何一个单独的组件的故障会导致整个系统的不可用。
- 通过冗余设计和高可用集群,确保系统没有单点故障
-
HPC(High Performance Computing):高性能集群:通过计算集群并行处理大量计算任务,以实现比单个计算机更高的处理能力。常用于科学研究、工程模拟、大数据处理等领域
1.2 系统可用性
SLA(Service-Level Agreement )服务等级协议(提供服务的企业与客户之间就服务的品质、水准、性能等方面所达成的双方共同认可的协议或契约)
计算公式:A = MTBF(平均故障间隔时间) / (MTBF+MTTR(平均修复时间))
99.95%:(602430)*(1-0.9995)=21.6分钟 #一般按一个月停机时间统计
指标 :99.9%, 99.99%, 99.999%,99.9999%
1.3系统故障
硬件故障:设计缺陷、wear out(损耗)、非人为不可抗拒因素
软件故障:设计缺陷 bug
1.4实现高可用
提升系统高用性的解决方案:降低MTTR- Mean Time To Repair(平均故障时间)
解决方案:建立冗余机制
-
active/passive 主/备
-
active/active 双主
-
active --> HEARTBEAT --> passive
-
active <–> HEARTBEAT <–> active
- active/passive 主/备
- 定义: 这是最基本的冗余机制之一,其中一个节点处于“Active”(活动)状态,处理所有的请求,而另一个节点处于“Passive”(被动)状态,只在Active节点发生故障时接管工作。
- Active --> HEARTBEAT --> Passive: 在这种模式下,Active节点定期发送心跳信号,Passive节点监控这些信号。如果心跳停止(通常是因为Active节点故障),Passive节点会自动接管。
- active/active 双主
- 定义: 两个或多个节点同时处于“Active”状态,并且都参与处理请求。如果其中一个节点发生故障,其他节点继续工作,而不会影响服务的可用性。
- Active <–> HEARTBEAT <–> Active: 两个Active节点互相发送心跳信号,同时处理流量。如果其中一个节点故障,另一个节点可以无缝接管。
1.5.VRRP – 虚拟路由冗余协议
VRRP(Virtual Router Redundancy Protocol)虚拟路由冗余协议,用于提高网络中的路由器的可靠性和可用性。通过允许多个路由器共享一个虚拟IP地址,VRRP可以确保当一个路由器出现故障时,网络流量能够自动切换到另一个路由器,而不会中断网络服务。
-
主要用于解决静态网关单点风险
- 物理层:路由器、三层交换机
- 软件层:keepalived
-
VRRP的工作过程图示
- 客户端通过互联网访问该高可用集群提供的服务
- 通过keepalive设备时,如果当前的主设备发生故障,备份设备将通过接管虚拟 IP 地址和服务请求,确保服务的高可用性和连续性。
- 主设备将请求分发给位于后端的真实服务器集群(如Real Server 1和Real Server 2)。这些服务器处理请求并将响应返回给客户端。
1.5.1 VRRP相关术语
-
虚拟路由器:Virtual Router
-
虚拟路由器标识:VRID(0-255),唯一标识虚拟路由器
-
VIP:Virtual IP
-
VMAC:Virutal MAC (00-00-5e-00-01-VRID)
-
物理路由器:
- master:主设备
- backup:备用设备
- priority:优先级 (0-255)
1.5.2 VRRP相关技术
-
通告:心跳,优先级等;周期性
-
工作方式:抢占式,非抢占式,延迟抢占
-
安全认证:
-
无认证
-
简单字符认证:预共享密钥
-
MD5
-
-
工作模式:
-
主/备:单虚拟路由器
-
主/主:主/备(虚拟路由器1),备/主(虚拟路由器2)
主机1和主机2为两个不同业务系统拥有两个不同的VIP,并且主1/主2 设备互为备用,当一台主机出现问题后,出现问题主机的VIP会发到另一台主机中,直至修复完成,恢复初始。
-
二、Keepalived高可用集群的部署
2.1Keepalived的简介
Keepalived 是一个用于Linux系统的高可用性(HA)解决方案,主要用于负载均衡器的故障切换和健康检查。它最常用于配合 LVS(Linux Virtual Server)
,确保在主服务器发生故障时,服务可以无缝地切换到备用服务器,保持系统的高可用性。
vrrp 协议的软件实现,原生设计目的为了高可用 ipvs服务
官网:http://keepalived.org/
功能:
-
基于vrrp协议完成地址流动
-
为vip地址所在的节点生成ipvs规则(在配置文件中预先定义)
-
为ipvs集群的各RS做健康状态检测
-
基于脚本调用接口完成脚本中定义的功能,进而影响集群事务,以此支持nginx、haproxy等服务
2.2Keepalived架构
官方文档:
https://keepalived.org/doc/
http://keepalived.org/documentation.html
-
用户空间核心组件:
- vrrp stack:VIP消息通告
- checkers:监测real server
- system call:实现 vrrp 协议状态转换时调用脚本的功能
- SMTP:邮件组件
- IPVS wrapper:生成IPVS规则
- Netlink Reflector:网络接口
- WatchDog:监控进程
-
控制组件:提供keepalived.conf 的解析器,完成Keepalived配置
-
IO复用器:针对网络目的而优化的自己的线程抽象
-
内存管理组件:为某些通用的内存管理功能(例如分配,重新分配,发布等)提供访问权限
2.3Keepalived的环境部署
2.3.1环境设备
主机 | IP | VIP | 角色 |
---|---|---|---|
Client | 172.25.254.0.30 | null | 客户端(测试机) |
KA1 | 172.25.254.0.40 | 虚拟IP:172.25.254.100 | keepalive |
KA2 | 172.25.254.0.50 | 虚拟IP:172.25.254.100 | keepalive |
RealServer1 | 172.25.254.110 | null | 真实服务器(RS) |
RealServer2 | 172.25.254.120 | null | 真实服务器(RS) |
注意:以下所有案例的操作环境为Rhel7.9
2.3.2设备部署图示
- 各节点时间必须同步:ntp, chrony
- 关闭防火墙及SELinux
- 各节点之间可通过主机名互相通信:非必须
- 建议使用/etc/hosts文件实现:非必须
- 各节点之间的root用户可以基于密钥认证的ssh服务完成互相通信:非必须
2.3.3 设置主机及相关配置
主机网卡都设置为NAT模式,配置网络,使其全部都能ping通
-
client
[root@client ~]# vim /etc/sysconfig/network-scripts/ifcfg-eth0 # 进入网络配置文件 DEVICE=eth0 ONBOOT=yes BOOTPROTO=none IPADDR1=172.25.254.30 NETMASK1=255.255.255.0 DNS1=114.114.114.114 GATEWAY1=172.25.254.2 NAME=eth0 [root@client ~]# systemctl stop firewalld # 关闭防火墙 [root@client ~]# systemctl mask firewalld # 将防火墙写入null永久关闭 [root@client ~]# setenforce 0 # 设置selinux为宽容模式
-
Keepalived
# KA1 [root@ka1 ~]# vim /etc/sysconfig/network-scripts/ifcfg-eth0 # 进入网络配置文件 DEVICE=eth0 ONBOOT=yes BOOTPROTO=none IPADDR1=172.25.254.40 NETMASK1=255.255.255.0 DNS1=114.114.114.114 GATEWAY1=172.25.254.2 NAME=eth0 [root@ka1 ~]# systemctl stop firewalld # 关闭防火墙 [root@ka1 ~]# systemctl mask firewalld # 将防火墙写入null永久关闭 [root@ka1 ~]# setenforce 0 # 设置selinux为宽容模式 # KA2 [root@ka2 ~]# vim /etc/sysconfig/network-scripts/ifcfg-eth0 # 进入网络配置文件 DEVICE=eth0 ONBOOT=yes BOOTPROTO=none IPADDR1=172.25.254.50 NETMASK1=255.255.255.0 DNS1=114.114.114.114 GATEWAY1=172.25.254.2 NAME=eth0 [root@ka2 ~]# systemctl stop firewalld # 关闭防火墙 [root@ka2 ~]# systemctl mask firewalld # 将防火墙写入null永久关闭 [root@ka2 ~]# setenforce 0 # 设置selinux为宽容模式
-
RealServer
# realserver1 [root@realserver1 ~]# vim /etc/sysconfig/network-scripts/ifcfg-eth0 # 进入网络配置文件 DEVICE=eth0 ONBOOT=yes BOOTPROTO=none IPADDR1=172.25.254.110 NETMASK1=255.255.255.0 DNS1=114.114.114.114 GATEWAY1=172.25.254.2 NAME=eth0 [root@realserver1 ~]# systemctl stop firewalld # 关闭防火墙 [root@realserver1 ~]# systemctl mask firewalld # 将防火墙写入null永久关闭 [root@realserver1 ~]# setenforce 0 # 设置selinux为宽容模式 # 配置realserver1的apache服务 [root@realserver1 ~]# yum install httpd -y # 下载apcahe服务 [root@realserver1 ~]# echo realserver1-172.25.254.110 > /var/www/html/index.html # 写入内容到httpd的发布目录 [root@realserver1 ~]# systemctl enable --now httpd # 设置立即并在开机时启动apache服务 # realserver2 [root@ka2 ~]# vim /etc/sysconfig/network-scripts/ifcfg-eth0 # 进入网络配置文件 DEVICE=eth0 ONBOOT=yes BOOTPROTO=none IPADDR1=172.25.254.120 NETMASK1=255.255.255.0 DNS1=114.114.114.114 GATEWAY1=172.25.254.2 NAME=eth0 [root@realserver2 ~]# systemctl stop firewalld # 关闭防火墙 [root@realserver2 ~]# systemctl mask firewalld # 将防火墙写入null永久关闭 [root@realserver2 ~]# setenforce 0 # 设置selinux为宽容模式 # 配置realserver2的apache服务 [root@realserver2 ~]# yum install httpd -y # 下载apcahe服务 [root@realserver2 ~]# echo realserver1-172.25.254.110 > /var/www/html/index.html # 写入内容到httpd的发布目录 [root@realserver2 ~]# systemctl enable --now httpd # 设置立即并在开机时启动apache服务 # 测试 [root@client ~]# curl 172.25.254.110 realserver1-172.25.254.110 [root@client ~]# curl 172.25.254.120 realserver2-172.25.254.120
2.4.Keepalived安装与配置
2.4.1Keepalived安装
# 在两台Keepalive中安装keepalive
[root@KA1 ~]# dnf install keepalived -y # 下载安装keepalive
[root@KA1 ~]# systemctl start keepalived # 开启keepalive
[root@KA1 ~]# ps axf | grep keepalived # 查看与 Keepalived 相关的进程
注:RHEL7中可能会遇到一下bug
systemctl restart keepalived #新配置可能无法生效 systemctl stop keepalived;systemctl start keepalived #无法停止进程,需要 kill 停 止
2.4.2Keepalived的相关文件
[root@ka1 ~]# rpm -ql keepalived # 查看keppalive的相关文件
/etc/keepalived -- 主程序文件
/etc/keepalived/keepalived.conf -- 主配置文件
/etc/sysconfig/keepalived -- Unit File的环境配置文件
/usr/share/doc/keepalived/ -- 配置文件示例
/lib/systemd/system/keepalived.service -- Unit File
2.5Keepalived配置
2.5.1配置文件组成部分
配置文件:/etc/keepalived/keepalived.conf
配置文件组成
-
GLOBAL CONFIGURATION
Global definitions: 定义邮件配置,route_id,vrrp配置,多播地址等
-
VRRP CONFIGURATION
VRRP instance(s): 定义每个vrrp虚拟路由器
-
LVS CONFIGURATION
Virtual server group(s)
Virtual server(s): LVS集群的VS和RS
2.5.2配置语法说明
- 查看keepalive的帮助文档
man 5 keepalived.conf
2.5.2.1全局配置
[root@ka1 ~]# cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
1234567891@qq.com # keepalived 发生故障切换时邮件发送的目标邮箱,可以按行区分写多个
}
notification_email_from keepalived@HaHa.org # 发邮件的地址
smtp_server 127.0.0.1 # 邮件服务器地址
smtp_connect_timeout 30 # 邮件服务器连接timeout
router_id ka2.HaHa.org # 每个keepalived主机唯一标识
# 建议使用当前主机名,但多节点重名不影响
vrrp_skip_check_adv_addr # 对所有通告报文都检查,会比较消耗性能
#启用此配置后,如果收到的通告报文和上一个报文是同一个路由器,则跳过检查,默认值为全检查
vrrp_strict #严格遵循vrrp协议
#启用此项后以下状况将无法启动服务:
#1.无VIP地址
#2.配置了单播邻居
#3.在VRRP版本2中有IPv6地址
#建议不加此项配置
vrrp_garp_interval 0 # 报文发送延迟,0表示不延迟
vrrp_gna_interval 0 # 消息发送延迟
vrrp_mcast_group4 224.0.0.18 # 指定组播IP地址范围
}
2.5.2.2虚拟路由配置
[root@ka1 ~]# cat /etc/keepalived/keepalived.conf
. . . . . .
vrrp_instance VI_1 {
state MASTER # 设置为主keepalive
interface eth0 # 绑定为当前虚拟路由器使用的物理接口,如:eth0,可以和VIP不在一个网卡
virtual_router_id 100 # 每个虚拟路由器惟一标识,范围:0-255,每个虚拟路由器此值必须唯一
# 否则服务无法启动
# 同属一个虚拟路由器的多个keepalived节点必须相同
# 务必要确认在同一网络中此值必须唯一
priority 100 # 当前物理节点在此虚拟路由器的优先级,范围:1-254
# 值越大优先级越高,每个keepalived主机节点此值不同
advert_int 1 # vrrp通告的时间间隔,默认1s
authentication { # 认证机制
auth_type PASS # AH为IPSEC认证(不推荐),PASS为简单密码(建议使用)
auth_pass 1111 # 预共享密钥,仅前8位有效
# 同一个虚拟路由器的多个keepalived节点必须一样
}
virtual_ipaddress { # 虚拟IP,生产环境可能指定上百个IP地址
<IPADDR>/<MASK> brd <IPADDR> dev <STRING> scope <SCOPE> label <LABEL>
172.25.254.100 # 指定VIP,不指定网卡,默认为eth0,注意:不指定/prefix,默认32
172.25.254.101/24 dev eth1
172.25.254.102/24 dev eth2 label eth2:1
}
}
2.6Keepalived案例实现
2.6.1Keepalived的全局配置及虚拟路由
-
配置MASTER端
[root@ka1 ~]# cat /etc/keepalived/keepalived.conf ! Configuration File for keepalived global_defs { notification_email { 1234567891@qq.com } notification_email_from keepalived@HaHa.org smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id ka2.HaHa.org vrrp_skip_check_adv_addr vrrp_strict vrrp_garp_interval 0 vrrp_gna_interval 0 vrrp_mcast_group4 224.0.0.18 } vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 100 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 172.25.254.100/24 dev eth0 label eth0:1 } } [root@ka1 ~]# systemctl restart keepalived # 重启keepalive
-
配置BACKUP端
[root@ka2 ~]# cat /etc/keepalived/keepalived.conf ! Configuration File for keepalived global_defs { notification_email { 1234567891@qq.com } notification_email_from keepalived@HaHa.org smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id ka2.HaHa.org vrrp_skip_check_adv_addr vrrp_strict vrrp_garp_interval 0 vrrp_gna_interval 0 vrrp_mcast_group4 224.0.0.18 } vrrp_instance VI_1 { state BACKUP interface eth0 virtual_router_id 100 # 相同id管理同一个虚拟路由 priority 80 # 低优先级 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 172.25.254.100/24 dev eth0 label eth0:1 } } [root@ka2 ~]# systemctl restart keepalived # 重启keepalive
-
测试
# 对比VIP会分配到那台KA,明显KA1的优先级较高,会发到KA1中 [root@ka1 ~]# ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.25.254.40 netmask 255.255.255.0 broadcast 172.25.254.255 . . . eth0:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.25.254.100 netmask 255.255.255.0 broadcast 0.0.0.0 . . . [root@ka2 ~]# ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.25.254.50 netmask 255.255.255.0 broadcast 172.25.254.255 . . .
当ka1宕掉后,备份主机会自动接管该VIP
[root@client ~]# tcpdump -i eth0 -nn host 224.0.0.18 # 捕获并显示接口 eth0 上发往或来自 IP 地址 224.0.0.18 的网络数据包。 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes 22:07:07.063568 IP 172.25.254.40 > 224.0.0.18: VRRPv2, Advertisement, vrid 100, prio 100, authtype simple, intvl 1s, length 20 22:07:08.065045 IP 172.25.254.40 > 224.0.0.18: VRRPv2, Advertisement, vrid 100, prio 100, authtype simple, intvl 1s, length 20 -------------------------------------------------------------------------------------- 当down ka1后,ka2接管VIP数据包从50流向18 [root@ka1 ~]# systemctl stop keepalived -------------------------------------------------------------------------------------- 22:20:41.008034 IP 172.25.254.50 > 224.0.0.18: VRRPv2, Advertisement, vrid 100, prio 80, authtype simple, intvl 1s, length 20 22:20:42.009616 IP 172.25.254.50 > 224.0.0.18: VRRPv2, Advertisement, vrid 100, prio 80, authtype simple, intvl 1s, length 20 当ka1回来时,数据流向恢复正常
2.6.2启用keepalived的日志功能
[root@ka1 ~]# vim /etc/sysconfig/keepalived # 打开Unit File的环境配置文件
14 KEEPALIVED_OPTIONS="-D -S 6" -- 添加指定同步组ID
[root@ka1 ~]# vim /etc/rsyslog.conf # 添加日志收集
72 # Save boot messages also to boot.log
73 local7.* /var/log/boot.log
74 local6.* /var/log/keepalive.log
不需要去创建指定的日志采集文件,重启配置后会自动生成
[root@ka1 ~]# systemctl restart rsyslog # 重启日志采集服务
[root@ka1 ~]# systemctl restart keepalived # 重启keepalive
# 查看日志文件
[root@ka1 ~]# tail -f /var/log/keepalive.log
Aug 12 23:19:47 KA1 Keepalived_healthcheckers[9734]: Removing service [192.168.200.5]:1358 from VS [10.10.10.3]:1358
Aug 12 23:19:47 KA1 Keepalived_healthcheckers[9734]: Lost quorum 1-0=1 > 0 for VS [10.10.10.3]:1358
Aug 12 23:19:47 KA1 Keepalived_healthcheckers[9734]: Remote SMTP server [127.0.0.1]:25 connected.
Aug 12 23:19:47 KA1 Keepalived_healthcheckers[9734]: SMTP alert successfully sent.
Aug 12 23:19:50 KA1 Keepalived_healthcheckers[9734]: Timeout connecting server [192.168.201.100]:443.
Aug 12 23:19:50 KA1 Keepalived_healthcheckers[9734]: Check on service [192.168.201.100]:443 failed after 3 retry.
2.6.3实现独立子配置文件
当生产环境复杂时, /etc/keepalived/keepalived.conf
文件中内容过多,不易管理
将不同集群的配置,比如:不同集群的VIP配置放在独立的子配置文件中利用include 指令可以实现包含
子配置文件
格式:
include /path/file
示例:
[root@ka1 ~]# mkdir /etc/keepalived/conf.d # 创建存放子配置文件目录
# 创建并将虚拟路由配置的内容写入子配置文件
[root@ka1 ~]# vim /etc/keepalived/conf.d/172.25.254.100.conf
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 100
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.25.254.100/24 dev eth0 label eth0:1
}
}
# 在keepalive中配置读取子配置文件的路径
[root@ka1 ~]# vim /etc/keepalived/keepalived.conf
43 include "/etc/keepalived/conf.d/*.conf" -- 相关子配置文件
[root@ka1 ~]# systemctl restart keepalived
# 测试
[root@client ~]# tcpdump -i eth0 -nn host 224.0.0.18
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
23:31:35.817738 IP 172.25.254.40 > 224.0.0.18: VRRPv2, Advertisement, vrid 100, prio 100, authtype simple, intvl 1s, length 20
23:31:36.819107 IP 172.25.254.40 > 224.0.0.18: VRRPv2, Advertisement, vrid 100, prio 100, authtype simple, intvl 1s, length 20
23:31:37.820580 IP 172.25.254.40 > 224.0.0.18: VRRPv2, Advertisement, vrid 100, prio 100, authtype simple, intvl 1s, length 20
注:当配置了子配置文件后,需要将keepalive原主配置文件的虚拟路由配置端注释掉
三、Keepalived企业应用示例
3.1实现master/slave的Keepalived单主架构
- MASTER配置与 BACKUP配置中的配置一致
当正常配置文件时,外部直接访问虚拟路由的VIP是不支持的,因此需要我们手动开启
[root@ka1 ~]# vim /etc/keepalived/keepalived.conf
3 global_defs {
4 notification_email {
5 2895453274@qq.com
6 }
7 notification_email_from keepalived@HaHa.org
8 smtp_server 127.0.0.1
9 smtp_connect_timeout 30
10 router_id ka2.HaHa.org
11 vrrp_skip_check_adv_addr
12 # vrrp_strict # 添加此选项无法访问vip,可以用nft list ruleset查看
# 因此需要将其注释掉
13 vrrp_garp_interval 0
14 vrrp_gna_interval 0
15 vrrp_mcast_group4 224.0.0.18
16 # vrrp_iptables # 或者添加vrrp_iptables
17 }
# 测试
[root@client ~]# ping 172.25.254.100 # 访问VIP
PING 172.25.254.100 (172.25.254.100) 56(84) bytes of data.
64 bytes from 172.25.254.100: icmp_seq=1 ttl=64 time=0.080 ms
64 bytes from 172.25.254.100: icmp_seq=2 ttl=64 time=0.279 ms
或 # 抓包观察
[root@client ~]# tcpdump -i eth0 -nn host 224.0.0.18
注:需要将MASTER和BACKUP同时设置,为防止当一台keppalive宕掉时,另一台接管VIP后,会出现访问不了的情况
3.2抢占模式和非抢占模式
3.2.1非抢占模式 – nopreempt
默认为抢占模式preempt,即当高优先级的主机恢复在线后,会抢占低先级的主机的master角色,这样会使vip在KA主机中来回漂移,造成网络抖动,建议设置为非抢占模式 nopreempt ,即高优先级主机恢复后,并不会抢占低优先级主机的master角色
非抢占模块下,如果原主机down机, VIP迁移至的新主机, 后续也发生down时,仍会将VIP迁移回原主机
注意:要关闭 VIP抢占,必须将各 keepalived 服务器state配置为BACKUP
1.# ka1主机配置
[root@ka1 ~]# vim /etc/keepalived/keepalived.conf
19 vrrp_instance VI_1 {
20 state MASTER
21 interface eth0
22 virtual_router_id 100
23 priority 100 # 优先级高
24 advert_int 1
25 nopreempt # 非抢占模式
26 authentication {
27 auth_type PASS
28 auth_pass 1111
29 }
30 virtual_ipaddress {
31 172.25.254.100/24 dev eth0 label eth0:1
32 }
33 }
[root@ka1 ~]# systemctl restart keepalived
2.# ka2主机配置
[root@ka2 ~]# vim /etc/keepalived/keepalived.conf
19 vrrp_instance VI_1 {
20 state BACKUP
21 interface eth0
22 virtual_router_id 100
23 priority 80 # 优先级低
24 advert_int 1
25 nopreempt # 非抢占模式
26 authentication {
27 auth_type PASS
28 auth_pass 1111
29 }
30 virtual_ipaddress {
31 172.25.254.100/24 dev eth0 label eth0:1
32 }
33 }
[root@ka2 ~]# systemctl restart keepalived
查看VIP:
1.初始查看VIP
# ka1主机
[root@ka1 ~]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.25.254.40 netmask 255.255.255.0 broadcast 172.25.254.255
. . . . . .
eth0:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.25.254.100 netmask 255.255.255.0 broadcast 0.0.0.0
. . . . . .
# ka2主机
[root@ka2 ~]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.25.254.50 netmask 255.255.255.0 broadcast 172.25.254.255
当两台ka主机正常运行时,VIP会先到优先级高的主机中
2.# 关闭ka1后,VIP将会被ka2接管,即使当ka1又重新启动后,VIP还是会在ka2中
# 关闭ka1的keepalive服务
[root@ka1 ~]# systemctl stop keepalived
[root@ka1 ~]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.25.254.40 netmask 255.255.255.0 broadcast 172.25.254.255
. . . . . .
[root@ka2 ~]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.25.254.50 netmask 255.255.255.0 broadcast 172.25.254.255
. . . . . .
eth0:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.25.254.100 netmask 255.255.255.0 broadcast 0.0.0.0
. . . . . .
# 重新打开ka1的keepalive服务
[root@ka1 ~]# systemctl restart keepalived
[root@ka1 ~]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.25.254.40 netmask 255.255.255.0 broadcast 172.25.254.255
[root@ka2 ~]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.25.254.50 netmask 255.255.255.0 broadcast 172.25.254.255
. . . . . .
eth0:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.25.254.100 netmask 255.255.255.0 broadcast 0.0.0.0
. . . . . .
可以看到该VIP不会发生抢占,直至另一台down掉后才会滑向另一台主机
3.2.2抢占延迟模式-- preempt_delay
抢占延迟模式,即优先级高的主机恢复后,不会立即抢回VIP,而是延迟一段时间(默认300s)再抢回VIP
通常:企业中在做非抢占延迟模式时将时间设定为5min左右
preempt_delay # 指定抢占延迟时间为#s,默认延迟300s
注意:需要各keepalived服务器state为BACKUP,并且不要启用 vrrp_strict
1.# ka1主机
[root@ka1 ~]# vim /etc/keepalived/keepalived.conf
19 vrrp_instance VI_1 {
20 state BACKUP
21 interface eth0
22 virtual_router_id 100
23 priority 100 # 优先级高
24 advert_int 1
25 #nopreempt
26 preempt_delay 5s # 抢占延迟5s
27 authentication {
28 auth_type PASS
29 auth_pass 1111
30 }
31 }
[root@ka1 ~]# systemctl restart keepalived
2.# ka2主机
[root@ka2 ~]# vim /etc/keepalived/keepalived.conf
19 vrrp_instance VI_1 {
20 state BACKUP
21 interface eth0
22 virtual_router_id 100
23 priority 80 # 优先级低
24 advert_int 1
25 # nopreempt
26 preempt_delay 5s # 抢占延迟5s
27 authentication {
28 auth_type PASS
29 auth_pass 1111
30 }
31 }
[root@ka2 ~]# systemctl restart keepalived.service
查看VIP:
1.初始查看VIP
# ka1主机
[root@ka1 ~]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.25.254.40 netmask 255.255.255.0 broadcast 172.25.254.255
. . . . . .
eth0:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.25.254.100 netmask 255.255.255.0 broadcast 0.0.0.0
. . . . . .
# ka2主机
[root@ka2 ~]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.25.254.50 netmask 255.255.255.0 broadcast 172.25.254.255
当两台ka主机正常运行时,VIP会先到优先级高的主机中
2.# 关闭ka1后,VIP将会被ka2接管,当ka1又重新启动,5s后VIP会滑回ka1中
# 关闭ka1的keepalive服务
[root@ka1 ~]# systemctl stop keepalived
[root@ka1 ~]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.25.254.40 netmask 255.255.255.0 broadcast 172.25.254.255
. . . . . .
[root@ka2 ~]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.25.254.50 netmask 255.255.255.0 broadcast 172.25.254.255
. . . . . .
eth0:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.25.254.100 netmask 255.255.255.0 broadcast 0.0.0.0
. . . . . .
# 重新打开ka1的keepalive服务,等待5s后
[root@ka1 ~]# systemctl restart keepalived
[root@ka1 ~]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.25.254.40 netmask 255.255.255.0 broadcast 172.25.254.255
. . . . . .
eth0:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.25.254.100 netmask 255.255.255.0 broadcast 0.0.0.0
. . . . . .
# ka2主机
[root@ka2 ~]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.25.254.50 netmask 255.255.255.0 broadcast 172.25.254.255
. . . . . .
3.3VIP单播配置
默认keepalived主机之间利用多播相互通告消息,会造成网络拥塞,可以替换成单播,减少网络流量
注意:启用 vrrp_strict 时,不能启用单播
- 格式:
#在所有节点vrrp_instance语句块中设置对方主机的IP,建议设置为专用于对应心跳线网络的地址,而非使用业务网络
unicast_src_ip <IPADDR> -- 指定发送单播的源IP
unicast_peer {
<IPADDR> -- 指定接收单播的对方目标主机IP
......
}
#启用 vrrp_strict 时,不能启用单播,否则服务无法启动,因此当在配置单播模式时需要将vrrp_strict注释
3.3.1配置keepalived
-
MASTER主机配置
[root@ka1 ~]# vim /etc/keepalived/keepalived.conf global_defs { notification_email { 1234567891@qq.com } notification_email_from keepalived@HaHa.org smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id ka2.HaHa.org vrrp_skip_check_adv_addr # vrrp_strict -- 注释此参数,与vip单播模式冲突 vrrp_garp_interval 0 vrrp_gna_interval 0 vrrp_mcast_group4 224.0.0.18 } vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 100 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 172.25.254.100/24 dev eth0 label eth0:1 } unicast_src_ip 172.25.254.40 # 本机IP unicast_peer { 172.25.254.50 # 指向对方主机IP # 如果有多个keepalived,再加其它节点的IP } } [root@ka1 ~]# systemctl restart keepalived
-
BACKUP主机配置
[root@ka2 ~]# vim /etc/keepalived/keepalived.conf global_defs { notification_email { 2895453274@qq.com } notification_email_from keepalived@HaHa.org smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id ka2.HaHa.org vrrp_skip_check_adv_addr #vrrp_strict # 注释此参数,与vip单播模式冲突 vrrp_garp_interval 0 vrrp_gna_interval 0 vrrp_mcast_group4 224.0.0.18 } vrrp_instance VI_1 { state BACKUP interface eth0 virtual_router_id 100 priority 80 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 172.25.254.100/24 dev eth0 label eth0:1 } unicast_src_ip 172.25.254.50 # 本机ip unicast_peer { 172.25.254.40 # 对端主机 } } [root@ka1 ~]# systemctl restart keepalived
-
抓包查看单播效果
# ka1主机 [root@ka1 ~]# tcpdump -i eth0 -nn src host 172.25.254.40 and dst 172.25.254.50 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes 16:09:42.359397 IP 172.25.254.40 > 172.25.254.50: VRRPv2, Advertisement, vrid 100, prio 100, authtype simple, intvl 1s, length 20 16:09:43.359731 IP 172.25.254.40 > 172.25.254.50: VRRPv2, Advertisement, vrid 100, prio 100, authtype simple, intvl 1s, length 20 16:09:44.360174 IP 172.25.254.40 > 172.25.254.50: VRRPv2, Advertisement, vrid 100, prio 100, authtype simple, intvl 1s, length 20 16:09:45.361362 IP 172.25.254.40 > 172.25.254.50: VRRPv2, Advertisement, vrid 100, prio 100, authtype simple, intvl 1s, length 20 # ka2主机 [root@ka2 ~]# tcpdump -i eth0 -nn src host 172.25.254.50 and dst 172.25.254.40 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes 16:10:57.865739 IP 172.25.254.50 > 172.25.254.40: VRRPv2, Advertisement, vrid 200, prio 100, authtype simple, intvl 1s, length 20 16:10:58.866326 IP 172.25.254.50 > 172.25.254.40: VRRPv2, Advertisement, vrid 200, prio 100, authtype simple, intvl 1s, length 20 16:10:59.867192 IP 172.25.254.50 > 172.25.254.40: VRRPv2, Advertisement, vrid 200, prio 100, authtype simple, intvl 1s, length 20 16:11:00.867298 IP 172.25.254.50 > 172.25.254.40: VRRPv2, Advertisement, vrid 200, prio 100, authtype simple, intvl 1s, length 20
3.4Keepalived邮件通知
3.4.1Keepalived通知脚本配置
当keepalived的状态变化时,可以自动触发脚本的执行,比如:发邮件通知用户
默认以用户keepalived_script身份执行脚本
如果此用户不存在,以root执行脚本可以用下面指令指定脚本执行用户的身份
global_defs {
......
script_user <USER>
......
}
3.4.2.1通知脚本类型
-
当前节点成为主节点时触发的脚本
notify_master <STRING>|<QUOTED-STRING>
-
当前节点转为备节点时触发的脚本
notify_backup <STRING>|<QUOTED-STRING>
-
当前节点转为**“失败”状态**时触发的脚本
notify_fault <STRING>|<QUOTED-STRING>
-
通用格式的通知触发机制,一个脚本可完成以上三种状态的转换时的通知
notify <STRING>|<QUOTED-STRING>
-
当停止VRRP时触发的脚本
notify_stop <STRING>|<QUOTED-STRING>
3.4.2.2 创建通知脚本
[root@ka1 ~]# vim /etc/keepalived/mail.sh # 创建新的mial脚本文件
#!bin/bash
mail_dst="1234567891@qq.com"
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
3.4.2.3脚本调用的方法
在Keepalived的主配置文件/etc/keepalived/keepalived.conf 的vrrp_instance VI_1 语句块的末尾加下面行
notify_master "/etc/keepalived/mail.sh master" -- 当 Keepalived切换到 MASTER 状态时,执行 mail.sh脚本,参数 master 会被传递给 mail.sh 脚本,生成通知邮件,告知管理员当前服务器已经成为主节点。
notify_backup "/etc/keepalived/mail.sh backup" -- 当 Keepalived切换到 BACKUP 状态时,执行 mail.sh脚本,参数backup会被传递给 mail.sh 脚本,生成通知邮件,告知管理员当前服务器切换到备用状态。
notify_fault "/etc/keepalived/mail.sh fault" -- 当 Keepalived 检测到故障(如无法访问重要的资源或服务)时,执行mail.sh脚本,参数 fault 会被传递mail.s脚本,生成故障通知邮件,提醒管理员及时处理问题。
3.4.2 邮件配置
在接收端选择使用QQ邮箱进行接收,发送端则为keepalived服务器。
-
在QQ邮箱生成授权码
-
Keepalive服务器配置
1.# 安装邮件发送工具 [root@Ka1 ~]# dnf install mailx -y 2.# 邮箱配置 [root@ka1 ~]# vim /etc/mail.rc -- 对mial的配置文件进行编译 ------------------------------在mail.rc的配置文件中的末尾进行添加-------------------------- set from=1234567891@qq.com -- 设置发件人的电子邮件地址 set smtp=smtp.qq.com -- 腾讯QQ邮箱的SMTP服务器地址,负责处理发送的电子邮件。 set smtp-auth-user=1234567891@qq.com -- 设置用于SMTP服务器身份验证的用户名 set smtp-auth-password=abcsbjgpmbztdgij -- SMTP服务器身份验证的密码,该密码为QQ邮箱中生成 的授权码 set smtp-auth=login -- 指定使用 login 方式进行SMTP身份验证 set ssl-verify=ignore -- 设置忽略SSL证书验证
当多台Keepalived主机时,配置一致。
-
发送邮件进行测试
[root@ka1 ~]# echo 你好!这是keepalived的邮件邮件通知测试! |mail -s test 1234567891@qq.com
3.4.3 实现Keepalived状态切换的邮件通知
# 配置好以上邮件通知邮件配置后,进行以下配置
1.# 在所有的Keepalived节点中配置通知脚本
# ka1节点
# 脚本配置
[root@ka1 ~]# vim /etc/keepalived/mail.sh # 创建新的mial脚本文件
#!bin/bash
mail_dst="1234567891@qq.com"
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@ka1 ~]# chmod +x /etc/keepalived/mail.sh # 添加可执行权限,使文件成为可执行的脚本
# ka2节点
[root@ka2 ~]# touch /etc/keepalived/mail.sh # 创建新mail脚本文件
[root@ka2 ~]# chmod +x /etc/keepalived/mail.sh # 添加可执行权限,使文件成为可执行的脚本
[root@ka1 ~]# scp /etc/keepalived/mail.sh root@172.25.254.50:/etc/keepalived/mail.sh # 在ka1中将配置好的脚本文件远程拷贝到ka2中
2.# 脚本调用
# ka1节点
[root@ka1 ~]# vim /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
. . . . . .
notify_master "/etc/keepalived/mail.sh master"
notify_backup "/etc/keepalived/mail.sh backup"
notify_fault "/etc/keepalived/mail.sh fault"
}
[root@ka1 ~]# systemctl restart keepalived
# ka2节点
[root@ka2 ]# vim /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
. . . . . .
notify_master "/etc/keepalived/mail.sh master"
notify_backup "/etc/keepalived/mail.sh backup"
notify_fault "/etc/keepalived/mail.sh fault"
}
[root@ka2 ]# systemctl restart keepalived
测试:
# 模拟master掉线
[root@ka1 ~]# systemctl restart keepalived
当ka1掉线后,收到通知邮件ka2成为MASTER
# 重新启动master
[root@ka1 ]# systemctl restart keepalived
当ka1恢复为MASTER后,收到通知邮件ka2又为BACKUP
3.5实现MASTER/MASTER的Keepalived双主结构
master/slave的单主架构,同一时间只有一个Keepalived对外提供服务,此主机繁忙,而另一台主机却很空闲,利用率低下,可以使用master/master的双主架构,解决此问题。
- master/master 的双主架构:
即将两个或以上VIP分别运行在不同的keepalived服务器,以实现服务器并行提供web访问的目的,提高服务器资源利用率
配置双主架构,即在原来的主/备架构的基础上,再ka1添加BACKUP模块,在ka2中添加MASTER模块并且添加新的VIP
# ka1主机配置
[root@ka1 ~]# vim /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
state MASTER # 主
interface eth0
virtual_router_id 100
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.25.254.100/24 dev eth0 label eth0:1
}
}
vrrp_instance VI_2{
state BACKUP # 备
interface eth0
virtual_router_id 200 # 设置新的id
priority 80 # 优先级为80
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.25.254.200/24 dev eth0 label eth0:2 # 新的子网卡
}
}
[root@ka1 ~]# systemctl restart keepalived
# ka2主机配置
[root@ka2 ~]# vim /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
state BACKUP # 备
interface eth0
virtual_router_id 100
priority 80
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.25.254.100/24 dev eth0 label eth0:1
}
}
vrrp_instance VI_2 {
state MASTER # 主
interface eth0
virtual_router_id 200
priority 100 # 优先级为100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.25.254.200/24 dev eth0 label eth0:2
}
}
[root@ka1 ~]# systemctl restart keepalived
查看IP:
# ka1主机
[root@ka1 ~]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.25.254.40 netmask 255.255.255.0 broadcast 172.25.254.255
. . . . . .
eth0:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.25.254.100 netmask 255.255.255.0 broadcast 0.0.0.0
. . . . . .
# ka2主机
[root@ka2 ~]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.25.254.50 netmask 255.255.255.0 broadcast 172.25.254.255
. . . . . .
eth0:2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.25.254.200 netmask 255.255.255.0 broadcast 0.0.0.0
. . . . . .
-
若为多节点的舵主架构则需要添加多组虚拟路由配置
实战案例:三个节点的三主架构实现
#第一个节点ka1配置: Vrrp instance 1:MASTER,优先级100 Vrrp instance 2:BACKUP,优先级80 Vrrp instance 3:BACKUP,优先级60 #第二个节点ka2配置: Vrrp instance 1:BACKUP,优先级60 Vrrp instance 2:MASTER,优先级100 Vrrp instance 3:BACKUP,优先级80 #第三个节点ka3配置: Vrrp instance 1:BACKUP,优先级80 Vrrp instance 2:BACKUP,优先级60 Vrrp instance 3:MASTER,优先级100
3.6实现IPVS的高可用性
3.6.1 IPVS相关配置
3.6.1.1 虚拟服务器的配置结构
virtual_server IP port {
. . .
real_server {
. . .
}
real_server {
. . .
}
…
}
3.6.1.2 virtual server(虚拟服务器)的定义格式
virtual_server IP port # 定义虚拟主机IP地址及其端口
virtual_server fwmark int # ipvs的防火墙打标,实现基于防火墙的负载均衡集群
virtual_server group string # 使用虚拟服务器组
3.6.1.3 虚拟服务配置
virtual_server IP port { # VIP和PORT
delay_loop <INT> # 检查后端服务器的时间间隔
lb_algo rr|wrr|lc|wlc|lblc|sh|dh # 定义调度方法
lb_kind NAT|DR|TUN # 集群的类型,注意要大写
persistence_timeout <INT> # 持久连接时长
protocol TCP|UDP|SCTP # 指定服务协议,一般为TCP
sorry_server <IPADDR> <PORT> # 所有RS故障时,备用服务器地址
real_server <IPADDR> <PORT> { # RS的IP和PORT
weight <INT> # RS权重
notify_up <STRING>|<QUOTED-STRING> # RS上线通知脚本
notify_down <STRING>|<QUOTED-STRING> # RS下线通知脚本
HTTP_GET|SSL_GET|TCP_CHECK|SMTP_CHECK|MISC_CHECK { ... } #定义当前主机健康状态检测方法
}
}
#注意:括号必须分行写,两个括号写在同一行,如: }} 会出错
3.6.1.4 应用层检测
应用层检测:HTTP_GET|SSL_GET
HTTP_GET|SSL_GET {
url {
path <URL_PATH> # 定义要监控的URL
status_code <INT> # 判断上述检测机制为健康状态的响应码,一般为 200
}
connect_timeout <INTEGER> # 客户端请求的超时时长, 相当于haproxy的timeout server
nb_get_retry <INT> # 重试次数
delay_before_retry <INT> # 重试之前的延迟时长
connect_ip <IP ADDRESS> # 向当前RS哪个IP地址发起健康状态检测请求
connect_port <PORT> # 向当前RS的哪个PORT发起健康状态检测请求
bindto <IP ADDRESS> # 向当前RS发出健康状态检测请求时使用的源地址
bind_port <PORT> # 向当前RS发出健康状态检测请求时使用的源端口
}
3.6.1.5 TCP监测
传输层检测:TCP_CHECK
TCP_CHECK {
connect_ip <IP ADDRESS> # 向当前RS的哪个IP地址发起健康状态检测请求
connect_port <PORT> # 向当前RS的哪个PORT发起健康状态检测请求
bindto <IP ADDRESS> # 发出健康状态检测请求时使用的源地址
bind_port <PORT> # 发出健康状态检测请求时使用的源端口
connect_timeout <INTEGER> # 客户端请求的超时时长
# 等于haproxy的timeout server
}
3.6.2 IPVS高可用实战案例
3.6.2.1 实现单主的LVS-DR模式
准备web服务器并使用脚本绑定VIP至web服务器lo网卡,若想在测试中查看到两台服务器都下线后,可再设置sorryserver服务器
- 两台后端RS主机配置
1.下载apache服务,写入内容到发布目录
2.使用虚拟网卡添加VIP
3.关闭ARP的响应
重申:需要关闭所有环境下的防火墙以及将Selinux设置为0
# realserver1主机
[root@realserver1 ~]# yum install httpd -y
[root@realserver1 ~]# echo realserver1-172.25.254.110 > /var/www/html/index.html
[root@realserver1 ~]# ip addr add 172.25.254.100/32 dev lo
[root@realserver1 ~]# echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
[root@realserver1 ~]# echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
[root@realserver1 ~]# echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
[root@realserver1 ~]# echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
# realserver2主机
[root@realserver1 ~]# yum install httpd -y
[root@realserver1 ~]# echo realserver2-172.25.254.120 > /var/www/html/index.html
[root@realserver1 ~]# ip addr add 172.25.254.100/32 dev lo
[root@realserver1 ~]# echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
[root@realserver1 ~]# echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
[root@realserver1 ~]# echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
[root@realserver1 ~]# echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
注意:以上的环回VIP以及arp配置为临时设置,若想永久配置需要到相关配置文件进行更改或添加
在RS中进行VIP以及arp响应的永久配置
# 配置lo虚拟环回网卡的VIP [root@realserver1 ~]# vim /etc/sysconfig/network-scripts/ifcfg-lo DEVICE=lo ONBOOT=yes NAME=loopback BOOTPROTO=none IPADDR1=172.25.254.100 NETMASK1=255.255.255.255 DNS1=114.114.114.114 GATEWAY1=172.25.254.2 [root@realserver1 ~]# systemctl restart network # 配置arp响应 [root@realserver1 ~]# sysctl -a | grep arp # 过滤查看arp的相关参数 [root@realserver1 ~]# cat /etc/sysctl.d/arp.conf # 在sysctl的子配置目录下新建配置文件 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@realserver1 ~]# sysctl --system # 加载并应用所有系统级别的内核参数配置文件
当多台RS主机时,配置与以上配置一致
- 配置Keepalived
# 下载LVS服务并在keepaliced中配置策略
# ka1主机
[root@ka1 ~]# yum install ipvsadm -y # 下载LVS服务
[root@ka1 ~]# vim /etc/keepalived/keepalived.conf
virtual_server 172.25.254.100 80 { -- 定义虚拟服务器
delay_loop 6 -- 设置健康检查的循环间隔为 6 秒
lb_algo wrr -- 指定负载均衡算法为加权轮询
lb_kind DR -- 负载均衡的模式为 DR
protocol TCP -- 负载均衡的协议为 TCP
real_server 172.25.254.110 80 { -- 定义后端服务器
weight 1 -- 后端服务器的权重为 1
HTTP_GET { -- 定义HTTP 健康检查方法
url {
path / -- 健康检查将发送一个HTTP GET请求到服务器的根路径 /
status_code 200 -- 期望的HTTP状态码为200(OK),如果服务器返回此状态码,则视为健康。
}
connect_timeout 3 -- 设置连接超时时间为 3 秒
nb_get_retry 2 -- 在连接失败时,重新尝试的次数为 2 次
delay_before_retry 2 -- 设置每次重试之前的延迟时间为 2 秒
}
}
real_server 172.25.254.120 80{
weight 1
HTTP_GET {
url {
path /
status_code 200
}
connect_timeout 3
nb_get_retry 2
delay_before_retry 2
}
}
}
[root@ka1 ~]# systemctl restart keepalived
# ka2主机
[root@ka2 ~]# yum install ipvsadm -y
[root@ka2 ~]# vim /etc/keepalived/keepalived.conf
virtual_server 172.25.254.100 80 {
delay_loop 6
lb_algo wrr
lb_kind DR
protocol TCP
real_server 172.25.254.110 80 {
weight 1
HTTP_GET {
url {
path /
status_code 200
}
connect_timeout 3
nb_get_retry 2
delay_before_retry 2
}
}
real_server 172.25.254.120 80 {
weight 1
HTTP_GET {
url {
path /
status_code 200
}
connect_timeout 3
nb_get_retry 2
delay_before_retry 2
}
}
}
[root@ka2 ~]# systemctl restart keepalived
- 访问测试结果
[root@client ~]# for i in {1..6}; do curl 172.25.254.100; done
realserver1 - 172.25.254.101
realserver2 - 172.25.254.102
realserver1 - 172.25.254.101
realserver2 - 172.25.254.102
realserver1 - 172.25.254.101
realserver2 - 172.25.254.102
[root@rhel7-ka1 ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.25.254.100:80 wrr
-> 172.25.254.110:80 Route 1 0 6
-> 172.25.254.120:80 Route 1 0 6
- 模拟故障
1.# 第一台RS1故障,自动切换至RS2
[root@realserver1 ~]# systemctl stop httpd # 当RS1故障
[root@client ~]# for i in {1..6}; do curl 172.25.254.100; done
# 全部流浪被定向到RS2中
realserver2 - 172.25.254.102
realserver2 - 172.25.254.102
realserver2 - 172.25.254.102
realserver2 - 172.25.254.102
realserver2 - 172.25.254.102
realserver2 - 172.25.254.102
# 查看策略,当RS1出故障时,策略会自动将RS1的策略踢出
[root@ka1 ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.25.254.100:80 wrr
-> 172.25.254.120:80 Route 1 0 12 # RS1被踢出保留RS2
2.# 后端RS服务器都故障,启动Sorry Server
[root@realserver2 ~]#systemctl stop httpd
[root@client ~]# curl 172.25.254.100
sorry server
[root@ka1 ~]# ipvsadm -Ln
3.# 陆续启动RS1 RS2
[root@ka1 ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.25.254.100:80 wrr
-> 172.25.254.110:80 Route 1 0 3
-> 172.25.254.120:80 Route 1 0 9
3.# ka1故障,自动切换至ka2
[root@ka1 ~]# systemctl stop keepalived
[root@ka2 ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.25.254.100:80 wrr
-> 172.25.254.110:80 Route 1 0 0
-> 172.25.254.120:80 Route 1 0 0
3.7 实现其他应用的高可用性VRRP Script
keepalived利用 VRRP Script 技术,可以调用外部的辅助脚本进行资源监控,并根据监控的结果实现优先动态调整,从而实现其它应用的高可用性功能
参考配置文件:/usr/share/doc/keepalived/keepalived.conf.vrrp.localcheck
3.7.1 VRRP Script配置
VRRP Script配置分两步来实现
-
定义脚本
vrrp_script:自定义资源监控脚本,vrrp实例根据脚本返回值,公共定义,可被多个实例调用,定义在vrrp实例之外的独立配置块,一般放在global_defs设置块之后。
通常此脚本用于监控指定应用的状态。一旦发现应用的状态异常,则触发对MASTER节点的权重减至低于SLAVE节点,从而实现 VIP 切换到 SLAVE 节点
vrrp_script <SCRIPT_NAME> { script <STRING>|<QUOTED-STRING> # 此脚本返回值为非0时,会触发下面OPTIONS执行 OPTIONS }
此文件自行建立新的脚本文件,在配置调用脚本文件时将路径填写相应的脚本文件路径即可
-
调用脚本
track_script:调用vrrp_script定义的脚本去监控资源,定义在VRRP实例之内,调用事先定义的vrrp_script
track_script { SCRIPT_NAME_1 SCRIPT_NAME_2 }
此脚本配置在keepalived的主配置
/etc/keepalived/keepalived.conf
文件下进行编写
3.7.1.1 定义VRRP Script
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.7.1.2 调用VRRP Script
vrrp_instance test {
... ...
track_script {
check_down
}
}
3.7.2 VRRP Script实战案例:
3.7.2.1 利用脚本实现主从角色交换
- 配置脚本文件
# 配置脚本文件
[root@ka1 ~]# vim /etc/keepalived/test.sh
#!/bin/bash
[ ! -f "/mnt/haha" ] -- 当检测是否存在该文件时,不存在为0执行脚本,存在不执行脚本
[root@ka1 ~]# chmod +x /etc/keepalived/test.sh
# 检测脚本的返回值
[root@ka1 ~]# sh /etc/keepalived/test.sh # 不存在/mnt/haha文件返回值为0
[root@ka1 ~]# echo $?
0
[root@ka1 ~]# touch /mnt/haha # 存在/mnt/haha文件返回值为1
[root@ka1 ~]# sh /etc/keepalived/test.sh
[root@ka1 ~]# echo $?
1
- 配置调用脚本文件
# 在global_defs { }模块的下一个编写
[root@ka1 ~]# vim /etc/keepalived/keepalived.conf
vrrp_script check_haha{
script "/etc/keepalived/test.sh"
interval 1
weight -30
fall 2
rise 2
timeout 2
}
vrrp_instance VI_1 {
. . . . . .
track_script{
check_haha
}
}
[root@ka1 ~]# systemctl restart keepalived
3.测试
在调用脚本上的过程,当检测到不存在/mnt/haha文件时,返回值为0,不会执行脚本中的weight设置,保持当前MASTER的优先级,VIP会继续存在MASTER中,若存在/mnt/haha文件时,返回值为非0,则执行脚本中的weight,将原本的优先级-脚本中设定的优先级,降低优先级,VIP此时会飘向BACKUP中
# 不存在/mnt/haha文件,VIP存在MASTER主机中
# ka1
[root@ka1 ~]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.25.254.40 netmask 255.255.255.0 broadcast 172.25.254.255
. . . . . .
eth0:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.25.254.100 netmask 255.255.255.0 broadcast 0.0.0.0
. . . . . .
# ka2
[root@ka2 ~]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.25.254.50 netmask 255.255.255.0 broadcast 172.25.254.255
. . . . . .
eth0:2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.25.254.200 netmask 255.255.255.0 broadcast 0.0.0.0
. . . . . .
# 存在/mnt/haha文件,VIP飘向BACKUP主机中
# ka1
[root@ka1 ~]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.25.254.40 netmask 255.255.255.0 broadcast 172.25.254.255
. . . . . .
# ka2
[root@ka2 ~]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.25.254.50 netmask 255.255.255.0 broadcast 172.25.254.255
. . . . . .
eth0:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.25.254.100 netmask 255.255.255.0 broadcast 0.0.0.0
. . . . . .
eth0:2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.25.254.200 netmask 255.255.255.0 broadcast 0.0.0.0
. . . . . .
3.7.2.2 实现Haproxy高可用
若该案例是接着以上3.6.2.1 实现单主的LVS-DR模式
的案例来做的话,需要将其环境还原,否则以下的实验无法进行访问到真实服务器
1.下载并配置haproxy
# ka1主机与ka2主机都需要配置,且两者配置一致
[root@ka1 ~]# yum install haproxy -y
[root@ka1 ~]# vim /etc/haproxy/haproxy.cfg # 在末尾添加以下
listen webcluster
bind 172.25.254.100:80
mode http
balance roundrobin
server web1 172.25.254.110:80 check inter 3 fall 2 rise 5
server web2 172.25.254.120:80 check inter 3 fall 2 rise 5
[root@ka1 ~]# systemctl enable --now haproxy -- 设置立即启动和开机自启
# 测试haproxy的可用
[root@client ~]# for i in {1..2}; do curl 172.25.254.100; done
realserver1-172.25.254.110
realserver2-172.25.254.120
2.配置Keepalived主机
1.# 在两个ka1和ka2两个节点启用内核参数,ka1和ka2的配置一致
[root@ka1 ~]# vim /etc/sysctl.conf
net.ipv4.ip_nonlocal_bind=1
[root@ka1 ~]# sysctl -p # 加载配置的内核参数
[root@ka1 ~]# chmod +X /etc/keepalived/haproxy.sh # 赋予脚本可执行权限
2.# 在Ka1中编写检查脚本
[root@ka1 ~]# vim /etc/keepalived/haproxy.sh
[root@ka1 ~]# cat /etc/keepalived/haproxy.sh
#!/bin/bash
/usr/bin/killall -0 haproxy
3.# 在Ka1和ka2中进行配置并调用脚本文件,ka1和ka2的配置一致
[root@ka1 ~]# vim /etc/keepalived/keepalived.conf
vrrp_script check_haproxy {
script "/etc/keepalived/haproxy.sh"
interval 1
weight -30
fall 2
rise 2
timeout 2
}
vrrp_instance VI_1 {
. . . . . .
track_script{
check_haproxy
}
}
[root@ka1 ~]# systemctl restart keepalived
3.测试
# 在客户端进行循环测试
[root@client ~]# while true
> do
> curl 172.25.254.100;sleep 0.5
> done
realserver1-172.25.254.110
realserver2-172.25.254.120
realserver1-172.25.254.110
# 查看VIP的位置
# ka1
[root@ka1 ~]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.25.254.40 netmask 255.255.255.0 broadcast 172.25.254.255
. . . . . .
eth0:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.25.254.100 netmask 255.255.255.0 broadcast 0.0.0.0
. . . . . .
# ka2
[root@ka2 ~]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.25.254.50 netmask 255.255.255.0 broadcast 172.25.254.255
. . . . . .
eth0:2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.25.254.200 netmask 255.255.255.0 broadcast 0.0.0.0
. . . . . .
# 模拟故障,关闭ka1的keepalived服务
[root@ka1 ~]# systemctl stop keepalived
最后在循环测试中发现,能够继续访问后面的真实服务器,但此时的VIP已经飘向BACKUP主机了