一、LVS简介
LVS(Linux Virtual Server,Linux虚拟服务器)是由章文嵩博士开发的一款高性能负载均衡软件,它工作在Linux内核层面,通过IP负载均衡技术将请求分发到后端真实服务器,实现高可用、高性能的服务集群。
LVS主要由三部分组成:
-
ipvsadm:用户空间的管理工具,用于配置LVS规则
-
IPVS:工作在内核空间的负载均衡模块
-
调度算法:多种负载均衡算法供选择
二、LVS的三种工作模式
LVS支持三种工作模式:
-
NAT模式(Network Address Translation)
-
DR模式(Direct Routing,直接路由)
-
TUN模式(IP Tunneling,IP隧道)
三、NAT模式详解
3.1 NAT模式原理
NAT模式通过网络地址转换实现负载均衡,特点是:
-
Director(调度器)作为所有请求的入口和出口
-
请求和响应都经过Director
-
Real Server(真实服务器)的网关指向Director
-
Director需要开启IP转发功能
数据流向:
Client -> Director(VIP) -> Director(DIP) -> Real Server(RIP)
Client <- Director(VIP) <- Director(DIP) <- Real Server(RIP)
3.2 NAT模式环境搭建
3.2.1 网络拓扑
|----------|--------|---------------|-------------------|
| 角色 | 网卡 | IP地址 | 说明 |
| Director | ens160 | 192.168.58.3 | VIP(外网) |
| Director | ens224 | 192.168.0.100 | DIP(内网) |
| RS1 | ens160 | 192.168.0.10 | 网关指向192.168.0.100 |
| RS2 | ens160 | 192.168.0.20 | 网关指向192.168.0.100 |
3.2.2 Director配置
配置双网卡:
vmset.sh ens160 192.168.58.3 vsnode
vmset.sh ens224 192.168.0.100 vsnode noroute
开启IP转发:
echo net.ipv4.ip_forward=1 >> /etc/sysctl.conf
sysctl -p
[root@vsnode ~]# vmset.sh ens160 192.168.58.3 vsnode
[root@vsnode ~]# vmset.sh ens224 192.168.0.100 vsnode noroute
3.2.3 Real Server配置
RS1配置:
配置网卡和网关:
vmset.sh ens160 192.168.0.10 RS1 noroute
nmcli connection modify ens160 ipv4.gateway 192.168.0.100
nmcli connection reload
nmcli connection up ens160
安装Apache:
dnf install httpd -y
systemctl enable --now httpd
echo RS1 - 192.168.0.10 > /var/www/html/index.html
RS2配置:
配置网卡和网关:
vmset.sh ens160 192.168.0.20 RS2 noroute
nmcli connection modify ens160 ipv4.gateway 192.168.0.100
nmcli connection reload
nmcli connection up ens160
安装Apache:
dnf install httpd -y
systemctl enable --now httpd
echo RS2 - 192.168.0.20 > /var/www/html/index.html
#RS1
#设定网络
[root@RS1 ~]# vmset.sh ens160 192.168.0.10 RS1 noroute
[root@RS1 ~]# nmcli connection modify ens160 ipv4.gateway 192.168.0.100
[root@RS1 ~]# nmcli connection reload
[root@RS1 ~]# nmcli connection up ens160
[root@RS1 ~]# route -n
#设定访问业务真实数据
[root@RS1 ~]# dnf install httpd -y
[root@RS1 ~]# systemctl enable --now httpd
[root@RS1 ~]# echo RS1 - 192.168.0.10 > /var/www/html/index.html
#RS2
#设定网络
[root@RS1 ~]# vmset.sh ens160 192.168.0.20 RS1 noroute
[root@RS1 ~]# nmcli connection modify ens160 ipv4.gateway 192.168.0.100
[root@RS1 ~]# nmcli connection reload
[root@RS1 ~]# nmcli connection up ens160
[root@RS1 ~]# route -n
#设定访问业务真实数据
[root@RS1 ~]# dnf install httpd -y
[root@RS1 ~]# systemctl enable --now httpd
[root@RS1 ~]# echo RS2 - 192.168.0.20 > /var/www/html/index.html
[root@vsnode ~]# curl 192.168.0.10
[root@vsnode ~]# curl 192.168.0.20
3.3 NAT模式LVS配置
清空原有规则:
ipvsadm -C
添加虚拟服务(VIP):
ipvsadm -A -t 192.168.58.3:80 -s wrr
添加真实服务器:
ipvsadm -a -t 192.168.58.3:80 -r 192.168.0.10:80 -m -w 1
ipvsadm -a -t 192.168.58.3:80 -r 192.168.0.20:80 -m -w 1
查看规则:
ipvsadm -Ln
#1,开启内核路由功能
[root@vsnode ~]# echo net.ipv4.ip_forward=1 >> /etc/sysctl.conf
[root@vsnode ~]# sysctl -p
#2.编写策略
[root@vsnode ~]# ipvsadm -C
[root@vsnode ~]# ipvsadm -A -t 192.168.58.3:80 -s wrr
[root@vsnode ~]# ipvsadm -a -t 192.168.58.3:80 -r 192.168.0.10:80 -m -w 1
[root@vsnode ~]# ipvsadm -a -t 192.168.58.3:80 -r 192.168.0.20:80 -m -w 1
[root@vsnode ~]# ipvsadm -Ln
#测试
[root@vsnode ~]# for i in {1..10};do curl 192.168.58.3;done
#更改权重
[root@vsnode ~]# ipvsadm -e -t 192.168.58.3:80 -r 192.168.0.10:80 -m -w 2
[root@vsnode ~]# ipvsadm -Ln
#测试
[root@vsnode ~]# for i in {1..10};do curl 192.168.58.3;done
RS2 - 192.168.0.20
参数说明:
-
-A:添加虚拟服务
-
-t:TCP协议
-
-s wrr:加权轮询算法
-
-a:添加真实服务器
-
-r:真实服务器地址
-
-m:NAT模式
-
-w:权重
3.4 NAT模式测试
测试负载均衡:
for i in {1..10}; do curl 192.168.58.3; done
修改权重:
ipvsadm -e -t 192.168.58.3:80 -r 192.168.0.10:80 -m -w 2
再次测试:
for i in {1..10}; do curl 192.168.58.3; done
3.5 NAT模式规则持久化
方法1:保存到自定义文件:
ipvsadm-save -n > /mnt/ipvs.rule
ipvsadm -C
ipvsadm-restore < /mnt/ipvs.rule
方法2:使用systemd服务:
ipvsadm-save -n > /etc/sysconfig/ipvsadm
systemctl enable --now ipvsadm.service
[root@vsnode ~]# watch -n 1 ipvsadm -Ln
#利用自定义文件进行持久化
[root@vsnode ~]# ipvsadm-save -n
[root@vsnode ~]# ipvsadm-save -n > /mnt/ipvs.rule
[root@vsnode ~]# ipvsadm -C
[root@vsnode ~]# ipvsadm-restore < /mnt/ipvs.rule
#利用守护进程进行规则持久化
[root@vsnode ~]# ipvsadm-save -n > /etc/sysconfig/ipvsadm
[root@vsnode ~]# ipvsadm -C
[root@vsnode ~]# systemctl enable --now ipvsadm.service
3.6 NAT模式特点总结
优点:
-
配置简单,易于理解
-
Real Server可以是任意操作系统
-
支持端口映射
缺点:
-
Director容易成为瓶颈(请求和响应都经过Director)
-
Real Server必须与Director在同一网段
-
Director需要开启IP转发
四、DR模式详解
4.1 DR模式原理
DR模式(直接路由模式)通过修改MAC地址实现负载均衡,特点是:
-
请求经过Director,响应直接返回给客户端
-
Director和Real Server都配置VIP
-
Real Server的VIP配置在lo接口上
-
需要抑制Real Server的ARP响应
数据流向:
Client -> Director(VIP) -> Real Server(VIP)
Client <- Real Server(VIP) [直接返回,不经过Director]
4.2 DR模式环境搭建
4.2.1 网络拓扑
|----------|--------|------------------|-------|
| 角色 | 网卡 | IP地址 | 说明 |
| Router | ens160 | 192.168.58.3 | 连接外网 |
| Router | ens224 | 192.168.0.100 | 连接内网 |
| Director | ens160 | 192.168.0.50 | DIP |
| Director | lo | 192.168.0.200/32 | VIP |
| RS1 | ens160 | 192.168.0.10 | RIP |
| RS1 | lo | 192.168.0.200/32 | VIP |
| RS2 | ens160 | 192.168.0.20 | RIP |
| RS2 | lo | 192.168.0.200/32 | VIP |
| Client | ens160 | 192.168.58.4 | 测试客户端 |
4.2.2 Router配置
停止ipvsadm服务:
systemctl disable --now ipvsadm.service
ipvsadm -C
配置双网卡:
vmset.sh ens160 192.168.58.3 vsnode
vmset.sh ens224 192.168.0.100 vsnode noroute
开启IP转发:
echo net.ipv4.ip_forward=1 >> /etc/sysctl.conf
sysctl -p
配置SNAT:
iptables -t nat -A POSTROUTING -o ens224 -j SNAT --to-source 192.168.0.100
iptables -t nat -A POSTROUTING -o ens160 -j SNAT --to-source 192.168.58.3
#在路由器中
[root@router ~]# systemctl disable --now ipvsadm.service
[root@router ~]# ipvsadm -C
#在路由器中
[root@router ~]# vmset.sh ens160 192.168.58.3 vsnode
[root@router ~]# vmset.sh ens224 192.168.0.100 vsnode noroute
#设定内核路由功能
[root@router ~]# echo net.ipv4.ip_forward=1 >> /etc/sysctl.conf
[root@router ~]# sysctl -p
#数据转发策略
[root@router ~]# iptables -t nat -A POSTROUTING -o ens224 -j SNAT --to-source 192.168.0.100
[root@vsnode ~]# iptables -t nat -A POSTROUTING -o ens160 -j SNAT --to-source 192.168.58.3
4.2.3 Director配置
配置物理网卡:
vmset.sh ens160 192.168.0.50 vsnode noroute
配置lo接口VIP:
cd /etc/NetworkManager/system-connections/
cp -p ens160.nmconnection lo.nmconnection
vim lo.nmconnection
lo.nmconnection内容:
connection
id=lo
type=loopback
interface-name=lo
ipv4
method=manual
address1=127.0.0.1/8
address2=192.168.0.200/32
加载配置:
nmcli connection reload
nmcli connection up ens160
nmcli connection up lo
#vsnode 调度器
[root@vsnode ~]# vmset.sh ens160 192.168.0.50 vsnode noroute
[root@vsnode ~]# vim /etc/NetworkManager/system-connections/ens160.nmconnection
[connection]
id=ens160
type=ethernet
interface-name=ens160
[ipv4]
method=manual
address1=192.168.0.50/24,192.168.0.100
[root@vsnode ~]# cd /etc/NetworkManager/system-connections/
[root@vsnode system-connections]# cp -p ens160.nmconnection lo.nmconnection
[root@vsnode system-connections]# vim lo.nmconnection
[connection]
id=lo
type=loopback
interface-name=lo
[ipv4]
method=manual
address1=127.0.0.1/8
address2=192.168.0.200/32
[root@RS1 system-connections]# nmcli connection reload
[root@RS1 system-connections]# nmcli connection up ens160
[root@RS1 system-connections]# nmcli connection up lo
#检测
root@vsnode system-connections]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.0.100 0.0.0.0 UG 100 0 0 ens160
192.168.0.0 0.0.0.0 255.255.255.0 U 100 0 0 ens160
192.168.0.0 0.0.0.0 255.255.255.0 U 100 0 0 ens160
[root@vsnode system-connections]# ip a
#客户端
[root@client ~]# vmset.sh ens160 192.168.58.4 client norouter
[root@client ~]# vim /etc/NetworkManager/system-connections/ens160.nmconnection
[connection]
id=ens160
type=ethernet
interface-name=ens160
[ipv4]
method=manual
address1=192.168.58.4/24,192.168.58.3
dns=8.8.8.8;
[root@client ~]# nmcli connection reload
[root@client ~]# nmcli connection up ens160
[root@client ~]# route -n
#检测
[root@client ~]# ping 192.168.0.200
4.2.4 Real Server配置
RS1配置:
配置物理网卡:
vmset.sh ens160 192.168.0.10 RS1 noroute
nmcli connection modify ens160 ipv4.gateway 192.168.0.100
nmcli connection reload
nmcli connection up ens160
配置lo接口VIP:
cd /etc/NetworkManager/system-connections/
cp -p ens160.nmconnection lo.nmconnection
vim lo.nmconnection
lo.nmconnection内容:
connection
id=lo
type=loopback
interface-name=lo
ethernet
ipv4
address1=127.0.0.1/8
address2=192.168.0.200/32
method=manual
加载配置:
nmcli connection reload
nmcli connection up lo
抑制ARP响应(关键配置):
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/lo/arp_announce
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
#RS1
[root@RS1 ~]# vmset.sh ens160 192.168.0.10 RS1 noroute
[root@RS1 ~]# nmcli connection modify ens160 ipv4.gateway 192.168.0.100
[root@RS1 ~]# nmcli connection reload
[root@RS1 ~]# nmcli connection up ens160
[root@RS1 ~]# route -n
#在lo上设定vip
[root@RS1 ~]# cd /etc/NetworkManager/system-connections/
[root@RS1 system-connections]# cp -p ens160.nmconnection lo.nmconnection
[root@RS1 system-connections]# vim lo.nmconnection
[connection]
id=lo
type=loopback
interface-name=lo
[ethernet]
[ipv4]
address1=127.0.0.1/8
address2=192.168.0.200/32
method=manual
[root@RS1 system-connections]# nmcli connection reload
[root@RS1 system-connections]# nmcli connection up lo
#arp禁止响应
[root@rs1 ~]# echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
[root@rs1 ~]# echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
[root@rs1 ~]# echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
[root@rs1 ~]# echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
RS2配置:
配置物理网卡:
vmset.sh ens160 192.168.0.20 RS2 noroute
nmcli connection modify ens160 ipv4.gateway 192.168.0.100
nmcli connection reload
nmcli connection up ens160
配置lo接口VIP(同RS1):
cd /etc/NetworkManager/system-connections/
cp -p ens160.nmconnection lo.nmconnection
vim lo.nmconnection
lo.nmconnection内容:
connection
id=lo
type=loopback
interface-name=lo
ethernet
ipv4
address1=127.0.0.1/8
address2=192.168.0.200/32
method=manual
加载配置:
nmcli connection reload
nmcli connection up lo
抑制ARP响应:
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/lo/arp_announce
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
#RS2
[root@RS2 ~]# vmset.sh ens160 192.168.0.20 RS2 noroute
[root@RS2 ~]# nmcli connection modify ens160 ipv4.gateway 192.168.0.100
[root@RS2 ~]# nmcli connection reload
[root@RS2 ~]# nmcli connection up ens160
[root@RS2 ~]# route -n
#在lo上设定vip
[root@RS2 ~]# cd /etc/NetworkManager/system-connections/
[root@RS2 system-connections]# cp -p ens160.nmconnection lo.nmconnection
[root@RS2 system-connections]# vim lo.nmconnection
[connection]
id=lo
type=loopback
interface-name=lo
[ethernet]
[ipv4]
address1=127.0.0.1/8
address2=192.168.0.200/32
method=manual
[root@RS2 system-connections]# nmcli connection reload
[root@RS2 system-connections]# nmcli connection up lo
#arp禁止响应
[root@rs2 ~]# echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
[root@rs2 ~]# echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
[root@rs2 ~]# echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
[root@rs2 ~]# echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
4.3 DR模式LVS配置
添加虚拟服务:
ipvsadm -A -t 192.168.0.200:80 -s wrr
添加真实服务器(使用-g参数表示DR模式):
ipvsadm -a -t 192.168.0.200:80 -r 192.168.0.10:80 -g
ipvsadm -a -t 192.168.0.200:80 -r 192.168.0.20:80 -g
查看规则:
ipvsadm -Ln
输出示例:
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.0.200:80 wrr
-> 192.168.0.10:80 Route 1 0 0
-> 192.168.0.20:80 Route 1 0 0
在RS1和RS2中解决响应问题
[root@rs1 ~]# echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
[root@rs1 ~]# echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
[root@rs1 ~]# echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
[root@rs1 ~]# echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
[root@rs2 ~]# echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
[root@rs2 ~]# echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
[root@rs2 ~]# echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
[root@rs2 ~]# echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
在lvs中配置策略
[root@lvs ~]# ipvsadm -A -t 192.168.0.100:80 -s wrr
[root@lvs ~]# ipvsadm -a -t 192.168.0.100:80 -r 192.168.0.10:80 -g
[root@lvs ~]# ipvsadm -a -t 192.168.0.100:80 -r 192.168.0.20:80 -g
[root@lvs ~]# ipvsadm -Ln
4.4 DR模式测试
在Client上测试:
for N in {1..6}; do curl 192.168.0.200; done
输出示例:
RS2 server - 192.168.0.10
RS1 server - 192.168.0.20
RS2 server - 192.168.0.10
RS1 server - 192.168.0.20
RS2 server - 192.168.0.10
RS1 server - 192.168.0.20
[root@node10 ~]# for N in {1..6};do curl 192.168.0.200;done
4.5 ARP抑制原理
DR模式中,Director和Real Server都配置了相同的VIP,为什么不会冲突?
关键配置:
让Real Server不响应ARP请求:
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
让Real Server不使用VIP发送ARP:
echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
arp_ignore参数:
-
0:响应所有ARP请求(默认)
-
1:只响应目标IP是本地接口IP的ARP请求
arp_announce参数:
-
0:使用任意本地接口的IP作为ARP源地址
-
1:尽量避免使用不属于目标子网的接口IP作为ARP源地址
-
2:总是使用最佳本地接口IP作为ARP源地址
4.6 DR模式特点总结
优点:
-
性能高,响应直接返回给客户端,不经过Director
-
Director不再是瓶颈
-
支持更大的并发量
缺点:
-
配置复杂,需要配置VIP和ARP抑制
-
Real Server必须与Director在同一物理网络
-
不支持端口映射
-
Real Server必须支持抑制ARP(Linux系统)
五、NAT模式 vs DR模式对比
|--------|---------------------------|-----------------------------|
| 特性 | NAT模式 | DR模式 |
| 性能 | 一般(请求和响应都经过Director) | 高(响应直接返回) |
| 配置复杂度 | 简单 | 复杂 |
| 网络要求 | Real Server与Director在同一网段 | Real Server与Director在同一物理网络 |
| 端口映射 | 支持 | 不支持 |
| 操作系统要求 | 任意 | 需要支持ARP抑制(主要是Linux) |
| 扩展性 | 受Director性能限制 | 更好的扩展性 |
| 适用场景 | 小型集群、测试环境 | 大型集群、生产环境 |
六、LVS常用调度算法
|------|-------------------------|------------------|
| 算法 | 名称 | 说明 |
| rr | 轮询(Round Robin) | 依次将请求分配到不同的RS |
| wrr | 加权轮询(Weighted RR) | 根据权重分配请求 |
| lc | 最少连接(Least Connections) | 将请求分配到当前连接数最少的RS |
| wlc | 加权最少连接 | 带权重的最少连接算法 |
| lblc | 基于局部性的最少连接 | 根据目标IP查找最近使用的RS |
| dh | 目标地址哈希 | 根据目标IP选择RS |
| sh | 源地址哈希 | 根据源IP选择RS |
| sed | 最短预期延迟 | 不考虑非活动连接 |
| nq | 永不排队 | 如果有空闲RS立即分配 |
七、LVS监控与维护
7.1 实时监控
使用watch命令实时监控:
watch -n 1 ipvsadm -Ln
7.2 常用管理命令
查看规则:
ipvsadm -Ln
查看统计信息:
ipvsadm -Ln --stats
查看速率信息:
ipvsadm -Ln --rate
清空规则:
ipvsadm -C
删除虚拟服务:
ipvsadm -D -t 192.168.58.3:80
删除真实服务器:
ipvsadm -d -t 192.168.58.3:80 -r 192.168.0.10:80
修改真实服务器权重:
ipvsadm -e -t 192.168.58.3:80 -r 192.168.0.10:80 -m -w 2