Keepalived 实现高可用

1. Keepalived 概述

Keepalived 是一个基于 VRRP(Virtual Router Redundancy Protocol,虚拟路由冗余协议) 的高可用性(HA,High Availability)解决方案,主要用于:

  • IP 故障转移(IP Failover):确保服务 IP 在服务器故障时自动迁移到备用节点。
  • 负载均衡健康检查:监控后端服务器状态,自动剔除故障节点(通常结合 LVS、Nginx、HAProxy 使用)。
  • 轻量级高可用集群:适用于 Web 服务器、数据库、防火墙等场景。

VRRP 协议

  • 是一种网络容错协议,用于在多个路由器(或负载均衡器)之间实现高可用性(HA),确保当主设备故障时,备份设备能无缝接管流量。
  • 多个设备组成一个VRRP 组(VRID),这个组里面有一个master 和多个 backup,其中master上面有一个对外提供服务的 VIP(Virtual IP Address)。
  • master 会发组播,当 backup 收不到 VRRP 包时就认为 master 宕掉了,这时就需要根据 VRRP 的优先级来选举一个 backup 当 master。VIP会自动漂移过去。
    • 优先级:范围 1-254,优先级高的节点成为 Master(默认 100),值越大优先级越高。
    • 原Master恢复后,若优先级高于当前Master,会重新抢占角色(需配置nopreempt禁止抢占,具体配置方式后面详细介绍)。
  • 注意:
    • VRRP 依赖局域网LAN多播或广播,所以要求必须在同一个局域网内。
    • VRRP通告消息直接封装在IP数据包中发送,因此VRRP数据包本质上就是普通的IP数据包,所以说VRRP协议不需要特殊的网络设备来解析。

2. Keepalived 典型架构

                    +-------------+
                    |   Client    |
                    +------+------+
                           |
                           | VIP: 192.168.1.100
           +----------------+----------------+
           |                                 |
 +---------+---------+             +---------+---------+
 |   Master Node     |             |   Backup Node     |
 | (Keepalived Master)|             | (Keepalived Backup)|
 | IP: 192.168.1.1   |             | IP: 192.168.1.2   |
 | VIP: 192.168.1.100|             | VIP: -            |
 +-------------------+             +-------------------+
TeX

3. Keepalived 主要模块

keealived 的组成主要有三个模块,分别是 core、check 和 vrrp。

  • core 模块为keepalived的核心,负责主进程的启动、维护以及全局配置文件的加载和解析。
  • check 负责健康检查,包括常见的各种检查方式。
  • vrrp 模块是来实现 VRRP 协议的。

4. Keepalived 部署示例

4.1. 安装

yum install keepalived -y
apt install keepalived -y

# 源码安装
# 下载地址:
https://www.keepalived.org/download.html

# 安装
tar -zxvf keepalived-2.2.8.tar.gz
cd keepalived-2.2.8
./configure --prefix=/usr/local/keepalived --sysconf=/etc make && make install
# 参数说明
--sysconf  # keepalived 核心配置文件所在位置,固定位置,如果改成其他位置则 keepalived启动会报错
--prefix  # 指定 Keepalived 的安装路径,编译后的二进制文件、库等将安装到此目录下

# 如果报错: the build will not support IPVS with IPv6.Please install libnl/libnl-3 dev xxxxxxx 解决方案:
# 安装 libnl/libnl-3依赖 
yum -y install libnl libnl-devel libnl3* libnl3-devel*
# 再重新安装 keepalived
Bash

4.2. 配置文件

主节点:

# /etc/keepalived/keepalived.conf

! Configuration File for keepalived
global_defs {
    script_user root 
    enable_script_security
}

# 健康检测参数配置
vrrp_script chk_nginx {
    # 定义健康检测脚本路径
    script "/etc/keepalived/check_port.sh"
    # 每隔3s运行一次上面的脚本
    interval 3
    # 如果脚本运行失败,则在 priority 的基础上权重值减 20
    # 一旦 priority 低于备节点,则基于下述 advert_int 的设置 1s 内vrrp就能检测到然后完成主备切换
    weight -20
}

vrrp_instance VI_1 {
    # 表示状态是 MASTER 主机还是备用机 BACKUP,初始都设置为 BACKUP,然后通过 priority 的高低来决定谁是主
    state BACKUP
    # 绑定 VIP 的网卡
    interface ens33
    # 所有主备节点保持一致,代表在一个路由组里
    virtual router_id 251
    # 当前节点的优先级,
    priority 100
    # 设定VRRP设备发送广播消息的时间间隔为 1s 一次,以确定VRRP群组成员的状态同步,确保主挂掉后能够快速进行主备切换
    advert int 1
    # 非抢占式
    nopreempt
    # 认证权限密码,防止非法节点进入
    authentication {
        auth_type PASS
        auth_pass 1234
    }
    # 引用上述定义的健康检测配置
    track_script {
        chk_nginx
}
    # 虚拟 IP(VIP),可以有多个
    virtual_ipaddress {
    192.168.2.200
    }
}
Bash

备节点:

# 
vrrp_instance VI_1 {
    state BACKUP         # 初始状态为 Backup
    priority 90          # 优先级低于 Master
    # 其他配置与 Master 相同
}
Bash

4.3. 健康检测脚本示例

将脚本保存到 /etc/keepalived/ 目录,并赋予可执行权限:

#!/bin/bash

# 定义日志文件路径(可选,用于调试)
LOG_FILE="/var/log/keepalived-nginx-check.log"
NGINX_RESTART_MAX_ATTEMPTS=1  # 最大重启尝试次数

# 记录日志函数
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
}

# 检查 Nginx 是否正常运行
check_nginx() {
    # 检查1: Nginx 进程是否存在
    if ! pgrep -x "nginx" > /dev/null; then
        log "Nginx process not found. Attempting to restart..."
        return 1
    fi

    # 检查2: Nginx 端口是否可访问,这里以 80 端口为例
    if ! curl -s -I --connect-timeout 3 http://127.0.0.1:80 > /dev/null; then
        log "Nginx port 80 is unreachable. Attempting to restart..."
        return 1
    fi

    # 检查3: HTTP 状态码是否为 200
    HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:80)
    if [ "$HTTP_STATUS" != "200" ]; then
        log "Nginx returned HTTP $HTTP_STATUS. Attempting to restart..."
        return 1
    fi

    return 0  # 所有检查通过
}

# 尝试重启 Nginx
restart_nginx() {
    log "Restarting Nginx (attempt $((RESTART_ATTEMPTS + 1))..."
    systemctl restart nginx
    sleep 2  # 等待 Nginx 启动
}

# 主逻辑
RESTART_ATTEMPTS=0
while [ $RESTART_ATTEMPTS -lt $NGINX_RESTART_MAX_ATTEMPTS ]; do
    if check_nginx; then
        log "Nginx is healthy."
        exit 0
    else
        restart_nginx
        ((RESTART_ATTEMPTS++))
    fi
done

# 如果所有重启尝试均失败
log "Nginx could not be restored after $NGINX_RESTART_MAX_ATTEMPTS attempts."
exit 1  # 触发 Keepalived 切换
Bash

注意:脚本运行时间不能超过 Keepalived 配置的脚步运行间隔时间,否则脚本在运行时会被 kill -15 终止。

4.4. 启动

# 设置开机自启
systemctl enable keepalived 
systemctl start keepalived 

# 查看状态
systemctl status keepalived
Bash

4.5. 查看当前节点的优先级命令

方法 1:通过系统日志实时查看

Keepalived 会在主备切换时记录优先级信息到系统日志(默认 /var/log/messages 或 journalctl):

# 查看 Keepalived 日志(Linux 系统通用)
sudo grep -i "priority" /var/log/messages

# 或使用 journalctl(Systemd 系统)
sudo journalctl -u keepalived -n 50 | grep -i "priority"
Bash

输出示例:

Keepalived[PID]: VRRP_Instance(VI_1) Changing effective priority from 100 to 80

# 此方法可看到优先级动态变化(如因 vrrp_script 健康检查失败导致优先级降低)。
Bash

方法 2:通过 ip vrrp 命令查看(Linux 内核 ≥4.3)

如果系统支持 ip vrrp 命令(需内核模块 vrrp),可直接查看当前 VRRP 实例的优先级:

ip vrrp show
Bash

输出示例:

eth0    51      master    192.168.1.100    90     advert_int 1

# 第5列(90):当前节点的优先级。
Bash
上一篇
下一篇