一、LVS简介
1、什么是LVS
LVS(Linux Virtual Server)是一种基于Linux平台的开源负载均衡解决方案,主要用于实现服务器集群的负载均衡和高可用性。该项目是由中国的章文嵩博士主导开发的开源项目,目前已被集成到Linux内核中。LVS的主要目的是通过将多台服务器组成一个虚拟服务器集群,实现高性能和高可用性的网络服务。
2、LVS架构
LVS的整体架构包括负载均衡器(Load Balancer)、后端服务器(Real Server)和客户端三部分。负载均衡器负责接收来自客户端的请求,并根据调度算法将请求转发到后端服务器进行处理,处理结果再返回给客户端。
3、LVS工作模式
(1)、在LVS-NAT模式下,请求报文的目标地址和响应报文的源地址都会被修改,适用于小规模集群。
(2)在LVS-DR模式下,仅修改请求报文的目标MAC地址,后端服务器直接将响应报文发回客户端,适用于大规模集群。
(3)、在LVS-TUN模式下,通过IP隧道将请求报文发送到后端服务器,后端服务器解封装后直接将响应报文发回客户端,适用于地理位置分散的集群。
4、LVS调度算法
静态算法
(1)、RR:roundrobin 轮询 RS分别被调度,当RS配置有差别时不推荐 。
(2)、WRR:Weighted RR,加权轮询根据RS的配置进行加权调度,性能差的RS被调度的次数少 。
(3)、SH:Source Hashing,实现session sticky,源IP地址hash;将来自于同一个IP地址的请求始终发往 第一次挑中的RS,从而实现会话绑定 。
(4)、DH:Destination Hashing;目标地址哈希,第一次轮询调度至RS,后续将发往同一个目标地址的请 求始终转发至第一次挑中的RS,典型使用场景是正向代理缓存场景中的负载均衡,如:宽带运营商 。
动态算法
主要根据RS当前的负载状态及调度算法进行调度Overhead=value较小的RS会被调度。
(1)、LC:least connections(最少链接发) 适用于长连接应用Overhead(负载值)=activeconns(活动链接数) x 256+inactiveconns(非活动链接数) 。
(2)、WLC:Weighted LC(权重最少链接) 默认调度方法Overhead=(activeconns x 256+inactiveconns)/weight 。
(3)、SED:Shortest Expection Delay, 初始连接高权重优先Overhead=(activeconns+1+inactiveconns) x 256/weight 但是,当node1的权重为1,node2的权重为10,经过运算前几次的调度都会被node2承接 。
(4)、NQ:Never Queue,第一轮均匀分配,后续SED
(5)、LBLC:Locality-Based LC,动态的DH算法,使用场景:根据负载状态实现正向代理
(6)、LBLCR:LBLC with Replication,带复制功能的LBLC,解决LBLC负载不均衡问题,从负载重的复制到负载轻的RS。
4.15版本内核后新增算法
(1)、FO(Weighted Fai Over)调度算法:常用作灰度发布。在此FO算法中,遍历虚拟服务所关联的真实服务器链表,找到还未过载(未设置IP_VS_DEST_F OVERLOAD标志)的且权重最高的真实服务器,进行调度 当服务器承接大量链接,我们可以对此服务器进行过载标记(IP_VS_DEST_F OVERLOAD),那么vs调度器就不会把链接调度到有过载标记的主机中。
(2)、OVF(Overflow-connection)调度算法 基于真实服务器的活动连接数量和权重值实现。将新连接调度到权重值最高的真实服务器,直到其活动 连接数量超过权重值,之后调度到下一个权重值最高的真实服务器,在此OVF算法中,遍历虚拟服务相关 联的真实服务器链表,找到权重值最高的可用真实服务器。一个可用的真实服务器需要同时满足以下条件:
未过载(未设置IP_VS_DEST_F OVERLOAD标志)
真实服务器当前的活动连接数量小于其权重值
其权重值不为零
二、NAT模式配置
实验环境
一台LVS主机:两个网卡,一个选择nat模式,网段为172.25.254.0;一个选择仅主机模式,网段为192.168.0.0
两台webserver主机(RS):一个网卡,选择仅主机模式,网段为192.168.0.0
网络配置
lvs主机
[root@lvs bin]# vmset.sh eth0 172.25.254.100 lvs
[root@lvs ~]# cat /etc/NetworkManager/system-connections/eth0.nmconnection
[connection]
id=eth0
type=ethernet
interface-name=eth0[ipv4]
address1=172.25.254.100/24,172.25.254.2
method=manual
dns=114.114.114.114;
[root@lvs bin]# vmset.sh eth1 192.168.0.100 lvs[root@lvs bin]# vim /etc/NetworkManager/system-connections/eth1.nmconnection
[root@lvs bin]# cat /etc/NetworkManager/system-connections/eth1.nmconnection
[connection]
id=eth1
type=ethernet
interface-name=eth1[ipv4]
address1=192.168.0.100/24
method=manual[root@lvs ~]# nmcli connection reload
[root@lvs ~]# nmcli connection up eth0
[root@lvs ~]# nmcli connection up eth1
[root@lvs ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 172.25.254.2 0.0.0.0 UG 102 0 0 eth0
172.25.254.0 0.0.0.0 255.255.255.0 U 102 0 0 eth0
192.168.0.0 0.0.0.0 255.255.255.0 U 103 0 0 eth1
webserver1
[root@webserver1 bin]# vmset.sh eth0 192.168.0.10 webserver1
[root@webserver1 ~]# vim /etc/NetworkManager/system-connections/eth0.nmconnection
[root@webserver1 ~]# cat /etc/NetworkManager/system-connections/eth0.nmconnection
[connection]
id=eth0
type=ethernet
interface-name=eth0[ipv4]
address1=192.168.0.10/24,192.168.0.100
method=manual[root@webserver1 ~]# nmcli connection reload
[root@webserver1 ~]# nmcli connection up eth0
[root@webserver1 ~]# 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
webserver2
[root@webserver2 bin]# vmset.sh eth0 192.168.0.20 webserver2
[root@webserver2 ~]# vim /etc/NetworkManager/system-connections/eth0.nmconnection
[root@webserver2 ~]# cat /etc/NetworkManager/system-connections/eth0.nmconnection
[connection]
id=eth0
type=ethernet
interface-name=eth0[ipv4]
address1=192.168.0.20/24,192.168.0.100
method=manual
[root@webserver2 ~]# nmcli connection reload
[root@webserver2 ~]# nmcli connection up eth0
[root@webserver2 ~]# 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
打开内核路由功能
[root@lvs ~]# vim /etc/sysctl.conf
[root@lvs ~]# cat /etc/sysctl.conf
# sysctl settings are defined through files in
# /usr/lib/sysctl.d/, /run/sysctl.d/, and /etc/sysctl.d/.
#
# Vendors settings live in /usr/lib/sysctl.d/.
# To override a whole file, create a new file with the same in
# /etc/sysctl.d/ and put new settings there. To override
# only specific settings, add a file with a lexically later
# name in /etc/sysctl.d/ and put new settings there.
#
# For more information, see sysctl.conf(5) and sysctl.d(5).
net.ipv4.ip_forward=1
[root@lvs ~]# sysctl -p
net.ipv4.ip_forward = 1[root@lvs ~]# systemctl stop firewalld
webserver中安装和启动http服务
(以webserver1为例)
[root@webserver1 ~]# dnf install httpd -y
[root@webserver1 ~]# echo webserver1 - 192.168.0.10 > /var/www/html/index.html
[root@webserver1 ~]# systemctl enable --now httpd
[root@webserver1 ~]# systemctl stop firewalld
LVS主机中安装LVS软件并配置策略
[root@lvs ~]# dnf install ipvsadm -y
[root@lvs ~]# ipvsadm -A -t 172.25.254.100:80 -s rr
[root@lvs ~]# ipvsadm -a -t 172.25.254.100:80 -r 192.168.0.10 -m
[root@lvs ~]# ipvsadm -a -t 172.25.254.100:80 -r 192.168.0.20 -m
[root@lvs ~]# 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 rr
-> 192.168.0.10:80 Masq 1 0 0
-> 192.168.0.20:80 Masq 1 0 0
测试
[root@lvs ~]# for i in {1..10}
> do
> curl 172.25.254.100
> done
三、DR模式配置
实验环境
一台client主机:一个网卡,选择nat模式,网段为172.25.254.0
一台router主机:两个网卡,一个选择nat模式,网段为172.25.254.0;一个选择仅主机模式,网段为192.168.0.0
一台LVS主机
两台webserver主机
(在以上NAT模式配置的基础上进行)
网络配置
LVS主机
[root@lvs bin]# nmcli connection delete eth0
[root@lvs bin]# nmcli connection delete eth1
[root@lvs bin]# vmset.sh eth1 192.168.0.50 lvs
[root@lvs bin]# vim /etc/NetworkManager/system-connections/eth1.nmconnection
[root@lvs bin]# cat /etc/NetworkManager/system-connections/eth1.nmconnection
[connection]
id=eth1
type=ethernet
interface-name=eth1[ipv4]
address1=192.168.0.50/24,192.168.0.100
method=manual
[root@lvs bin]# nmcli connection reload
[root@lvs bin]# nmcli connection up eth1[root@lvs ~]# ip a a dev lo 192.168.0.200/32
[root@lvs ~]# 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 103 0 0 eth1
192.168.0.0 0.0.0.0 255.255.255.0 U 103 0 0 eth1
router
[root@router bin]# vmset.sh eth0 172.25.254.100 router
[root@router bin]# vmset.sh eth1 192.168.0.100 router
[root@router bin]# vim /etc/NetworkManager/system-connections/eth1.nmconnection
[root@router bin]# cat /etc/NetworkManager/system-connections/eth1.nmconnection
[connection]
id=eth1
type=ethernet
interface-name=eth1[ipv4]
address1=192.168.0.100/24
method=manual[root@router ~]# nmcli connection reload
[root@router ~]# nmcli connection up eth0
[root@router ~]# nmcli connection up eth1
client
[root@client bin]# vmset.sh eth0 172.25.254.200 client
[root@client ~]# vim /etc/NetworkManager/system-connections/eth0.nmconnection
[root@client ~]# cat /etc/NetworkManager/system-connections/eth0.nmconnection
[connection]
id=eth0
type=ethernet
interface-name=eth0[ipv4]
address1=172.25.254.200/24,172.25.254.100
method=manual[root@client ~]# nmcli connection reload
[root@client ~]# nmcli connection up eth0
webserver(以webserver1为例)
[root@webserver1 ~]# ip a a dev lo 192.168.0.200/32
router中打开内核路由功能
[root@router bin]# vim /etc/sysctl.conf
[root@router bin]# cat /etc/sysctl.conf
# sysctl settings are defined through files in
# /usr/lib/sysctl.d/, /run/sysctl.d/, and /etc/sysctl.d/.
#
# Vendors settings live in /usr/lib/sysctl.d/.
# To override a whole file, create a new file with the same in
# /etc/sysctl.d/ and put new settings there. To override
# only specific settings, add a file with a lexically later
# name in /etc/sysctl.d/ and put new settings there.
#
# For more information, see sysctl.conf(5) and sysctl.d(5).
net.ipv4.ip_forward=1
[root@router bin]# sysctl -a | grep ip_forward
net.ipv4.ip_forward = 1
net.ipv4.ip_forward_update_priority = 1
net.ipv4.ip_forward_use_pmtu = 0
RS主机中使vip不对外生效
(以webserver1为例)
[root@webserver1 ~]# echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
[root@webserver1 ~]# echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
[root@webserver1 ~]# echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
[root@webserver1 ~]# echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
LVS主机中配置策略
[root@lvs ~]# ipvsadm -A -t 192.168.0.200:80 -s wrr
[root@lvs ~]# ipvsadm -a -t 192.168.0.200:80 -r 192.168.0.10:80 -g -w 1
[root@lvs ~]# ipvsadm -a -t 192.168.0.200:80 -r 192.168.0.20:80 -g -w 2
[root@lvs ~]# 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
测试
[root@client ~]# for i in {1..10}; do curl 192.168.0.200; done
四、防火墙标签解决轮询错误
实验环境
延用DR模式的配置
webserver安装mod_ssl支持https
[root@webserver1 ~]# yum install mod_ssl -y
[root@webserver1 ~]# systemctl restart httpd[root@webserver2 ~]# yum install mod_ssl -y
[root@webserver2 ~]# systemctl restart httpd
测试同一IP不同端口的查询情况
对443端口设定规则
[root@lvs ~]# ipvsadm -A -t 192.168.0.200:443 -s rr
[root@lvs ~]# ipvsadm -a -t 192.168.0.200:443 -r 192.168.0.10:443 -g
[root@lvs ~]# ipvsadm -a -t 192.168.0.200:443 -r 192.168.0.20:443 -g
[root@lvs ~]# 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
TCP 192.168.0.200:443 rr
-> 192.168.0.10:443 Route 1 0 0
-> 192.168.0.20:443 Route 1 0 0
同一IP的查询结果会重复出现
[root@client ~]# curl 192.168.0.200;curl -k https://192.168.0.200
webserver2 - 192.168.0.20
webserver2 - 192.168.0.20
解决办法
LVS中为同一IP的不同端口打上同一个标签,使其成为一个整体
[root@lvs ~]# iptables -t mangle -A PREROUTING -d 192.168.0.200 -p tcp -m multiport --dports 80,443 -j MARK --set-mark 66
清除之前的策略,设定新的调度规则
[root@lvs ~]# ipvsadm -C
[root@lvs ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
[root@lvs ~]# ipvsadm -A -f 66 -s rr
[root@lvs ~]# ipvsadm -a -f 66 -r 192.168.0.10 -g
[root@lvs ~]# ipvsadm -a -f 66 -r 192.168.0.20 -g
测试
[root@client ~]# curl 192.168.0.200;curl -k https://192.168.0.200
webserver2 - 192.168.0.20
webserver1 - 192.168.0.10
五、LVS持久链接
在lvs调度器中设定延迟时间
默认为360秒
[root@lvs ~]# ipvsadm -E -f 66 -s rr -p 3000
[root@lvs ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
FWM 66 rr persistent 3000
-> 192.168.0.10:0 Route 1 0 0
-> 192.168.0.20:0 Route 1 0 0