文章目录
- 一、Keepalive基础
- vrrp技术
- Keepalived介绍
- Keepalived架构
- 二、 Keepalived 相关文件
- 配置文件组成
- 全局配置
- 虚拟路由器配置
- 三、配置lvs和keepalive联动
- 服务器架构
- 抢占模式配置
- 配置单播、组播
- 配置通知模块
- 日志功能
- 脑裂现象
- 四、keepalived和nginx联动
- keepalive和其他应用的高可用 VRRP Script
- 实验效果
一、Keepalive基础
vrrp技术
技术原理
通过在冗余网关间共享虚拟MAC和IP地址,保证数据转发时并不是转给某一个具体网关的IP,而是把数据转发给虚拟网关的IP,因此,不论哪一个路由器成为主路由,都不会影响数据通信。通过组播协议对数据端口进行监控,一旦检测数据转发的端口坏掉,主路由器会停发HELLO包,备路由器提升为主路由,实现数据的稳定高效转发。
在VRRP协议中,有两组重要的概念:VRRP路由器和虚拟路由器,主控路由器和备份路由器。VRRP路由器是指运行VRRP的路由器,是物理实体;虚拟路由器是指VRRP协议创建的,是逻辑概念。一组VRRP路由器协同工作,共同构成一台虚拟路由器。该虚拟路由器对外表现为一个具有唯一固定的IP地址和MAC地址的逻辑路由器。处于同一个VRRP组中的路由器具有两种互斥的角色:主控路由器和备份路由器,一个VRRP组中有且只有一台处于主控角色的路由器,可以有一个或者多个处于备份角色的路由器VRRP协议从路由器组中选出一台作为主控路由器,负责ARP解析和转发IP数据包,组中的其他路由器作为备份的角色并处于待命状态,当由于某种原因主控路由器发生故障时,其中的一台备份路由器能在瞬间的时延后升级为主控路由器,由于此切换非常迅速而且不用改变IP地址和MAC地址,故对终端使用者系统是透明的。
VRRP相关术语
- 虚拟路由器:Virtual Router 不是真实存在,虚构出来的。
- 虚拟路由器标识:VRID(0-255),唯一标识虚拟路由器 。
- VIP:Virtual IP 对外提供服务的地址
- VMAC:Virutal MAC 虚拟MAC地址
- 物理路由器:
- master:主设备
- backup:备用设备
- priority:优先级
Keepalived介绍
功能
- 基于vrrp协议完成地址流动
- 为vip地址所在的节点生成ipvs规则(在配置文件中预先定义)
- 为ipvs集群的各RS做健康状态检测
- 基于脚本调用接口完成脚本中定义的功能,进而影响集群事务,以此支持nginx、haproxy等服务。
Keepalived架构
-
用户空间核心组件:
- vrrp stack:虚拟IP消息通告
- checkers:监测后端真实服务器的服务是否存活
- system call:实现 vrrp 协议状态转换时调用脚本的功能
- SMTP:邮件组件(报警邮件)
- IPVS wrapper:生成IPVS规则(直接生成ipvsadm)
- Netlink Reflector:网络接口(让虚拟地址ip地址飘动)
-
WatchDog:监控进程(整个架构是否有问题)
-
控制组件:提供keepalived.conf 的解析器,完成Keepalived配置。
-
IO复用器:针对网络目的而优化的自己的线程抽象。
-
内存管理组件:为某些通用的内存管理功能(例如分配,重新分配,发布等)提供访问权限。
二、 Keepalived 相关文件
配置文件组成
主配置文件:/etc/keepalived/keepalived.conf
-
GLOBAL CONFIGURATION
Global definitions(全局配置):定义邮件配置,route_id ,vrrp配置,组播地址 等 -
VRRP CONFIGURATION
VRRP instance(s):定义vrrp协议中的每个vrrp虚拟路由器的规则,基本信息 -
LVS CONFIGURATION(lvs调度服务器的规则设置)
Virtual server group(s)
Virtual server(s):LVS集群的VS和RS
全局配置
global_defs {notification_email {root@localhost#keepalived 发生故障切换时邮件发送的目标邮箱,可以按行区分写多个root@localhost
2769741114@qq.com }notification_email_from keepalived@localhost #发邮件的地址smtp_server 127.0.0.1 #邮件服务器地址smtp_connect_timeout 30 #邮件服务器连接timeoutrouter_id LVS01#每个keepalived主机唯一标识,建议使用当前主机名,但多节点重名不影响vrrp_skip_check_adv_addr #对所有通告报文都检查,会比较消耗性能,启用此配置后,如果收到的通告报文和上一个报文是同一个路由器,则跳过检查,默认值为全检查
vrrp_strict
#严格遵守VRRP协议,启用此项后以下状况将无法启动服务:1.无VIP地址 2.配置了单播邻居 3.在VRRP版本2中有IPv6地址,开启动此项并且没有配置vrrp_iptables时会自动开启iptables防火墙规则,默认导致VIP无法访问,建议不加此项配置。vrrp_garp_interval 0 #gratuitous ARP messages 免费ARP报文发送延迟,0表示不延迟vrrp_gna_interval 0 #unsolicited NA messages (不请自来)消息发送延迟vrrp_mcast_group4 225.0.0.18#指定组播IP地址范围:224.0.0.0到239.255.255.255,默认值:224.0.0.18 vrrp_iptables #此项和vrrp_strict同时开启时,则不会添加防火墙规则,如果无配置vrrp_strict项,则无需启用此项配置
}
注意:
默认keepalived主机之间利用多播相互通告消息,可能会造成网络拥塞,可以替换成单播,来减少网络流量。
启用vrrp_strict 时,不能启用单播。
虚拟路由器配置
vrrp_instance <STRING> {
#<String>为vrrp的实例名,一般为业务名称配置参数......}
#配置参数:
state MASTER|BACKUP
#当前节点在此虚拟路由器上的初始状态,状态为MASTER或者BACKUP
interface IFACE_NAME
#绑定为当前虚拟路由器使用的物理接口,如:eth0,bond0,br0,可以和VIP不在一个网卡
virtual_router_id VRID
#每个虚拟路由器惟一标识,范围:0-255,每个虚拟路由器此值必须唯一,否则服务无法启动,同属一个虚拟路由器的多个keepalived节点必须相同,务必要确认在同一网络中此值必须唯一
priority 100
#当前物理节点在此虚拟路由器的优先级,范围:1-254,值越大优先级越高,每个keepalived主机节点此值不同
advert_int 1
#vrrp通告的时间间隔,默认1s
authentication {
#认证机制auth_type AH|PASS #AH为IPSEC认证(不推荐),PASS为简单密码(建议使用)auth_pass <PASSWORD> #预共享密钥,仅前8位有效,同一个虚拟路由器的多个keepalived节点必须一样
}
include /etc/keealived/conf.d/*.conf
virtual_ipaddress {
#虚拟IP,生产环境可能指定上百个IP地址<IPADDR>/<MASK> brd <IPADDR> dev <STRING> scope <SCOPE> label <LABEL>192.168.200.100 #指定VIP,不指定网卡,默认为,注意:不指定/prefix,默认为/32192.168.200.101/24 dev eth1 #指定VIP的网卡,建议和interface指令指定的网卡不在一个网卡192.168.200.102/24 dev eth2 label eth2:1 #指定VIP的网卡label ifconfig eth2:1 192.168.200.102/24
}
track_interface {
#配置监控网络接口,一旦出现故障,则转为FAULT状态实现地址转移eth0eth1…
}
三、配置lvs和keepalive联动
服务器架构
整体架构
主keepalived:192.168.232.10
备keepalived:192.168.232.20
web1:192.168.232.30
web2:192.168.232.40
vip:192.168.232.188
客户机:192.168.232.50
1.准备环境
systemctl stop firewalld.service
setenforce 0
yum install epel-release.noarch -y
yum install ipvsadm keepalived -y
#lvs需要安装额外源
2.配置web,选用httpd
配置成功。
3.配置主keepalived
启动lvs
ipvsadm-save > /etc/sysconfig/ipvsadm
systemctl start ipvsadm.service
修改keepalived配置文件:
cd /etc/keepalived/
cp keepalived.conf keepalived.conf.bak
备份
主服务器配置
! Configuration File for keepalivedglobal_defs {notification_email {acassen@firewall.locfailover@firewall.locsysadmin@firewall.loc}notification_email_from Alexandre.Cassen@firewall.locsmtp_server 127.0.0.1修改邮箱指向自己smtp_connect_timeout 30router_id LVS_01本路由器的服务器的名称指定服务器名称主备需要不一样vrrp_skip_check_adv_addr#vrrp_strictvrrp_garp_interval 0vrrp_gna_interval 0
}vrrp_instance VI_1 {
定义VRRP热备实例state MASTER指定服务器类型MASTER为主 BACKUP为备interface ens33修改网卡名称,表示承载VIP地址的物理接口virtual_router_id 51指定虚拟路由器的ID号主备需要一致priority 100设定优先级数字越大优先级越高。advert_int 1通告间隔即心跳线authentication {auth_type PASS认证类型auth_pass 1111修改认证密码,主备需要一样}virtual_ipaddress {192.168.232.188指定群集vip地址,可以是多个}
}virtual_server 192.168.232.188 80 {delay_loop 6健康间隔时间6秒lb_algo rr调度算法轮询lb_kind DRLVS模式为DRpersistence_timeout 0连接保持时间,通常不会为0,这里是因为体现实验效果,改为0。protocol TCP采用TCP协议real_server 192.168.232.30 80 {修改为真实的主机地址以及端口号 weight 1权重为1TCP_CHECK {connect_prot 80检查目标端口connect_timeout 3连接超时nb_get_retry 3重试次数delay_before_retry 3重试间隔时间}}real_server 192.168.232.40 80 {weight 1TCP_CHECK {connect_prot 80connect_timeout 3nb_get_retry 3delay_before_retry 3}
从服务器配置
将主服务器配置远程拷贝至从服务器上。
scp keepalived.conf 192.168.232.20:/etc/keepalived/
12 router_id LVS_02
20 state BACKUP
23 priority 80
至此主从服务器配置完成,还需要将ipv4路由转发设置一下。
vim /etc/sysctl.conf
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.ens33.send_redirects = 0
sysctl -p
主从都需要。
http服务器配置
设置虚拟ip
ifconfig lo:0 192.168.232.188 netmask 255.255.255.255
内核设置
vim /etc/sysctl.conf
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.default.arp_ignore = 1
net.ipv4.conf.default.arp_announce = 2
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2
sysctl -p
设置路由
route add -host 192.168.232.188 dev lo:0
主服务器上效果
备服务器上效果,并没有192.168.232.188这个IP地址
实验效果:
测试负载均衡:
测试keeplived:
在主服务器上停止keepalive。
地址实现漂移。
抢占模式配置
keepalive有三种抢占模式,分别是抢占模式,非抢占模式,延迟抢占模式。
默认是抢占模式,当主节点恢复之后会立即抢占回来,会造成两次网络动荡。这种模式有一定弊端。
非抢占模式配置
必须将keepalived服务器state配置为BACKUP
vrrp_instance VI_1 {state BACKUP #都为BACKUPinterface ens33virtual_router_id 66priority 100 #优先级高advert_int 1nopreempt #添加此行,都为nopreempt
开启抓包后,关闭主机1,再开启主机1,发现并没有切换至主服务器上,非抢占模式配置成功。
tcpdump -i ens33 -nn host 224.0.0.18
延迟抢占,可以避免主节点频繁切换。
preempt_delay 指定抢占延迟时间为#s,默认延迟300s
注意: 需要各keepalived服务器state为BACKUP,并且不要启用 vrrp_strict
state BACKUPinterface ens33virtual_router_id 51priority 100advert_int 1preempt_delay 3
配置单播、组播
单播模式下,Keepalived 节点之间通过单独的 IP 地址进行通信。
优点:
- 更安全,因为只有指定的节点才能收到通信内容。
- 适用于防火墙内部署,因为可以直接使用私有 IP。
- 可以通过配置绑定 IP 地址来指定使用特定网卡进行通信。
缺点:
- 需要手动配置每个节点的对端 IP 地址。
- 当节点数量增加时,配置维护难度会增大。
组播模式下,Keepalived 节点使用一个预定义的组播地址进行通信。
优点:
- 无需手动配置每个节点的对端 IP 地址。
- 当节点数量增加时,配置管理更加简单。
- 可以更方便地跨网段部署 Keepalived。
缺点:
- 需要确保网络环境支持组播功能。
- 组播地址的配置需要小心,避免与其他应用程序冲突。
- 相比单播,组播可能会对网络带宽产生更大的负载。
单播配置
vrrp_instance VI_1 {interface eth0state MASTERpriority 100virtual_ipaddress {192.168.1.100/24}unicast_peer {192.168.1.101192.168.1.102}
}
在这个配置中:
- interface eth0 指定了 VRRP 实例使用的网络接口。
- state MASTER 表示当前节点是主节点。
- priority 100 设置了 VRRP 优先级为 100。
- virtual_ipaddress 定义了虚拟 IP 地址。
- unicast_peer 指定了单播对端 IP 地址列表。
主从两边都需要修改。
组播配置
vrrp_instance VI_1 {interface eth0state MASTERpriority 100virtual_ipaddress {192.168.1.100/24}multicast_group 224.0.0.19
}
必须确保在所有节点上使用相同的组播地址,也要确保是组播地址。
配置通知模块
模拟环境:当主从节点发生变化之后,肯定需要人员去维护,但是如何知道呢?这边展示了利用邮件通知运维人员。
通知脚本
当前节点成为主节点时触发的脚本
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>
邮箱配置
vim /etc/mail.rc
set from=QQ号@qq.com
set smtp=smtp.qq.com
set smtp-auth-user=QQ号@qq.com
set smtp-auth-password=
配置脚本
#!/bin/bash
#
contact='2769741114@qq.com'
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 inmaster)notify master;;
backup)notify backup;;
fault)notify fault;;
*)echo "Usage: $(basename $0) {master|backup|fault}"exit 1;;
esac
keepalived配置文件
vrrp_instance VI_1 {state BACKUPinterface ens33virtual_router_id 51priority 100preempt_delay 30advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {192.168.91.16}notify_master "/opt/keepalive.sh master"notify_backup "/opt/keepalive.sh backup"notify_fault "/opt/keepalive.sh fault"需要调用脚本
}
日志功能
这是keepalive的启动文件
vim /lib/systemd/system/keepalived.service
[Unit]
Description=LVS and VRRP High Availability Monitor
After=syslog.target network-online.target[Service]
Type=forking
PIDFile=/var/run/keepalived.pid
KillMode=process
EnvironmentFile=-/etc/sysconfig/keepalived
ExecStart=/usr/sbin/keepalived $KEEPALIVED_OPTIONS
ExecReload=/bin/kill -HUP $MAINPID[Install]
WantedBy=multi-user.target
打开环境变量的文件
vim /etc/sysconfig/keepalived
KEEPALIVED_OPTIONS="-D -S 6"
vim /etc/rsyslog.conf
ocal6.* /var/log/keepalived.log
然后重启两个服务即可
systemctl restart rsyslog.service
systemctl restart keepalived.service
脑裂现象
什么是脑裂?
在高可用(HA)系统中,当联系2个节点的“心跳线”断开时,本来为一整体、动作协调的HA系统,就分裂成为2个独立的个体。
由于相互失去了联系,都以为是对方出了故障。两个节点上的HA软件像“裂脑人”一样,争抢“共享资源”、争起“应用服务”,就会发生严重后果。共享资源被瓜分、两边“服务”都起不来了;或者两边“服务”都起来了,但同时读写“共享存储”,导致数据损坏。
哪些原因导致脑裂?
- 高可用服务器对之间心跳线链路发生故障,导致无法正常通信。
- 因心跳线坏了(包括断了,老化)。
- 因网卡及相关驱动坏了,ip配置及冲突问题(网卡直连)
- 因心跳线间连接的设备故障(网卡及交换机)
- 高可用服务器上开启了 iptables防火墙阻挡了心跳消息传输。
- 高可用服务器上心跳网卡地址等信息配置不正确,导致发送心跳失败
- 其他服务配置不当等原因,如心跳方式不同,心跳广插冲突、软件Bug等。
- 多组keepalive服务器造成 组播冲突 1.换组播地址 2.改成单播
总之,心跳线的问题。
如何解决keepalived脑裂问题?
在实际生产环境中,我们从以下方面防止脑裂:
1.同时使用串行电缆和以太网电缆连接、同时使用两条心跳线路,这样一条线路断了,另外一条还是好的,依然能传送心跳消息。
2.当检查脑裂时强行关闭一个心跳节点(这个功能需要特殊设备支持,如stonith、fence)相当于备节点接收不到心跳消息,通过单独的线路发送关机命令关闭主节点的电源。
四、keepalived和nginx联动
keepalive和其他应用的高可用 VRRP Script
keepalived利用 VRRP Script 技术,可以调用外部的辅助脚本进行资源监控,并根据监控的结果实现优先动态调整,从而实现其它应用的高可用性功能。可以和任何软件组合形成,高可用的架构。
分两步实现:
定义脚本
vrrp_script:自定义资源监控脚本,vrrp实例根据脚本返回值,公共定义,可被多个实例调用,定义在vrrp实例之外的独立配置块,一般放在global_defs设置块之后。通常此脚本用于监控指定应用的状态。一旦发现应用的状态异常,则触发对MASTER节点的权重减至低于SLAVE节点,从而实现 VIP 切换到 SLAVE 节点。
vrrp_script <SCRIPT_NAME> { #定义一个检测脚本,在global_defs 之外配置script <STRING>|<QUOTED-STRING> #shell命令或脚本路径(注意执行权限) 0 不会执行以下操作, 1 就会执行以下操作interval <INTEGER> #间隔时间,单位为秒,默认1秒timeout <INTEGER> #超时时间weight <INTEGER:-254..254> #默认为0,如果设置此值为负数,当上面脚本返回值为非0时,会将此值与本节点权重相加可以降低本节点权重,即表示fall. 如果是正数,当脚本返回值为0,会将此值与本节点权重相加可以提高本节点权重,即表示 rise.通常使用负值fall <INTEGER> #执行脚本连续几次都失败,则转换为失败,建议设为2以上rise <INTEGER> #执行脚本连续几次都成功,把服务器从失败标记为成功user USERNAME [GROUPNAME] #执行监测脚本的用户或组 init_fail #设置默认标记为失败状态,监测成功之后再转换为成功状态
}
vrrp_script check_down {script "/etc/keepalived/ng.sh" #指明脚本的位置 interval 1 #每隔1s 执行一次检测weight -30 #如果 脚本执行失败自动减少优先级30fall 3 # 3次不成功才标注为失败 rise 2 #nginx 重新起来后检测两次成功 才真的成功 timeout 2 #超时时间 2s
}
注意:这边的优先级-30要根据实际情况加减。
调用脚本
track_script:调用vrrp_script定义的脚本去监控资源,定义在VRRP实例之内,调用事先定义的vrrp_script
SCRIPT_NAME_1
主keepalived和nginx:192.168.232.10
备keepalived和nginx:192.168.232.20
web1:192.168.232.30
web2:192.168.232.40
vip:192.168.232.188
客户机:192.168.232.50
配置后端真实服务器
systemctl stop firewalld
setenforce 0
yum install httpd -y
vim /etc/httpd/conf/httpd.conf
keepalive off
echo 7-3 > /var/www/html/index.html
systemctl start httpd
配置代理服务器
vim /etc/nginx/nginx.confupstream web {server 192.168.232.30;server 192.168.232.40;}location / {proxy_pass http://web;}
两台机子的配置是一样的,远程拷贝即可。在主配置中也需要将nginx的长连接关闭。
主服务器的keepalive配置
! Configuration File for keepalivedglobal_defs {notification_email {acassen@firewall.locfailover@firewall.locsysadmin@firewall.loc}notification_email_from Alexandre.Cassen@firewall.locsmtp_server 127.0.0.1 修改邮箱地址smtp_connect_timeout 30router_id LVS_01 修改名称vrrp_skip_check_adv_addr#vrrp_strict关闭严格模式vrrp_garp_interval 0vrrp_gna_interval 0
}vrrp_script check_down {script "/etc/keepalived/ng.sh"指明脚本位置interval 1每隔1s执行一次检测weight -30如果脚本执行失败自动减少优先级30fall 33次不成功标注为失败rise 2nginx重新起来后检测两次成功后才真的成功。timeout 2超时时间2s
}vrrp_instance VI_1 {state MASTERinterface ens33virtual_router_id 51priority 100advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {192.168.232.188}track_script {check_down}
}vim /etc/keepalived/ng.sh
killall -0 nginxchmod +x /etc/keepalived/ng.sh
scp /etc/keepalived/keepalived.conf 192.168.232.20://etc/keepalived/
实验效果
测试负载均衡是否成功
关闭7-1的keepalive,切换至7-2的服务。
重启开始7-1,关闭7-1的nginx
效果配置成功。