day5-keepalived通过ARP漂移实现容灾

在两台 CentOS 7 服务器上使用 Keepalived 实现主备容灾(双网卡方案)

一、VRRP 核心原理

Keepalived 基于 VRRP(虚拟路由冗余协议) 工作,其核心机制如下:

  1. 虚拟路由器:多台物理服务器组成一个虚拟路由器,并共享一个虚拟IP(VIP)
  2. 主备角色:一台为主(MASTER),负责处理业务;其余为备(BACKUP),随时准备接管
  3. 心跳机制:主服务器定期发送VRRP通告包,宣告自己存活
  4. 接管流程:当备服务器在预设时间内未收到心跳,认为主服务器故障,接管VIP继续提供服务
  5. 优先级仲裁:多个备服务器时,根据配置的优先级(priority)决定谁接管VIP

双网卡方案优势:将业务流量和心跳流量物理隔离,即使业务网络拥堵也不影响心跳检测的稳定性。

二、实现效果

  • 无缝切换:主服务器故障时,VIP自动漂移到备服务器,业务零中断,切换时间1-3秒
  • 故障检测:可监控服务状态(如HTTP),当服务异常时触发切换,而不仅限于服务器宕机
  • 心跳隔离:专用网卡处理VRRP心跳,避免业务流量干扰,提高可靠性
  • 自动恢复:主服务器恢复后可自动或手动将VIP切回,根据配置灵活调整

三、环境与网络拓扑

服务器配置

  • 服务器A(主):业务IP 192.168.1.10,心跳IP 10.0.0.1
  • 服务器B(备):业务IP 192.168.1.20,心跳IP 10.0.0.2
  • 虚拟IP:192.168.1.100(绑定在业务网卡上)
+---------------+                +---------------+
| 服务器A (主)  |                | 服务器B (备)  |
|               |                |               |
| eth0:192.168.1.10 -业务网络-  eth0:192.168.1.20|
| VIP:192.168.1.100              |               |
|               |                |               |
| eth1:10.0.0.1  ---心跳网络---  eth1:10.0.0.2  |
+---------------+                +---------------+

关键设计

  • 业务网卡(eth0):处理实际业务流量,绑定VIP
  • 心跳网卡(eth1):仅用于Keepalived心跳通信,实现物理隔离

四、实现步骤

1. 安装 Keepalived

sudo yum install -y keepalived

2. 配置主服务器(A)

1. 主服务器(A)配置

编辑 /etc/keepalived/keepalived.conf

1. 全局配置段
global_defs {
   router_id MASTER_SERVER            # 路由器标识,集群内应唯一
   notification_email {               # 告警邮件接收地址
     admin@example.com
   }
   notification_email_from keepalived@example.com  # 发件人地址
   smtp_server 127.0.0.1              # 邮件服务器地址
   smtp_connect_timeout 30            # 连接超时时间
   script_user root                   # 脚本执行用户
   enable_script_security             # 启用脚本安全模式
   vrrp_skip_check_adv_addr           # 跳过检查通告包源地址
   vrrp_strict                        # 严格遵守VRRP协议
   vrrp_garp_interval 1               # GARP报文发送间隔
   vrrp_gna_interval 1                # 免费ARP报文发送间隔
   log_facility local0                # 使用local0设施记录日志
}

1. 服务健康检查脚本
vrrp_script chk_httpd {
    script "/etc/keepalived/check_httpd.sh"  # 检查脚本路径
    interval 2                               # 检查间隔(秒)
    weight -5                                # 检查失败时的优先级调整值
    fall 2                                   # 连续失败多少次才算真失败
    rise 1                                   # 连续成功多少次才算真成功
    user root                                # 执行用户
    timeout 2                                # 脚本执行超时时间
}

1. VRRP实例配置
vrrp_instance VI_1 {
    state MASTER                             # 初始状态为MASTER
    interface eth0                           # 绑定VIP的网卡
    virtual_router_id 51                     # 虚拟路由器ID,集群内必须相同
    priority 100                             # 优先级,值越大越优先成为MASTER
    advert_int 1                             # VRRP通告间隔(秒)
    authentication {
        auth_type PASS                       # 认证类型,PASS或AH
        auth_pass Ha7kQp9L                   # 认证密码,集群内必须相同
    }

    1. 使用单播方式进行VRRP通信(适用于跨VLAN环境)
    unicast_src_ip 10.0.0.1                  # 本机心跳网卡IP
    unicast_peer {
        10.0.0.2                             # 备服务器心跳网卡IP
    }

    1. 虚拟IP配置
    virtual_ipaddress {
        192.168.1.100/24 dev eth0 label eth0:vip  # VIP地址配置及标签
    }

    1. 健康检查关联
    track_script {
        chk_httpd                            # 关联上面定义的检查脚本
    }

    1. 优先级变动通知脚本(可选)
    notify_master "/etc/keepalived/notify_master.sh"  # 成为MASTER时执行
    notify_backup "/etc/keepalived/notify_backup.sh"  # 成为BACKUP时执行
    notify_fault "/etc/keepalived/notify_fault.sh"    # 发生故障时执行

    1. 抢占模式设置
    nopreempt                                # 不启用抢占模式,避免频繁切换
    preempt_delay 300                        # 抢占延迟(秒,仅在未设置nopreempt时有效)

    1. GARP设置
    garp_master_delay 1                      # 成为MASTER后发送GARP的延迟
    garp_master_repeat 3                     # GARP报文发送次数

    1. 调试日志级别
    debug                                    # 启用调试日志
}

2. 备服务器(B)配置

编辑 /etc/keepalived/keepalived.conf

1. 全局配置段
global_defs {
   router_id BACKUP_SERVER            # 路由器标识,集群内应唯一
   notification_email {               # 告警邮件接收地址
     admin@example.com
   }
   notification_email_from keepalived@example.com  # 发件人地址
   smtp_server 127.0.0.1              # 邮件服务器地址
   smtp_connect_timeout 30            # 连接超时时间
   script_user root                   # 脚本执行用户
   enable_script_security             # 启用脚本安全模式
   vrrp_skip_check_adv_addr           # 跳过检查通告包源地址
   vrrp_strict                        # 严格遵守VRRP协议
   vrrp_garp_interval 1               # GARP报文发送间隔
   vrrp_gna_interval 1                # 免费ARP报文发送间隔
   log_facility local0                # 使用local0设施记录日志
}

1. 服务健康检查脚本
vrrp_script chk_httpd {
    script "/etc/keepalived/check_httpd.sh"  # 检查脚本路径
    interval 2                               # 检查间隔(秒)
    weight -5                                # 检查失败时的优先级调整值
    fall 2                                   # 连续失败多少次才算真失败
    rise 1                                   # 连续成功多少次才算真成功
    user root                                # 执行用户
    timeout 2                                # 脚本执行超时时间
}

1. VRRP实例配置
vrrp_instance VI_1 {
    state BACKUP                             # 初始状态为BACKUP
    interface eth0                           # 绑定VIP的网卡
    virtual_router_id 51                     # 虚拟路由器ID,集群内必须相同
    priority 90                              # 优先级,值低于主服务器
    advert_int 1                             # VRRP通告间隔(秒)
    authentication {
        auth_type PASS                       # 认证类型,PASS或AH
        auth_pass Ha7kQp9L                   # 认证密码,集群内必须相同
    }

    1. 使用单播方式进行VRRP通信(适用于跨VLAN环境)
    unicast_src_ip 10.0.0.2                  # 本机心跳网卡IP
    unicast_peer {
        10.0.0.1                             # 主服务器心跳网卡IP
    }

    1. 虚拟IP配置
    virtual_ipaddress {
        192.168.1.100/24 dev eth0 label eth0:vip  # VIP地址配置及标签
    }

    1. 健康检查关联
    track_script {
        chk_httpd                            # 关联上面定义的检查脚本
    }

    1. 优先级变动通知脚本(可选)
    notify_master "/etc/keepalived/notify_master.sh"  # 成为MASTER时执行
    notify_backup "/etc/keepalived/notify_backup.sh"  # 成为BACKUP时执行
    notify_fault "/etc/keepalived/notify_fault.sh"    # 发生故障时执行

    1. GARP设置
    garp_master_delay 1                      # 成为MASTER后发送GARP的延迟
    garp_master_repeat 3                     # GARP报文发送次数

    1. 调试日志级别
    debug                                    # 启用调试日志
}

3. 健康检查脚本

创建 /etc/keepalived/check_httpd.sh,内容如下:

#!/bin/bash
1. 服务检查脚本 - 监控Apache HTTP服务
1. 返回0表示成功,非0表示失败

1. 记录日志的函数
log_msg() {
    local message="$1"
    logger -t keepalived_check_httpd "$message"
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $message" >> /var/log/keepalived_scripts.log
}

1. 检查httpd进程是否运行
if ! pgrep httpd > /dev/null; then
    log_msg "HTTP服务未运行,尝试启动..."
    systemctl start httpd
    sleep 2

    1. 再次检查是否成功启动
    if ! pgrep httpd > /dev/null; then
        log_msg "HTTP服务启动失败,将触发Keepalived切换!"
        exit 1
    else
        log_msg "HTTP服务成功重启"
    fi
fi

1. 尝试访问本地web服务
if ! curl -s --max-time 2 http://localhost/ > /dev/null; then
    log_msg "无法访问HTTP服务,将触发Keepalived切换!"
    exit 2
fi

1. 一切正常
log_msg "HTTP服务运行正常"
exit 0

4. 状态变更通知脚本(可选)

创建主状态通知脚本 /etc/keepalived/notify_master.sh

#!/bin/bash
1. 当节点成为MASTER时执行的脚本

1. 记录事件
logger -t keepalived "节点已成为MASTER状态,VIP已接管"

1. 发送邮件通知
echo "服务器$(hostname)已成为Keepalived的MASTER节点,接管VIP $(date)" | mail -s "Keepalived: $(hostname) 成为MASTER" admin@example.com

1. 执行其他自定义操作,如启动特定服务等
1. systemctl start some-service

exit 0

创建备状态通知脚本 /etc/keepalived/notify_backup.sh

#!/bin/bash
1. 当节点成为BACKUP时执行的脚本

1. 记录事件
logger -t keepalived "节点已成为BACKUP状态,VIP已释放"

1. 发送邮件通知
echo "服务器$(hostname)已成为Keepalived的BACKUP节点,释放VIP $(date)" | mail -s "Keepalived: $(hostname) 成为BACKUP" admin@example.com

1. 执行其他自定义操作,如停止特定服务等
1. systemctl stop some-service

exit 0

创建故障通知脚本 /etc/keepalived/notify_fault.sh

#!/bin/bash
1. 当节点检测到故障时执行的脚本

1. 记录事件
logger -t keepalived "节点检测到故障,可能进入FAULT状态"

1. 发送邮件通知
echo "服务器$(hostname)的Keepalived检测到故障,可能进入FAULT状态 $(date)" | mail -s "Keepalived: $(hostname) 检测到故障" admin@example.com

1. 可以尝试一些故障自修复操作
1. systemctl restart network

exit 0

5. 脚本权限设置

为所有脚本添加执行权限:

chmod +x /etc/keepalived/check_httpd.sh
chmod +x /etc/keepalived/notify_master.sh
chmod +x /etc/keepalived/notify_backup.sh
chmod +x /etc/keepalived/notify_fault.sh

5. 启动服务

两台服务器均执行:

systemctl start keepalived
systemctl enable keepalived

五、工作原理详解

1. 初始状态

  • 主服务器启动后,进入MASTER状态,绑定VIP并开始提供服务
  • 备服务器启动后,进入BACKUP状态,监听主服务器的VRRP通告

2. 故障检测机制

Keepalived有三种故障检测方式:

  • 心跳中断检测:备服务器未收到主服务器VRRP通告
  • 服务检测track_script检测到本地服务异常
  • 接口监控track_interface检测到网卡故障

3. 故障转移过程

当主服务器发生故障时:

  1. 备服务器等待3×advert_int时间未收到心跳
  2. 备服务器将自身状态提升为MASTER
  3. 发送免费ARP(Gratuitous ARP)广播,更新网络中的ARP表
  4. 在自己的eth0上绑定VIP
  5. 接管业务流量,整个过程对客户端透明

4. 心跳网络的重要性

  • 普通配置:心跳和业务共用一个网卡,业务高峰可能导致心跳丢包,引发误切换
  • 双网卡配置:心跳走专用网卡,与业务完全隔离,即使业务网络拥堵,心跳依然稳定

六、防火墙配置

为了确保Keepalived正常工作,需要在两台服务器的防火墙中放行VRRP协议和业务服务端口。

使用firewalld(CentOS 7默认防火墙)

1. 允许VRRP协议(IP协议112)通信
sudo firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 \
  --in-interface eth1 --protocol 112 --destination 224.0.0.18 --jump ACCEPT

1. 允许单播VRRP通信(如果使用unicast模式)
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" \
  source address="10.0.0.0/24" protocol value="112" accept'

1. 允许HTTP服务(根据实际业务需要调整)
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https

1. 重新加载防火墙规则
sudo firewall-cmd --reload

使用iptables

如果使用iptables作为防火墙,可以执行:

1. 允许VRRP协议
sudo iptables -A INPUT -i eth1 -p 112 -d 224.0.0.18 -j ACCEPT

1. 允许单播VRRP通信
sudo iptables -A INPUT -s 10.0.0.0/24 -p 112 -j ACCEPT

1. 允许HTTP服务
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT

1. 保存规则
sudo service iptables save

关闭防火墙(测试环境可选)

在测试环境中,如果遇到问题,可以暂时关闭防火墙进行测试:

1. 临时关闭
sudo systemctl stop firewalld

1. 永久关闭
sudo systemctl disable firewalld

七、启动并验证服务

1. 启动Keepalived服务

在两台服务器上分别启动Keepalived服务:

1. 启动服务
sudo systemctl start keepalived

1. 设置开机自启
sudo systemctl enable keepalived

1. 检查服务状态
sudo systemctl status keepalived

2. 检查VIP绑定状态

在主服务器上执行以下命令,确认VIP已正确绑定:

ip addr show eth0

应该能看到类似以下输出,表明VIP已绑定到eth0接口:

2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:a8:b8:c4 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.10/24 brd 192.168.1.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet 192.168.1.100/24 scope global secondary eth0:vip
       valid_lft forever preferred_lft forever

3. 查看Keepalived日志

检查日志以确认Keepalived的运行状态:

1. 查看Keepalived专用日志
sudo cat /var/log/keepalived.log

1. 查看系统日志中的Keepalived信息
sudo grep keepalived /var/log/messages

4. 测试VIP访问

从其他客户端机器上测试是否可以通过VIP访问服务:

1. Ping测试VIP连通性
ping 192.168.1.100

1. 如果运行Web服务,测试HTTP访问
curl http://192.168.1.100/

八、故障切换测试

进行以下测试,验证高可用功能是否正常:

1. 模拟主服务器故障

在主服务器上执行:

1. 停止Keepalived服务
sudo systemctl stop keepalived

1. 或者关闭网卡
sudo ifconfig eth0 down

2. 观察VIP漂移

在备服务器上查看IP地址,确认VIP是否成功漂移:

ip addr show eth0

3. 模拟业务服务故障

在主服务器上停止HTTP服务:

sudo systemctl stop httpd

等待几秒钟,观察VIP是否因为健康检查失败而漂移到备服务器。

4. 模拟心跳网络故障

在主服务器上禁用心跳网卡:

sudo ifconfig eth1 down

观察VIP是否成功漂移到备服务器。

5. 恢复测试

在完成上述测试后,恢复服务并观察VIP行为:

1. 重新启动Keepalived
sudo systemctl start keepalived

1. 或启用网卡
sudo ifconfig eth0 up
sudo ifconfig eth1 up

1. 启动业务服务
sudo systemctl start httpd

九、故障排查

当Keepalived出现问题时,可以按照以下步骤进行故障排查:

1. 检查服务状态

1. 查看Keepalived运行状态
sudo systemctl status keepalived

1. 查看Keepalived进程
ps -ef | grep keepalived

2. 检查日志信息

1. 查看Keepalived日志
sudo tail -f /var/log/keepalived.log

1. 查看系统日志
sudo tail -f /var/log/messages

3. 检查网络配置

1. 查看网卡状态
ip addr show

1. 查看路由表
ip route show

1. 检查网络连通性
ping -I eth0 192.168.1.20  # 业务网卡连通性测试
ping -I eth1 10.0.0.2      # 心跳网卡连通性测试

4. 检查防火墙规则

1. 检查防火墙状态
sudo systemctl status firewalld

1. 查看防火墙规则
sudo firewall-cmd --list-all

5. 常见问题及解决方案

问题1:VIP无法正常漂移

  • 检查两台服务器的virtual_router_id是否一致
  • 检查authentication密码是否一致
  • 检查心跳网络是否正常通信
  • 检查防火墙是否允许VRRP协议通行

问题2:两台服务器同时拥有VIP(脑裂)

  • 检查心跳网络是否正常
  • 验证unicast_peer配置是否正确
  • 增加额外的监控机制,如添加track_interface监控心跳网卡

问题3:服务检测脚本不生效

  • 检查脚本权限是否正确
  • 验证脚本路径是否正确
  • 检查脚本中的命令是否可以在系统中执行
  • 使用debug参数增加日志信息进行排查

问题4:VIP能ping通但业务无法访问

  • 检查业务服务是否正常运行
  • 验证防火墙是否允许业务端口通行
  • 检查SELinux是否阻止了服务访问

十、配置参数详解

全局配置参数

参数名称 说明 示例值
router_id 路由器标识,应在集群内唯一 MASTER_SERVER
notification_email 告警邮件接收地址 admin@example.com
smtp_server 邮件服务器地址 127.0.0.1
vrrp_garp_interval GARP报文发送间隔(秒) 1
log_facility 日志设施 local0

VRRP实例参数

参数名称 说明 示例值
state 初始状态,MASTER或BACKUP MASTER
interface 绑定VIP的网卡名称 eth0
virtual_router_id 虚拟路由器ID,集群内必须相同 51
priority 优先级,值越大越优先成为MASTER 100
advert_int VRRP通告间隔(秒) 1
unicast_src_ip 本机心跳源IP地址 10.0.0.1
unicast_peer 对端心跳IP地址列表 10.0.0.2
nopreempt 是否禁用抢占模式 (不设置为启用抢占)
preempt_delay 抢占延迟(秒) 300

检查脚本参数

参数名称 说明 示例值
script 检查脚本路径 /etc/keepalived/check_httpd.sh
interval 检查间隔(秒) 2
weight 检查失败时的优先级调整值 -5
fall 连续失败多少次才算真失败 2
rise 连续成功多少次才算真成功 1

十一、优化与最佳实践

  1. 心跳网络冗余

    • 考虑为心跳网络配置双线路或绑定两个物理接口,避免单点故障
    • 可以考虑添加第三条网络链路作为心跳检测的备份通道
  2. 调整切换灵敏度

    • 根据业务重要性调整advert_int、fall和rise参数
    • 重要业务可以降低fall值提高响应速度,非关键业务可以提高fall值避免误切换
  3. 预防脑裂问题

    • 使用多条心跳线路
    • 在健康检查脚本中增加外部判断条件(如网关可达性)
    • 配置fence设备强制隔离故障节点
  4. 监控与告警

    • 配置邮件、短信或第三方监控系统对Keepalived状态变化进行告警
    • 记录详细的日志用于故障分析
  5. 安全加固

    • 使用强密码或AH认证方式增强VRRP安全
    • 限制心跳网段的访问控制
    • 定期更改认证密码

十二、总结

Keepalived双网卡主备方案通过以下机制保障业务高可用:

  1. 物理隔离:业务与心跳分离,提高检测可靠性
  2. 快速切换:基于VRRP协议实现1-3秒内的故障转移
  3. 多级检测:支持心跳检测、服务检测等多重机制
  4. 简单高效:配置简单,无需复杂集群管理,维护成本低

这种架构特别适合对可靠性有较高要求、但又不希望过于复杂的中小型业务系统。对于更高可用性需求,可以考虑在此基础上扩展到多节点集群方案。

sudo systemctl restart network
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇