01. 什么是 LVS?(通俗理解)
LVS 全称 Linux Virtual Server,即 Linux 虚拟服务器。它是由章文嵩博士开发的,现在已经集成在 Linux 内核中(IPVS模块),因此性能非常强悍。
通俗比喻: 想象一家生意火爆的餐厅(网站)。
-
**以前(单机模式):**只有一个服务员,既要门口迎宾,又要点菜端盘子,客人一多就累垮了(服务器宕机)。
-
现在(LVS集群模式): 我们聘请了一个极速前台(LVS Director)。
-
这个前台不负责做菜(不处理具体业务,如 PHP、数据库)。
-
只负责站在门口 (监听端口),把进来的客人分配给后面几十个服务员(Real Server)。
-
因为她只负责"分流",所以处理速度极快,能抗住巨大的并发量。
-
02. LVS核心术语
-
DS (Director Server - 负载均衡调度器): 就是上面的"前台"。它是集群的入口 ,负责接收用户请求并根据算法转发。
-
RS (Real Server - 真实服务器): 就是后面的"服务员"。它们是真正干活的服务器(比如运行着 Nginx, Tomcat, MySQL 的机器)。
-
VIP (Virtual IP - 虚拟 IP): 这是对外公布的 IP 地址。就像餐厅的"招牌电话",用户只知道访问这个 IP,不知道后面具体是谁在服务。
-
RIP (Real IP - 真实 IP): 后面 RS(服务员)自己真实的网卡 IP,用于内部通信。
-
DIP (Director IP - 调度器 IP): 调度器 (DS)用来和后端 RS 通信的 IP。
-
CIP (Client IP - 客户端 IP): 发起请求的用户的电脑 IP。
03. LVS 的三种工作模式
1. NAT 模式 (地址转换模式)
原理: 类似于家里的路由器。
-
用户发请求给 VIP。
-
DS 收到后,把数据包的目标 IP 修改为后端的 RIP,转发过去。
-
RS 处理完,把结果发回给 DS。
-
DS 再把源 IP 改回 VIP,发给用户。
-
特点: 进出都要经过 DS。
-
缺点: DS 容易成为瓶颈(因为所有回包流量通常很大,都要经过它)。
-
比喻: 快递员(用户)把包裹给前台,前台改个标签给员工;员工处理完把包裹给前台,前台再改标签给快递员。前台非常忙。
2.DR 模式 (直接路由模式) ------ 企业最常用
原理: 修改 MAC 地址。
-
用户发请求给 VIP。
-
DS 收到后,不修改 IP ,只是把数据包的目标 MAC 地址 改成某台RS 的 MAC 地址 ,扔给 RS。
-
RS 收到包,发现目标 IP 是 VIP (RS 上也配置了这个 VIP,但藏在回环接口 lo 上不让外人知道),于是处理请求。
-
RS 处理完,直接 通过自己 的网关把数据包发回给用户 ,不走 DS 了。
-
特点: 进流量走 DS,出流量直接回用户。
-
优点: 性能极高,因为回包流量通常是请求流量的几十倍,DS 再也不用处理回包了。
-
限制: DS 和 RS 必须在同一个物理网络(二层互通)。
-
比喻: 客户给前台递个条子,前台把条子递给员工。员工处理完,直接把货发给客户,不用再经过前台。
3. TUN 模式 (IP 隧道模式)
原理: 给数据包再"包"一层。 DS 在原有的数据包外面再封装一层 IP 报文发给 RS。RS 拆开后处理,也是直接返回给用户。
- 场景: 这里的 DS 和 RS 可以跨越互联网(异地容灾),但配置较复杂,RS 必须支持隧道协议,由于不常用,这里就不细究。
04. 常用调度算法
静态算法(不考虑服务器当前忙不忙):
-
RR (Round Robin - 轮询): 一人一个,按顺序来。绝对公平。
-
WRR (Weighted Round Robin - 加权轮询): 谁能力强(配置高),谁多干点。比如 A 机器 8 核,B 机器 4 核,那就让 A 接 2 单,B 接 1 单。
动态算法(看谁闲着给谁):
-
LC (Least Connections - 最少连接): 谁身上的连接数少,就分给谁。
-
WLC (Weighted Least Connections - 加权最少连接): (最常用) 综合考虑权重和当前连接数。
05.NAT模式实验
1. 实验拓扑规划 (环境准备)
在 NAT 模式中,LVS 调度器(Director)充当了类似'路由器'的角色。它必须拥有两张网卡:一张连接公网(业务网段),一张连接内网(后端服务器网段)。最关键的一点是:后端真实服务器(RS)的网关必须指向调度器(DS)的内网 IP,否则数据包有去无回。
实验 IP 规划表:
| 主机角色 | 主机名 | 网卡配置 | IP 地址 | 网关 (Gateway) | 备注 |
|---|---|---|---|---|---|
| 调度器 | lvs-server |
eth0 (外网) | 172.25.254.200 | 172.25.254.2 | VIP (对外服务) |
| eth1 (内网) | 192.168.0.100 | 无 | DIP (对内连接/仅主机) | ||
| 真实服务器1 | server1 |
eth0 | 192.168.0.10 | 192.168.0.100 | 仅主机模式 |
| 真实服务器2 | server2 |
eth0 | 192.168.0.20 | 192.168.0.100 | 仅主机模式 |
| 测试客户端 | foundation |
eth0 | 172.25.254.100 | - | 你的母机 |
2. 分步实施步骤
第一步:基础环境配置 (所有节点)
为了排除干扰,建议在实验初期关闭防火墙和 SELinux
bash
# 在 lvs-server, server1, server2 上执行
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
# 记得修改 /etc/selinux/config 设为 disabled 以便永久生效
第二步:配置调度器 (LVS Director) 网络
LVS 调度器需要配置双网卡,并开启内核路由转发功能。
1.配置 IP (使用 nmcli):
bash
# 配置外网网卡 (VIP)
nmcli connection modify eth0 ipv4.addresses 172.25.254.200/24 ipv4.gateway 172.25.254.2 ipv4.method manual connection.autoconnect yes
nmcli connection up eth0
# 配置内网网卡 (DIP) - 假设第二块网卡为 eth1
nmcli connection modify eth1 ipv4.addresses 192.168.0.100/24 ipv4.method manual connection.autoconnect yes
nmcli connection up eth1
2.开启路由转发 (核心步骤):
注: 因为 NAT 模式下,LVS 主机相当于一台路由器,Linux 默认是禁止转发数据包的,必须开启。
bash
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl -p
第三步:配置真实服务器 (Real Servers) 网络
配置 Server1:
bash
# 注意:网关必须指向 LVS 的内网 IP (192.168.0.100)
nmcli connection modify eth0 ipv4.addresses 192.168.0.10/24 ipv4.gateway 192.168.0.100 ipv4.method manual connection.autoconnect yes
nmcli connection up eth0
配置 Server2:
bash
# 同样指向 LVS 内网 IP
nmcli connection modify eth0 ipv4.addresses 192.168.0.20/24 ipv4.gateway 192.168.0.100 ipv4.method manual connection.autoconnect yes
nmcli connection up eth0
第四步:部署 Web 服务 (Real Servers)
为了测试效果,我们在两台 RS 上安装 httpd,并写入不同的内容,以便区分流量被分发到了哪台机器。
在 Server1 上:
bash
yum install httpd -y
echo "This is Server 1 (192.168.0.10)" > /var/www/html/index.html
systemctl enable --now httpd
在 Server2 上:
bash
yum install httpd -y
echo "This is Server 2 (192.168.0.20)" > /var/www/html/index.html
systemctl enable --now httpd
验证连通性:
此时,在 lvs-server 上应该能 curl 192.168.0.10 和 curl 192.168.0.20 并看到不同的内容

第五步:配置 LVS 规则 (Director)
我们需要安装 ipvsadm 工具并编写规则(LVS主机上进行)
安装工具:
bash
yum install ipvsadm -y
编写策略 (NAT模式):
bash
# 1. 清空旧规则
ipvsadm -C
# 2. 添加虚拟服务 (VIP:端口)
# -A: 添加服务
# -t: TCP协议
# -s rr: 调度算法为轮询 (Round Robin)
ipvsadm -A -t 172.25.254.200:80 -s rr
# 3. 添加后端真实服务器 (RIP:端口)
# -a: 添加 Real Server
# -t: 指定所属的虚拟服务
# -r: Real Server 的 IP
# -m: 指定为 NAT 模式 (Masquerade)
ipvsadm -a -t 172.25.254.200:80 -r 192.168.0.10:80 -m
ipvsadm -a -t 172.25.254.200:80 -r 192.168.0.20:80 -m
查看规则状态:
bash
ipvsadm -Ln
输出示例:
实验验证:
此时切换测试机(172.25.254.100),连续执行:
bash
curl 172.25.254.200
预期结果:
到这就完成了 LVS-NAT 模式的搭建。我们可以看到,客户端只需要访问 172.25.254.200 这个 VIP,请求就会被自动分发到后端的私有网络中。
3.额外配置:IPVS持久化
1. 核心概念:什么是持久化?
LVS 的持久化不是指数据保存到硬盘,而是指 连接的"亲缘性"。
-
默认情况 (无持久化): LVS 像一个绝对公平的交警,按照算法(比如轮询 rr),把你的第 1 个包给 Server1,第 2 个包给 Server2......
-
开启持久化 (
-p参数): LVS 会记录一个小本本(内存中的持久化模板 )。一旦记录了"IP A -> Server1",那么在设定的倒计时内,IP A 发来的所有请求,无视调度算法,统统扔给 Server1。
2. 实验步骤:配置持久化
在你现有的 LVS-NAT 环境中,我们将原来的"轮询"改为"带持久化的轮询"。
第一步:修改 LVS 规则
我们不需要删除原来的规则,直接使用 -E (Edit) 参数修改即可。
命令语法: ipvsadm -E -t VIP:端口 -s 算法 -p [时间秒]
在 LVS 调度器上执行:
bash
# 修改 VIP 172.25.254.200:80 的规则
# -E: 修改现有服务
# -s rr: 依然保持轮询算法
# -p 30: 开启持久化,时间为 30 秒 (为了实验效果,设置短一点)
ipvsadm -E -t 172.25.254.200:80 -s rr -p 30
第二步:查看效果
执行查看命令,你会发现多了一个 persistent 标志:
验证实验:
回到测试机 (172.25.254.100)
操作 1:连续访问
bash
for i in {1..5}; do curl 172.25.254.200; done
预期结果:
全为RS1或RS2
操作 2:等待超时
等待 35 秒(超过我们设置的 30 秒)
等待结束后,再次执行 curl 172.25.254.200
预期结果:
LVS 可能会把你分配到另一台机器上(因为持久化模板过期了,LVS 重新按照轮询算法分配了一次)
06.DR模式实验
1.实验环境
在 DR 模式下,LVS 调度器和所有真实服务器 (RS) 必须在同一个物理广播域(同一个网段)。
1.LVS 调度器 (DS):
-
保留 仅一张网卡 即可(比如 eth0)。
-
VMware 模式: 设置为 NAT 模式 (VMnet8)。
-
IP配置: 设为
172.25.254.200(作为 DIP - 调度器 IP)。 -
VIP配置: 设为
172.25.254.250(作为 VIP - 对外服务 IP)。
2.真实服务器 (RS1 & RS2):
-
VMware 模式: 全部改为 NAT 模式 (VMnet8)。
-
注意: 不要再用"仅主机模式"了,把它们拉回到和 LVS 同一个网络。
-
IP配置:
-
RS1:
172.25.254.10 -
RS2:
172.25.254.20
-
-
网关 (Gateway): 这是最大的坑!
-
在 NAT 模式下,网关指向 LVS。
-
在 DR 模式下,网关必须指向真实的路由器(即 VMware 的网关,通常是 172.25.254.2)。 RS 必须有能力自己上网/回复客户端。
-
2. 实验步骤详解
第一步:初始化环境 (所有节点)
为了防止之前的实验干扰,建议清空 IPVS 规则并重启网络。
bash
# 在 LVS 上
ipvsadm -C
# 确保防火墙关闭
systemctl stop firewalld
setenforce 0
第二步:配置 LVS 调度器 (Director)
调度器需要两个 IP:一个是自己的 IP (DIP),一个是服务的 IP (VIP)。VIP 通常绑定在网卡别名上。
bash
# 1. 确保 DIP 已经配置 (假设 eth0 是 172.25.254.200)
ip addr show eth0
# 2. 配置 VIP (绑定在 eth0 上)
# 这行命令的意思是:在 eth0 上再加一个 IP,作为 VIP
ip addr add 172.25.254.250/32 dev eth0
#这里掩码用 /32 是为了只广播这一个 IP,不产生路由条目干扰。
第三步:配置真实服务器 RS
RS 也需要配置 VIP,但是 这个 VIP 必须配置在 回环接口 (lo) 上。
原因: RS 收到 LVS 转过来的包,目标 IP 是 VIP。如果 RS 身上没有 VIP,它会丢弃这个包。但如果把 VIP 配在物理网卡上,就会和 LVS 的 VIP 冲突(IP 冲突)。所以要藏在 lo 上。
操作(在 Server1 和 Server2 上都要做):
1.配置 VIP 到回环接口:
bash
ip addr add 172.25.254.250/32 dev lo
2.配置 ARP 抑制:
既然 RS 上也有 VIP,为了不让局域网内的其他机器(包括路由器)知道 RS 上有这个 IP,我们需要"封住 RS 的嘴"。
arp_ignore=1: 别人问 VIP 是谁,我坚决不回答(除非问的是我的物理 IP)。
arp_announce=2: 我发包出去时,坚决不用 VIP 作为源地址。
bash
# 临时生效命令
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
第四步:配置 LVS 转发策略
回到 LVS 调度器 ,配置规则。注意这次要用 -g 参数 (Gateway/DR模式)。
bash
# 1. 添加虚拟服务
ipvsadm -A -t 172.25.254.250:80 -s rr
# 2. 添加后端服务器
# -g : 指定为 DR 模式 (Gatewaying)
ipvsadm -a -t 172.25.254.250:80 -r 172.25.254.10:80 -g
ipvsadm -a -t 172.25.254.250:80 -r 172.25.254.20:80 -g
# 3. 查看状态
ipvsadm -Ln
预期结果:
验证实验:
在测试机 (172.25.254.100) 上进行测试。
访问 VIP:
bash
curl 172.25.254.250
预期结果:
轮询显示 Server1 和 Server2 的内容。
3.额外配置:防火墙标记和会话粘滞
为什么需要"防火墙标记 + 会话粘滞"?
想象一个常见的电商场景:
-
用户在浏览商品时,通过 HTTP (80端口) 访问。
-
用户点击"去支付",跳转到了 HTTPS (443端口)。
-
问题来了: 如果 LVS 把 80 的请求分给了 Server1,却把 443 的请求分给了 Server2,那么用户在 Server1 上的购物车/登录状态就丢了!
解决方案: 我们需要把 HTTP 和 HTTPS 看作一个整体 。无论用户访问 80 还是 443,只要是同一个用户,都必须坚持发给同一台后端服务器。这就需要 FWM (Firewall Mark) 登场了。
实验目标:端口绑定与全会话保持
我们将通过 iptables 给数据包打上"标签",然后 LVS 识别这个标签进行统一调度。
1. 准备工作:后端 RS 开启 SSL
为了测试 HTTPS,我们需要让后端两台 RS 支持 443 端口。
在 Server1 和 Server2 上执行:
bash
# 1. 安装 mod_ssl 模块 (会让 httpd 支持 SSL)
yum install mod_ssl -y
# 2. 重启 httpd 服务
systemctl restart httpd
# 3. 验证端口
ss -antl | grep 443
# 看到 443 端口处于 LISTEN 状态即成功
预期结果:
2. LVS 调度器配置:
我们利用 Linux 防火墙 (iptables) 的 mangle 表。它的作用不是拦截数据,而是修改数据。 下面的命令意思是:"凡是发往 VIP (172.25.254.250) 的 TCP 数据包,不管是 80 端口还是 443 端口,统统要在脑门上盖一个章,号码是 66。"
bash
# 1. 确保 ipvsadm 规则已清空 (为了看清效果)
ipvsadm -C
# 2. 使用 iptables 打标记
# -t mangle: 指定 mangle 表
# -A PREROUTING: 在路由前链操作
# -d 172.25.254.250: 目标是我们的 VIP
# -p tcp: 协议是 TCP
# -m multiport --dports 80,443: 指定多个端口
# -j MARK --set-mark 66: 动作是打标记,标记号为 66 (数字随便定,只要和后面对应)
iptables -t mangle -A PREROUTING -d 172.25.254.250 -p tcp -m multiport --dports 80,443 -j MARK --set-mark 66
3. LVS 调度器配置:基于标记调度
现在,LVS 不再盯着"IP:端口"看了,而是盯着"标记号码"看。
在 LVS 调度器上执行:
bash
# 添加虚拟服务
# 注意:这里不再是 -t (TCP) 或 -u (UDP),而是 -f (Firewall Mark)
# -f 66: 监听标记为 66 的流量
# -s rr: 轮询算法
# -p: 开启持久化 (默认 360 秒),这是实现"粘滞"的关键
ipvsadm -A -f 66 -s rr -p
# 添加后端真实服务器
# -r: Real Server IP
# -g: DR 模式 (Gateway)
ipvsadm -a -f 66 -r 172.25.254.10 -g
ipvsadm -a -f 66 -r 172.25.254.20 -g
预期结果:
4. 实验验证 (见证 HTTP 和 HTTPS 的绑定)
回到客户端进行测试,为了验证"粘滞"效果,我们需要先访问 HTTP,再访问 HTTPS,看看是否都在同一台机器上。
访问 HTTP:
访问 HTTPS:注意:因为是自签名证书,curl 需要加
-k(insecure) 参数忽略证书报错。
两次测试得到的必须是同一Server










