高可用-Keepalived 解析

高可用 - Keepalived 解析

官网:https://www.keepalived.org/


HA 集群能解决哪些问题?

当计划使用 HA 集群时,有一个重要问题需要回答:服务放到 HA 集群中,可用性是否会增加?

回答这个问题,需要弄清楚服务的能力以及客户端如何配置。

取决于具体方案。例如 DNS 和 LDAP 自带故障转移或负载均衡,再放入 HA 集群往往收益不大。DNS/LDAP 可使用多实例、master/slave 或多 master,并在多服务器间同步数据;客户端也可配置多个服务器地址,本身已具备冗余,因此再放入 HA 集群通常不会明显增加可用性。

未自带 Failover 或 LB 的服务,配置为 HA 集群则收益明显。例如在 OpenStack 方案中,将 RabbitMQ、Galera 等放入 HA 集群会带来很大好处。

但并不是所有可用性问题都能靠 HA 集群解决:

  • 若应用程序因 bug 导致 crash,即使配置了 HA,应用仍会 crash;故障会漂移到其他节点,但其他节点运行相同版本,同样可能 crash。
  • HA 集群不提供端到端冗余。集群本身正常,若网络架构存在单点导致集群不可达,客户端仍无法访问。需整体设计,避免集群内外任何组件成为单点。

Keepalived 介绍

Keepalived 是用 C 语言编写的路由软件,主要目标是为 Linux 及基于 Linux 的基础设施提供简单而健壮的负载均衡与高可用能力。

Keepalived 起初为 LVS 设计,用于监控集群中各服务节点状态。它依据 TCP/IP 参考模型第三、四、五层机制检测节点;若某节点异常或故障,Keepalived 会自动将其从集群中剔除,无需人工干预,人工主要负责修复故障节点。

后来 Keepalived 加入 VRRP 功能。VRRP(Virtual Router Redundancy Protocol,虚拟路由冗余协议)用于解决静态路由单点故障,实现网络不间断运行。因此 Keepalived 同时具备:服务健康检测与故障隔离、HA 集群(VRRP) 两类能力。


VRRP 协议

现实中,主机间通信多依赖静态路由或默认网关;网关路由器一旦故障,通信即中断,路由器成为单点瓶颈。VRRP 即用于解决该问题。

VRRP 是一种主备模式协议,可在网络故障时透明切换设备,尽量不影响主机间数据通信。

VRRP 可将两台或多台物理路由器虚拟成一台虚拟路由器,通过虚拟 IP(VIP,可多个)对外提供服务。虚拟路由器内部多台物理路由器协同工作,同一时刻仅一台作为主路由器(Master)对外服务。Master 通常由选举产生,持有 VIP,负责 ARP、ICMP 转发等;其余为 BACKUP,不持有对外 VIP,主要接收 Master 的 VRRP 通告。Master 故障时,BACKUP 重新选举,新的 Master 接管服务,对用户尽量透明。

每个虚拟路由器有唯一标识 VRID;一个 VRID 与一组 IP 构成一个虚拟路由器。VRRP 报文通过 IP 多播发送。Master 持续发送 VRRP 报文,BACKUP 接收并监控 Master;一般 BACKUP 不会抢占,除非其 priority 更高。Master 不可用时,BACKUP 收不到通告即认定 Master 故障,多台 BACKUP 选举,priority 最高者成为新 Master,切换速度很快,从而保证服务持续可用。


工作原理

Keepalived 通过 VRRP 实现高可用,并可监控集群节点运行状态、做故障隔离。其工作涉及 TCP/IP 网络层、传输层、应用层

网络层

涉及 IP、ICMP、ARP、RARP 等。常见方式是通过 ICMP 向集群各节点发包(类似 ping);无响应则判定节点故障并剔除。

传输层

涉及 TCP、UDP。通过 TCP 端口探测判断节点端口是否正常(如 Web 的 80、SSH 的 22);无响应则剔除对应节点。

应用层

可结合 FTP、SMTP、DNS 等高层协议,或通过自定义脚本检测进程/服务;结果与预期不符则剔除节点。


脑裂(Split-Brain)

在 Keepalived 高可用集群中,脑裂指主从(或双主)节点因通信中断,各自认为对方故障,同时争抢资源(如 VIP),导致集群状态混乱。

脑裂产生的原因

核心是心跳失败但节点实际仍存活,常见原因:

  1. 网络问题:心跳专线、交换机故障、断网或高延迟。
  2. 防火墙规则 :节点间 VRRP 协议(默认 UDP 112) 被屏蔽。
  3. 资源耗尽:CPU/内存/负载过高,无法响应心跳。
  4. 配置错误vrrp_instancestatepriorityauthentication 等不一致,无法正常协商。

脑裂的危害

  • 双节点同时持有 VIP,客户端请求混乱。
  • 若管理数据库、存储等,可能双写、数据不一致。
  • 集群失去高可用意义,甚至因资源竞争导致服务崩溃。

如何避免脑裂?

通过 多重检测资源隔离 预防:

增加心跳检测线路

除主网络外,增加备用线路(独立网卡、交叉网线等)。在 keepalived.conf 中指定多网卡检测:

conf 复制代码
vrrp_instance VI_1 {
    state MASTER
    interface eth0          # 主网卡
    virtual_router_id 51
    priority 100
    advert_int 1
    track_interface {
        eth0
        eth1                # 备用网卡
    }
}
启用 VRRP 认证
conf 复制代码
vrrp_instance VI_1 {
    # ... 其他配置
    authentication {
        auth_type PASS      # PASS 或 AH
        auth_pass 123456    # 所有节点必须一致
    }
}
配置防火墙规则
bash 复制代码
# 允许 VRRP 协议(CentOS 示例)
firewall-cmd --add-protocol=vrrp --permanent
firewall-cmd --reload
部署 fence 或 notify 脚本

使用 fence (如 fence_virshfence_ipmilan)或脚本,检测到脑裂时隔离异常节点。

conf 复制代码
vrrp_instance VI_1 {
    notify_master "/etc/keepalived/check_split_brain.sh master"
    notify_backup "/etc/keepalived/check_split_brain.sh backup"
}

脚本可通过 ping、端口检测确认对端;若脑裂可对异常节点执行 killreboot(需严格评估风险)。

降低脑裂影响范围
  • 数据库:主从 + 读写分离,避免双写。
  • 存储:分布式锁(如 Redis)控制独占。
  • 仅在确认集群状态正常时对外提供 VIP 服务。
监控与告警

通过 Zabbix、Prometheus 等监控 Keepalived 状态、vrrp_script 检测;发现双主等情况及时告警。

总结

脑裂本质是通信失效与状态判断不一致 。预防核心是 「多重检测 + 自动隔离」:多线路心跳、认证降低误判;脚本与 fence 在脑裂时快速隔离;配合监控及时干预。


Keepalived 高可用技术实践

网络拓扑

主机名 IP 地址 服务器角色
client2.rich.cloud 10.1.1.21 客户端
client1.rich.cloud 10.1.8.21 客户端
router.rich.cloud 10.1.1.20, 10.1.8.20 路由器
web1.rich.cloud 10.1.8.11 Web 服务器
web2.rich.cloud 10.1.8.12 Web 服务器

网络说明:

  1. 所有主机:第一块网卡 ens33,第二块网卡 ens192
  2. 默认第一块网卡 NAT,第二块 Host-only。
  3. 网关:10.1.1.0/24 网段网关为 10.1.1.2010.1.8.0/24 网段网关为 10.1.8.20

基础配置

网关配置命令参考:

bash 复制代码
# 10.1.1.0/24 网段网关为 10.1.1.20
nmcli connection modify ens33 ipv4.gateway 10.1.1.20
nmcli connection up ens33

# 10.1.8.0/24 网段网关为 10.1.8.20
nmcli connection modify ens33 ipv4.gateway 10.1.8.20
nmcli connection up ens33
配置 router
bash 复制代码
# 开启 firewalld,配置 SNAT,使不同网段经路由器访问公网
systemctl enable firewalld.service --now
firewall-cmd --add-masquerade --permanent
firewall-cmd --reload

# 开启 IP 转发
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
# 或:sed -i 's/ip_forward=0/ip_forward=1/g' /etc/sysctl.conf
sysctl -p
配置 Web
bash 复制代码
yum install -y nginx
echo "Welcome to $(hostname)" > /usr/share/nginx/html/index.html
systemctl enable nginx.service --now

访问后端 Nginx:

bash 复制代码
[root@client1 ~]# curl 10.1.8.11
Welcome to web1.rich.cloud
[root@client1 ~]# curl 10.1.8.12
Welcome to web2.rich.cloud

配置 Keepalived

配置 web2(BACKUP)
bash 复制代码
yum install -y keepalived
cp /etc/keepalived/keepalived.conf{,.ori}
vim /etc/keepalived/keepalived.conf
conf 复制代码
! Configuration File for keepalived

global_defs {
    router_id web2
}

vrrp_instance nginx {
    state BACKUP
    interface ens33
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass Rich@123
    }
    virtual_ipaddress {
        10.1.8.100
    }
}

参数说明:

参数 说明
router_id 路由器名称,每节点不同
state MASTER / BACKUP
interface 绑定 VIP 的网卡
virtual_router_id 虚拟路由器 ID,1--255,集群内相同
priority 优先级,越大越优先
authentication VRRP 心跳认证
virtual_ipaddress VIP 地址
bash 复制代码
# 查看 IP
[root@web2 ~]# ip -br a show ens33
ens33  UP  10.1.8.12/24  10.1.8.100/24  ...

# 启动服务
[root@web2 ~]# systemctl enable keepalived.service --now
配置 web1(MASTER)
bash 复制代码
yum install -y keepalived
cp /etc/keepalived/keepalived.conf{,.ori}
vim /etc/keepalived/keepalived.conf
conf 复制代码
! Configuration File for keepalived

global_defs {
    router_id web1
}

vrrp_instance nginx {
    state MASTER
    interface ens33
    virtual_router_id 51
    priority 110          # MASTER 优先级应高于 BACKUP
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass Rich@123
    }
    virtual_ipaddress {
        10.1.8.100
    }
}
bash 复制代码
systemctl enable keepalived.service --now

[root@web1 ~]# ip -br a show ens33
ens33  UP  10.1.8.11/24  10.1.8.100/24  ...

[root@web2 ~]# ip -br a show ens33
ens33  UP  10.1.8.12/24

高可用验证

bash 复制代码
[root@client2 ~]# curl 10.1.8.100
Welcome to web1.rich.cloud

# 关闭 web1 的 keepalived
[root@web1 ~]# systemctl stop keepalived.service
[root@client1 ~]# curl 10.1.8.100
Welcome to web2.rich.cloud

# 再次启动 web1
[root@web1 ~]# systemctl start keepalived.service
[root@client1 ~]# curl 10.1.8.100
Welcome to web1.rich.cloud

keepalived 配置文件说明

配置文件:/etc/keepalived/keepalived.conf,主要包括三部分:

  • GLOBAL:全局配置
  • VRRPD:VRRP 协议配置
  • LVS:LVS 服务管理配置

配置示例

conf 复制代码
! Configuration File for keepalived

# 全局配置
global_defs {
    notification_email {
        acassen@firewall.loc
        failover@firewall.loc
        sysadmin@firewall.loc
    }
    notification_email_from Alexandre.Cassen@firewall.loc
    smtp_server 192.168.200.1
    smtp_connect_timeout 30
    router_id LVS_DEVEL
    vrrp_skip_check_adv_addr
    vrrp_strict
    vrrp_garp_interval 0
    vrrp_gna_interval 0
}

# VRRP 协议配置
vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.200.16
        192.168.200.17
        192.168.200.18
    }
}

# LVS 服务管理配置
virtual_server 192.168.200.100 443 {
    delay_loop 6
    lb_algo rr
    lb_kind NAT
    persistence_timeout 50
    protocol TCP

    real_server 192.168.201.100 443 {
        weight 1
    }
}

详细信息参考:keepalived.conf(5) 手册页。

Keepalived 日志

在 web1、web2 节点执行:

bash 复制代码
# 配置 rsyslog
vim /etc/rsyslog.d/keepalived.conf
# 添加:local0.*    /var/log/keepalived.log

vim /etc/sysconfig/keepalived
# 将 KEEPALIVED_OPTIONS="-D"
# 改为:KEEPALIVED_OPTIONS="-D -d -S 0"

systemctl restart rsyslog
systemctl restart keepalived.service

tail -f /var/log/keepalived.log

Keepalived 心跳(组播源 IP)

参数 mcast_src_ip 示例:

conf 复制代码
global_defs {
    router_id Cluster1
}

vrrp_instance Nginx {
    state MASTER
    interface ens36
    mcast_src_ip 20.0.0.11
    virtual_router_id 51
    priority 110
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass rich@123
    }
    virtual_ipaddress {
        10.1.1.10/24
    }
}

Keepalived 高可用技术小结

Keepalived 基于 VRRP 实现高可用,核心通过 VIP 提供统一访问入口,支持主备、双主等部署模式。通过 priority 确定主节点;主节点故障时备节点自动接管 VIP 与服务,实现较快切换;还可配合健康检查脚本监测后端服务。常与 LVS、Nginx 等负载均衡组件联动,解决单点故障,为 Web、数据库等构建稳定的高可用架构。

相关推荐
fiveym1 小时前
Linux systemctl服务管理全解析:命令+原理+运维最佳实践
linux·运维·服务器
xlq223221 小时前
56.自定义协议
linux·服务器·网络·网络协议
learning-striving2 小时前
华为云欧拉操作系统的服务器实例中手工部署 Docker
linux·运维·服务器·docker·容器·华为云
戴西软件2 小时前
戴西软件入选2026年安徽省制造业数智化转型服务商名单
java·大数据·服务器·前端·人工智能
小此方2 小时前
Re:Linux系统篇(十五)工具篇 ·六:GDB 调试从底层逻辑到高阶实战
linux·运维·服务器·chrome
白菜欣10 小时前
Linux — 进程控制
android·linux·运维
JoneBB10 小时前
ABAP Webservice连接
运维·开发语言·数据库·学习
Tolalal11 小时前
Vmware Ubuntu虚拟机扩容
linux·运维·ubuntu
咚为12 小时前
比AccessLog更全面的原生Nginx 日志记录
运维·nginx·junit