资讯动态

Keepalived 1.2.13编译配置实战:VRRP双机热备与虚拟IP漂移

发布时间:2026/10/15 13:52:11 来源:尧图企业网站定制
简介Keepalived 1.2.13 源码压缩包面向网络运维工程师、Linux 后端开发者以及需要搭建双机热备环境的系统架构师用于构建基于 VRRP 协议的高可用服务。包内共 188 个文件核心为 62 个 h 头文件与 61 个 c 源文件同时带有 keepalived.conf 配置示例、init 启动脚本、pem 证书及版本说明完整呈现该版本在 VRRP 状态机、健康检查和 LVS 集成方面的代码实现整包仅 334KB便于快速下载和本地编译。已有 368 人学习适合希望深挖 MASTER/BACKUP 状态机切换逻辑以及理解 TCP、HTTP、ICMP 多种健康检查机制的中高级运维人员。借助其中的 man 手册和 genhash 工具源码读者可以逐项对照配置参数理解 advert_int、priority、track_script 等关键指令的含义也能在故障排查时直接借助 vrrp 报文分析虚拟 IP 漂移过程。进一步地可参考资源内置的样例与目录结构结合 Nginx、MySQL 设计 Web 服务和数据库的高可用集群把源码级知识转化为实际运维能力。1. 拿到 keepalived-1.2.13.tar.gz这不是一个过时软件而是一份 HA 体系的活教材如果你在维护一套 Nginx 或者 LVS 入口大概率听过 keepalived 这个名字它靠 VRRP 协议漂移虚拟 IP让两台机器在彼此眼皮底下做故障接管。但很多人第一次面对 keepalived-1.2.13.tar.gz 这个压缩包时第一反应是版本是不是太老了。实际上这个版本是一个非常稳定的经典分支CentOS 6/7 时代的运维几乎都是从这个版本起步的今天依然有人在生产环境里用它做双机热备。与其追新版本踩一堆编译和新特性坑不如先把这个包的编译、配置和故障切换逻辑吃透你后面迁移到新版也就多几步的事。这篇笔记会直接照着 keepalived-1.2.13 源码包展开从 VRRP 原理讲到编译参数再落到一份可复制的双机主备配置最后把我在模拟项目X里踩过的坑一次说清。适合正在搭负载均衡入口、或者刚接手老集群想弄明白这个VIP是怎么飘的的开发者。2. 先搞懂 keepalived 到底在干什么VRRP 协议、组件分工与版本选型2.1 VRRP 协议的核心逻辑虚拟 IP 为什么不会丢keepalived 最底层的本事来自 VRRPVirtual Router Redundancy Protocol虚拟路由冗余协议。它不是让两台机器同时提供服务而是把一组路由器或者服务器抽象成一个虚拟路由器对外只暴露一个虚拟 IPVIP。这个 VIP 在某一时刻只属于一台机器这台机器叫 Master其余机器叫 Backup。Master 周期性发送 VRRP 广播报文Backup 收到就安心待命一旦 Backup 连续几个周期没收到报文它就认定 Master 挂了立刻把自己提升为 Master并且广播 ARP 通知交换机VIP 的 MAC 地址变了。注意几个细节。第一VRRP 报文默认走组播组播地址是 224.0.0.18协议号 112所以防火墙和交换机必须放行这条链路。第二Master 和 Backup 之间不是靠应用层心跳而是靠 VRRP 报文的优先级priority决定身份。priority 默认为 100数值越大越容易成为 Master。第三VRRP 本身不管你的 Nginx 是否真的活着它只管这台机器是否还能发报文。所以需要额外加一层服务检测脚本这就是后面 vrrp_script 干的事。2.2 keepalived 的两个核心进程vrrpd 与 checkerskeepalived 启动后会拉起多个子进程最关键的是 vrrpd 和 checkers。vrrpd 负责 VRRP 报文的收发和 VIP 的漂移逻辑checkers 负责健康检查比如检测后端真实服务器的端口是否通、HTTP 状态码是否正常这个主要用在 LVS 场景下做后端摘除与恢复。所以 keepalived 实际有两种主流用法。第一种是把它当 LVS 的调度器高可用组件配合 ipvsadm 做四层负载均衡checkers 进程去探活后端 RS。第二种是把它当 Nginx 等应用入口的 HA 工具只用到 VRRP 功能依靠 vrrp_script 外挂脚本检测 Nginx 进程或端口状态挂掉就让 VIP 漂走。我们接下来主要讨论第二种因为部署简单可以直接套到你的 Nginx 双机场景。2.3 为什么选 1.2.13版本演进的边界与依赖差异keepalived 1.2.13 发布至今已经有年头但它有一个优势编译依赖非常传统popt、openssl、libnl 三件套就够不涉及新版本链接库的折腾。而 1.3.x 和 2.x 系列开始引入更多新特性比如 VRRP v3 的 IPv6 支持、更强的脚本框架、DBus 接口同时对编译器版本和内核头文件更敏感如果在老系统上编译反而更麻烦。从学习角度讲1.2.13 的配置文件语法是所有版本里最经典的vrrp_instance、vrrp_script、virtual_ipaddress 这些核心概念从 1.2.x 一直延续到 2.x几乎没有破坏性变更。先把这个版本跑通你后续升级只是增加字段而已。我一般建议老机器稳定优先直接用 1.2.13 的包即可新机器如果对 IPv6 或 VRRPv3 有需求再去考虑新版。3. 编译与安装configure 参数、make 报错和开机自启3.1 编译前的环境准备在开始前先确认几样东西操作系统是 CentOS 6/7 或者同类 RHEL 系gcc 编译器有内核开发头文件有。然后用下面的命令装依赖yum install -y gcc openssl-devel popt-devel libnl-devel这里解释一下三个依赖各自的角色。openssl-devel 提供加密库主要用于后面配置文件中密码认证和生成随机数等场景没有它 configure 会直接报错找不到 OpenSSLpopt-devel 是命令行参数解析库keepalived 的主程序解析启动参数靠它libnl-devel 是 netlink 库keepalived 需要通过 netlink 与内核通信来配置 IP 地址和路由信息在 1.2.13 这个版本上缺少 libnl 会导致编译失败或运行时无法操作 VIP。注意这里有一个坑libnl 库在 CentOS 6 上包名是 libnl-devel而在 CentOS 7 上保留了 libnl3-devel 的选项但 1.2.13 默认编译依赖的是 libnl 版本一组如果你的系统同时装了 libnl3需要在 configure 时用 --enable-libnl 指定老库版本。这个下面会专门讲到。3.2 configure 参数详解与编译命令解压源码包并按下面的顺序操作tar -zxvf keepalived-1.2.13.tar.gz cd keepalived-1.2.13 ./configure --prefix/usr/local/keepalived --sysconfdir/etc/keepalived --with-kernel/usr/src/kernels/$(uname -r) make -j4 make installconfigure 这一步有几个参数值得细说。--prefix 指定安装路径我习惯装到 /usr/local/keepalived这样不影响系统自带的文件布局--sysconfdir 是配置文件目录默认是 /etc/keepalived这个路径不需要改因为后面 systemd 或者 init 脚本默认都会找这个目录--with-kernel 指向内核源码或头文件目录在 CentOS 上如果没装 kernel-devel这个路径可能不存在建议 yum install -y kernel-devel 先补上否则编译时 VRRP 相关模块可能缺少内核头文件。如果 configure 报错找不到 libnl加下面这个参数显式指定./configure --prefix/usr/local/keepalived --sysconfdir/etc/keepalived --enable-libnl这里 --enable-libnl 的作用是强制让 configure 使用 libnl 而不是 libnl3因为 keepalived 1.2.13 的代码是为老版 libnl API 写的。如果你系统里只有 libnl3用这个参数还不能解决那么就得软链一个 libnl.so.1 出来或者安装 compat-libnl 库。3.3 安装后的服务配置与 PATH 设置安装完成后keepalived 的可执行文件和配置模板会散落到几个目录里。我一般会做三件事第一把二进制路径加入 PATH第二把源码包里 contrib 目录下的 init 脚本拷到 /etc/init.d/ 下第三创建一个简单的配置文件验证版本。ln -s /usr/local/keepalived/sbin/keepalived /usr/sbin/keepalived cp /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/keepalived chmod x /etc/init.d/keepalived chkconfig --add keepalived keepalived --version上面第三句是为了让 init 脚本能管理这个服务老版本 CentOS 用 chkconfig 很顺手。执行 keepalived --version 如果能看到 Keepalived v1.2.13 字样说明编译安装成功。如果确认安装没问题但 systemd 方式启动报错找不到二进制就检查一下 /etc/init.d/keepalived 脚本里定义的 KEEPALIVED_BIN 路径改成实际的 sbin 路径即可。4. 双机主备配置实战从单机启动到自动漂移4.1 全局定义与 vrrp_instance 结构配置文件默认路径是 /etc/keepalived/keepalived.conf。这一节直接给出一份可以在两台机器上用的主备配置先看主节点的global_defs { router_id LVS_HA_01 notification_email { adminexample.com } smtp_server 127.0.0.1 smtp_connect_timeout 30 } vrrp_script chk_nginx { script /usr/local/sbin/check_nginx.sh interval 2 weight -20 fall 2 rise 1 } vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 123456 } virtual_ipaddress { 192.168.1.100/24 dev eth0 } track_script { chk_nginx } }说明一下这个文件里每个字段的含义。global_defs 里的 router_id 是 Keepalived 自身的标识不影响 VRRP 报文里面的 router id所以一组集群里的两台机器可以不同notification_email 和 smtp_server 用于发告警邮件如果要启用需要本机有邮件服务这个坑我在后面会提。vrrp_script 块定义了一个名为 chk_nginx 的检测操作它会在每个 interval 周期2秒执行一次后面的脚本并返回一个退出码。如果退出码非 0就认为检测失败当前节点的 priority 会被执行 weight 值这里是 -20的偏移。注意 direction检测成功时如果 rise 达到 1 次priority 就恢复原值失败时连续 fail 2 次才认为真的挂掉这是防止脚本抖动导致频繁切换。vrrp_instance 是核心。state MASTER 表示这个节点初始身份就是主节点priority 100 配合 backup 节点的 90实现主备身份判定interface eth0 是承载 VRRP 组播的物理网卡两台机器的这个网卡必须在同一个广播域virtual_router_id 51 是 VRRP 实例的 ID同一组集群内必须一致且不同集群不能共用同一个 ID否则会互相干扰advert_int 1 表示每秒发送一次 VRRP 报文。auth_pass 是明文密码两台机器要保持一致虽然叫密码但 VRRP v2 里只是做类型校验不做加密别当成防护手段。备节点配置只有三处不同state 改成 BACKUPpriority 改成 90router_id 改成 LVS_HA_02。另外备节点也照样写 vrrp_script 和 track_script因为切换过来后它要对自己的 Nginx 做检测如果它也挂了VIP 还会继续漂移如果还有第三台。4.2 实现健康检查脚本检测 Nginx 进程和端口上面配置里用到了 /usr/local/sbin/check_nginx.sh这个脚本是 VRRP 之外最重要的一环。如果没有它只要机器没宕机keepalived 就认为一切正常哪怕 Nginx 已经停了两小时VIP 也不会漂移到备机。脚本我一般写成这样#!/bin/bash if [ $(ps -ef | grep -c [n]ginx) -eq 0 ]; then exit 1 fi if ! nc -z 127.0.0.1 80 2/dev/null; then exit 1 fi exit 0这个脚本有两个检测逻辑。第一个通过 ps 查进程数确认 nginx 进程是否存在[n]ginx 的写法是为了避免 grep 自身进程被统计进去这是个老 trick第二个用 nc 探测本机 80 端口是否还能建立 TCP 连接防止进程还活着但服务已经假死的情况。如果两者任一不满足就返回 1此时 keepalived 会认为本机异常执行 priority 递减。很多人在这一步容易犯一个错脚本没有加执行权限。或者脚本的首行不是 #!/bin/bash直接导致 keepalived 无法执行。建议在配置完脚本后先手动执行一次 chmod x再用绝对路径跑一下看退出码是不是符合预期。keepalived 执行脚本时使用的是 root 权限所以脚本里面调用的命令路径第一定要完整否则切换瞬间环境中 PATH 不完整而导致误判。4.3 启动 Keepalived 并验证 VIP 状态配置全部就绪后在两台机器上分别启动/etc/init.d/keepalived start然后立即在主节点上查看 VIP 是否被正确绑定ip addr show dev eth0正常情况下主节点的 eth0 上会多出一个 192.168.1.100/24 的地址。如果没出现先不要慌大概率是配置里 dev eth0 和系统实际网卡名不一致也可能是防火墙拦截了 VRRP 协议。验证主备关系最直接的方法是看系统日志tail -f /var/log/messages | grep Keepalived在主节点看到 Entering MASTER STATE 说明它已经抢占为主备节点看到 Entering BACKUP STATE 说明它处于待命。这时可以尝试手动执行 /etc/init.d/keepalived restart 或者直接 kill 掉主节点的 keepalived 进程观察备节点是否在几秒内绑定 VIP。我第一次做这个实验时大概在 3 秒内就完成了切换也就是一个 advertise 周期加脚本检测周期的余量。有一点需要提醒这里所有命令都在 root 下执行。如果配置里写了 shutdown 或者 restart 等操作会在脚本逻辑中去做不要在配置文件里直接调 service restart 这种命令那会让 keepalived 进程在重启时发信号搞挂自己。5. 避坑锦囊Keepalived 实战中高频踩翻车的五个问题5.1 主备同时持有 VIP 导致 IP 冲突现象两台机器上都出现了 192.168.1.100 这个地址网络里出现 IP 冲突告警服务时好时坏。原因最常见的两种。第一两台机器的 virtual_router_id 不一致。只要 ID 不同两边就会各自为政都认为自己该持有 VIP。第二防火墙把 VRRP 组播封了备机收不到 Master 的报文误以为 Master 挂了就接管了 VIP。解决检查两边配置中的 virtual_router_id 和 authentication 字段是否完全一致然后在交换机或本机 iptables 里放行协议号 112 的组播包。我一般用 iptables -I INPUT -p vrrp -j ACCEPT 放行本机入站同时对出站不要做限制。如果发现两台机器都起来先停掉一台排查 ID 和防火墙不要直接重启服务。5.2 本来没挂却发生了切换现象主节点进程健康日志里却看到 Lost VP from ... 然后 VIP 漂移到了备机过一会儿又切回来。原因主节点在短时间内没有发出 VRRP 报文可能是突发负载导致 keepalived 进程调度延迟或者网卡驱动丢包。另一个常见原因是 vrrp_script 的 weight 设置太小脚本检测偶发超时就把 priority 减到 90和备节点持平甚至低于备节点。解决把 advert_int 增大到 2减少报文频率同时把 vrrp_script 里的 fall 改为 3意思是连续失败 3 次才降权。如果脚本检测本身不稳定在脚本里增加超时和重试逻辑不要用一条快速失败的网络请求去做检测。5.3 切换后服务起不来现象主节点 keepalived 停掉后备节点成功变成了 Master但是访问 VIP 发现服务不可用日志显示 VIP 绑定了但业务进程没起来。原因备机上只有 keepalived 在跑Nginx 没启动而 keepalived 不会负责拉起业务进程。很多人以为 VIP 过去就等于服务过去了其实完全两回事。解决在 vrrp_instance 里配置 notify 脚本比如 notify_master 或者 notify_backup在切换事件触发后执行对应的启动操作。我一般会在 notify_master 脚本里先 sleep 1 等 VIP 绑定完成再检测端口如果没监听就直接启动 Nginxnotify_backup 脚本里可以执行停止操作释放资源。5.4 配置文件里写了邮件通知切换时卡住现象主备切换的时候 keepalived 进程突然没有响应过了很久才恢复日志里全是 sendmail 相关的报错。原因global_defs 里配置了 notification_email 和 smtp_server但本机没有启动邮件服务或者 smtp_server 地址写错导致 keepalived 在处理邮件发送时阻塞等待。这个在低版本尤其常见收不到也不会影响切换但会拖住进程。解决如果不依赖邮件告警就直接把 notification_email 和 smtp_server 注释掉如果有告警需求确保本机 postfix 在运行或者把 smtp_connect_timeout 调小到 5 秒避免长时间阻塞。5.5 系统重启后 keepalived 没起来导致单点现象机房断电或者服务器被强制重启后VIP 落在了备机但主节点起来后 keepalived 没自动启动导致主节点一直处于空闲状态。原因chkconfig 里没有把 keepalived 设为开机自启或者 init 脚本对应的软链接没放进正确的 runlevel 目录。解决先确认 chkconfig --list keepalived 输出里 2、3、4、5 都是 on如果没开就执行 chkconfig --level 235 keepalived on。同时检查 /etc/init.d/keepalived 脚本头部是否包含 # chkconfig: 2345 80 90 这样的注释行如果没有init 脚本会直接拒绝被 chkconfig 管理。我遇到过脚本拷过来后没有执行权限chkconfig 添加时报错的情况先 chmod x 再 add 是固定动作。6. 用手动秒级切换验证配置捕获 VIP 漂移的全过程配置跑通之后不要急着宣布大功告成我每次都会强制手动做一轮完整的故障切换验证把漂移动作拆开来看确认每一环都符合预期。先做一次干净的停主节点动作。在 Master 上执行 /etc/init.d/keepalived stop然后在 Backup 上盯日志正常情况下应该在 advert_int 乘以 3 的秒数内看到 Entering MASTER STATE然后立刻检查 Backup 的 eth0 上是否出现 VIP再用 curl 访问 VIP 确认服务可用。这个验证能确认 VRRP 报文的交互链路是通的也能确认 notify_master 拉起业务的逻辑是正常的。接下来再测一个更接近真实故障的场景停掉 Nginx 而不是整个 keepalived。在主节点执行 service nginx stop然后等脚本检测周期预期是在 fall 2 次失败之后 priority 降低VIP 漂移到备机。这个场景能验证 vrrp_script 是否真正生效。很多人停 keepalived 一切正常但停 Nginx 却不切换问题就出在不清楚脚本检测的结果会被 track_script 拉起来还是降权。第三步是抓包验证。用 tcpdump 在备机上直接抓 VRRP 报文tcpdump -i eth0 vrrp -n -vv这个命令会抓到组播地址 224.0.0.18 上的 VRRP 包其中包含 priority 字段。正常稳定时备机收到的报文里 priority 是 100当主节点 Nginx 挂掉后你再看报文里的 priority 变成了 80说明脚本降权生效。备机看到比自己低的 priority 报文就会等一个 Skew Time 后接管 VIP。Skew Time 的计算公式是 (256 - priority) / 256priority 90 的时候延迟大约 0.65 秒所以切换速度很快。最后一步是恢复验证。把 Nginx 重新拉起等脚本检测恢复priority 回到 100主备重新回到初始状态备机上的 VIP 会被移除。这里要留意日志里是否出现 Sending gratuitous ARP on eth0这个 gratuitous ARP 是 keepalived 切换后主动广播的用来让交换机快速刷新 MAC 地址表如果你的网络环境里交换机动地址学习特别慢就要考虑把 garp 相关的刷新次数调大。从那以后我每次配置 keepalived 都会强制把这三个验证走一遍停 keepalived、停业务进程、抓包确认 priority 变化。只做其中一项的集群迟早会在真出故障时给你上一课。希望这份 keepalived-1.2.13 的拆解笔记能让你少踩几个坑。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑