LVS-Keepalived-全解析

负载均衡 LVS 与高可用 Keepalived 全解析

本文是笔者学习 LVS(Linux Virtual Server)负载均衡与 Keepalived 高可用的一天笔记整理,从原理到实战,力求用最通俗的语言讲清楚这两个企业级架构的核心组件。


📖 目录

  • [第一部分:LVS 负载均衡全解析](#第一部分:LVS 负载均衡全解析)
    • [一、LVS 是什么](#一、LVS 是什么)
    • 二、核心角色与术语
    • [三、LVS 的工作原理 ------ netfilter 钩子](#三、LVS 的工作原理 —— netfilter 钩子)
    • [四、LVS 的四种工作模式](#四、LVS 的四种工作模式)
      • [4.1 NAT 模式](#4.1 NAT 模式)
      • [4.2 DR 模式(⭐ 重点)](#4.2 DR 模式(⭐ 重点))
      • [4.3 TUN 模式](#4.3 TUN 模式)
      • [4.4 FullNAT 模式](#4.4 FullNAT 模式)
    • 五、调度算法详解
    • [六、ipvsadm 命令速查](#六、ipvsadm 命令速查)
    • [七、实战:NAT 模式搭建](#七、实战:NAT 模式搭建)
    • [八、实战:DR 模式搭建](#八、实战:DR 模式搭建)
  • [第二部分:Keepalived 高可用全解析](#第二部分:Keepalived 高可用全解析)
    • [九、Keepalived 与 DR 模式集成](#九、Keepalived 与 DR 模式集成)
    • [十、VRRP 协议深度剖析](#十、VRRP 协议深度剖析)
    • [十一、Keepalived 配置文件全解](#十一、Keepalived 配置文件全解)
    • [十二、Keepalived 健康检查机制](#十二、Keepalived 健康检查机制)
    • 十三、脑裂(Split-Brain)问题与防范
    • [十四、实战:Keepalived + LVS-DR 高可用集群](#十四、实战:Keepalived + LVS-DR 高可用集群)
    • 十五、非抢占模式与高级配置

第一部分:LVS 负载均衡全解析

一、LVS 是什么

LVS (Linux Virtual Server)是章文嵩博士于 1998 年 开发的一款开源负载均衡软件,现已合入 Linux 内核主线。

你可以把 LVS 想象成一个 超级快递分拣中心

  • 大量用户请求(快递包裹)涌来
  • LVS(分拣中心)根据既定规则,把请求分发到后端的各个服务器(快递员)
  • 用户最终收到响应,完全感知不到背后有多少台服务器在协作

LVS 工作在 OSI 第四层(传输层) ,基于 IP:Port 做流量分发,因此性能极高,可以轻松处理百万级并发连接。


二、核心角色与术语

搞懂 LVS,首先要记住这几个角色:

术语 全称 含义 类比
Director / VS Virtual Server LVS 调度器本身,负责流量分发 快递分拣中心
RS Real Server 后端真实服务器(Nginx/Apache/Tomcat) 快递员
VIP Virtual IP 对客户端暴露的虚拟 IP 分拣中心的公开地址
DIP Director IP Director 与 RS 通信使用的 IP 分拣中心内部工号
RIP Real Server IP Real Server 自身的 IP 快递员的工号
CIP Client IP 客户端的 IP 寄件人地址

💡 记忆技巧:VIP 中的 V 是"虚"(Virtual),DIP 中的 D 是"调度器"(Director),RIP 中的 R 是"真实"(Real),CIP 中的 C 是"客户端"(Client)。


三、LVS 的工作原理 ------ netfilter 钩子

LVS 并非常规的用户态程序,而是 以内核模块(ipvs)的形式嵌入 Linux 内核的 netfilter 框架中。这意味着数据包的处理在内核态完成,不需要经过"用户态↔内核态"的来回拷贝,性能极高。

复制代码
数据包进入 Director 后的流转路径:

  网络 → PREROUTING → INPUT → [ IPVS 规则匹配 ] → POSTROUTING → 转发到 RS
                    ↑                                    ↑
              netfilter 钩子                        netfilter 钩子

关键步骤:

  1. 数据包到达 Director,先过 PREROUTING
  2. 检查目标 IP 是否为 VIP,若是则路由到 INPUT
  3. 在 INPUT 链,IPVS 模块 介入:根据调度算法选择一个 RS,修改数据包的目标地址
  4. 数据包经 POSTROUTING 链发出,到达 RS
  5. RS 处理请求后,响应数据包返回给客户端

🔑 核心理解:IPVS 本质上是 netfilter 框架的一个"插件",在 INPUT 链上截获发往 VIP 的数据包,改写地址后从 POSTROUTING 发出。


四、LVS 的四种工作模式

LVS 支持四种工作模式,分别对应不同的数据包修改方式:

模式 英文 原理 使用占比
NAT Network Address Translation 修改目标 IP(DNAT) 较少
DR Direct Routing 修改目标 MAC 地址 ≈99%
TUN IP Tunneling IP 隧道封装
FullNAT Full Network Address Translation 同时修改源和目标 IP 较少

4.1 NAT 模式

NAT 模式是最容易理解的模式------就像 快递中转站代收代发

复制代码
   客户端                          Director                        Real Server
   ┌─────┐                      ┌──────────┐                     ┌──────────┐
   │ CIP │ ──── 请求报文 ────→  │  VIP/DIP │ ──── DNAT ────→    │   RIP    │
   │     │ ←─── 响应报文 ────   │          │ ←─── 原路返回 ────  │          │
   └─────┘                      └──────────┘                     └──────────┘

   请求方向:CIP → VIP  变为  CIP → RIP  (改目标 IP)
   响应方向:RIP → CIP  变为  VIP → CIP  (改源 IP)

工作流程:

  1. 客户端发送请求到 VIP
  2. Director 收到后,将 目标 IP 从 VIP 改为 RIP(DNAT)
  3. RS 收到请求并处理
  4. RS 将响应发给 Director(因为 RS 的默认网关必须是 Director)
  5. Director 将 源 IP 从 RIP 改回 VIP(SNAT),发给客户端

优点:

  • 配置简单,易于理解
  • 支持端口映射(VIP:80 → RIP:8080)

缺点:

  • Director 需处理所有进出流量,容易成为瓶颈
  • RS 的网关必须指向 Director
  • 请求和响应都经过 Director,吞吐量受限于 Director 带宽

⚠️ NAT 模式下,Director 就像独木桥------所有人的进出都要经过它,当流量增大时,Director 首先扛不住。


4.2 DR 模式(⭐ 重点)

DR(Direct Routing)是 生产环境使用最多的模式 ,约 99% 的 LVS 集群采用此模式。它的核心思路非常巧妙------只改 MAC 地址,不改 IP 地址

复制代码
   客户端                          Director                        Real Server
   ┌─────┐                      ┌──────────┐                     ┌──────────┐
   │ CIP │ ──── 请求报文 ────→  │  VIP/DIP │ ──── 改MAC ────→   │ VIP(RIP) │
   │     │ ←─── 响应报文 ────────────────────────────────────   │          │
   └─────┘                      └──────────┘                     └──────────┘
                                  ↑                              ↑
                              只修改MAC                    响应直接回客户端!

数据包变化(精华):

复制代码
进入 Director 前:                      离开 Director 后:
┌──────────────────────┐              ┌──────────────────────┐
│ 源 IP:   CIP         │              │ 源 IP:   CIP         │  ← 不变!
│ 目标 IP: VIP         │              │ 目标 IP: VIP         │  ← 不变!
│ 源 MAC:  Client MAC  │              │ 源 MAC:  DIP 的 MAC  │
│ 目标 MAC: VIP 的 MAC │              │ 目标 MAC: RS 的 MAC  │  ← 只改这个!
└──────────────────────┘              └──────────────────────┘

工作流程:

  1. 客户端发请求到 VIP
  2. Director 收到后,不修改 IP 包,只把目标 MAC 地址改为某台 RS 的 MAC
  3. RS 收到后发现目标 IP(VIP)匹配自己的 lo 接口,正常处理
  4. RS 直接将响应发给客户端,不再经过 Director!

💡 这就是 DR 模式的核心优势------"来时有我,走时随意"。Director 只处理入站请求(通常请求数据量小),出站响应(通常数据量大)由 RS 直接返回客户端。这种非对称架构极大提高了吞吐量。

DR 模式的关键约束:

约束 说明
① RS 必须配置 VIP RS 的 lo(回环接口)上需绑定 VIP(/32 掩码)
② 必须抑制 ARP RS 不能响应 VIP 的 ARP 请求,否则 Director 的 VIP 会被"抢走"
③ RS 和 Director 同网段 需要通过 MAC 地址直接通信,不能跨越路由器
④ Director 的 VIP 对外可见 RS 的 VIP 隐藏(通过 ARP 抑制实现)

ARP 抑制详解(DR 模式最关键的技术细节):

为什么需要抑制 ARP?考虑这个场景:

  • Director 上有 VIP(对外提供服务)
  • RS 的 lo 上也绑了 VIP
  • 当路由器问"谁是 VIP?请告诉 MAC 地址"时,如果 RS 抢先回答了,客户端的流量就会绕过 Director 直连 RS,负载均衡就失效了!

解决方案:配置两个内核参数:

bash 复制代码
# arp_ignore = 1:只回应从该接口进来的 ARP 请求
# 如果 ARP 请求从 eth0 进来,而 VIP 配在 lo 上 → 不回应
net.ipv4.conf.all.arp_ignore = 1

# arp_announce = 2:通告 IP 时使用最佳本地地址
# 对外通告时,不宣告 lo 上的 VIP
net.ipv4.conf.all.arp_announce = 2

🎯 一句话总结 DR 模式:Director 和 RS 共享同一个 VIP,但只有 Director 的 VIP 对外"出声";RS 的 VIP 是"沉默"的,只用来接收 Director 转发过来的请求。


4.3 TUN 模式

TUN(IP Tunneling)模式在 DR 模式基础上增加了 IP 隧道封装,解决了 跨网段 的问题:

复制代码
   原始报文:[CIP → VIP] + 数据
   封装后:  [DIP → RIP] + [CIP → VIP] + 数据
             ↑ 新增的外层 IP 头    ↑ 原始报文

适用场景:RS 和 Director 不在同一物理网络,需要跨机房、跨地域部署时使用。

约束:

  • RS 操作系统必须支持 IP 隧道(ipip 模块)
  • 额外的 IP 头带来少量性能开销

4.4 FullNAT 模式

FullNAT 是淘宝对 LVS 的扩展,同时修改源 IP 和目标 IP:

  • NAT 只改目标 IP
  • FullNAT 连源 IP 也改(SNAT + DNAT 同时做)
  • 优点:RS 可以跨网段,Director 和 RS 不必在同一子网
  • 缺点:RS 看不到真实客户端 IP(CIP 被替换成 DIP)

五、调度算法详解

LVS 提供了丰富的调度算法,分为 静态动态 两大类:

静态调度算法(不关心 RS 当前状态)

算法 全称 含义 类比
RR Round Robin 轮询,依次分发 发扑克牌,一人一张
WRR Weighted RR 加权轮询,按权重比例分发 性能好的服务器多拿几张牌
DH Destination Hash 按目标 IP 哈希 同一目标 IP 的请求固定发到同一 RS
SH Source Hash 按源 IP 哈希 同一客户端的请求固定发到同一 RS

动态调度算法(根据 RS 当前连接数和负载)

算法 全称 含义
LC Least Connections 最少连接数优先
WLC Weighted LC 加权最少连接数(默认算法)
SED Shortest Expected Delay 最短预期延迟
NQ Never Queue 永不排队(SED 改进版)
LBLC Locality-Based LC 基于局部性的最少连接
LBLCR LBLC with Replication 带复制的 LBLC

WLC 算法公式(最常用):

复制代码
Overhead = (Active_Connections × 256 + Inactive_Connections) ÷ Weight

选择 Overhead 最小的 RS。+1×256 的设计是为了让活跃连接的影响远大于非活跃连接。

📌 生产建议:一般场景用 WRR ,长连接场景(如数据库代理)用 WLC


六、ipvsadm 命令速查

ipvsadm 是管理 LVS 规则的用户态工具,对应的内核模块是 ipvs

添加/修改虚拟服务

bash 复制代码
# 添加 TCP 虚拟服务(VIP:Port),调度算法为 rr
ipvsadm -A -t 10.1.8.100:80 -s rr

# 修改调度算法为 wrr
ipvsadm -E -t 10.1.8.100:80 -s wrr

# 删除虚拟服务
ipvsadm -D -t 10.1.8.100:80

参数说明:

  • -A:添加虚拟服务
  • -E:修改虚拟服务
  • -D:删除虚拟服务
  • -t:TCP 协议
  • -u:UDP 协议
  • -s:指定调度算法
  • -p:持久连接超时时间

添加/修改 Real Server

bash 复制代码
# 添加 RS(-g=DR模式, -i=TUN模式, -m=NAT模式)
ipvsadm -a -t 10.1.8.100:80 -r 10.1.8.11:80 -g -w 1
ipvsadm -a -t 10.1.8.100:80 -r 10.1.8.12:80 -g -w 2
ipvsadm -a -t 10.1.8.100:80 -r 10.1.8.13:80 -g -w 3

# 修改 RS 权重
ipvsadm -e -t 10.1.8.100:80 -r 10.1.8.12:80 -g -w 5

# 删除 RS
ipvsadm -d -t 10.1.8.100:80 -r 10.1.8.12:80

参数说明:

  • -a:添加 RS
  • -e:修改 RS
  • -d:删除 RS
  • -r:RS 的地址
  • -g:DR 模式(Gateway)
  • -i:TUN 模式(IPIP)
  • -m:NAT 模式(Masquerade)
  • -w:权重

查看与保存

bash 复制代码
# 查看规则(-n 不做 DNS 解析)
ipvsadm -Ln

# 查看连接状态
ipvsadm -Lnc

# 计数器清零
ipvsadm -Z

# 保存规则
ipvsadm-save -n > /etc/sysconfig/ipvsadm

# 清空所有规则
ipvsadm -C

七、实战:NAT 模式搭建

🖥️ 实验拓扑:7 台 CentOS 7 虚拟机

角色 主机名 VMnet1 IP VMnet8 IP 网关
外网客户端 client2 10.1.1.21 - 10.1.1.10
内网客户端 client1 - 10.1.8.21 10.1.8.10
LVS Director lvs 10.1.1.10 10.1.8.10 10.1.8.2
Web 服务器 1 web1 - 10.1.8.11 10.1.8.10
Web 服务器 2 web2 - 10.1.8.12 10.1.8.10
Web 服务器 3 web3 - 10.1.8.13 10.1.8.10

步骤 1:网络配置

bash 复制代码
# === 各节点设置主机名和 IP ===

# client2(外网客户端)
hostnamectl set-hostname client2.laogao.cloud
nmcli connection modify ens33 ipv4.method manual \
  ipv4.addresses 10.1.1.21/24 \
  ipv4.gateway 10.1.1.10 \
  ipv4.dns 223.5.5.5 autoconnect yes
nmcli connection up ens33

# lvs(Director,双网卡)
hostnamectl set-hostname lvs.laogao.cloud
nmcli connection modify ens33 ipv4.method manual \
  ipv4.addresses 10.1.8.10/24 \
  ipv4.gateway 10.1.8.2 \
  ipv4.dns 223.5.5.5 autoconnect yes
nmcli connection up ens33
# 添加第二块网卡(连接外网)
nmcli connection add type ethernet con-name ens36 ifname ens36 \
  ipv4.method manual ipv4.addresses 10.1.1.10/24 autoconnect yes
nmcli connection up ens36

# web1-3(Real Server,网关指向 Director)
# 以 web1 为例
hostnamectl set-hostname web1.laogao.cloud
nmcli connection modify ens33 ipv4.method manual \
  ipv4.addresses 10.1.8.11/24 \
  ipv4.gateway 10.1.8.10 \
  ipv4.dns 223.5.5.5 autoconnect yes
nmcli connection up ens33

步骤 2:Director 开启转发和 NAT

bash 复制代码
# 开启 IP 转发
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
sysctl -p

# 配置防火墙 NAT(MASQUERADE)
systemctl enable firewalld.service --now
firewall-cmd --set-default-zone=trusted
firewall-cmd --add-masquerade --permanent
firewall-cmd --add-masquerade

步骤 3:RS 部署 Web 服务

bash 复制代码
# 在每个 Web 节点上
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
yum install -y nginx
echo "Welcome to $(hostname)" > /usr/share/nginx/html/index.html
systemctl enable nginx.service --now

# 验证
curl 10.1.8.11  # → Welcome to web1.laogao.cloud
curl 10.1.8.12  # → Welcome to web2.laogao.cloud
curl 10.1.8.13  # → Welcome to web3.laogao.cloud

步骤 4:Director 配置 LVS 规则

bash 复制代码
yum install -y ipvsadm
touch /etc/sysconfig/ipvsadm
systemctl enable ipvsadm --now

# 添加虚拟服务(VIP: 10.1.1.10:80,调度算法 rr)
ipvsadm -A -t 10.1.1.10:80 -s rr

# 添加 Real Server(-m 表示 NAT 模式)
ipvsadm -a -t 10.1.1.10:80 -r 10.1.8.11 -m
ipvsadm -a -t 10.1.1.10:80 -r 10.1.8.12 -m
ipvsadm -a -t 10.1.1.10:80 -r 10.1.8.13 -m

# 查看规则
ipvsadm -Ln

输出示例:

复制代码
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  10.1.1.10:80 rr
  -> 10.1.8.11:80                 Masq    1      0          0
  -> 10.1.8.12:80                 Masq    1      0          0
  -> 10.1.8.13:80                 Masq    1      0          0

🔍 注意 Forward 列显示 Masq,这是 NAT 模式的标志。

步骤 5:测试负载均衡

bash 复制代码
# 从外网客户端发起 90 次请求
for i in {1..90}; do curl -s 10.1.1.10; done | sort | uniq -c

# 输出(RR 算法,均匀分配):
#   30 Welcome to web1.laogao.cloud
#   30 Welcome to web2.laogao.cloud
#   30 Welcome to web3.laogao.cloud

步骤 6:切换到 WRR 算法

bash 复制代码
# 修改调度算法为加权轮询
ipvsadm -E -t 10.1.1.10:80 -s wrr

# 设置权重(web1=1, web2=2, web3=3)
ipvsadm -e -t 10.1.1.10:80 -r 10.1.8.11 -m -w 1
ipvsadm -e -t 10.1.1.10:80 -r 10.1.8.12 -m -w 2
ipvsadm -e -t 10.1.1.10:80 -r 10.1.8.13 -m -w 3

# 再次测试(90 次请求,按 1:2:3 分配)
for i in {1..90}; do curl -s 10.1.1.10; done | sort | uniq -c
#   15 Welcome to web1.laogao.cloud   ← 1/6
#   30 Welcome to web2.laogao.cloud   ← 2/6
#   45 Welcome to web3.laogao.cloud   ← 3/6

八、实战:DR 模式搭建

DR 模式是企业级部署的标配,下面详细演示完整搭建过程。

实验拓扑

角色 主机名 VMnet8 IP 网关
路由器 router 10.1.8.20 (内网) / 10.1.1.20 (外网) 10.1.8.2
LVS Director lvs 10.1.8.10 10.1.8.20
Web 服务器 1 web1 10.1.8.11 10.1.8.20
Web 服务器 2 web2 10.1.8.12 10.1.8.20
Web 服务器 3 web3 10.1.8.13 10.1.8.20
内网客户端 client1 10.1.8.21 10.1.8.20
VIP - 10.1.8.100 -

步骤 1:路由器配置

bash 复制代码
hostnamectl set-hostname router.laogao.cloud
# 配置双网卡 + 开启转发
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
sysctl -p
systemctl enable firewalld.service --now
firewall-cmd --set-default-zone=trusted
firewall-cmd --add-masquerade --permanent
firewall-cmd --add-masquerade

步骤 2:Real Server 配置 ------ 关键步骤!

每个 RS 上要做两件事:① 绑 VIP 到 lo ② 抑制 ARP

bash 复制代码
# ===== 在每个 Web 节点上执行 =====

# ① 创建 dummy 接口,绑定 VIP(/32 掩码,不对外广播)
nmcli connection add type dummy ifname dummy con-name dummy \
  ipv4.method manual ipv4.addresses 10.1.8.100/32
nmcli connection up dummy

# ② 配置 ARP 抑制(核心!)
cat >> /etc/sysctl.conf << EOF
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.dummy.arp_ignore = 1
net.ipv4.conf.dummy.arp_announce = 2
EOF
sysctl -p

💡 arp_ignore = 1:只有 ARP 请求从目标接口进入时才回应。VIP 绑定在 dummy 上,ARP 请求从 eth0 进入 → 不回应!

💡 arp_announce = 2:对外通告时,始终使用最佳本地地址(eth0 的 RIP),不宣告 dummy 上的 VIP。

步骤 3:Director 配置

bash 复制代码
# Director 也绑定 VIP(对外提供服务)
nmcli connection add type dummy ifname dummy con-name dummy \
  ipv4.method manual ipv4.addresses 10.1.8.100/32
nmcli connection up dummy

# 安装并配置 LVS(注意:-g 表示 DR 模式)
yum install -y ipvsadm
touch /etc/sysconfig/ipvsadm
systemctl enable ipvsadm --now

ipvsadm -A -t 10.1.8.100:80 -s rr
ipvsadm -a -t 10.1.8.100:80 -r 10.1.8.11:80 -g
ipvsadm -a -t 10.1.8.100:80 -r 10.1.8.12:80 -g
ipvsadm -a -t 10.1.8.100:80 -r 10.1.8.13:80 -g
ipvsadm-save -n > /etc/sysconfig/ipvsadm

# 查看规则(注意 Forward 列为 Route,表示 DR 模式)
ipvsadm -Ln
复制代码
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  10.1.8.100:80 rr
  -> 10.1.8.11:80                 Route   1      0          0
  -> 10.1.8.12:80                 Route   1      0          0
  -> 10.1.8.13:80                 Route   1      0          0

🔍 Forward 列显示 Route 表示 DR 模式(对比 NAT 模式显示 Masq)。

步骤 4:测试

bash 复制代码
# 从客户端测试
for i in {1..90}; do curl -s 10.1.8.100; done | sort | uniq -c
#   30 Welcome to web1.laogao.cloud
#   30 Welcome to web2.laogao.cloud
#   30 Welcome to web3.laogao.cloud

步骤 5:生产级启动脚本

Real Server 脚本/usr/local/sbin/lvs-rs.sh):

bash 复制代码
#!/bin/bash
# description : LVS Real Server 启动/停止脚本

VIP=10.1.8.100

case "$1" in
start)
    echo -n "Start LVS Real Server ... "
    # 绑定 VIP
    if nmcli connection | grep -q dummy; then
        nmcli connection modify dummy ipv4.method manual ipv4.addresses $VIP/32
    else
        nmcli connection add type dummy ifname dummy con-name dummy \
          ipv4.method manual ipv4.addresses $VIP/32
    fi
    nmcli connection up dummy
    # 抑制 ARP
    echo "1" > /proc/sys/net/ipv4/conf/all/arp_ignore
    echo "2" > /proc/sys/net/ipv4/conf/all/arp_announce
    echo "1" > /proc/sys/net/ipv4/conf/dummy/arp_ignore
    echo "2" > /proc/sys/net/ipv4/conf/dummy/arp_announce
    echo OK
    ;;
stop)
    echo -n "Stop LVS Real Server ... "
    nmcli connection delete dummy
    # 恢复 ARP 默认值
    echo "0" > /proc/sys/net/ipv4/conf/all/arp_ignore
    echo "0" > /proc/sys/net/ipv4/conf/all/arp_announce
    echo "0" > /proc/sys/net/ipv4/conf/dummy/arp_ignore
    echo "0" > /proc/sys/net/ipv4/conf/dummy/arp_announce
    echo OK
    ;;
*)
    echo "Usage: $0 start|stop"
    exit 1
esac

Director Server 脚本/usr/local/sbin/lvs-ds.sh):

bash 复制代码
#!/bin/bash
# description : LVS Director Server 启动/停止脚本

VIP=10.1.8.100
PORT=80
rs1=10.1.8.11
rs2=10.1.8.12
rs3=10.1.8.13
interface=ens33
ipv=/sbin/ipvsadm

# 确保 ipvsadm 已安装
if ! rpm -q ipvsadm &>/dev/null; then
    yum install -y ipvsadm &>/dev/null
fi

case "$1" in
start)
    echo -n "Start LVS Director Server ... "
    # 绑定 VIP 到物理网卡
    if ! ip -br addr | grep -q $VIP; then
        nmcli connection modify ${interface} +ipv4.addresses $VIP/32
        nmcli connection up ${interface}
    fi
    # 配置 LB 规则
    $ipv -C
    $ipv -A -t $VIP:$PORT -s wrr
    $ipv -a -t $VIP:$PORT -r $rs1:$PORT -g -w 1
    $ipv -a -t $VIP:$PORT -r $rs2:$PORT -g -w 1
    $ipv -a -t $VIP:$PORT -r $rs3:$PORT -g -w 1
    echo OK
    ;;
stop)
    echo -n "Stop LVS Director Server ... "
    # 移除 VIP
    if ip -br addr | grep -q $VIP; then
        nmcli connection modify ${interface} -ipv4.addresses $VIP/32
        nmcli connection up ${interface}
    fi
    # 清空 LB 规则
    $ipv -C
    echo OK
    ;;
*)
    echo "Usage: $0 start|stop"
    exit 1
esac

第二部分:Keepalived 高可用全解析

前面我们搭建了 LVS-DR 集群,但有一个致命问题------Director 是单点! 如果 Director 宕机,整个集群就瘫痪了。接下来用 Keepalived 解决这个难题。


九、Keepalived 与 DR 模式集成

问题分析

回顾 LVS-DR 架构:

复制代码
         ┌──────────────┐
         │   客户端      │
         └──────┬───────┘
                │ VIP
         ┌──────▼───────┐
         │   Director   │  ← 单点故障!这台挂了全完了
         └──┬───┬───┬───┘
            │   │   │
      ┌─────▼   ▼   ▼─────┐
      │  RS1   RS2   RS3  │  ← 后端好好的,可惜没人分发流量了
      └───────────────────┘

解决思路:用两台(或多台)Director,一台做主(Master),一台做备(Backup),主备之间通过 VRRP 协议协商 VIP 的归属。

复制代码
         ┌──────────────┐
         │   客户端      │
         └──────┬───────┘
                │ VIP(飘来飘去)
        ┌───────┴───────┐
        │               │
   ┌────▼────┐    ┌─────▼────┐
   │ Master  │    │  Backup  │  ← Keepalived 管理的主备
   │ (LVS)   │◄──►│  (LVS)   │     VRRP 心跳
   └──┬───┬──┘    └──┬──┬───┘
      │   │          │  │
      ▼   ▼          ▼  ▼
   ┌──────────────────────┐
   │   RS1    RS2    RS3  │
   └──────────────────────┘

Keepalived 是什么

Keepalived 是一个用 C 语言编写的 Linux 守护进程,主要实现两大功能:

功能 说明
VRRP 高可用 实现主备节点的故障切换(Failover),VIP 在主备之间漂移
LVS 健康检查 自动检测后端 RS 的健康状态,自动剔除故障节点、恢复后自动加入

Keepalived 本质上是对 VRRP 协议 的完整实现,同时深度集成了 LVS 的管理能力。你可以把它理解为 "LVS 的自动驾驶系统"------不仅会开车(负载均衡),还能自动换备胎(故障切换)和检测发动机(健康检查)。


十、VRRP 协议深度剖析

10.1 什么是 VRRP

VRRP (Virtual Router Redundancy Protocol,虚拟路由冗余协议)是 IETF 标准协议(RFC 3768),用于解决局域网中默认网关单点故障的问题。

不严谨但好理解的类比:

想象公司前台只有一个人接电话。如果他请假了,所有电话就没人接了。VRRP 的做法是------安排两个人(一个主、一个备),共享同一个"前台分机号"(VIP),主前台正常接电话,备前台在旁边待命。主前台每隔一会儿喊一声"我还在!",如果备前台连续几次没听到,就自动接管分机号,开始接电话。

10.2 VRRP 核心概念

概念 说明
虚拟路由器 由 Master + Backup 组成的逻辑实体,对外表现为一台"永不宕机"的路由器
VRID Virtual Router Identifier(1-255),同一组 VRRP 实例共享
Master 主节点,持有 VIP 并处理流量
Backup 备节点,监听 Master 心跳,随时准备接管
Priority 优先级(0-255),值高者成为 Master。注意:IP 地址最大的节点在优先级相同时胜出
VIP 虚拟 IP,始终在 Master 上

10.3 VRRP 报文格式

VRRP 通过组播地址 224.0.0.18 发送通告报文:

复制代码
┌──────────────────────────────────────────┐
│  Ver (v2=IPv4, v3=IPv4+IPv6)             │
│  Virtual Rtr ID (VRID, 1-255)            │
│  Priority (0-255,0 表示 Master 主动放弃)  │
│  Count IP Addrs (VIP 个数)               │
│  Auth Type (无/PASS/MD5)                 │
│  Adver Int (通告间隔,默认 1 秒)           │
│  IP Address(es) (VIP 地址列表)            │
│  Authentication Data                     │
└──────────────────────────────────────────┘

10.4 VRRP 状态机

VRRP 协议定义了三态状态机:

复制代码
                    ┌──────────┐
          启动 ────►│Initialize│
                    └────┬─────┘
                         │ Priority=255 → 直接成为 Master
                    ┌────▼─────┐
              ┌────►│  Master   │◄────────────┐
              │     └──┬───┬───┘              │
              │        │   │ 收到更高优先级通告  │
              │        │   └──────────────────┘
              │        │ 主动关闭(priority=0)
              │   ┌────▼─────┐
              └───┤  Backup   │
    Master_Down  │          │ 收到低优先级 Master 通告
    超时后抢占    └──────────┘ ──────────────────┘

Master_Down 计时器计算公式:

复制代码
MASTER_DOWN = 3 × ADVER_INTERVAL + Skew_Time
Skew_Time  = (256 - Priority) / 256

💡 这意味着:优先级越高的 Backup,Skew_Time 越小,越感知到 Master 宕机并抢占。这是一个精妙的"优先级越高,反应越快"的设计。

10.5 VIP 漂移过程(完整流程)

以 web1(Master,Priority=110)和 web2(Backup,Priority=100)为例:

复制代码
时间线 ─────────────────────────────────────────────────────►

① 初始状态
   web1 [MASTER, VIP=10.1.8.100]  ←→  发送心跳(每秒1次)  ←→  web2 [BACKUP]

② web1 宕机(或 Keepalived 停止)
   web1 [DOWN]                                          web2 [等待...]
                                                         MASTER_DOWN 超时(约3秒)

③ web2 接管
   web1 [DOWN]                                          web2 [MASTER, VIP=10.1.8.100]
                                                        ↑ 发送 Gratuitous ARP 通告

④ web1 恢复
   web1 [启动,发现比自己优先级高 → 成为 MASTER]           web2 [收到更高优先级通告 → 降为 BACKUP]
   ↑ 再次发送 Gratuitous ARP

📡 Gratuitous ARP(免费 ARP):当 VIP 发生漂移时,新的 Master 会主动广播"我是 10.1.8.100,我的 MAC 是 xx:xx",让交换机和路由器立即更新 MAC 地址表,实现流量的无缝切换。


十一、Keepalived 配置文件全解

Keepalived 的配置文件位于 /etc/keepalived/keepalived.conf,分为三大块:

配置结构

复制代码
keepalived.conf
├── GLOBAL CONFIGURATION(全局配置)
│   ├── global_defs:router_id、邮件通知等
│   └── VRRP 全局参数
├── VRRPD CONFIGURATION(VRRP 实例配置)
│   └── vrrp_instance:state、priority、VIP、认证等
└── LVS CONFIGURATION(LVS 规则配置)
    └── virtual_server:调度算法、转发模式、RS 列表等

完整配置示例(带注释)

nginx 复制代码
! Configuration File for keepalived

# ============ 全局配置 ============
global_defs {
    # 路由器标识(在 LAN 中唯一)
    router_id LVS_DEVEL

    # 邮件通知(可选)
    # notification_email {
    #     admin@example.com
    # }
    # notification_email_from keepalived@example.com
    # smtp_server 192.168.200.1
    # smtp_connect_timeout 30

    # VRRP 全局参数
    vrrp_skip_check_adv_addr    # 不检查通告中的源地址
    # vrrp_strict               # 严格模式(会配置防火墙规则)
    vrrp_garp_interval 0        # Gratuitous ARP 发送间隔
    vrrp_gna_interval 0         # 无请求邻居通告间隔
}

# ============ VRRP 实例配置 ============
vrrp_instance VI_1 {
    state MASTER                  # MASTER 或 BACKUP
    interface eth0                # VIP 绑定的网卡
    virtual_router_id 51          # VRID,主备必须一致(1-255)
    priority 100                  # 优先级,高者成为 Master
    advert_int 1                  # 心跳通告间隔(秒)

    # 认证(主备必须一致)
    authentication {
        auth_type PASS            # PASS 或 AH
        auth_pass 1111            # 密码(最多 8 位)
    }

    # 虚拟 IP 地址
    virtual_ipaddress {
        192.168.200.16
        192.168.200.17
        192.168.200.18
    }

    # 追踪网卡状态(任一下降则降级)
    track_interface {
        eth0
        eth1
    }
}

# ============ LVS 虚拟服务配置 ============
virtual_server 192.168.200.100 443 {
    delay_loop 6                  # 健康检查间隔(秒)
    lb_algo rr                    # 调度算法:rr|wrr|lc|wlc|lblc|sh|dh
    lb_kind DR                    # 转发模式:NAT|DR|TUN
    persistence_timeout 50        # 持久连接超时(秒)
    protocol TCP                  # 协议:TCP|UDP|SCTP

    # 后端 Real Server
    real_server 192.168.201.100 443 {
        weight 1                  # 权重
        # TCP_CHECK / HTTP_GET / SSL_GET 等健康检查方式
        TCP_CHECK {
            connect_timeout 3
            retry 3
            delay_before_retry 3
        }
    }
}

十二、Keepalived 健康检查机制

Keepalived 不仅仅做 VRRP 高可用,它还能自动检测后端 RS 的健康状态,这是生产环境中不可或缺的能力。

支持的检查方式

检查类型 说明 适用场景
TCP_CHECK TCP 三次握手探测端口 通用 TCP 服务
HTTP_GET HTTP GET 请求 + 状态码/内容校验 Web 服务
SSL_GET HTTPS 握手 + GET 请求 HTTPS 服务
MISC_CHECK 执行自定义脚本 复杂业务逻辑
SMTP_CHECK SMTP 协议探测 邮件服务
DNS_CHECK DNS 查询探测 DNS 服务

配置示例:HTTP 健康检查

nginx 复制代码
virtual_server 10.1.8.100 80 {
    delay_loop 6
    lb_algo wrr
    lb_kind DR
    protocol TCP

    real_server 10.1.8.11 80 {
        weight 1
        HTTP_GET {
            url {
                path /health          # 检查的 URL 路径
                status_code 200       # 期望的状态码
                digest abc123def      # 可选:页面内容的 MD5
            }
            connect_timeout 3         # 连接超时
            nb_get_retry 3            # 重试次数
            delay_before_retry 3      # 重试间隔
        }
    }
}

当 RS 健康检查失败时,Keepalived 会自动将其从 LVS 转发列表中移除;恢复后自动加回。整个过程对客户端透明。


十三、脑裂(Split-Brain)问题与防范

什么是脑裂

脑裂 是指 VRRP 集群中,Master 和 Backup 同时认为自己持有 VIP,导致 IP 冲突、流量混乱。

打个比方:一个公司不能有两个 CEO 同时发号施令。脑裂就是两个 CEO 都认为自己是老大,结果公司乱成一团。

脑裂的常见原因

  1. 心跳线中断:主备之间的网络断了,双方都认为对方挂了
  2. 防火墙阻断 VRRP 组播:VRRP 使用 UDP 112 端口通信
  3. CPU 负载过高:Master 来不及发送心跳,Backup 误判其宕机
  4. 配置不一致:VRID 或认证密码不匹配

防范脑裂的五大措施

① 配置 VPN 专用心跳线
复制代码
主备之间用独立网线直连或专用 VLAN,不依赖业务网络。
② 放行 VRRP 协议(防火墙)
bash 复制代码
# 必须放行 VRRP 协议号 112
firewall-cmd --add-protocol=vrrp --permanent
firewall-cmd --reload
③ 配置认证
nginx 复制代码
vrrp_instance VI_1 {
    authentication {
        auth_type PASS
        auth_pass 123456        # 主备密码必须一致
    }
}
④ 编写脑裂检测脚本 + 通知回调
nginx 复制代码
vrrp_instance VI_1 {
    notify_master "/etc/keepalived/check_split_brain.sh master"
    notify_backup "/etc/keepalived/check_split_brain.sh backup"
    notify_fault  "/etc/keepalived/check_split_brain.sh fault"
}

检测思路:

  • 成为 Master 后,ping 网关或对端 IP
  • 如果也能 ping 通 VIP(说明对端也持有 VIP)→ 脑裂发生 → 自动降级或告警
⑤ 监控告警

通过 Zabbix / Prometheus 监控 Keepalived 状态变化,第一时间发现异常。


十四、实战:Keepalived + LVS-DR 高可用集群

🎯 目标:搭建两台 Director(一主一备)+ 两台 Web RS 的高可用负载均衡集群。

实验拓扑

角色 主机名 IP
客户端 client1 10.1.8.21
Director 1(Master) web1 10.1.8.11
Director 2(Backup) web2 10.1.8.12
VIP - 10.1.8.100

为了简化,这里将 Keepalived 直接安装在 Web 服务器上(也作为 Director)。

步骤 1:基础环境

bash 复制代码
# 所有节点设置主机名和网络(略,参考前面 NAT/DR 配置)

# web1 和 web2 安装 Web 服务
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
yum install -y nginx
echo "Welcome to $(hostname)" > /usr/share/nginx/html/index.html
systemctl enable nginx.service --now

步骤 2:web2(Backup)配置 Keepalived

bash 复制代码
yum install -y keepalived
cp /etc/keepalived/keepalived.conf{,.ori}
nginx 复制代码
! Configuration File for keepalived

global_defs {
    router_id web2              # 唯一标识
}

vrrp_instance nginx {
    state BACKUP                # 备节点
    interface ens33             # 绑定网卡
    virtual_router_id 51        # VRID,主备必须一致
    priority 100                # 优先级(比 Master 低)
    advert_int 1                # 心跳间隔 1 秒
    authentication {
        auth_type PASS
        auth_pass laogao@123
    }
    virtual_ipaddress {
        10.1.8.100/24           # VIP
    }
}
bash 复制代码
systemctl enable keepalived.service --now

# 验证:web2 上有 VIP(因为目前只有它一个,自动成为 Master)
ip -br a show ens33
# ens33 UP 10.1.8.12/24 10.1.8.100/24 ...

步骤 3:web1(Master)配置 Keepalived

nginx 复制代码
! Configuration File for keepalived

global_defs {
    router_id web1
}

vrrp_instance nginx {
    state MASTER                # 主节点
    interface ens33
    virtual_router_id 51
    priority 110                # 优先级 110 > 100,成为 Master
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass laogao@123
    }
    virtual_ipaddress {
        10.1.8.100/24
    }
}
bash 复制代码
systemctl enable keepalived.service --now

# 验证:web1 已抢占 VIP
ip -br a show ens33
# ens33 UP 10.1.8.11/24 10.1.8.100/24 ...  ← VIP 在这里!

此时再看 web2:

bash 复制代码
ip -br a show ens33
# ens33 UP 10.1.8.12/24 ...  ← VIP 消失了!(被 web1 抢占)

步骤 4:故障切换测试

bash 复制代码
# 访问 VIP------请求落在 Master(web1)上
curl 10.1.8.100
# Welcome to web1.laogao.cloud

# ===== 模拟故障:停止 web1 的 Keepalived =====
systemctl stop keepalived.service

# 再次访问------VIP 已漂移到 web2
curl 10.1.8.100
# Welcome to web2.laogao.cloud   ← 自动切换成功!

# ===== 恢复 web1 =====
systemctl start keepalived.service

# 访问------VIP 又回到 web1(优先级高,自动抢占)
curl 10.1.8.100
# Welcome to web1.laogao.cloud   ← 自动抢回!

✅ 整个切换过程对客户端完全透明,客户端始终访问 10.1.8.100,感知不到后端发生了故障切换。


十五、非抢占模式与高级配置

15.1 非抢占模式(nopreempt)

默认情况下,高优先级的节点恢复后会自动抢回 Master 角色。这在某些场景下可能不合适------比如你正在维护原来的 Master,不希望它刚恢复就又承担流量。

nginx 复制代码
vrrp_instance nginx {
    state BACKUP         # 注意:nopreempt 模式下,state 都配 BACKUP
    nopreempt            # 非抢占模式
    priority 110         # 优先级依然影响首次选举
    # ...
}

配置要点:

  • 所有节点 state 都设为 BACKUP
  • 只有优先级更高的那个节点会通过首次选举成为 Master
  • 主节点宕机恢复后,不会自动抢占,避免流量震荡

15.2 实战:非抢占模式

nginx 复制代码
# web1(优先级 110,但 state 也是 BACKUP)
vrrp_instance nginx {
    state BACKUP
    nopreempt
    interface ens33
    virtual_router_id 51
    priority 110
    # ...
}
nginx 复制代码
# web2(优先级 100)
vrrp_instance nginx {
    state BACKUP
    interface ens33
    virtual_router_id 51
    priority 100
    # ...
}

测试:

bash 复制代码
# 初始:web1 优先级高 → 成为 Master,持有 VIP
# 停止 web1 Keepalived → web2 接替,成为 Master
# 启动 web1 Keepalived → web1 因为有 nopreempt,不会抢回!
# web2 继续做 Master,web1 成为 Backup 等待

15.3 配置调试技巧

bash 复制代码
# 开启调试日志
vim /etc/sysconfig/keepalived
# 修改:
KEEPALIVED_OPTIONS="-D -d -S 0"
# -D:以守护进程运行
# -d:开启详细日志
# -S 0:syslog facility 设为 local0

# 配置独立日志文件
cat > /etc/rsyslog.d/keepalived.conf << EOF
local0.*    /var/log/keepalived.log
EOF

systemctl restart rsyslog
systemctl restart keepalived.service

# 实时查看
tail -f /var/log/keepalived.log

15.4 多网卡指定源 IP

当服务器有多块网卡时,需要明确指定 VRRP 通告的源 IP:

nginx 复制代码
vrrp_instance Nginx {
    state MASTER
    interface ens36
    mcast_src_ip 20.0.0.11    # 明确指定 VRRP 通告的源 IP
    virtual_router_id 51
    priority 110
    # ...
}

📊 总结与架构全景图

LVS + Keepalived 高可用负载均衡完整架构

复制代码
                          Internet
                             │
                    ┌────────▼────────┐
                    │    防火墙/路由器  │
                    └────────┬────────┘
                             │
                    ┌────────▼────────┐
                    │   VIP (虚拟IP)  │  ← Keepalived 管理 VIP 漂移
                    └───┬────────┬───┘
                        │        │
              ┌─────────▼──┐ ┌──▼─────────┐
              │ Director 1 │ │ Director 2  │  ← Keepalived VRRP 主备
              │  (Master)  │ │  (Backup)   │
              │  ipvsadm   │ │  ipvsadm    │  ← LVS 负载均衡
              └──────┬─────┘ └──────┬──────┘
                     │              │
               ┌─────┼──────────────┼──────┐
               │     │              │      │
          ┌────▼──┐ ┌▼─────┐  ┌────▼──┐   │
          │  RS1  │ │ RS2  │  │  RS3  │   │  ← Nginx/Apache/Tomcat
          └───────┘ └──────┘  └───────┘   │
               └──────────────────────────┘
                    Real Server Pool

关键要点速记

维度 要点
LVS 模式选择 DR 模式 ≈99% 场景首选(高性能、Director 不处理回包)
DR 模式关键 RS 绑定 VIP + ARP 抑制(arp_ignore=1, arp_announce=2)
调度算法 无状态→WRR,长连接→WLC
Keepalived VRRP 实现主备 + 健康检查自动踢除/恢复 RS
VIP 漂移 Gratuitous ARP 通知交换机更新 MAC 表
脑裂防范 独立心跳线 + 防火墙放行 + 认证 + 检测脚本 + 监控告警
非抢占 生产建议开启 nopreempt,避免 VIP 频繁漂移

📝 学习感悟:LVS 和 Keepalived 是 Linux 运维的"双子星"------LVS 解决"怎么分发",Keepalived 解决"分发者挂了怎么办"。两者结合,构成了互联网公司最经典的四层负载均衡高可用方案。掌握它们,你就拥有了处理百万级并发流量的基础能力。
🔗 本文基于笔者 2026 年 8 月 12 日的学习笔记整理,如有疏漏欢迎指正交流。

相关推荐
动词ing4 小时前
【C语言】命名规范
c语言·开发语言
琥珀色糖4 小时前
Linux makefile
linux·运维·服务器·makefile·make
大可-4 小时前
Go Air 热重载安装配置指南
开发语言·后端·golang
2401_894915534 小时前
Geo 优化源码部署避坑指南:解决访问异常、定位失效、收录卡顿问题
java·服务器·后端·缓存·开源
whyutianict_vv4 小时前
HCIE-Storage存储3.0排错题实战:归因框架与排查命令
linux·服务器·网络
Dovis(誓平步青云)4 小时前
《 固井工程软件 Cemsol 的数据管理与国产化适配实践》
android·java·开发语言·人工智能
大模型码小白4 小时前
AI安全前沿:AI大模型安全防护的前沿技术
java·网络·人工智能·python·深度学习·学习·安全
看浪的路人4 小时前
第6讲:SQL 解析器
java·开发语言·数据库
小趴菜一只4 小时前
linux权限维持
linux·运维·服务器