高可用集群KEEPALIVED实战解析
高可用集群KEEPALIVED
集群类型
-
LB(Load Balance,负载均衡) 常见实现:LVS、HAProxy、nginx(http/upstream, stream/upstream)
-
HA(High Availability,高可用集群) 应用场景:数据库、Redis等
-
SPoF(Single Point of Failure,单点故障) 目标:解决系统中单点失效导致整体不可用的问题
-
HPC(High Performance Computing,高性能集群)
系统可用性
-
SLA(Service-Level Agreement,服务等级协议) 服务提供方与客户之间就服务品质、性能等达成的协议 计算公式:
A = MTBF / (MTBF + MTTR)
-
MTBF:Mean Time Between Failures,平均无故障时间
-
MTTR:Mean Time To Repair,平均修复时间
-
-
高可用性指标
-
99.9%
-
99.99%
-
99.999%
-
99.9999%
-
例如:
99.95% SLA下,月可用性 = (60*24*30)*(1-0.9995) ≈ 21.6分钟停机
-
系统故障类型
-
硬件故障:设计缺陷、损耗、自然灾害等不可抗力
-
软件故障:设计缺陷、bug等
实现高可用的思路
-
降低MTTR:尽量缩短故障恢复时间
-
冗余机制:
-
active/passive(主/备)
-
active/active(双主)
-
主动-被动心跳:active --> HEARTBEAT --> passive
-
双主互为心跳:active <--> HEARTBEAT <--> active
-
VRRP(Virtual Router Redundancy Protocol)
-
作用:虚拟路由冗余协议,解决静态网关单点故障风险
-
部署层次:
-
物理层:路由器、三层交换机
-
软件层:keepalived
-
VRRP 相关术语
-
虚拟路由器(Virtual Router)
-
虚拟路由器标识(VRID 0-255):唯一标识一个虚拟路由器
-
VIP(Virtual IP):对外提供服务的虚拟IP
-
VMAC(Virtual MAC):如 00-00-5e-00-01-VRID
-
物理路由器角色:
-
master(主设备)
-
backup(备用设备)
-
priority(优先级)
-
VRRP 相关技术
-
通告:心跳、优先级信息定期广播
-
工作方式:
-
抢占式(优先级高的设备可自动成为主)
-
非抢占式
-
-
安全认证:
-
无认证
-
简单字符认证(预共享密钥)
-
MD5认证
-
-
工作模式:
-
主/备:单虚拟路由器
-
主/主:如主/备(虚拟路由器1),备/主(虚拟路由器2)
-
Keepalived 部署
keepalived 简介
-
VRRP协议的软件实现,最初为高可用IPVS负载均衡设计
-
官网:Keepalived for Linux
主要功能:
-
基于vrrp协议实现VIP地址漂移
-
为VIP所在节点生成IPVS规则(可在配置文件定义)
-
对IPVS集群的各RS(Real Server)做健康检查
-
通过脚本调用接口支持nginx、haproxy等服务的高可用
Keepalived 架构
-
官方文档: Keepalived User Guide — Keepalived 1.4.3 documentation Keepalived for Linux
核心用户空间组件:
-
vrrp stack:负责VIP消息通告和状态切换
-
checkers:健康检查real server
-
system call:调用脚本实现状态切换时的自定义处理
-
SMTP:邮件通知组件
-
IPVS wrapper:自动生成IPVS规则
-
Netlink Reflector:网络接口,用于与内核通信
-
WatchDog:进程监控
控制组件:
-
提供keepalived.conf配置文件解析器,完成配置加载和管理
IO复用器:
-
针对网络需求优化的线程模型
内存管理组件:
-
提供通用内存分配、回收等功能
小结
-
Keepalived通过实现VRRP协议和健康检测脚本,提供主备/主主等高可用架构,解决了网络和服务单点故障问题。
-
配合LVS、nginx、haproxy等负载均衡器,可实现高可用、高性能的服务集群。
-
配置灵活,支持多种认证、通告与健康检查机制,是企业级高可用架构的重要工具。
环境准备
配置环境
root@KA2 | 172.25.254.60 |
---|---|
root@KA1 | 172.25.254.50 |
root@rs11 | 172.25.254.10 |
root@rs22 | 172.25.254.20 |
在两个rs11和rs22安装httpd
[root@rs22 ~]# dnf install httpd -y[root@rs11 ~]# dnf install httpd -y
开启httpd
[root@rs22 ~]# systemctl enable --now httpd[root@rs11 ~]# systemctl enable --now httpd
这里四台主机全用代码脚本配置
在KA1和KA2上安装keepalived
[root@KA1 ~]# dnf install keepalived[root@KA2 ~]# dnf install keepalived
ka1和ka2配置文件
开启keepalived
[root@KA1 ~]# systemctl enable --now keepalived.service[root@KA2 ~]# systemctl enable --now keepalived.service
测试
keepalived日志分离
重新启动
[root@KA1 ~]# systemctl restart keepalived.service
在日志文件里修改
重新启动
[root@KA1 ~]# systemctl restart keepalived.service
keepalived独立子配置文件
建立子目录并修改
非抢占模式和延迟抢占
在ka1和ka2中修改配置文件
重启
延迟抢占
在ka1和ka2中修改配置文件
重启
单播模式设定
在配置文件里修改
重启
ka2
重启
邮件通知
在mail配置文件修改
[root@KA1 ~]# vim /etc/keepalived/mail.sh
在 vrrp_instance WEB_VIP语句块的末尾加下面行
邮件配置
安装邮箱发送工具
[root@KA1 ~]# dnf install mailx -y
QQ邮箱配置
[root@KA1 ~]# vim /etc/mail.rcset smtp=3036573431@qq.comset smtp-auth=loginset smtp-auth-user=3036573431@qq.comset smtp-auth-password=regtYbWevbPdftftgset from=3036573431@qq.comset ssl-verify=ignore
[root@kA1~]#killall keepalived #模拟master故障
查看邮箱
实现 master/master 的 Keepalived 双主架构
master/slave的单主架构,同一时间只有一个Keepalived对外提供服务,此主机繁忙,而另一台主机却很空闲,利用率低下,可以使用master/master的双主架构,解决此问题。
master/master 的双主架构:
即将两个或以上VIP分别运行在不同的keepalived服务器,以实现服务器并行提供web访问的目的,提高服务器资源利用率
配置环境
root@KA2 | 172.25.254.60 |
---|---|
root@KA1 | 172.25.254.50 |
root@rs11 | 172.25.254.10 |
root@rs22 | 172.25.254.20 |
该命令,可检测报错
keepalived -t -f /etc/keepalived/keepalived.conf
KA1操作
global_defs {notification_email {3036573531@qq.com}notification_email_from 3036573431@qq.comsmtp_server 127.0.0.0smtp_connect_timeout 30router_id LVS_DEVELvrrp_skip_check_adv_addr# vrrp_strictvrrp_garp_interval 1vrrp_gna_interval 1vrrp_mcast_group4 224.0.0.44enable_script_securityscript_user root}vrrp_instance WEB_VIP {state MASTER #主interface eth0virtual_router_id 51priority 100advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {172.25.254.100/24 dev eth0 label eth0:0}unicast_src_ip 172.25.254.50unicast_peer { 172.25.254.60}}vrrp_instance DB_vip {state BACKUP #备interface eth0virtual_router_id 52priority 80advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {172.25.254.200/24 dev eth0 label eth0:1}}
重启服务 systemctl restart keepalived.service
[root@KA1 ~]# ifconfigeth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500inet 172.25.254.50 netmask 255.255.255.0 broadcast 172.25.254.255inet6 fe80::1784:f6b9:d579:72b5 prefixlen 64 scopeid 0x20<link>ether 00:0c:29:de:e6:9d txqueuelen 1000 (Ethernet)RX packets 5105 bytes 396948 (387.6 KiB)RX errors 0 dropped 0 overruns 0 frame 0TX packets 7543 bytes 842452 (822.7 KiB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0eth0:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500inet 172.25.254.100 netmask 255.255.255.0 broadcast 0.0.0.0ether 00:0c:29:de:e6:9d txqueuelen 1000 (Ethernet)lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536inet 127.0.0.1 netmask 255.0.0.0inet6 ::1 prefixlen 128 scopeid 0x10<host>loop txqueuelen 1000 (Local Loopback)RX packets 0 bytes 0 (0.0 B)RX errors 0 dropped 0 overruns 0 frame 0TX packets 0 bytes 0 (0.0 B)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
KA2设置
! Configuration File for keepalivedglobal_defs {notification_email {3036573431@qq.com}notification_email_from 3036573431@qq.comsmtp_server 127.0.0.0smtp_connect_timeout 30router_id LVS_DEVELvrrp_skip_check_adv_addr#vrrp_strictvrrp_garp_interval 1vrrp_gna_interval 1vrrp_mcast_group4 224.0.0.44enble_script_securityscript_user root}vrrp_instance WEB_VIP {state BACKUP #备interface eth0virtual_router_id 51priority 80advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {172.25.254.100/24 dev eth0 label eth0:0}unicast_src_ip 172.25.254.60unicast_peer { 172.25.254.50}}vrrp_instance VI_60 {state MASTER #主interface eth0virtual_router_id 52priority 100advert_int 1authentication {auth_type PASSauth_pass 1111} virtual_ipaddress {172.25.254.200 dev eth0 label eth0:1}}
重启服务 systemctl restart keepalived.service
[root@KA2 ~]# ifconfig
实验测试
关掉KA2keepalived服务
[root@KA2 ~]# systemctl stop keepalived.service
在KA1上查看,KA1出现两个vip顶替两个KA1工作
在启动KA2keepalived服务,查看到VIP自动回到
[root@KA2 ~]# systemctl start keepalived.service
实现其它应用的高可用性 VRRP Script
ipvs设定
给rs1和rs2都配置lo永久
在kA1和KA2安装ipvsadm
[root@KA1 ~]# dnf install ipvsadm -y
利用脚本实现主从角色切换
建立放脚本文件
[root@KA1 ~]# mkdir -p /etc/keepalived/scripts
编写脚本
[root@KA1 ~]# vim /etc/keepalived/scripts/lee.sh#!/bin/bash[ ! -f /mnt/lee]
[root@KA1 ~]# chmod +x /etc/keepalived/scripts/lee.sh #给脚本一个可执行权限
global_defs {notification_email {3036573531@qq.com}notification_email_from 3036573431@qq.comsmtp_server 127.0.0.0smtp_connect_timeout 30router_id LVS_DEVELvrrp_skip_check_adv_addr# vrrp_strictvrrp_garp_interval 1vrrp_gna_interval 1vrrp_mcast_group4 224.0.0.44enable_script_securityscript_user root}vrrp_script TEST_CHECK {script "/etc/keepalived/scripts/lee.sh"interval 1weight -30fall 2rise 2timeout 2}vrrp_instance WEB_VIP {state MASTER #主interface eth0virtual_router_id 51priority 100advert_int 1authentication {auth_type PASSauth_pass 1111}track_srcipt{TEST_CHECK}virtual_ipaddress {172.25.254.100/24 dev eth0 label eth0:0}unicast_src_ip 172.25.254.50unicast_peer { 172.25.254.60}}vrrp_instance DB_vip {state BACKUP #备interface eth0virtual_router_id 52priority 80advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {172.25.254.200/24 dev eth0 label eth0:1}}
[root@KA1 ~]# systemctl restart keepalived.service #重启服务[root@KA1 ~]# touch /mnt/lee[root@KA1 ~]# /etc/keepalived/scripts/lee.sh[root@KA1 ~]# echo $?1
脚本生效减少KA1权重减30低于KA2权重
到KA2服务器查看VIP是否迁移过来
[root@KA1 ~]# rm -fr /mnt/lee[root@KA1 ~]# /etc/keepalived/scripts/lee.sh[root@KA1 ~]# echo $?0
实现keepalived和HAProxy双高可用
安装haproxy KA1和KA2操作相同
[rootKA1和KA2 ~]# dnf install haproxy -yvim /etc/haproxy/haproxy.cfglisten webclusterbind *:80mode tcpbalance roundrobinserver web1 172.25.254.10:80 check inter 3 fall 2 rise 3server web2 172.25.254.20:80 check inter 3 fall 2 rise 3
当前KA2没有VIP需要加参数,KA1也要加
[root@KA2 ~]# vim /etc/sysctl.confnet.ipv4.ip_nonlocal_bind = 1[root@KA2 ~]# sysctl -pnet.ipv4.ip_nonlocal_bind = 1
或者用以下方式[root@KA1 ~]# echo net.ipv4.ip_nonlocal_bind=1 >> /etc/sysctl.conf[root@KA1 ~]# sysctl -p #使其生效net.ipv4.ip_nonlocal_bind = 1
打开KA1和KA2 haproxy服务
[root@KA2 ~]# systemctl enable --now haproxy.serviceCreated symlink /etc/systemd/system/multi-user.target.wants/haproxy.service → /usr/lib/systemd/system/haproxy.service.
检查KA1和KA2的80端口是否打开
命令 netstat -antlupe | grep 80
测试