1、简介

LVS是Linux Virtual Server的简写,意即Linux虚拟服务器,是一个虚拟的服务器集群系统。在1998年5月由章文嵩博士成立,是中国国内最早出现的自由软件项目之一。
LVS 工作原理简述:用户请求LVS VIP,LVS根据转发方式和算法,将请求转发给后端服务器,后端服务器接受到请求,返回给用户。对于用户来说,看不到WEB后端具体的应用。

2、LVS 负载均衡原理

实现LVS负载均衡转发方式有三种,分别为NAT、DR、TUN模式,LVS均衡算法包括:RR(round-robin)、LC(least_connection)、W(weight)RR、WLC模式等(RR为轮询模式,LC为最少连接模式)。

LVS NAT原理:用户请求LVS VIP到达director(LVS服务器:LB),director将请求的报文的目标IP地址改成后端的realserver IP地址,同时将报文的目标端口也改成后端选定的realserver相应端口,最后将报文发送到realserver,realserver将数据返给director,director再把数据发送给用户。(两次请求都经过director,所以访问大的话,director会成为瓶颈)。

注意事项:
1、LVS服务器至少2块物理网卡,一块连接公网(VIP),一块连接内网;
2、后端Realserver机器的默认网关设置为LVS的内网IP地址;
3、保证LVS内网网卡通常跟Realserver在同一网段;
4、LVS NAT模式后端Realserver机器数量不超过30台;
5、用户的请求进入和返回均会经过LVS,LVS会成为瓶颈。

lvs第三方负载 lvs负载均衡算法有哪些_lvs第三方负载


LVS DR原理:用户请求LVS VIP到达director(LB均衡器),director将请求的报文的目标MAC地址改成后端的realserver MAC地址,目标IP为VIP(不变),源IP为用户IP地址(保持不变),然后Director将报文发送到realserver,realserver检测到目标为自己本地VIP,如果在同一个网段,然后将请求直接返给用户。如果用户跟realserver不在一个网段,则通过网关返回用户。注意事项:

1、LVS服务器和后端Realserver必须在同网段;

2、LVS修改请求报文的目标MAC,目标IP(VIP)不变;

3、realServer端需将VIP配置在lo网卡以保证多个相同的VIP之间不冲突;

4、realServer端的网关指向路由器下一跳(默认网关),保证数据能够出去(访问外网);

5、所有的realServer端服务器要抑制VIP ARP广播,禁止VIP响应解析,而且保证真实网卡不能抑制ARP广播。

lvs第三方负载 lvs负载均衡算法有哪些_IP_02


LVS TUN原理:用户请求LVS到达director,director通过IP-TUN加密技术将请求的报文的目标MAC地址改成后端的realserver MAC地址,目标IP为VIP(不变),源IP为用户IP地址(保持不变),然后Director将报文发送到realserver,realserver基于IP-TUN解密,然后检测到目标为自己本地VIP,如果在同一个网段,然后将请求直接返给用户。如果用户跟realserver不在一个网段,则通过网关返回用户。

lvs第三方负载 lvs负载均衡算法有哪些_lvs第三方负载_03

3、LVS 负载均衡实现–NAT模式

LVS负载均衡技术实现是基于Linux内核模块IP_VS。IP_VS模块与iptables一样是直接工作在内核中,互联网主流的Linux发行版默认都已经集成了ipvs模块,因此只需安装管理工具ipvsadm。

LVS 端机器配置:

安装ipvsadm

yum install -y ipvsadm

机器配置双网卡,一个对内一个对外

[root@localhost ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.0.0.159  netmask 255.255.255.0  broadcast 10.0.0.255
        inet6 fe80::20ff:bdcd:8409:96e9  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:b7:36:91  txqueuelen 1000  (Ethernet)
        RX packets 13589  bytes 18950235 (18.0 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 5881  bytes 445749 (435.3 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ens37: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.30.78  netmask 255.255.255.0  broadcast 192.168.30.255
        inet6 fe80::f862:a92f:f830:61ef  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:b7:36:9b  txqueuelen 1000  (Ethernet)
        RX packets 16826  bytes 1910791 (1.8 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 123  bytes 10246 (10.0 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 1207  bytes 106216 (103.7 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 1207  bytes 106216 (103.7 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
# 添加虚拟服务器IP
[root@localhost ~]# ipvsadm -A -t 10.0.0.159:80 -s rr

# 添加realserver后端服务 
[root@localhost ~]# ipvsadm -a -t 10.0.0.159:80 -r 192.168.30.79:80 -m -w 2

# 查看
[root@localhost ~]# ipvsadm -L -n
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  10.0.0.159:80 rr
  -> 192.168.30.79:80             Masq    2      0          0

ipvsadm 参数解析

-A						增加一台虚拟服务器VIP地址;
-t						虚拟服务器提供的是tcp服务;
-s						使用的调度算法;
-a						在虚拟服务器中增加一台后端真实服务器;
-r						指定真实服务器地址;
-w						后端真实服务器的权重;
-m						设置当前转发方式为NAT模式;-g为直接路由模式;-i  模式为隧道模式
-D						删除虚拟服务器VIP地址
-d						删除虚拟服务器中后端真实服务器

开启 IP 转发

[root@localhost ~]# cat /proc/sys/net/ipv4/ip_forward
0
[root@localhost ~]# echo 1 > /proc/sys/net/ipv4/ip_forward
[root@localhost ~]# cat /proc/sys/net/ipv4/ip_forward
1

realServer端配置:

将192.168.30.79 机器网关设置为LVS内网网卡Ip地址,然后重启生效

[root@localhost ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens33

GATEWAY=192.168.30.78

[root@localhost ~]# /etc/init.d/network restart

启动nginx

[root@localhost ~]# systemctl start nginx

访问 LVS 外网IP,跳转到realServer

lvs第三方负载 lvs负载均衡算法有哪些_Server_04


LVS 服务机器查看

[root@localhost ~]# ipvsadm -L -n
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  10.0.0.159:80 rr
  -> 192.168.30.79:80             Masq    2      1          1

4、LVS 负载均衡实现–DR模式

realServer配置:

添加lo子网卡

[root@localhost ~]# cd /etc/sysconfig/network-scripts/
[root@localhost network-scripts]# cp ifcfg-lo ifcfg-lo:1
[root@localhost network-scripts]# vim ifcfg-lo:1

DEVICE=lo:1
IPADDR=10.0.0.152
NETMASK=255.255.255.255
NETWORK=127.0.0.0
BROADCAST=127.255.255.255
ONBOOT=yes
NAME=loopback

[root@localhost network-scripts]# ifup lo:1
[root@localhost network-scripts]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.0.0.150  netmask 255.255.255.0  broadcast 10.0.0.255
        inet6 fe80::996:6962:aea5:f905  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:68:03:e2  txqueuelen 1000  (Ethernet)
        RX packets 667  bytes 79050 (77.1 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 423  bytes 60923 (59.4 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 51642  bytes 78221180 (74.5 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 51642  bytes 78221180 (74.5 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo:1: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 10.0.0.152  netmask 255.255.255.255
        loop  txqueuelen 1000  (Local Loopback)

此时可以从外部ping通VIP,需进行arp抑制,阻止lo网卡响应组播消息。

进行arp抑制

# arp_ignore 参数 1 表示只响应目标IP是本地真实网卡上配置的IP
# arp_announce 参数2 表示忽略报文的源IP地址,使用主机上能够跟用户通信的真实网卡发生数据

echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce
echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce

LVS 端配置:

设置ip_vs模块

[root@localhost ~]# lsmod |grep -i ip_vs
[root@localhost ~]# modprobe ip_vs
[root@localhost ~]# lsmod |grep -i ip_vs
ip_vs                 145497  0 
nf_conntrack          133095  1 ip_vs
libcrc32c              12644  3 xfs,ip_vs,nf_conntrack

添加VIP和realServer

[root@localhost ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
[root@localhost ~]# ipvsadm -A -t 10.0.0.152:80 -s rr
[root@localhost ~]# ipvsadm -a -t 10.0.0.152:80 -r 10.0.0.150 -g -w 100
[root@localhost ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  10.0.0.152:80 rr
  -> 10.0.0.150:80                Route   100    0          0

添加子网卡,设置VIP

[root@localhost network-scripts]# cd /etc/sysconfig/network-scripts/
[root@localhost network-scripts]# cp ifcfg-ens33 ifcfg-ens33:1
[root@localhost network-scripts]# vim ifcfg-ens33:1

TYPE=Ethernet
BOOTPROTO=static
DEVICE=ens33:1
ONBOOT=yes
IPADDR=10.0.0.152
NETMASK=255.255.255.0                       

[root@localhost network-scripts]# ifup ifcfg-ens33:1
[root@localhost network-scripts]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.0.0.148  netmask 255.255.255.0  broadcast 10.0.0.255
        inet6 fe80::fe63:b144:f5f4:17ed  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:cd:2b:78  txqueuelen 1000  (Ethernet)
        RX packets 18476  bytes 17269630 (16.4 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 20558  bytes 1492968 (1.4 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ens33:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.0.0.152  netmask 255.0.0.0  broadcast 10.255.255.255
        ether 00:0c:29:cd:2b:78  txqueuelen 1000  (Ethernet)

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 8741  bytes 769266 (751.2 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 8741  bytes 769266 (751.2 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

浏览器访问:

lvs第三方负载 lvs负载均衡算法有哪些_lvs第三方负载_05

5、LVS + keepalived

LVS和keepalived结合使用,可以省去 添加VIP和realServer 步骤。LVS+Keepalived负载均衡高可用集群架构适用于千万级并发网站,在互联网企业得到大力的应用。

[root@localhost network-scripts]# vim /etc/keepalived/keepalived.conf 

! Configuration File for keepalived
global_defs {
  notification_email {
      ***@163.com
 }
    notification_email_from   ***@163.com
    smtp_server 127.0.0.1
    smtp_connect_timeout 30
}

# VIP1
vrrp_instance VI_1 {
     state MASTER
     interface ens33
     virtual_router_id 151
     priority 100
     advert_int 5
     authentication {
         auth_type  PASS
         auth_pass  1111

     }
     virtual_ipaddress {
         10.0.0.152
     }
}
virtual_server 10.0.0.152 80{
    delay_loop 6
    lb_algo rr
    lb_kind DR
persistence_timeout  60
    protocol TCP
    real_server 10.0.0.150 80 {
        weight 100
        TCP_CHECK {
        connect_timeout 10
        nb_get_retry 3
        delay_before_retry 3
        connect_port 80
        }
    }


[root@localhost network-scripts]# systemctl start keepalived
[root@localhost network-scripts]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  10.0.0.152:80 rr persistent 60
  -> 10.0.0.150:80                Route   100    0          0

访问浏览器

lvs第三方负载 lvs负载均衡算法有哪些_lvs第三方负载_06