LVS(Linux Virtual Server)
LVS 全称 Linux Virtual Server,是 Linux 内核层实现的高性能、高可用的负载均衡集群技术,由章文嵩博士开发,目前是 Linux 内核的标准模块之一。它的核心作用是将前端的请求流量分发到后端多台真实服务器(Real Server)上,从而提升服务的并发处理能力和可用性。

一.实验环境

主机名 角色
server1 调度器(VS)
server2 真实服务器(RS)
server3 真实服务器(RS)
server4 测试机
2.1 LVS简介

2.1.1 什么是LVS
项目    说明
全称    Linux Virtual Server(Linux虚拟服务器)
本质    负载调度器,集成在Linux内核中
作者    章文嵩(阿里开源贡献者)
典型应用    阿里四层SLB(Server Load Balance)基于 LVS + Keepalived 实现
官网    http://www.linuxvirtualserver.org/ #### 3.1.2 LVS核心术语

缩写 全称 角色说明
VS Virtual Server 虚拟服务器,负责调度分发请求
RS Real Server 真实服务器,负责实际处理业务
2.2.1 工作原理
核心逻辑:VS根据请求报文的目标IP、协议、端口,通过调度算法挑选合适的RS进行转发
2.3.1 关键IP地址 定义

缩写 全称  说明   类比
CIP    Client IP  客户端主机的IP  顾客的住址
VIP  Virtual Server IP  VS外网IP,对外暴露的访问地址   门店招牌地址
         
DIP Director IP VS内网IP,连接后端RS的地址   店长内部联络号
        
RIP   Real Server IP 真实业务主机的IP 

后厨各工位分功

2.3.2 数据流向

CIP <--> VIP == DIP <--> RIP

2.4 LVS集群的四种工作模式
模式    全称    核心机制    使用频率
lvs-nat    NAT模式    修改请求报文的目标IP(DNAT)    ⭐⭐⭐
lvs-dr    直接路由模式    重新封装MAC地址    ⭐⭐⭐⭐⭐ 最常用
lvs-tun    隧道模式    在原IP报文外新增IP首部    ⭐⭐ 远距离场景
lvs-fullnat    全NAT模式    同时修改源IP和目标IP    ⭐ 需重新编译内核

核心特点
特性 说明
本质 多目标IP的DNAT(目标地址转换)
网络要求 RIP和DIP必须在同一IP网络,使用私网地址
网关设置 RS的网关必须指向DIP
流量走向 请求和响应都必须经过Director
端口映射 支持修改目标端口
系统要求 VS必须是Linux,RS可以是任意OS
2.4.1 NAT 模式详解
核心特点
特性 说明
本质 多目标IP的DNAT(目标地址转换)
网络要求 RIP和DIP必须在同一IP网络,使用私网地址
网关设置 RS的网关必须指向DIP
流量走向 请求和响应都必须经过Director
端口映射 支持修改目标端口
系统要求 VS必须是Linux,RS可以是任意OS

内核处理位置

关键位置:IPVS作用点在 PREROUTING → INPUT 链之间

注意:iptables的PREROUTING规则会干扰IPVS工作,部署LVS时需清空防火墙策略

安装httpd

[root@RS1 ~]# systemctl enable httpd --now
Created symlink /etc/systemd/system/multi-user.target.wants/httpd.service → /usr/lib/systemd/system/httpd.service.
[root@RS1 ~]# echo RS1 - 192.168.0.10 > /var/www/html/index.html
[root@RS1 ~]# curl 192.168.0.10
RS1 - 192.168.0.10

开启调度器内核转发

[root@DR ~]# echo net.ipv4.ip_forward=1 >> /etc/sysctl.conf
[root@DR ~]# sysctl -p
net.ipv4.ip_forward = 1
[root@DR ~]#

配置ipvs

[root@DR ~]# dnf install ipvsadm -y
[root@DR ~]# ipvsadm -C
[root@DR ~]# ipvsadm  -A -t 172.25.254.100:80  -s wrr
[root@DR ~]# ipvsadm -a -t  172.25.254.100:80 -r 192.168.0.10 -m -w 1
[root@DR ~]# ipvsadm -a -t  172.25.254.100:80 -r 192.168.0.20 -m -w 1
[root@DR ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  172.25.254.100:80 wrr
  -> 192.168.0.10:80              Masq    1      0          0
  -> 192.168.0.20:80              Masq    1      0          0
[root@DR ~]# systemctl restart  ipvsadm.service
[root@DR ~]# curl 172.25.254.100
RS1 - 192.168.0.10
[root@DR ~]# curl 172.25.254.100
RS2 - 192.168.0.20
[root@DR ~]# curl 172.25.254.100
RS1 - 192.168.0.10
[root@DR ~]# curl 172.25.254.100
RS2 - 192.168.0.20
[root@DR ~]# curl 172.25.254.100
RS1 - 192.168.0.10
[root@DR ~]# curl 172.25.254.100
RS2 - 192.168.0.20
[root@DR ~]# curl 172.25.254.100
RS1 - 192.168.0.10

ipvs持久化

利用自定义文件进行持久化

[root@DR ~]# ipvsadm-save -n
-A -t 172.25.254.100:80 -s wrr
-a -t 172.25.254.100:80 -r 192.168.0.10:80 -m -w 1
-a -t 172.25.254.100:80 -r 192.168.0.20:80 -m -w 1
[root@DR ~]# ipvsadm-save -n > /mnt/ipvs.rule
[root@DR ~]# ipvsadm -C
[root@DR ~]# ipvsadm-restore < /mnt/ipvs.rule
[root@DR ~]# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  172.25.254.100:80 wrr
  -> 192.168.0.10:80              Masq    1      0          0
  -> 192.168.0.20:80              Masq    1      0          0
[root@DR ~]#

DR实验实操

主机名    ip    vip    角色
client    172.25.254.10 vmware NAT    null    测试主机
router    NAT-eth0:172.25.254.100,仅主机-eth1:192.168.0.10    null    路由器
lvs    192.168.0.200,GW 192.168.0.10 仅主机    lo:192.168.0.100    调度器
RS1    192.168.0.101,GW 192.168.0.10 仅主机    lo:192.168.0.100    web服务器1
RS2    192.168.0.102, GW 192.168.0.10 仅主机    lo:192.168.0.100    web服务器2
 

实验配置

[root@router ~]# 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
    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:61:87:fd brd ff:ff:ff:ff:ff:ff
    altname enp3s0
    altname ens160
    inet 172.25.254.100/24 brd 172.25.254.255 scope global noprefixroute eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::3fa1:87d2:5cf9:b034/64 scope link noprefixroute
       valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:0c:29:61:87:07 brd ff:ff:ff:ff:ff:ff
    altname enp19s0
    altname ens224
    inet 192.168.0.100/24 brd 192.168.0.255 scope global noprefixroute eth1
       valid_lft forever preferred_lft forever
    inet6 fe80::e4ac:effc:837f:ec6e/64 scope link tentative noprefixroute
       valid_lft forever preferred_lft forever


[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
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:0c:29:a2:8c:26 brd ff:ff:ff:ff:ff:ff
    altname enp3s0
    altname ens160
    inet 192.168.0.10/24 brd 192.168.0.255 scope global noprefixroute eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::3fa1:87d2:5cf9:b034/64 scope link noprefixroute
       valid_lft forever preferred_lft forever


[root@RS2 ~]# 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
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:0c:29:46:6d:2b brd ff:ff:ff:ff:ff:ff
    altname enp3s0
    altname ens160
    inet 192.168.0.20/24 brd 192.168.0.255 scope global noprefixroute eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::e90:1704:51c8:2b6b/64 scope link noprefixroute
       valid_lft forever preferred_lft forever


[root@DR1 ~]# 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
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:0c:29:b8:06:d9 brd ff:ff:ff:ff:ff:ff
    altname enp3s0
    altname ens160
    inet 192.168.0.50/24 brd 192.168.0.255 scope global noprefixroute eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::6355:ed82:1687:35a1/64 scope link noprefixroute
       valid_lft forever preferred_lft forever



[root@client ~]# 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
    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:a6:62:22 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::e90:1704:51c8:2b6b/64 scope link noprefixroute
       valid_lft forever preferred_lft forever

调度器的配置

[root@DR1 ~]# 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

client的配置

[root@client ~]# 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
    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:a6:62:22 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::e90:1704:51c8:2b6b/64 scope link noprefixroute
       valid_lft forever preferred_lft forever

测试

[root@client ~]# curl 192.168.0.200
RS2 - 192.168.0.20
[root@client ~]# curl 192.168.0.200
RS1 - 192.168.0.10
[root@client ~]# curl 192.168.0.200
RS2 - 192.168.0.20
[root@client ~]# curl 192.168.0.200
RS1 - 192.168.0.10
[root@client ~]# curl 192.168.0.200
RS2 - 192.168.0.20
[root@client ~]# curl 192.168.0.200
RS1 - 192.168.0.10

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐