目录
1.1LVS相关知识
1.1.1 LVS简介
LVS 是 Linux Virtual Server 的简称,也就是 Linux 虚拟服务器。这是一个由章文嵩博士发起的一个开源项目,它的官方网站是www.linuxvirtualserver.org,现在 LVS 已经是 Linux 内核标准的一部分。
LVS 可以达到的技术目标是:通过 LVS 达到的负载均衡技术和 Linux 操作系统实现一个高性能高可用的 Linux 服务器集群,它具有良好的可靠性、可扩展性和可操作性。从而以低廉的成本实现最优的性能。
1.1.2LVS体系结构
LVS 架构从逻辑上可分为Load Balance(负载调度器)、Real Server(Server 集群层)和Shared Storage(共享存储层)。
第一层:Load Balance(负载调度器),它是访问整个群集系统的唯一入口,对外使用所有服务器共有的虚拟IP地址,也成为群集IP地址。
负载均衡器:是服务器群集系统的单个入口点,可运行 IPVS,该 IPVS 在 Linux 内核或 KTCPVS 内部实现 IP 负载均衡技术,在 Linux 内核中实现应用程序级负载平衡。使用 IPVS 时,要求所有服务器提供相同的服务和内容,负载均衡器根据指定的调度算法和每个服务器的负载将新的客户端请求转发到服务器。无论选择哪个服务器,客户端都应获得相同的结果。使用 KTCPVS 时,服务器可以具有不同的内容,负载均衡器可以根据请求的内容将请求转发到其他服务器。由于 KTCPVS 是在 Linux 内核内部实现的,因此中继数据的开销很小,因此仍可以具有较高的吞吐量。
第二层:Real Server(Server 集群层),群集所提供的应用服务,比如:HTTP、FTP服务器池来承担,每个节点具有独立的真实IP地址,只处理调度器分发过来的客户机请求。
服务器群集的节点可根据系统所承受的负载进行分担。当所有服务器过载时,可添加多台服务器来处理不断增加的工作负载。对于大多数 Internet 服务(例如Web),请求通常没有高度关联,并且可以在不同服务器上并行运行。因此,随着服务器群集的节点数增加,整体性能几乎可以线性扩展。
第三层:Shared Storage(共享存储层),为服务器池中的所有节点提供稳定、一致的文件存储服务,确保整个群集的统一性,可使用 NAS 设备或提供 NFS (Network File System)网络文件系统共享服务的专用服务器。
共享存储:可以是数据库系统,网络文件系统或
分布式文件系统。服务器节点需要动态更新的数据应存储在基于数据的系统中,当服务器节点并行在数据库系统中读写数据时,数据库系统可以保证并发数据访问的一致性。静态数据通常保存在网络文件系统(例如 NFS 和 CIFS)中,以便可以由所有服务器节点共享数据。但是,单个网络文件系统的可伸缩性受到限制,例如,单个 NFS / CIFS 只能支持 4 到 8 个服务器的数据访问。对于大型集群系统,分布式/集群文件系统可以用于共享存储,例如 GPFS,Coda 和 GFS,然后共享存储也可以根据系统需求进行扩展。
1.1.3 LVS相关术语
- LB (Load Balancer 负载均衡)
- HA (High Available 高可用)
- Failover (失败切换)
- Cluster (集群)
- LVS (Linux Virtual Server Linux 虚拟服务器)
- DS (Director Server),指的是前端负载均衡器节点
- RS (Real Server),后端真实的工作服务器
- VIP (Virtual IP),虚拟的IP地址,向外部直接面向用户请求,作为用户请求的目标的 IP 地址
- DIP (Director IP),主要用于和内部主机通讯的 IP 地址
- RIP (Real Server IP),后端服务器的 IP 地址
- CIP (Client IP),访问客户端的 IP 地址
1.1.4 LVS工作模式
原生只有3种模式(NAT,TUN,DR), fullnat工作模式默认不支持
LVS-NAT(Network Address Translation):在该模式下,负载均衡器不仅需要修改请求报文的目标地址,还需要修改响应报文的源地址,适用于小规模集群。
LVS-DR(Direct Routing):在该模式下,负载均衡器只修改请求报文的目标MAC地址,而不修改IP地址,后端服务器直接将响应报文发回客户端,适用于大规模集群。
LVS-TUN(IP Tunneling):该模式通过IP隧道将请求转发到后端服务器,后端服务器直接将响应报文发回客户端,适用于地理位置分散的集群。
1.1.5 LVS工作原理
LVS-NAT工作原理
在LVS-NAT模式下,负载均衡器通过NAT(网络地址转换)技术将客户端的请求报文目标地址修改为后端服务器的IP地址,同时记录会话信息。当后端服务器处理完请求后,负载均衡器将响应报文的源地址修改为负载均衡器的IP地址,再返回给客户端。
LVS-DR工作原理
在LVS-DR模式下,负载均衡器仅修改请求报文的目标MAC地址,而不修改IP地址。负载均衡器将请求发送到后端服务器后,后端服务器直接将响应报文发回客户端。由于不修改IP地址,该模式具有较高的处理效率。
LVS-TUN工作原理
在LVS-TUN模式下,负载均衡器通过IP隧道将请求报文发送到后端服务器。后端服务器解封装后处理请求,并直接将响应报文发回客户端。该模式适用于地理位置分散的集群。
三种工作模式的对比
VS/NAT | VS/TUN | VS/DR | |
---|---|---|---|
server | any | tunneling | non-arp device |
server network | private | LAN/WAN | LAN |
server number | low (10~20) | high | high |
server gateway | load balancer | own router | own router |
模式与特点 | NAT 模式 | IPIP 模式 | DR 模式 |
---|---|---|---|
对服务器的要求 | 服务节点可以使任何操作系统 | 必须支持 IP 隧道,目前只有 Linux 系统支持 | 服务器节点支持虚拟网卡设备,能够禁用设备的 ARP 响应 |
网络要求 | 拥有私有 IP 地址的局域网络 | 拥有合法 IP 地址的局域,网或广域网 | 拥有合法 IP 地址的局域,服务器节点与负载均衡器必须在同一个网段 |
通常支持节点数量 | 10 到 20 个,根据负载均衡器的处理能力而定 | 较高,可以支持 100 个服务节点 | 较高,可以支持 100 个服务节点 |
网关 | 负载均衡器为服务器节点网关 | 服务器的节点同自己的网关或者路由器连接,不经过负载均衡器 | 服务节点同自己的网关或者路由器连接,不经过负载均衡器 |
服务节点安全性 | 较好,采用内部 IP,服务节点隐蔽 | 较差,采用公用 IP 地址,节点安全暴露 | 较差,采用公用 IP 地址,节点安全暴露 |
IP 要求 | 仅需要一个合法的 IP 地址作为 VIP 地址 | 除了 VIPO 地址外,每个服务器界定啊需要拥有合法的 IP 地址,可以直接从路由到客户端 | 除了 VIP 外,每个服务节点需拥有合法的 IP 地址,可以直接从路由到客户端 |
特点 | 地址转换 | 封装 IP | 修改 MAC 地址 |
配置复杂度 | 简单 | 复杂 | 复杂 |
1.1.6 LVS调度算法
固定调度算法:rr,wrr,dh,sh
动态调度算法:wlc,lc,lblc,lblcr,SED,NQ
固定调度算法:即调度器不会去判断后端服务器的繁忙与否,一如既往得将请求派发下去。
动态调度算法:调度器会去判断后端服务器的繁忙程度,然后依据调度算法动态得派发请求。
rr | 轮询:Round Robin,将收到的访问请求按顺序轮流分配给群集中的各节点真实服务器中,不管服务器实际的连接数和系统负载。 |
wrr | 加权轮询:Weighted Round Robin,根据真实服务器的处理能力轮流分配收到的访问请求,调度器可自动查询各节点的负载情况,并动态跳转其权重,保证处理能力强的服务器承担更多的访问量。 |
dh | 目标地址散列调度算法:DH,该算法是根据目标 IP 地址通过散列函数将目标 IP 与服务器建立映射关系,出现服务器不可用或负载过高的情况下,发往该目标 IP 的请求会固定发给该服务器。 |
sh | 源地址散列调度算法:SH,与目标地址散列调度算法类似,但它是根据源地址散列算法进行静态分配固定的服务器资源。 |
wlc | 加权最少连接:Weighted Least Connections,服务器节点的性能差异较大的情况下,可以为真实服务器自动调整权重,权重较高的节点将承担更大的活动连接负载。 |
lc | 最少连接:Least Connections,根据真实服务器已建立的连接数进行分配,将收到的访问请求优先分配给连接数少的节点,如所有服务器节点性能都均衡,可采用这种方式更好的均衡负载。 |
lblc | 基于局部性的最少连接:LBLC,基于局部性的最少连接调度算法用于目标 IP 负载平衡,通常在高速缓存群集中使用。如服务器处于活动状态且处于负载状态,此算法通常会将发往 IP 地址的数据包定向到其服务器。如果服务器超载(其活动连接数大于其权重),并且服务器处于半负载状态,则将加权最少连接服务器分配给该 IP 地址。 |
lblcr | 复杂的基于局部性的最少连接:LBLCR,具有复杂调度算法的基于位置的最少连接也用于目标IP负载平衡,通常在高速缓存群集中使用。与 LBLC 调度有以下不同:负载平衡器维护从目标到可以为目标提供服务的一组服务器节点的映射。对目标的请求将分配给目标服务器集中的最少连接节点。如果服务器集中的所有节点都超载,则它将拾取群集中的最少连接节点,并将其添加到目标服务器群中。如果在指定时间内未修改服务器集群,则从服务器集群中删除负载最大的节点,以避免高度负载。 |
SED | 最短延迟调度:SED,最短的预期延迟调度算法将网络连接分配给具有最短的预期延迟的服务器。如果将请求发送到第 i 个服务器,则预期的延迟时间为(Ci +1)/ Ui,其中 Ci 是第 i 个服务器上的连接数,而 Ui 是第 i 个服务器的固定服务速率(权重) 。 |
NQ | 永不排队调度:NQ,从不队列调度算法采用两速模型。当有空闲服务器可用时,请求会发送到空闲服务器,而不是等待快速响应的服务器。如果没有可用的空闲服务器,则请求将被发送到服务器,以使其预期延迟最小化(最短预期延迟调度算法)。 |
1.2 ipvsadm工具使用
安装ipsadm
[root@172 ~]# yum install ipvsadm
ipsadm常见参数
选项 | 作用 |
-A | 添加一个虚拟服务,使用IP地址、端口号、协议来唯一定义一个虚拟服务 |
-E | 编辑一个虚拟服务 |
-D | 删除一个虚拟服务 |
-C | 清空虚拟服务表 |
-R | 从标准输入中还原虚拟服务规则 |
-S | 保存虚拟服务规则值标准输出,输出的规则可以使用-R导入还原 |
-a | 在虚拟服务中添加一台真实服务器 |
-e | 在虚拟服务中编辑一台真实服务器 |
-d | 在虚拟服务中减少一台真实服务器 |
-L | 显示虚拟服务列表 |
-t | 使用TCP服务,该参数后需要跟主机与端口信息 |
-u | 使用UDP服务,该参数会需要跟主机与端口信息 |
-s | 指定LVS所采用的的调度算法 |
-r | 设置真实服务器IP地址与端口信息 |
-g | 设置LVS工作模式为DR直连路由模式 |
-i | 设置LVS工作模式为TUN隧道模式 |
-m | 设置LVS工作模式为NAT地址转换模式 |
-w | 设置指定服务器的权重 |
-c | 连接状态,需要配合-L使用 |
-n | 数字格式输出 |
实例
管理虚拟服务
添加地址为192.168.1.100:80的虚拟服务,指定调度算法为轮询。
ipvsadm -A -t 192.168.1.100:80 -s rr
修改虚拟服务的算法为加权轮询
ipvsadm -E -t 192.168.1.100:80 -s wrr
删除一个虚拟服务
ipvsadm -D -t 192.168.1.100:80
管理真实服务
添加一个真实服务器,使用DR模式,设置权重为2
ipvsadm -a -t 192.168.1.100:80 -r 192.168.1.123 -g -w 2
修改真实服务器的权重为5
ipvsadm -e -t 192.168.1.100:80 -r 192.168.1.123 -g -w 5
删除一个真实服务器
ipvsadm -d -t 192.168.1.100:80 -r 192.168.1.123
1.3 LVS部署(实验部分)
1.3.1 LVS-NAT模式部署
实验环境
主机名 | IP | VIP | 角色 |
lvs | 仅主机-eth1::192.168.0.100 | nat-eth0:172.25.254.100 | 调度器 |
webserver1 | 仅主机:192.168.0.10 , GW 192.168.0.100 | NULL | 真实服务器(RS) |
webserver2 | 仅主机:192.168.0.20 , GW 192.168.0.100 | NULL | 真实服务器(RS) |
client | nat:172.25.254.10 | 测试机 |
实验步骤
(1)实验环境配置
client
lvs
lvs调度器要多一块“仅主机”网卡去连接两台真实服务器
webserver
webserver1和webserver2的网卡都是“仅主机”模式
(2)在lvs中启用内核路由功能
[root@lvs ~]# echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
[root@lvs ~]# sysctl -p
net.ipv4.ip_forward = 1
(3)在lvs中安装ipvsadm
[root@lvs ~]# yum install ipvsadm -y
(4)在webserver1和webserver2中安装httpd,并关闭防火墙
webserver1
[root@webserver1 ~]# yum install httpd -y
[root@webserver1 ~]# echo "welcome to webserver1 - 192.168.0.10" > /var/www/html/index.html
[root@webserver1 ~]# systemctl enable --now httpd
[root@webserver1 ~]# systemctl stop firewalld
webserver2
[root@webserver2 ~]# yum install httpd -y
[root@webserver2 ~]# echo "welcome to webserver2 - 192.168.0.20" > /var/www/html/index.html
[root@webserver2 ~]# systemctl enable --now httpd
[root@webserver2 ~]# systemctl stop firewalld
在lvs中检测一下
(5)在lvs中添加调度策略
[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:80 -m
[root@lvs ~]# ipvsadm -a -t 172.25.254.100:80 -r 192.168.0.20:80 -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 1
-> 192.168.0.20:80 Masq 1 0 0
(6)保存规则
# /etc/sysconfig/下原本是没有ipvsadm这个文件的,执行第一条命令会自动创建
[root@lvs ~]# ipvsadm -Sn > /etc/sysconfig/ipvsadm
[root@lvs ~]# cat /etc/sysconfig/ipvsadm
-A -t 172.25.254.100:80 -s rr
-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
(7)删除所有规则
[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
(8)重新加载规则
[root@lvs ~]# ipvsadm -R < /etc/sysconfig/ipvsadm
[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
(9)测试
连续访问10次
1.3.2 LVS-DR模式部署
实验环境
主机名 | IP | VIP | 角色 |
client | nat:172.25.254.10 | NULL | 测试机 |
router | NAT-eth0:172.25.254.100 , 仅主机 - eth1:192.168.0.100 | NULL | 路由器 |
lvs | 192.168.0.50 , GW 192.168.0.100 仅主机 | lo:192.168.0.200 | 调度器 |
RS1 | 192.168.0.10 , GW 192.168.0.100 仅主机 | lo:192.168.0.200 | 真实服务器1 |
RS2 | 192.168.0.20, GW 192.168.0.100 仅主机 | lo:192.168.0.200 | 真实服务器2 |
实验步骤
(1)实验环境配置
client:
router:
router有两块网卡,一块NAT,一块仅主机
lvs:
ip addr add dev lo 192.168.0.200/32
# 该命令用于配置环回IP,但为临时配置,重启系统后失效
# 且只能用ip a查看,ifconfig看不到该信息
RS1:
RS2:
(2)在router中启用内核路由功能
[root@router ~]# echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
[root@router ~]# sysctl -p
net.ipv4.ip_forward = 1
(3)在RS1和RS2中解决vip响应问题
DR 模型中各主机上均需要配置 VIP ,解决地址冲突的方式有三种:(1) 在前端网关做静态绑定(2) 在各 RS 使用 arptables(3) 在各 RS 修改内核参数,来限制 arp 响应和通告的级别限制响应级别 :arp_ignore
- 0:默认值,表示可使用本地任意接口上配置的任意地址进行响应
- 1:仅在请求的目标IP配置在本地主机的接收到请求报文的接口上时,才给予响应
限制通告级别 :arp_announce
- 0:默认值,把本机所有接口的所有信息向每个接口的网络进行通告
- 1:尽量避免将接口信息向非直接连接网络进行通告
- 2:必须避免将接口信息向非本网络进行通告
[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/all/arp_announce
[root@RS1 ~]# echo 2 > /proc/sys/net/ipv4/conf/lo/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/all/arp_announce
[root@RS2 ~]# echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
(4)在RS1和RS2中安装httpd包,并关闭防火墙
RS1:
[root@RS1 ~]# yum install httpd -y
[root@RS1 ~]# echo "welcome to RS1 - 192.168.0.10" > /var/www/html/index.html
[root@RS1 ~]# systemctl enable --now httpd
[root@RS1 ~]# systemctl stop firewalld
RS2:
[root@RS2 ~]# yum install httpd -y
[root@RS2 ~]# echo "welcome to RS2 - 192.168.0.20" > /var/www/html/index.html
[root@RS2 ~]# systemctl enable --now httpd
[root@RS2 ~]# systemctl stop firewalld
(5)在lvs中安装ipvsadm,并添加策略
[root@lvs ~]# yum install ipvsadm -y
[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 2 0 0
[root@lvs ~]# systemctl stop firewalld
(6)客户端测试
1.3.3 防火墙标记解决调度问题
(1)轮询规则中可能会遇到的错误
以http 和 https 为例,当我们在 RS 中同时开放 80 和 443 端口,那么默认控制是分开轮询的,这样我们就出现了一个轮询错乱的问题
当我第一次访问 80 被轮询到 RS1 后下次访问 443 仍然可能会被轮询到 RS1 上
问题呈现
以上一个实验“LVS-DR模式部署”做完的环境为例:
1)为了更好的看到效果,更改虚拟服务的算法为轮询
[root@lvs ~]# ipvsadm -E -t 192.168.0.200:80 -s rr
2)在 RS1 和 RS2 中安装 mod_ssl并重启 apache:
(RS安装mod ssl模块 是为了让rs支持https)
[root@RS1 ~]# yum install mod_ssl -y
[root@RS2 ~]# yum install mod_ssl -y
[root@RS1 ~]# systemctl restart httpd
[root@RS2 ~]# systemctl restart httpd
3)查看httpd端口
[root@RS2 ~]# netstat -antlupe | grep httpd
tcp6 0 0 :::80 :::* LISTEN 0 30875 2601/httpd
tcp6 0 0 :::443 :::* LISTEN 0 30883 2601/httpd4)添加调度策略
[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 rr
-> 192.168.0.10:80 Route 1 0 0
-> 192.168.0.20:80 Route 2 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 05)测试错误结果
(2)防火墙标记解决轮询调度问题
先把原来的策略删除
[root@lvs ~]# ipvsadm -C
在vs调度器中设定端口标签,人为80和443是一个整体
[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 ~]# iptables -t mangle -nL
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
MARK tcp -- 0.0.0.0/0 192.168.0.200 multiport dports 80,443 MARK set 0x42
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
lvs调度配置
[root@lvs ~]# ipvsadm -C
[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@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
-> 192.168.0.10:0 Route 1 0 0
-> 192.168.0.20:0 Route 1 0 0
客户机测试:
可以看到,问题解决