keepalived
### 大坑 VIP 要设置成32位掩码,否则BACKUP无法ping通
### broadcast 也不一样
man keepalived
man keepalived.conf
keepalived vrrp 虚拟路由器冗余协议 ( Virtual Router Redundancy Protocol )的实现
vrrp_instance 虚拟路由器
keepalived:
- global
- vrrp
- LVS
脚本配置文件: /etc/sysconfig/keepalived
修改日志记录
LVS NAT模型 同步组, 同进退
同步组
vrrp_sync_group vg_1 {
group {
vi_1
vi_2
}
}
vrrp_instance vi_1 {
eth0
vip
}
vrrp_instance vi_2 {
eth1
dip
}
健康检测脚本
脚本权限问题
global中设置
enable_script_security
定义两个虚拟路由器 vrrp_instance, 三主机
host-1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | global_defs { notification_email { root@localhost } notification_email_from root@localhost smtp_server localhost smtp_connect_timeout 30 router_id LVS_DEVEL #vrrp_strict # 严格遵守VRRP协议 vrrp_garp_interval 0 vrrp_gna_interval 0 script_user root enable_script_security # 脚本权限必须为744,其它用户不能有执行权限 } vrrp_instance vi_1 { state MASTER # BACKUP 初始状态 interface ens33 # 绑定网卡, 在此网卡上配置 VIP virtual_router_id 51 # VRID, unique across vrrp_instance priority 100 mcast_src_ip 192.168.8.11 # 多播源地址, 通常是本机 IP 地址 advert_int 1 # MASTER通告自身信息之组播信息发送间隔,两个节点设置必须一样 #nopreempt ## 默认抢占模式 authentication { auth_type PASS auth_pass password } virtual_ipaddress { 192.168.8.200/24 brd 192.168.8.255 scope global label ens33:0 # 24位掩码不行 } } vrrp_instance vi_2 { state BACKUP # 修改 interface ens33 # 依据实际网卡修改 virtual_router_id 52 # 修改 priority 90 # 修改 mcast_src_ip 192.168.8.11 # 修改 advert_int 1 authentication { auth_type PASS auth_pass password } virtual_ipaddress { 192.168.8.210/24 brd 192.168.8.255 scope global label ens33:0 # 修改 } } |
host-2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | global_defs { notification_email { root@localhost } notification_email_from root@localhost smtp_server localhost smtp_connect_timeout 30 router_id LVS_DEVEL #vrrp_strict # 严格遵守VRRP协议 vrrp_garp_interval 0 vrrp_gna_interval 0 script_user root enable_script_security # 脚本权限必须为744,其它用户不能有执行权限 } vrrp_instance vi_1 { state BACKUP # BACKUP 初始状态 interface ens33 # 绑定网卡, 在此网卡上配置 VIP virtual_router_id 51 # VRID, unique across vrrp_instance priority 95 mcast_src_ip 192.168.8.12 # 多播源地址, 通常是本机 IP 地址 advert_int 1 # MASTER通告自身信息之组播信息发送间隔,两个节点设置必须一样 #nopreempt ## 默认抢占模式 authentication { auth_type PASS auth_pass password } virtual_ipaddress { 192.168.8.200/24 brd 192.168.8.255 scope global label ens33:0 } } vrrp_instance vi_2 { state BACKUP # 修改 interface ens33 # 依据实际网卡修改 virtual_router_id 52 # 修改 priority 95 # 修改 mcast_src_ip 192.168.8.12 # 修改 advert_int 1 authentication { auth_type PASS auth_pass password } virtual_ipaddress { 192.168.8.210/24 brd 192.168.8.255 scope global label ens33:0 # 修改 } } |
host-3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | global_defs { notification_email { root@localhost } notification_email_from root@localhost smtp_server localhost smtp_connect_timeout 30 router_id LVS_DEVEL #vrrp_strict # 严格遵守VRRP协议 vrrp_garp_interval 0 vrrp_gna_interval 0 script_user root enable_script_security # 脚本权限必须为744,其它用户不能有执行权限 } vrrp_instance vi_1 { state BACKUP # BACKUP 初始状态 interface ens33 # 绑定网卡, 在此网卡上配置 VIP virtual_router_id 51 # VRID, unique across vrrp_instance priority 90 mcast_src_ip 192.168.8.13 # 多播源地址, 通常是本机 IP 地址 advert_int 1 # MASTER通告自身信息之组播信息发送间隔,两个节点设置必须一样 #nopreempt ## 默认抢占模式 authentication { auth_type PASS auth_pass password } virtual_ipaddress { 192.168.8.200/24 brd 192.168.8.255 scope global label ens33:0 } } vrrp_instance vi_2 { state MASTER # 修改 interface ens33 # 依据实际网卡修改 virtual_router_id 52 # 修改 priority 100 # 修改 mcast_src_ip 192.168.8.13 # 修改 advert_int 1 authentication { auth_type PASS auth_pass password } virtual_ipaddress { 192.168.8.210/24 brd 192.168.8.255 scope global label ens33:0 # 修改 } } |
effect
keepalived配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | SLAVE需要修改state为BACKUP interface 根据网卡名称修改 priority BACKUP设为95,90, 多个BACKUP的priority也需各不相同 state 仅对初始状态有效, 对后续争夺VIP无效 mcast_src_ip 修改 vrrp_script 必须定义在调用前 ! Configuration File for keepalived #--------------------------------------------------------------------- # global #--------------------------------------------------------------------- global_defs { notification_email { root@localhost } notification_email_from root@localhost smtp_server localhost smtp_connect_timeout 30 router_id LVS_DEVEL # 所有节点可相同 vrrp_skip_check_adv_addr #vrrp_strict # 严格遵守VRRP协议 vrrp_garp_interval 0 vrrp_gna_interval 0 script_user root enable_script_security # 脚本权限必须为744,其它用户不能有执行权限 # 设置组播地址, 最好不设置 vrrp_mcast_group4 224.0.0.18 # optional, default 224.0.0.18 vrrp_mcast_group6 ff02::12 # optional, default ff02::12 } #--------------------------------------------------------------------- # vrrp_script #--------------------------------------------------------------------- vrrp_script check_script { script "/etc/keepalived/check_script.sh" # 不能使用 '' interval 2 weight -20 user root } vrrp_script check_1 { script "/etc/keepalived/check_1.sh" interval 1 fall 3 rise 2 } #--------------------------------------------------------------------- # vrrp_instance #--------------------------------------------------------------------- vrrp_instance vi_1 { state MASTER # BACKUP 初始状态 interface ens33 # 绑定网卡, 在此网卡上配置 VIP virtual_router_id 51 # VRID, unique across vrrp_instance priority 100 mcast_src_ip 192.168.8.11 # 多播源地址, 通常是本机 IP 地址 unicast_peer { # 单播目标地址, 和多播选一个 192.168.8.8 192.168.8.7 } advert_int 1 # MASTER通告自身信息之组播信息发送间隔,两个节点设置必须一样 #nopreempt ## 默认抢占模式 authentication { auth_type PASS auth_pass $(openssl rand -hex 4) } virtual_ipaddress { # VIP 192.168.8.200 # 默认32位 mask # 设置成默认的32位掩码, broadcast 不要设置 192.168.8.200/24 brd 192.168.8.255 dev ens33 scope global label ens33:0 } track_script { # 检测脚本 check_script } track_interface { # 检测网卡接口, 如果此网卡down掉, 则失去VIP ens33 # 不能为 lo } notify_master "/etc/keepalived/notify.sh master" # 转为master时,发送 notify_backup "/etc/keepalived/notify.sh backup" # 转为backup时,发送 notify_fault "/etc/keepalived/notify.sh fault" # 转为fault时,发送 } "nopreempt" allows the lower priority machine to maintain the master role, even when a higher priority machine comes back online. NOTE: For this to work, the initial state of this entry must be BACKUP |
发送邮件脚本 /etc/keepalived/notify.sh
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | #!/bin/env bash recipient= 'root@localhost' vip= '192.168.8.200' function notify() { local subject= "$(hostname) ==> $1,vip($vip) floating" local body= "$(date +'%F %T'): vrrp transition, $(hostname) changed to $1" echo "$body" | mailx -s "$subject" $recipient } case $1 in master) notify master ;; backup) notify backup ;; fault) notify fault ;; *) echo "Usage: $(basename $0) {master|backup|fault}" exit 5 ;; esac |
检查脚本 /etc/keepalived/check_script.sh
nginx
1 2 3 4 5 6 7 8 9 10 11 | #!/bin/bash if [[ `ps -C nginx --no-header | wc --lines` -eq 0 ]];then systemctl restart nginx echo -e '\e[7m nginx restarting\e[0m' sleep 1 if [[ `ps -C nginx --no-header | wc --lines` -eq 0 ]];then systemctl stop keepalived echo -e '\e[7m keepalived shutdown\e[0m' fi fi |
apiserver kubernetes
1 烂
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #!/bin/bash err=0 for i in $(seq 1 3); do n=$(pgrep haproxy) if [[ $n == "" ]];then let err=$err+1 sleep 1 continue else err=0 break fi done if [[ $err != 0 ]];then echo "systemctl stop keepalived" systemctl stop keepalived exit 2 else exit 0 fi |
2 优
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #!/bin/bash APISERVER_DEST_PORT=6443 APISERVER_VIP=192.168.8.200 function error(){ echo "*** $*" 1>&2 exit 2 } curl --silent --max-time 2 --insecure https: //localhost:${APISERVER_DEST_PORT} -o /dev/null || \ error "Error GET https://localhost:${APISERVER_DEST_PORT}" if ip addr | grep -q ${APISERVER_VIP};then curl --silent --max-time 2 --insecure https: //${APISERVER_VIP}:${APISERVER_DEST_PORT} -o /dev/null || \ error "Error GET https://${APISERVER_VIP}:${APISERVER_DEST_PORT}" fi |
Tencent Cloud:
注意事项
-
推荐使用单播方式进行 VRRP 通信。
-
推荐使用 Keepalived(1.2.24版本及以上)。
-
确保已经配置以下 garp 相关参数。因为 keepalived 依赖 ARP 报文更新 IP 信息,如果缺少以下参数,会导致某些场景下,主设备不发送 ARP 导致通信异常。
garp_master_delay 1 garp_master_refresh 5
-
确保同一 VPC 下的每个主备集群需要配置不同的 vrrp router id。
-
确定没有采用 strict 模式,即需要删除“vrrp_strict” 配置。
-
控制单个网卡上配置的 VIP 数量,建议目前在单个网卡绑定的高可用虚拟 IP 数量不超过5个。如果需要使用多个虚拟 IP,建议在 keepalived 配置文件的 global_defs 段落添加或修改配置 “vrrp_garp_master_repeat 1”。
-
通过调节 adver_int 参数的大小,在抗网络抖动及灾害恢复速度进行平衡取舍。当 advert_int 参数过小,容易受网络抖动影响发生频繁倒换和暂时 双主(脑裂) 直到网络恢复。当 advert_int 参数过大,会导致主机器故障后,主备倒换慢(即服务暂停时间长)。请充分评估双主(脑裂)对业务的影响!
-
track_script 脚本的具体执行项(如 checkhaproxy )中的 interval 参数请适当提高,避免脚本执行超时导致 FAULT 状态的发生。
keepalived.conf
! Configuration File for keepalived
#---------------------------------------------------------------------
# global
#---------------------------------------------------------------------
global_defs {
notification_email {
root@localhost
}
notification_email_from root@localhost
smtp_server localhost
smtp_connect_timeout 30
router_id LVS_DEVEL # 所有节点可相同
vrrp_skip_check_adv_addr
#vrrp_strict # 严格遵守VRRP协议
vrrp_garp_interval 0
vrrp_gna_interval 0
script_user root
enable_script_security # 脚本权限必须为744,其它用户不能有执行权限
}
#---------------------------------------------------------------------
# vrrp_script
#---------------------------------------------------------------------
vrrp_script check_script {
script "/etc/keepalived/check_script.sh" # 不能使用 ''
interval 5
user root
fall 3
rise 1
}
#---------------------------------------------------------------------
# vrrp_instance
#---------------------------------------------------------------------
vrrp_instance vi_1 {
state BACKUP # BACKUP 初始状态
interface eth0 # 绑定网卡, 在此网卡上配置 VIP
virtual_router_id 51 # VRID, unique across vrrp_instance
priority 100
nopreempt # 非抢占模式
# preempt_delay 10 # 仅 state MASTER 时生效
advert_int 5 # MASTER通告自身信息之组播信息发送间隔,两个节点设置必须一样
garp_master_delay 1 # 当切换位master后,多久更新ARP缓存
garp_master_refresh 5 # master发送ARP报文的时间间隔
unicast_src_ip 10.0.0.201 # 本机内网IP
unicast_peer { # 单播目标地址, 和多播选一个
10.0.0.202 # peer IP
}
authentication {
auth_type PASS
auth_pass vitriolic
}
virtual_ipaddress { # VIP
# 设置成默认的32位掩码, broadcast 不要设置
10.0.0.200/32 dev eth0 scope global
}
track_script { # 检测脚本
check_script
}
track_interface { # 检测网卡接口, 如果此网卡down掉, 则失去VIP
eth0 # 不能为 lo
}
notify_master "/etc/keepalived/notify.sh MASTER" # 转为master时,发送
notify_backup "/etc/keepalived/notify.sh BACKUP" # 转为backup时,发送
notify_fault "/etc/keepalived/notify.sh FAULT" # 转为fault时,发送
notify_stop "/etc/keepalived/notify.sh STOP"
}
notify.sh
#!/bin/bash
#/etc/keepalived/notify_action.sh
log_file=/var/log/keepalived.log
function log_write()
{
echo "[`date '+%Y-%m-%d %T'`] $1" >> $log_file
}
[ ! -d /var/keepalived/ ] && mkdir -p /var/keepalived/
case "$1" in
"MASTER" )
echo -n "$1" > /var/keepalived/state
log_write " notify_master"
echo -n "0" /var/keepalived/vip_check_failed_count
;;
"BACKUP" )
echo -n "$1" > /var/keepalived/state
log_write " notify_backup"
;;
"FAULT" )
echo -n "$1" > /var/keepalived/state
log_write " notify_fault"
;;
"STOP" )
echo -n "$1" > /var/keepalived/state
log_write " notify_stop"
;;
*)
log_write "notify_action.sh: STATE ERROR!!!"
;;
esac
- 在传统的物理网络中,可以通过 keepalived 的 VRRP 协议协商主备状态,其原理是:主设备周期性发送免费 ARP 报文刷新上联交换机的 MAC 表或终端 ARP 表,触发 VIP 迁移到主设备上。
- 推荐使用单播方式进行 VRRP 通信
- 确保已经配置以下 garp 相关参数。因为 keepalived 依赖 ARP 报文更新 IP 信息,如果缺少以下参数,会导致某些场景下,主设备不发送 ARP 导致通信异常。
-
garp_master_delay 1 garp_master_refresh 5
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律