virual serve

LVS(Linux Virtual Server,Linux 虚拟服务器) 是 Linux 内核原生的高性能四层负载均衡方案,由章文嵩博士开发,已集成进 Linux 内核,用于将流量分发到后端服务器集群,提升系统并发与可用性。

一、LVS DR(直接路由)模式(设计调度器,路由器,客户端,后端服务器)

1.调度器初始化配置

bash 复制代码
# 1. 配置调度器eth0网卡IP为192.168.0.50,主机标识vsnode。norouter:不自动添加默认路由(避免路由冲突)
# 注:vmset.sh是实验环境自定义脚本,等价于ip addr add 192.168.0.50/24 dev eth0
[root@vsnode ~]# vmset.sh  eth0 192.168.0.50 vsnode  norouter
# 2. 编辑NetworkManager的eth0网卡配置文件(持久化IP/网关配置)
[root@vsnode ~]# vim /etc/NetworkManager/system-connections/eth0.nmconnection
[connection]
id=eth0
type=ethernet  #以太网
interface-name=eth0  #绑定网卡


[ipv4]
method=manual
address1==192.168.0.50/24,192.168.0.100

# 3. 进入NetworkManager配置文件目录(存放所有网卡的持久化配置)
[root@vsnode ~]# cd  /etc/NetworkManager/system-connections/
# 4. 复制eth0的配置文件为lo.nmconnection(快速生成回环网卡配置模板,-p:保留原文件权限/属性)
# 注:DR模式中调度器需要在lo(回环网卡)绑定VIP,因此需单独配置lo
[root@vsnode system-connections]#  cp -p eth0.nmconnection lo.nmconnection
# 5. 编辑lo(回环网卡)配置文件,核心目的:绑定VIP(192.168.0.200)
[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
# 6. 重载NetworkManager配置(使修改后的网卡配置生效,无需重启服务)
[root@RS1 system-connections]# nmcli connection reload
[root@RS1 system-connections]# nmcli connection up eth0
连接已成功激活(D-Bus 活动路径:/org/freedesktop/NetworkManager/ActiveConnection/7)
[root@RS1 system-connections]# nmcli connection up  lo
连接已成功激活(D-Bus 活动路径:/org/freedesktop/NetworkManager/ActiveConnection/8)


#检测
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 eth0
192.168.0.0     0.0.0.0         255.255.255.0   U     100    0        0 eth0
192.168.0.0     0.0.0.0         255.255.255.0   U     100    0        0 eth0
[root@vsnode system-connections]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet 192.168.0.200/32 brd 192.168.0.255 scope global noprefixroute eth0
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:0c:29:41:e5:8b brd ff:ff:ff:ff:ff:ff
    altname enp3s0
    altname ens160
    inet 192.168.0.50/24 brd 192.168.0.255 scope global secondary noprefixroute eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::e40:8975:6b9:fea8/64 scope link noprefixroute
       valid_lft forever preferred_lft forever

2.路由器初始化

bash 复制代码
# 1. 停止ipvsadm服务并禁用开机自启(--now:立即停止)
# 作用:清理旧的LVS调度规则,防止原有配置影响新的路由/NAT设置
[root@router ~]# systemctl disable --now ipvsadm.service
Removed "/etc/systemd/system/multi-user.target.wants/ipvsadm.service".
# 2. 清空所有IPVS(LVS)规则(-C:Clear,清空)
# 作用:彻底重置LVS调度器,删除所有已配置的虚拟服务和后端服务器规则
[root@router ~]# ipvsadm -C

#在路由器中
[root@router ~]# vmset.sh eth0 172.25.254.100 vsnode
[root@router ~]# vmset.sh eth1 192.168.0.100 vsnode noroute、

#设定内核路由功能
# 3.将net.ipv4.ip_forward=1写入/etc/sysctl.conf,实现永久开启IP转发
[root@router ~]# echo net.ipv4.ip_forward=1 >> /etc/sysctl.conf
[root@router ~]# sysctl  -p
net.ipv4.ip_forward = 1

#数据转发策略
[root@router ~]# iptables -t nat -A POSTROUTING -o eth1 -j SNAT --to-source 192.168.0.100
[root@vsnode ~]# iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 172.25.254.100

3.客户端

bash 复制代码
# norouter参数:避免脚本自动添加默认路由,后续手动配置网关指向调度器(保证流量走LVS集群)
[root@client ~]# vmset.sh  eth0 172.25.254.99 client norouter
连接已成功激活(D-Bus 活动路径:/org/freedesktop/NetworkManager/ActiveConnection/4)
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:0c:29:e5:75:af brd ff:ff:ff:ff:ff:ff
    altname enp3s0
    altname ens160
    inet 172.25.254.99/24 brd 172.25.254.255 scope global noprefixroute eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fee5:75af/64 scope link tentative noprefixroute
       valid_lft forever preferred_lft forever
client
#编辑NetworkManager的eth0网卡配置文件(实现IP/网关/DNS的永久生效)
[root@client ~]# vim /etc/NetworkManager/system-connections/eth0.nmconnection
[connection]
id=eth0
type=ethernet
interface-name=eth0

# 核心作用:客户端所有跨网段流量(如访问192.168.0.200)都会转发到调度器,实现负载均衡
[ipv4]
method=manual
address1=172.25.254.99/24,172.25.254.100
dns=8.8.8.8;

[root@client ~]# nmcli connection reload
[root@client ~]# nmcli connection up eth0
连接已成功激活(D-Bus 活动路径:/org/freedesktop/NetworkManager/ActiveConnection/5)
[root@client ~]# route  -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         172.25.254.100  0.0.0.0         UG    100    0        0 eth0
172.25.254.0    0.0.0.0         255.255.255.0   U     100    0        0 eth0


#检测
[root@client ~]# ping 192.168.0.200
PING 192.168.0.200 (192.168.0.200) 56(84) 比特的数据。
64 比特,来自 192.168.0.200: icmp_seq=1 ttl=128 时间=1.08 毫秒

4.RS1和RS2

bash 复制代码
#RS1/RS2
[root@RS1 ~]# vmset.sh eth0 192.168.0.10 RS1 noroute
# 修改eth0网卡的NetworkManager配置,设置默认网关为192.168.0.100(LVS调度器后端IP)
# 核心作用:DR模式下RS1的回包需先指向调度器,确保流量路径正确(客户端→调度器→RS1→调度器→客户端)
[root@RS1 ~]# nmcli connection modify eth0 ipv4.gateway 192.168.0.100
#重载NetworkManager配置(使网关修改生效)
[root@RS1 ~]# nmcli connection reload
[root@RS1 ~]# nmcli connection up eth0
[root@RS1 ~]# 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 eth0
192.168.0.0     0.0.0.0         255.255.255.0   U     100    0        0 eth0

#在lo上设定vip
[root@RS1 ~]# cd /etc/NetworkManager/system-connections/
#复制eth0的配置文件为lo.nmconnection
# 作用:无需手动新建lo配置文件,基于eth0的模板修改即可
[root@RS1 system-connections]# cp -p eth0.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
连接已成功激活(D-Bus 活动路径:/org/freedesktop/NetworkManager/ActiveConnection/6)
[root@RS1 system-connections]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet 192.168.0.200/32 scope global lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
       
 #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

易错点:

  • 常见错误:配置 NetworkManager 文件时出现address1==xxx双等号语法错误,导致 VIP 绑定到 eth0 而非 lo;
  • 参数持久化:ARP 抑制参数(arp_ignore/arp_announce)当前为临时生效,需写入/etc/sysctl.conf实现重启不丢失;
  • 规则补全:需在调度器上添加 LVS 核心规则(ipvsadm -A -t 192.168.0.200:80 -s rr),才能实现流量分发到 RS1/RS2

二、利用火墙标记解决轮询错误

1.在rs主机中同时开始http和https两种协议

bash 复制代码
#在RS1和RS2中开启https
# 安装 Apache 的 SSL 模块(mod_ssl 是实现 HTTPS 的核心模块)
[root@RS1+RS2 ~]# dnf install mod_ssl -y
# 重启 httpd 服务,使 mod_ssl 模块生效
[root@RS1+RS2 ~]# systemctl restart httpd
[root@RS1+RS2 ~]# systemctl restart httpd#验证

2.在vsnode中添加https的轮询策略

bash 复制代码
root@vsnode boot]# ip^Cadm -A -t 192.168.0.200:80  -s rr
[root@vsnode boot]# ipvsadm -a -t 192.168.0.200:80 -r 192.168.0.20 -g
[root@vsnode boot]# ipvsadm -a -t 192.168.0.200:80 -r 192.168.0.10 -g
[root@vsnode boot]# ipvsadm -A -t 192.168.0.200:443 -s rr
[root@vsnode boot]# ipvsadm -a -t 192.168.0.200:443 -r 192.168.0.10:443 -g
[root@vsnode boot]# ipvsadm -a -t 192.168.0.200:443 -r 192.168.0.20:443 -g
[root@vsnode boot]# 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 rr
  -> 192.168.0.10:80              Route   1      0          0
  -> 192.168.0.20:80              Route   1      0          0
TCP  192.168.0.200:443 rr
  -> 192.168.0.10:443             Route   1      0          0
  -> 192.168.0.20:443  

3.轮询错误展示

bash 复制代码
[root@client ~]# curl  192.168.0.200;curl -k https://192.168.0.200
RS2 - 192.168.0.20
RS2 - 192.168.0.20

#当上述设定完成后http和https是独立的service,轮询会出现重复问题

#问题原因:HTTP 和 HTTPS 是独立的 LVS 虚拟服务
80 和 443 端口分别创建了独立的 LVS 虚拟服务(192.168.0.200:80 和 192.168.0.200:443),且都使用 rr(轮询)算法。

rr 算法是按虚拟服务独立计数的:80 端口的轮询计数器和 443 端口的计数器互不干扰。
但是同时执行 curl 80端口 + curl 443端口 时,两个请求分别走各自的轮询序列,大概率会命中同一台服务器(比如第一次 80 端口轮询到 RS2,443 端口轮询也刚到 RS2),就出现了重复问题。

#如何解决:使用 persistent(持久连接)特性(适合需要会话粘滞的场景)

[root@vsnode boot]# iptables -t mangle -A PREROUTING -d 192.168.0.200 -p tcp -m multiport --dports 80,443 -j MARK --set-mark  6666

[root@vsnode boot]# ipvsadm -A -f 6666 -s rr
[root@vsnode boot]# ipvadm  -a -f 6666 -r 192.168.0.10 -g
[root@vsnode boot]# ipvsadm  -a -f 6666 -r 192.168.0.20 -g


#测试:在客户端
[root@client ~]# curl  192.168.0.200;curl -k https://192.168.0.200
RS2 - 192.168.0.20
RS1 - 192.168.0.10
相关推荐
lzhailb1 小时前
keepalived
运维
zl_dfq1 小时前
Linux 之 【网络套接字编程】(网络字节序、字节序转换函数、套接字编程类型、标准套接字编程的头文件、sockaddr结构、整数IP与字符串IP的转换)
linux·网络
不知名。。。。。。。。2 小时前
Linux---序列化
linux
江畔何人初2 小时前
MySQL 服务器进程的三层结构
linux·运维·服务器·云原生·mysal
陈桴浮海2 小时前
MySQL 主从复制与 GTID 环形复制
linux·mysql·云原生
YYDataV数据可视化2 小时前
【P2P音视频通信系统】之信令服务器详解
服务器·音视频·p2p·信令服务器
坐吃山猪2 小时前
Neo4j02_CQL语句使用
运维·服务器·数据库
白太岁2 小时前
C++:(6) 常用 linux 命令:进程管理、日志查看、网络端口与文件权限
linux·运维·服务器
西安同步高经理2 小时前
便携式小型1588主时钟源用途及解决方案,1588时钟服务器,1588v2时钟
运维·服务器