keepalived 1.2.13 编译安装与 VIP 漂移验证 简介Keepalived 1.2.13 源码压缩包面向具备 Linux 基础的运维工程师、网络架构学习者以及需要构建高可用服务的技术人员尤其适合初中级读者围绕 VRRP 虚拟路由冗余与 LVS 负载均衡场景提供源码研读与配置实践的基础素材。压缩包共 188 个文件以 62 个 .h 头文件和 61 个 .c 源文件为主体并包含配置样例、安装与初始化脚本、手册页等辅助内容整体约 334KB体量轻便却覆盖核心实现与常用配置入口。已有 369 人学习下载可见其在 Keepalived 版本研究和实验环境中具有一定参考价值。读者可借助源码理解主备切换、虚拟 IP 接管、健康检查及 track_script 等机制结合随包示例梳理 global_defs、vrrp_instance、virtual_server_group 等配置结构并把握优先级、通告间隔、故障检测与 LVS 转发之间的关系为 Nginx、MySQL 等高可用部署、运行维护和故障排查积累可复用的分析路径。1. 一台老 CentOS 7 上的 keepalived-1.2.13.tar.gz折腾掉我半天给一套双机网关做虚拟 IP 漂移翻遍内网源只翻到 keepalived-1.2.13.tar.gz 这一个包yum 里能装到的新版本语法又不兼容。这套 keepalived 场景其实很常见两台机器共用一个 VIP主挂了备顶上中间靠 VRRP 组播互相确认存活。装得不好后果很直接——要么 VIP 在主备两台机器上同时挂着、流量分成两半要么切换时业务断几十秒日志里全是VRRP_Instance的告警。下面这条路径是我在 CentOS 7.6 和 Ubuntu 16.04 上各跑通一次后记下来的编译安装流程从依赖包怎么挑、configure 参数怎么取舍到配置文件怎么写、装完怎么验证真能漂移新手照着敲能落地熟手可以直接看版本对照和踩坑那几段。2. 装前把依赖对齐keepalived 1.2.13 认哪几套组合keepalived 1.2.13 在 2012 年发布源码是纯 C autotools没有预编译包可用必须自己编译。它不像现在的新版本那样一个apt install就完事configure 阶段要主动检查几个开发库和内核头文件缺一样就直接退出。所以装之前的第一件事不是解压而是把编译环境和版本组合确定下来否则后面 make 报错时你得从头判断是库的问题还是代码的问题。2.1 三个必须装对的开发包keepalived 1.2.13 的 configure 会硬性检查 OpenSSL 和 poptlibnl 则是能装就装。我在两台机器上试过的组合是# CentOS 7 系 yum install -y gcc gcc-c make \ openssl-devel \ popt-devel \ libnl-devel \ kernel-devel-$(uname -r) \ zlib-devel # Ubuntu / Debian 系 apt-get install -y build-essential \ libssl-dev \ libpopt-dev \ libnl-3-dev libnl-genl-3-dev \ linux-headers-$(uname -r) \ zlib1g-devopenssl-devel是给 VRRP 认证用的1.2.13 里主备之间的auth_pass走 HMAC/MD5 校验没有这个库 configure 会直接报OpenSSL is not properly installed。popt-devel容易被漏掉——它是 keepalived 自己解析命令行参数用的缺了会报Popt library not found而且这个报错信息不提示你去装哪个包很多人第一次见会以为是配置问题。libnl-devel负责通过 netlink 拿网卡和地址信息缺了 configure 通常会退回老的 ioctl 实现多数单网卡机器能编过但在网卡多、别名 IP 多的机器上会出现取不到接口状态的玄学现象能装就顺手装上。kernel-devel只有在你打算同时用 LVS 时才必须后面一节细说。提示kernel-devel-$(uname -r)里的版本号必须和uname -r完全一致。直接yum install kernel-devel会装上仓库里最新的内核头文件和当前运行内核不匹配configure 检查时一样找不到目标头文件。2.2 内核头文件与 --with-kernel-dir 的取舍keepalived 1.2.13 的 configure 脚本在没有加--disable-lvs的情况下会去内核目录里找include/net/ip_vs.h找不到就报错退出。CentOS 上这个文件在/usr/src/kernels/$(uname -r)/include/net/ip_vs.h而 configure 默认找的路径是/usr/src/linux——这个目录在 CentOS 发行版上根本不存在所以必须显式指定# 先确认头文件真的在 ls -l /usr/src/kernels/$(uname -r)/include/net/ip_vs.h如果这条命令能列出文件就可以在 configure 时加--with-kernel-dir/usr/src/kernels/$(uname -r)。如果装完 kernel-devel 后/usr/src/kernels/下是空的或者版本对不上说明装的是别的内核的头文件用rpm -qa | grep kernel-devel看一眼版本再决定是重装还是补装。如果你这台机器只做 VRRP 漂移不打算跑 LVS 负载均衡我的建议是干脆把 IPVS 相关的东西全关掉--disable-lvs --disable-lvs-syncd。这两个开关能让编译过程彻底不碰内核头文件省掉 kernel-devel 这一整条依赖链编译时间也短一截。代价是编出来的二进制没有virtual_server能力后面配置里也就不能写 LVS 段。对绝大多数只做 VIP 漂移的场景来说这个取舍是划算的。2.3 版本组合对照表哪些系统上能一次编译通过1.2.13 的代码里有不少依赖 OpenSSL 1.0.x 内部结构的写法在 1.1 及以上版本上编译会冒出一堆告警个别发行版上会直接报错。我把实际试过的组合列出来方便你对号入座发行版与版本OpenSSL编译结果建议CentOS 6.91.0.1e一次通过最省心老版本首选CentOS 7.61.0.2k一次通过个别告警生产推荐组合Ubuntu 16.041.0.2g一次通过需要手动装 libpopt-devUbuntu 18.041.1.1告警多可编过编完跑一遍前台启动确认Ubuntu 20.04 及以上1.1.1 / 3.0大概率报错建议在容器里用老系统编好再拷二进制最后一行那个做法值得展开找一个 CentOS 7 的容器或虚拟机把 1.2.13 编出静态一点的二进制再拷到目标机上。keepalived 的可执行文件对 glibc 版本的依赖不算强跨同架构的老系统之间搬运基本没问题比在 OpenSSL 3.0 上硬改源码省事得多。搬过去之后记得ldd看一眼动态库依赖把缺的库补齐。3. 解压、configure 到 make install一条条命令落地依赖齐了之后就是标准的三步走但 keepalived 1.2.13 的每一步都有几个容易写错的点尤其是 prefix 和后缀参数。下面的命令我按顺序贴你可以直接抄但建议每执行一步都看一眼输出末尾有没有error。3.1 源码放置与解压mkdir -p /opt/src cd /opt/src tar -zxvf keepalived-1.2.13.tar.gz cd keepalived-1.2.13 # 顺手记录一下包本身的校验值方便多台机器比对是不是同一个包 sha256sum /opt/src/keepalived-1.2.13.tar.gz解压后的目录结构里configure、Makefile.in、keepalived/、lib/是主要部分。养成先ls一眼的习惯有些二次打包的压缩包里会多套一层目录直接cd keepalived-1.2.13会找不到 configure。sha256sum这一步在批量部署时很有用——主备两台机器编出来的二进制如果行为不一致先排除包本身不是同一个的概率。3.2 configure 参数逐个解释纯 VRRP 场景用这一套cd /opt/src/keepalived-1.2.13 ./configure \ --prefix/usr/local/keepalived \ --disable-lvs \ --disable-lvs-syncd \ 21 | tee /tmp/keepalived-configure.log要带 LVS 的话换成这一套./configure \ --prefix/usr/local/keepalived \ --with-kernel-dir/usr/src/kernels/$(uname -r) \ --disable-lvs-syncd \ 21 | tee /tmp/keepalived-configure.log--prefix/usr/local/keepalived决定了安装目录1.2.13 的默认值是/usr/local直接用它会把二进制塞进/usr/local/sbin和系统里别的东西混在一起后面做软链和写 systemd 单元时容易搞混所以我一般显式指定一个独立目录。--disable-lvs关掉整个 LVS 支持--disable-lvs-syncd只关掉同步守护部分前者更彻底。--with-kernel-dir前面说过只在需要 IPVS 时用。把输出 tee 到日志文件是个小习惯configure 报错往往夹在几十行检查信息中间滚屏之后想回看就没了。真出错的时候直接grep -i error /tmp/keepalived-configure.log再配合源码目录下自动生成的config.log基本能定位到是哪个库没找到。还有一个常被忽略的参数是--log-facility1.2.13 默认把日志打到 syslog 的 daemon 设施在 CentOS 上就是/var/log/messages。如果你们的日志采集只认 local0 到 local7configure 时加--log-facilitylocal5后面在 rsyslog 里单独配一条规则排查时不用在几千行 messages 里翻。3.3 make 与 make install以及文件落位make -j$(nproc) 21 | tee /tmp/keepalived-make.log # 编译完先确认二进制生成了再装 ls -l keepalived/keepalived make installmake -j$(nproc)用满 CPU 核数并行编译1.2.13 代码量不大单核也就一两分钟但并行能省点时间。编译失败的日志同样 grep 关键词OpenSSL 相关的报错通常是undefined reference to加一串函数名看到这种就回到 2.3 的版本对照表去核对 OpenSSL 版本。装完之后/usr/local/keepalived下应该是这样的结构/usr/local/keepalived/ ├── sbin/keepalived # 主程序 ├── bin/genhash # 生成 auth_pass 的小工具 ├── etc/keepalived/keepalived.conf # 示例配置 ├── etc/sysconfig/keepalived # 启动参数 └── etc/rc.d/init.d/keepalived # init 脚本注意这里的配置文件是示例不是给你直接用的。真正要生效的配置在/etc/keepalived/keepalived.conf这个目录 make install 不会创建得手动mkdir -p /etc/keepalived。bin/genhash是个挺实用的小工具早年间有人用它生成密码散列不过 1.2.13 的auth_pass实际只取明文前 8 位用它属于多此一举知道有这个东西就行。4. 配置 keepalived.confVRRP 实例与 VIP 漂移的骨架1.2.13 的配置语法比 2.x 少一些关键字从网上抄新版本配置是最常见的翻车方式。这一节给一份能在 1.2.13 上跑起来的最小骨架再逐段说明每个参数为什么这么写。4.1 全局块和 vrrp_instance 的最小骨架主节点/etc/keepalived/keepalived.conf的内容如下备节点只改state、priority、router_id三处global_defs { router_id node_a # 本机标识主备必须不同 notification_email { opsexample.com # 告警收件地址不用可以留空 } smtp_server 127.0.0.1 smtp_connect_timeout 30 } vrrp_script chk_gateway { script /etc/keepalived/chk_gateway.sh interval 2 # 每 2 秒执行一次 weight -20 # 脚本失败时优先级减 20 fall 2 # 连续失败 2 次才算故障 rise 2 # 连续成功 2 次才算恢复 } vrrp_instance VI_1 { state BACKUP # 两端都写 BACKUP靠优先级选举 interface eth0 virtual_router_id 51 # 同一组主备必须相同 priority 100 # 备节点写 90 advert_int 1 # 组播通告间隔单位秒 authentication { auth_type PASS auth_pass Kx7p2mQa # 只取前 8 位主备必须一致 } virtual_ipaddress { 192.0.2.10/24 dev eth0 } track_script { chk_gateway } notify_master /etc/keepalived/notify.sh master notify_backup /etc/keepalived/notify.sh backup notify_fault /etc/keepalived/notify.sh fault }global_defs里router_id是同组机器的唯一标识主备写成一样会导致日志分不清谁是谁。state这一项我建议两端都写 BACKUP让优先级来决定谁是主——如果一端写 MASTER 一端写 BACKUP主节点重启后可能出现短暂的抢占混乱两端都是 BACKUP 时优先级高的先抢到行为更可预期。virtual_router_id是这一组 VRRP 的编号同一个二层网络里不能和别的组冲突冲突的表现是两台机器疯狂抢占 VIP。auth_pass在 1.2.13 里只比较前 8 个字符写长了不报错但只有前 8 位生效主备两边长度不一致的时候特别容易出错。virtual_ipaddress里的 VIP 用 192.0.2.x 这种文档保留地址只是示例实际换成你们规划的空闲 IP掩码和出口网卡都要写清楚dev eth0漏掉的话 keepalived 可能把地址加到回环口上。4.2 健康检查脚本与 notify 脚本落地vrrp_script指向的脚本必须存在且可执行否则 keepalived 启动时不会报错只会在日志里刷Unable to open script然后一直认为检查失败。脚本本身要写得短、跑得快、返回码明确#!/bin/bash # /etc/keepalived/chk_gateway.sh # 返回 0 表示健康非 0 表示异常由 keepalived 根据 weight 调整优先级 GW192.0.2.1 COUNT2 if ping -c $COUNT -W 1 $GW /dev/null 21; then exit 0 fi exit 1这个脚本用 ping 探测上游网关-c 2发两个包-W 1每个包最多等 1 秒最坏情况阻塞 2 秒比interval 2略短不会造成检查任务堆积。真实场景里把 ping 换成你们自己的探测逻辑比如curl -s -o /dev/null -w %{http_code}判断后端端口或者读一个本地状态文件。关键是脚本的耗时必须明显小于interval否则 keepalived 会一直排队。notify 脚本负责在状态切换时做额外动作比如发告警、刷 ARP、重启依赖 VIP 的服务#!/bin/bash # /etc/keepalived/notify.sh # 参数由 keepalived 传入master / backup / fault STATE$1 LOG/var/log/keepalived-notify.log case $STATE in master) # 成为主节点后主动发一次免费 ARP让交换机刷新 MAC 表 arping -I eth0 -c 3 -U 192.0.2.10 $LOG 21 echo $(date %F %T) become MASTER $LOG ;; backup) echo $(date %F %T) become BACKUP $LOG ;; fault) echo $(date %F %T) enter FAULT $LOG ;; esac这里最值得写的是arping -U那一行。VIP 从备机挪到主机之后交换机上的 MAC 地址表还指着旧机器流量会继续往备机飘现象是 VIP 已经在新机器上了但业务仍然不通等 ARP 缓存老化通常几分钟才恢复。主动发免费 ARP 能把这个窗口压到秒级。两个脚本都要chmod 755属主 root。4.3 init.d 与 systemd 两种托管方式make install 生成的 init 脚本里路径是按/usr/sbin/keepalived写死的而我们的二进制在/usr/local/keepalived/sbin/下。最省事的做法是做软链再按老规矩把文件放到位mkdir -p /etc/keepalived cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/ cp /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/ cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/ ln -sf /usr/local/keepalived/sbin/keepalived /usr/sbin/keepalived chmod x /etc/init.d/keepalived chkconfig --add keepalived chkconfig keepalived on如果你用的是 systemd 系统直接写一份单元文件更干净路径全部显式指定不依赖软链# /etc/systemd/system/keepalived.service [Unit] DescriptionKeepalived VRRP Afternetwork.target [Service] Typeforking PIDFile/var/run/keepalived.pid ExecStart/usr/local/keepalived/sbin/keepalived -D -f /etc/keepalived/keepalived.conf ExecReload/bin/kill -HUP $MAINPID KillModeprocess Restarton-failure [Install] WantedBymulti-user.targetExecStart里的-D是详细日志开关排查阶段很有用稳定之后可以去掉少刷点日志。KillModeprocess是为了让 keepalived 自己管理那几个子进程否则 systemd 停服务时可能只杀掉父进程留下孤儿子进程继续持有 VIP。5. 踩坑排查1.2.13 编译和启动时的 5 个常见翻车点下面这几条是我在不同机器上实际撞过的按「现象 → 原因 → 解决」记遇到问题先按现象对号入座。5.1 configure 报 Popt library not found现象./configure跑到一半直接退出最后一行是configure: error: Popt library not found.前面没有任何关于 popt 的提示。原因系统装了 popt 运行时库但没装开发头文件或者装了popt-devel但版本太老configure 的探测程序链接不上。另外有一种少见情况是只装了libpopt0这类运行时包popt.h根本不存在。解决CentOS 上yum install -y popt-develDebian 系apt-get install -y libpopt-dev。装完确认/usr/include/popt.h存在然后删掉源码目录重新解压再 configure——1.2.13 的 configure 缓存会记住上次的探测结果直接重跑有时还是报同样的错。5.2 make 阶段报 OpenSSL 相关的未定义引用现象make到链接阶段报一串undefined reference to EVP_...或者error: dereferencing pointer to incomplete type指向keepalived/vrrp/vrrp_...下的源文件。原因系统上的 OpenSSL 是 1.1 或 3.01.2.13 的代码按 1.0.x 的结构体写法来访问内部字段新版本把这些结构改成了不透明类型编译期就炸。这不是你配置错了是版本跨代的问题。解决优先换一台 OpenSSL 1.0.x 的机器或容器编译编好把二进制拷过去ldd确认依赖的libssl.so.10目标机上也有。如果必须在本机编只能改源码里报错的那几处字段访问工作量不小且改完后续行为没法保证不推荐在生产环境这么干。5.3 启动后两台机器都有 VIP业务流量分叉现象ip addr show eth0在主备两台机器上都能看到 192.0.2.10抓包能看到两边都在发 VRRP 通告日志里反复出现Transition to MASTER STATE。原因排在第一的是防火墙拦了 VRRP 协议。VRRP 走 IP 协议号 112不是 TCP 也不是 UDP默认策略里经常被 DROP 掉两边互相收不到对方通告都以为自己是唯一的主。第二可能是virtual_router_id和同网段别的组撞了或者auth_pass主备不一致导致认证失败。解决先放行协议号。CentOS 7 用firewall-cmd --permanent --add-protocolvrrp firewall-cmd --reloadiptables 用iptables -I INPUT -p vrrp -j ACCEPT。然后用tcpdump -i eth0 -nn ip proto 112在两台机器上同时抓正常情况下应该看到双向的组播包。如果只有单向就是网络侧的组播被禁了常见于跨网段或虚拟化环境这种情况要么让网络侧放开组播要么换成单播方式通信1.2.13 支持在vrrp_instance里写unicast_peer指定对端地址。5.4 启动报 Unknown keyword配置改了不生效现象/var/log/messages里出现Unknown keyword vrrp_iptables之类keepalived 启动后在跑但配置里的某些段完全没生效。原因配置是从 2.x 的文档里抄的。vrrp_iptables、vrrp_strict、nopreempt的某些位置、track_interface的写法在不同版本上差异不小1.2.13 遇到不认识的词是忽略加告警不像新版本那样直接退出所以很容易误以为配置生效了。解决拿 1.2.13 源码目录里的keepalived/etc/keepalived/keepalived.conf示例当基准所有关键字在示例里找不到就不要写。排查时把服务停掉手工前台跑一次第一屏的告警会直接打出来比翻日志快。5.5 用 init 脚本起不来但手工敲命令能跑现象service keepalived start提示已启动ps里却找不到进程手工执行/usr/local/keepalived/sbin/keepalived -D又一切正常。原因init 脚本里的路径、pid 文件位置、配置目录三者有一个不对。最常见的是脚本按/usr/sbin/keepalived找二进制但软链没做或者/etc/keepalived目录压根没建程序读不到配置就退出了。解决先看/var/log/messages里脚本执行那一刻的输出再确认三件事——ls -l /usr/sbin/keepalived软链是否存在、ls /etc/keepalived/keepalived.conf是否存在、ps -ef | grep keepalived是否真有残留进程占着 pid 文件。三件事都对还起不来就改用 systemd 单元文件路径写死的托管方式比 init 脚本透明得多。6. 装完怎么验证从三个进程到一次真漂移编译装完、配置写好很多人到这一步就发一条「服务启动成功」收工了结果第一次真切换才发现不通。验证要分两层做先确认静态状态对再人为制造一次切换看它是不是真能漂。6.1 静态自检版本、配置、进程数# 1. 版本和编进去的选项 /usr/local/keepalived/sbin/keepalived --version # 2. 停掉服务前台跑一次看配置解析有没有告警 systemctl stop keepalived /usr/local/keepalived/sbin/keepalived -D -f /etc/keepalived/keepalived.conf -l # 3. 另开一个终端确认进程形态 ps -ef | grep [k]eepalived第一步的输出里会列出 configure 时启用的特性能看到是否带 LVS方便确认你编的是不是想要的那份。第二步是关键——1.2.13 没有-t这种纯语法检查参数新版本才有最接近的做法是用-D前台运行一遍配置解析的告警会直接打在屏幕上看到Unknown keyword或者Configuration file error就别急着往下走。第三步正常应该看到至少两个进程一个父进程一个 VRRP 子进程配置了virtual_server的话还会多一个 healthcheck 子进程。然后看 VIP 和日志ip addr show eth0 | grep 192.0.2.10 tail -f /var/log/messages | grep -i keepalived主节点上应该能看到 VIP备节点上没有。日志里应当出现VRRP_Instance(VI_1) Entering BACKUP STATE接着Entering MASTER STATE的序列备节点则一直停在 BACKUP。如果主节点状态在 MASTER 和 BACKUP 之间来回跳回到 5.3 检查组播和认证。6.2 动态验证制造一次真漂移静态检查都过了最后一步是拔电源式的真切换。我一般用最温和的方式在主节点上停服务观察备节点接管再启动主节点观察它是否按优先级夺回或者因为nopreempt不夺回。验证项操作期望结果VIP 落地ip addr show eth0只在主节点上出现备节点静默看备节点日志持续 BACKUP无 VIP切换速度主节点systemctl stop keepalived备节点 1 至 3 秒内转 MASTER流量连通切换过程中持续ping VIP丢包不超过 3 个回切行为主节点启动服务按优先级夺回或保持备机看配置切换时开一个窗口持续ping 192.0.2.10 -i 0.2另一个窗口抓tcpdump -i eth0 -nn ip proto 112能看到主节点停掉后组播通告消失备节点在advert_int * 3个周期内判定对方失效并抢占。如果 VIP 已经挪过去了但 ping 还是断多半是 4.2 里那个免费 ARP 没发或者上游交换机的 ARP 表没刷新。这套流程我在后来的每一次部署里都强制走一遍包括备节点重启后再切回来的那一遍——血泪经验是单向切换通了不代表双向都对回切时优先级和nopreempt的组合最容易被配错而这一遍恰恰是很多人省掉的。keepalived 1.2.13 这种老版本不会给你太多提示配置写错它也只是安静地跑着所以验证这一步没有后悔药可吃只能老老实实切一次看。希望这套流程能帮到你少在编译和漂移上耗时间。本文还有配套的精品资源点击获取