1. 集群和分布式
系统性能扩展方式:
- Scale UP:垂直扩展,向上扩展,增强,性能更强的计算机运行同样的服务
- Scale Out:水平扩展,向外扩展,增加设备,并行地运行多个服务调度分配问题,Cluster
垂直扩展不再提及:
随着计算机性能的增长,其价格会成倍增长
单台计算机的性能是有上限的,不可能无限制地垂直扩展
多核CPU意味着即使是单台计算机也可以并行的。那么,为什么不一开始就并行化技术?
1.1 集群 Cluster
Cluster:集群,为解决某个特定问题将多台计算机组合起来形成的单个系统
Cluster分为三种类型:
-
LB:Load Balancing,负载均衡,多个主机组成,每个主机只承担一部分访问请求
-
HA:High Availiablity,高可用,避免SPOF(single Point Of failure)
MTBF:Mean Time Between Failure 平均无故障时间,正常时间
MTTR:Mean Time To Restoration( repair)平均恢复前时间,故障时间
A = MTBF /(MTBF+MTTR) (0,1):99%,99.5%,99.9%,99.99%,99.999%
SLA:服务等级协议(简称:SLA,全称:service level agreement)。是在一定开销下为保障服务的性能和可用性,服务提供商与用户间定义的一种双方认可的协定。通常这个开销是驱动提供服务质量的主要因素。在常规的领域中,总是设定所谓的三个9,四个9来进行表示,当没有达到这种水平的时候,就会有一些列的惩罚措施,而运维,最主要的目标就是达成这种服务水平。
1年 = 365天 = 8760小时 90 = (1-90%)*365=36.5天 99 = 8760 * 1% = 87.6小时 99.9 = 8760 * 0.1% = 8760 * 0.001 = 8.76小时 99.99 = 8760 * 0.0001 = 0.876小时 = 0.876 * 60 = 52.6分钟 99.999 = 8760 * 0.00001 = 0.0876小时 = 0.0876 * 60 = 5.26分钟 99.9999= (1-99.9999%)*365*24*60*60=31秒
停机时间又分为两种,一种是计划内停机时间,一种是计划外停机时间,而运维则主要关注计划外停机时间。
- HPC:High-performance computing,高性能 www.top500.org
1.2 分布式系统
分布式存储: Ceph,GlusterFS,FastDFS,MogileFS
分布式计算:hadoop,Spark
分布式常见应用
- 分布式应用-服务按照功能拆分,使用微服务
- 分布式静态资源--静态资源放在不同的存储集群上
- 分布式数据和存储--使用key-value缓存系统
- 分布式计算--对特殊业务使用分布式计算,比如Hadoop集群
1.3 集群和分布式
集群:同一个业务系统,部署在多台服务器上。集群中,每一台服务器实现的功能没有差别,数据和代码都是一样的
分布式:一个业务被拆成多个子业务,或者本身就是不同的业务,部署在多台服务器上。分布式中,每一台服务器实现的功能是有差别的,数据和代码也是不一样的,分布式每台服务器功能加起来,才是完整的业务
分布式是以缩短单个任务的执行时间来提升效率的,而集群则是通过提高单位时间内执行的任务数来提升效率。
对于大型网站,访问用户很多,实现一个群集,在前面部署一个负载均衡服务器,后面几台服务器完成同一业务。如果有用户进行相应业务访问时,负载均衡器根据后端哪台服务器的负载情况,决定由给哪一台去完成响应,并且一台服务器垮了,其它的服务器可以顶上来。分布式的每一个节点,都完成不同的业务,如果一个节点垮了,那这个业务可能就会失败
1.4 LB Cluster 负载均衡集群
1.4.1 按实现方式划分
-
硬件
F5 Big-IP
Citrix Netscaler
A10
-
软件
lvs:Linux Virtual Server,阿里云四层 SLB (Server Load Balance)使用
nginx:支持七层调度,阿里云七层SLB使用 Tengine
haproxy:支持七层调度
ats:Apache Traffic Server,yahoo捐助给apache
perlbal:Perl 编写
pound
1.4.2 基于工作的协议层次划分
- 传输层(通用):DNAT 和 DPORT
- LVS:
- nginx:stream
- haproxy:mode tcp
- 应用层(专用):针对特定协议,常称为 proxy server
- http:nginx, httpd, haproxy(mode http), ...
- fastcgi:nginx, httpd, ...
- mysql:mysql-proxy, mycat...
1.4.3 负载均衡的会话保持
- session sticky:同一用户调度固定服务器
Source IP:LVS sh算法(对某一特定服务而言)
Cookie - session replication:每台服务器拥有全部session
session multicast cluster - session server:专门的session服务器
Redis,Memcached
1.5 HA 高可用集群实现
keepalived:vrrp协议
Ais:应用接口规范
- heartbeat
- cman+rgmanager(RHCS)
- coresync_pacemaker
2. Linux Virtual Server简介
2.1 LVS介绍
LVS:Linux Virtual Server,负载调度器,内核集成,章文嵩(花名 正明), 阿里的四层SLB(Server Load Balance)是基于LVS+keepalived实现
LVS 是全球最流行的四层负载均衡开源软件,由章文嵩博士(当前阿里云产品技术负责人)在1998年5月创立,可以实现LINUX平台下的负载均衡。
LVS 官网:http://www.linuxvirtualserver.org/
阿里SLB和LVS:
https://yq.aliyun.com/articles/1803
https://github.com/alibaba/LVS
2.2 LVS工作原理
LVS根据请求报文的目标IP和目标协议及端口将其调度转发至某RS,根据调度算法来挑选RS。LVS是内核级功能,工作在INPUT链的位置,将发往INPUT的流量进行“处理”
范例:查看内核支持LVS
[root@rocky8 ~]#grep -i -C 10 ipvs /boot/config-4.18.0-425.3.1.el8.x86_64
...(省略部分内容)...
CONFIG_NETFILTER_XT_MATCH_IPVS=m
CONFIG_NETFILTER_XT_MATCH_POLICY=m
...(省略部分内容)...
#
# IPVS transport protocol load balancing support lvs支持的传输协议
#
CONFIG_IP_VS_PROTO_TCP=y
CONFIG_IP_VS_PROTO_UDP=y
CONFIG_IP_VS_PROTO_AH_ESP=y
CONFIG_IP_VS_PROTO_ESP=y
CONFIG_IP_VS_PROTO_AH=y
CONFIG_IP_VS_PROTO_SCTP=y
#
# IPVS scheduler #lvs支持的调度算法
#
CONFIG_IP_VS_RR=m
CONFIG_IP_VS_WRR=m
CONFIG_IP_VS_LC=m
CONFIG_IP_VS_WLC=m
CONFIG_IP_VS_FO=m #新增
CONFIG_IP_VS_OVF=m #新增
CONFIG_IP_VS_LBLC=m
CONFIG_IP_VS_LBLCR=m
CONFIG_IP_VS_DH=m
CONFIG_IP_VS_SH=m
CONFIG_IP_VS_MH=m
CONFIG_IP_VS_SED=m
CONFIG_IP_VS_NQ=m
...(省略部分内容)...
2.3 LVS集群体系架构
2.4 LVS集群类型中的术语
VS:Virtual Server,Director Server(DS), Dispatcher(调度器),Load Balancer
RS:Real Server(lvs), upstream server(nginx), backend server(haproxy)
CIP:Client IP
VIP:Virtual serve IP LVS外网的IP
DIP:Director IP LVS内网的IP
RIP:Real server IP
访问流程:CIP <--> VIP == DIP <--> RIP
3. LVS 工作模式和相关命令
3.1 LVS集群的工作模式
- lvs-nat:修改请求报文的目标IP,多目标IP的DNAT
- lvs-dr:操纵封装新的MAC地址
- lvs-tun:在原请求IP报文之外新加一个IP首部
- lvs-fullnat:修改请求报文的源和目标IP,默认内核不支持
3.1.1 LVS的NAT模式
官方链接:
http://www.linuxvirtualserver.org/VS-NAT.html
lvs-nat:本质是多目标IP的DNAT,通过将请求报文中的目标地址和目标端口修改为某挑出的RS的RIP和PORT实现转发
(1)RIP和DIP应在同一个IP网络,且应使用私网地址;RS的网关要指向DIP
(2)请求报文和响应报文都必须经由Director转发,高负载场景中,Director易于成为系统瓶颈
(3)支持端口映射,可修改请求报文的目标PORT
(4)VS必须是Linux系统,RS可以是任意OS系统
注意:RS回包时进入LVS的顺序为:PREROUTING-FORWARD-POSTROUTING,上图为简化版没画该步骤
LVS由用户空间的ipvsadm和内核空间的IPVS组成,ipvsadm用来定义规则,IPVS利用ipvsadm定义的规则工作,IPVS工作在INPUT链上
NAT模式请求过程
- 当用户请求到达Director Server,此时请求的数据报文会先到内核空间的PREROUTING链。 此时报文的源IP为CIP,目标IP为VIP
- PREROUTING 检查发现数据包的目标IP是本机,将数据包送至INPUT链
- 当数据包到达INPUT链时,首先会被IPVS检查,如果数据包里面的目的地址及端口没有在规则里面,那么这条数据包将经过INPUT链送至用户空间,交给用户空间的进程来处理。如果数据包里面的目的地址及端口在规则里面,则修改数据包的目标IP地址为后端服务器IP,然后将数据包发至POSTROUTING链。 此时报文的源IP为CIP,目标IP为RIP
- POSTROUTING链通过选路,将数据包发送给Real Server
- Real Server比对发现目标为自己的IP,开始构建响应报文发回给Director Server。 此时报文的源IP为RIP,目标IP为CIP
- Director Server在响应客户端前,此时会将源IP地址修改为自己的VIP地址,然后响应给客户端。 此时报文的源IP为VIP,目标IP为CIP
3.1.2 LVS的DR模式
官方链接
http://www.linuxvirtualserver.org/VS-DRouting.html
LVS-DR:Direct Routing,直接路由,LVS默认模式,应用最广泛,通过为请求报文重新封装一个MAC首部进行转发,源MAC是DIP所在的接口的MAC,目标MAC是某挑选出的RS的RIP所在接口的MAC地址;源IP/PORT,以及目标IP/PORT均保持不变
上图5.6步骤回包的源mac地址应为RIP的MAC地址,非VIP-MAC
DR模式请求过程
- 客户端发送请求到 Director Server,请求的数据报文(源 IP 是 CIP,目标 IP 是 VIP) 到达内核空间。
- Director Server 和 Real Server 在同一个网络中,数据通过二层数据链路层来传输。
- 内核空间判断数据包的目标 IP 是本机 VIP,此时 IPVS 比对数据包请求的服务是否是集群服务,是集群服务就重新封装数据包。修改源MAC 地址为 Director Server 的 MAC 地址,修改目标 MAC 地址为 Real Server 的 MAC 地址,源IP 地址与目标 IP 地址没有改 变,然后将数据包发送给 Real Server。
- 到达 Real Server 的请求报文的 MAC 地址是自身的 MAC 地址,就接收此报文。数据包重新封装报文(源 IP 地址为VIP,目标 IP 为 CIP),将响应报文通过 lo 接口传送给物理网卡然后向外发出。
- Real Server 直接将响应报文传送到客户端。
DR模式的特点:
-
Director和各RS都配置有VIP
-
确保前端路由器将目标IP为VIP的请求报文发往Director
-
在前端网关做静态绑定VIP和Director的MAC地址
-
在RS上使用arptables工具(用的不多)
arptables -A IN -d $VIP -j DROP arptables -A OUT -s $VIP -j mangle --mangle-ip-s $RIP
-
在RS上修改内核参数以限制arp通告及应答级别 (常用配置)
/proc/sys/net/ipv4/conf/all/arp_ignore #接收到ARP请求时,网卡是否会忽略它,不进行arp应答 /proc/sys/net/ipv4/conf/all/arp_announce #免费arp通告
-
-
RS的RIP可以使用私网地址,也可以是公网地址;RIP与DIP在同一IP网络;RIP的网关不能指向DIP,以确保响应报文不会经由Director
-
RS和Director要在同一个物理网络
-
请求报文要经由Director,但响应报文不经由Director,而由RS直接发往Client
-
不支持端口映射(端口不能修改)
-
无需开启 ip_forward
-
RS可使用大多数OS系统
-
Real Server 上的 lo 接口配置 VIP 的 IP 地址
3.1.3 LVS的TUN模式
官方链接
http://www.linuxvirtualserver.org/VS-IPTunneling.html
转发方式:不修改请求报文的IP首部(源IP为CIP,目标IP为VIP),而在原IP报文之外再封装一个IP首部(源IP是DIP,目标IP是RIP),将报文发往挑选出的目标RS;RS直接响应给客户端(源IP是VIP,目标IP是CIP)
TUN模式特点:
- RIP和DIP可以不处于同一物理网络中,RS的网关一般不能指向DIP,且RIP可以和公网通信。也就是说集群节点可以跨互联网实现。DIP, VIP, RIP可以是公网地址
- RealServer的tun接口上需要配置VIP地址,以便接收director转发过来的数据包,以及作为响应的报文源IP
- Director转发给RealServer时需要借助隧道,隧道外层的IP头部的源IP是DIP,目标IP是RIP,而RealServer响应给客户端的IP头部是根据隧道内层的IP头分析得到的,源IP是VIP,目标IP是CIP
- 请求报文要经由Director,但响应不经由Director,响应由RealServer自己完成
- 不支持端口映射
- RS的OS系统须支持隧道功能
应用场景:
一般来说,TUN模式常会用来负载调度缓存服务器组,这些缓存服务器一般放置在不同的网络环境,可以就近折返给客户端。在请求对象不在Cache服务器本地命中的情况下,Cache服务器要向源服务器发送请求,将结果取回,最后将结果返回给用户。
LAN环境一般多采用DR模式,WAN环境虽然可以用TUN模式,但是一般在WAN环境下,请求转发更多的被haproxy/nginx/DNS等实现。因此,TUN模式实际应用的很少,跨机房的应用一般专线光纤连接或DNS调度
3.1.4 LVS的FULLNAT模式
通过同时修改请求报文的源IP地址和目标IP地址进行转发
CIP --> DIP
VIP --> RIP
fullnat模式特点:
-
VIP是公网地址,RIP和DIP是私网地址,且通常不在同一IP网络;因此,RIP的网关一般不会指向DIP
-
RS收到的请求报文源地址是DIP,因此,只需响应给DIP;但Director还要将其发往Client
-
请求和响应报文都经由Director
-
相对NAT模式,可以更好的实现LVS-RealServer间跨VLAN通讯
-
支持端口映射
注意:此类型kernel默认不支持
3.1.5 LVS工作模式总结和比较
NAT | TUN | DR | |
---|---|---|---|
Real Server 服务器要求 | any (所有无要求) | Tunneling (支持隧道) | Non-arp device (关闭arp应答) |
Real server network | private | LAN/WAN | LAN |
Real server number | low (10~20) | High (100) | High (100) |
Real server gateway | load balancer | own router | Own router |
优点 | 端口转换 | WAN | 性能最好 |
缺点 | 性能瓶颈 | 要求支持隧道,不支持端口转换 | 不支持跨网段和端口转换 |
lvs-nat与lvs-fullnat:
- 请求和响应报文都经由Director
- lvs-nat:RIP的网关要指向DIP
- lvs-fullnat:RIP和DIP未必在同一IP网络,但要能通信
lvs-dr与lvs-tun:
- 请求报文要经由Director,但响应报文由RS直接发往Client
- lvs-dr:通过封装新的MAC首部实现,通过MAC网络转发
- lvs-tun:通过在原IP报文外封装新IP头实现转发,支持远距离通信
3.2 LVS 调度算法
ipvs scheduler:根据其调度时是否考虑各RS当前的负载状态
分为两种:静态方法和动态方法
3.2.1 静态方法
仅根据算法本身进行调度
- RR:roundrobin,轮询,较常用,雨露均沾,大锅饭
- WRR:Weighted RR,加权轮询,较常用,权重越高,优先调度
- SH:Source Hashing,实现session sticky,源IP地址hash;将来自于同一个IP地址的请求始终发往第一次挑中的RS,从而实现会话绑定
- DH:Destination Hashing;目标地址哈希,第一次轮询调度至RS,后续将发往同一个目标地址的请求始终转发至第一次挑中的RS,典型使用场景是正向代理缓存场景中的负载均衡,如: Web缓存
3.2.2 动态方法
主要根据每RS当前的负载状态及调度算法进行调度Overhead=value 较小的RS将被调度
-
LC:least connections (最少连接)适用于长连接应用
Overhead=activeconns*256+inactiveconns 开销=活动连接数*256+非活动连接数
-
WLC:Weighted LC(加权最少连接),默认调度方法,较常用。权重越大,Overhead越小,优先调度
Overhead=(activeconns*256+inactiveconns)/weight 开销=(活动连接数*256+非活动连接数)/权重
-
SED:Shortest Expection Delay(最短期望延迟),初始连接高权重优先,只检查活动连接,而不考虑非活动连接
Overhead=(activeconns+1)*256/weight 开销=(活动连接数+1)*256/权重
-
NQ:Never Queue(永不排队),第一轮均匀分配,后续SED
-
LBLC:Locality-Based LC(本地负载均衡和本地缓存),动态的DH算法,使用场景:根据负载状态实现正向代理,实现Web Cache等
-
LBLCR:LBLC with Replication(本地负载均衡、本地缓存和复制),带复制功能的LBLC,解决LBLC负载不均衡问题,从负载重的复制到负载轻的RS,,实现Web Cache等
3.2.3 内核版本 4.15 版本后新增调度算法:FO和OVF
FO(Weighted Fail Over)调度算法,在此FO算法中,遍历虚拟服务所关联的真实服务器链表,找到还未过载(未设IP_VS_DEST_F_OVERLOAD标志)的且权重最高的真实服务器,进行调度,属于静态算法
OVF(Overflow-connection)调度算法,基于真实服务器的活动连接数量和权重值实现。将新连接调度到权重值最高的真实服务器,直到其活动连接数量超过权重值,之后调度到下一个权重值最高的真实服务器,在此OVF算法中,遍历虚拟服务相关联的真实服务器链表,找到权重值最高的可用真实服务器。,属于动态算法
一个可用的真实服务器需要同时满足以下条件:
- 未过载(未设置IP_VS_DEST_F_OVERLOAD标志)
- 真实服务器当前的活动连接数量小于其权重值
- 其权重值不为零
3.3 LVS 相关软件
3.3.1 程序包:ipvsadm
Unit File: ipvsadm.service
主程序:/usr/sbin/ipvsadm
规则保存工具:/usr/sbin/ipvsadm-save
规则重载工具:/usr/sbin/ipvsadm-restore
配置文件:/etc/sysconfig/ipvsadm-config
ipvs调度规则文件:/etc/sysconfig/ipvsadm
3.3.2 ipvsadm 命令
ipvsadm核心功能:
- 集群服务管理:增、删、改
- 集群服务的RS管理:增、删、改
- 查看
ipvsadm 工具用法:
#管理集群服务
ipvsadm -A|E -t|u|f service-address [-s scheduler] [-p [timeout]] [-M netmask]
[--pe persistence_engine] [-b sched-flags]
ipvsadm -D -t|u|f service-address #删除
ipvsadm –C #清空
ipvsadm –R #重载,相当于ipvsadm-restore
ipvsadm -S [-n] #保存,相当于ipvsadm-save
#管理集群中的RS
ipvsadm -a|e -t|u|f service-address -r server-address [-g|i|m] [-w weight]
ipvsadm -d -t|u|f service-address -r server-address
ipvsadm -L|l [options]
ipvsadm -Z [-t|u|f service-address]
管理集群服务:增、改、删
增、修改:
ipvsadm -A|E -t|u|f service-address [-s scheduler] [-p [timeout]]
说明
service-address:
-t|u|f:
-t: TCP协议的端口,VIP:TCP_PORT 如: -t 10.0.0.100:80
-u: UDP协议的端口,VIP:UDP_PORT
-f:firewall MARK,标记,一个数字
[-s scheduler]:指定集群的调度算法,默认为wlc
范例:
ipvsadm -A -t 10.0.0.100:80 -s wrr
删除:
ipvsadm -D -t|u|f service-address
管理集群上的RS:增、改、删
增、改:
ipvsadm -a|e -t|u|f service-address -r server-address [-g|i|m] [-w weight]
删:
ipvsadm -d -t|u|f service-address -r server-address
server-address:
rip[:port] 如省略port,不作端口映射
选项:
lvs类型:
-g: gateway, dr类型,默认
-i: ipip, tun类型
-m: masquerade, nat类型
-w weight:权重
范例:
ipvsadm -a -t 10.0.0.100:80 -r 10.0.0.8:8080 -m -w 3
清空定义的所有内容:
ipvsadm -C
清空计数器:
ipvsadm -Z [-t|u|f service-address]
查看:
ipvsadm -L|l [options]
--numeric, -n:以数字形式输出地址和端口号
--exact:扩展信息,精确值
--connection,-c:当前IPVS连接输出
--stats:统计信息
--rate :输出速率信息
ipvs规则:
/proc/net/ip_vs
ipvs连接:
/proc/net/ip_vs_conn
保存:建议保存至/etc/sysconfig/ipvsadm
ipvsadm-save > /PATH/TO/IPVSADM_FILE
ipvsadm -S > /PATH/TO/IPVSADM_FILE
systemctl stop ipvsadm.service #会自动保存规则至/etc/sysconfig/ipvsadm
重载:
ipvsadm-restore < /PATH/FROM/IPVSADM_FILE
systemctl start ipvsadm.service #会自动加载/etc/sysconfig/ipvsadm中规则
3.4 防火墙标记
FWM:FireWall Mark
MARK target 可用于给特定的报文打标记
--set-mark value
其中:value 可为0xffff格式,表示十六进制数字
借助于防火墙标记来分类报文,而后基于标记定义集群服务;可将多个不同的应用使用同一个集群服务进行调度
实现方法:
在Director主机打标记:
iptables -t mangle -A PREROUTING -d $vip -p $proto -m multiport --dports $port1,$port2,… -j MARK --set-mark NUMBER
在Director主机基于标记定义集群服务:
ipvsadm -A -f NUMBER [options]
范例:
#指定mangle表修改数据包字段,对目标地址172.16.0.100的tcp80 443端口的数据包标记设置为10
[root@lvs ~]#iptables -t mangle -A PREROUTING -d 172.16.0.100 -p tcp -m multiport --dports 80,443 -j MARK --set-mark 10
[root@lvs ~]#ipvsadm -C
[root@lvs ~]#ipvsadm -A -f 10 -s rr
[root@lvs ~]#ipvsadm -a -f 10 -r 10.0.0.7 -g
[root@lvs ~]#ipvsadm -a -f 10 -r 10.0.0.17 -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 10 rr
-> 10.0.0.7:0 Route 1 0 0
-> 10.0.0.17:0 Route 1 0 0
[root@lvs ~]#cat /proc/net/ip_vs
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
FWM 0000000A rr
-> 0A000011:0000 Route 1 0 0
-> 0A000007:0000 Route 1 0 0
范例:
#不加-s指定调度算法,使用默认wlc算法
[root@lvs ~]#ipvsadm -A -f 10
[root@lvs ~]#ipvsadm -a -f 10 -r 10.0.0.7 -g
[root@lvs ~]#ipvsadm -a -f 10 -r 10.0.0.17 -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 10 wlc
-> 10.0.0.7:0 Route 1 0 0
-> 10.0.0.17:0 Route 1 0 0
[root@lvs ~]#cat /proc/net/ip_vs
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
FWM 0000000A wlc
-> 0A000011:0000 Route 1 0 0
-> 0A000007:0000 Route 1 0 0
3.5 LVS 持久连接
session 绑定:对共享同一组RS的多个集群服务,需要统一进行绑定,lvs sh算法无法实现
持久连接( lvs persistence )模板:实现无论使用任何调度算法,在一段时间内(默认360s ),能够实现将来自同一个地址的请求始终发往同一个RS
ipvsadm -A|E -t|u|f service-address [-s scheduler] [-p [timeout]]
持久连接实现方式:
- 每端口持久(PPC):每个端口定义为一个集群服务,每集群服务单独调度
- 每防火墙标记持久(PFWMC):基于防火墙标记定义集群服务;可实现将多个端口上的应用统一调度,即所谓的port Affinity
- 每客户端持久(PCC):基于0端口(表示所有服务)定义集群服务,即将客户端对所有应用的请求都调度至后端主机,必须定义为持久模式
范例:
[root@lvs ~]#ipvsadm -E -f 10 -p
[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 10 wlc persistent 360
-> 10.0.0.7:0 Route 1 0 0
-> 10.0.0.17:0 Route 1 0 0
[root@lvs ~]#ipvsadm -E -f 10 -p 3600
[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 10 wlc persistent 3600
-> 10.0.0.7:0 Route 1 0 0
-> 10.0.0.17:0 Route 1 0 0
[root@lvs ~]#cat /proc/net/ip_vs_conn
Pro FromIP FPrt ToIP TPrt DestIP DPrt State Expires PEName PEData
TCP C0A80006 C816 AC100064 01BB 0A000011 01BB FIN_WAIT 67
TCP C0A80006 C812 AC100064 01BB 0A000011 01BB FIN_WAIT 67
TCP C0A80006 9A36 AC100064 0050 0A000011 0050 FIN_WAIT 65
TCP C0A80006 C806 AC100064 01BB 0A000011 01BB FIN_WAIT 65
TCP C0A80006 9A3E AC100064 0050 0A000011 0050 FIN_WAIT 66
TCP C0A80006 C81A AC100064 01BB 0A000011 01BB FIN_WAIT 67
TCP C0A80006 C80A AC100064 01BB 0A000011 01BB FIN_WAIT 66
TCP C0A80006 9A3A AC100064 0050 0A000011 0050 FIN_WAIT 66
TCP C0A80006 9A4E AC100064 0050 0A000011 0050 FIN_WAIT 68
TCP C0A80006 9A42 AC100064 0050 0A000011 0050 FIN_WAIT 67
TCP C0A80006 9A46 AC100064 0050 0A000011 0050 FIN_WAIT 67
TCP C0A80006 C81E AC100064 01BB 0A000011 01BB FIN_WAIT 68
IP C0A80006 0000 0000000A 0000 0A000011 0000 NONE 948
TCP C0A80006 C80E AC100064 01BB 0A000011 01BB FIN_WAIT 66
TCP C0A80006 9A4A AC100064 0050 0A000011 0050 FIN_WAIT 67
[root@lvs ~]#ipvsadm -Lnc
IPVS connection entries
pro expire state source virtual destination
TCP 00:46 FIN_WAIT 192.168.10.6:51222 172.16.0.100:443 10.0.0.17:443
TCP 00:46 FIN_WAIT 192.168.10.6:51218 172.16.0.100:443 10.0.0.17:443
TCP 00:45 FIN_WAIT 192.168.10.6:39478 172.16.0.100:80 10.0.0.17:80
TCP 00:45 FIN_WAIT 192.168.10.6:51206 172.16.0.100:443 10.0.0.17:443
TCP 00:46 FIN_WAIT 192.168.10.6:39486 172.16.0.100:80 10.0.0.17:80
TCP 00:47 FIN_WAIT 192.168.10.6:51226 172.16.0.100:443 10.0.0.17:443
TCP 00:45 FIN_WAIT 192.168.10.6:51210 172.16.0.100:443 10.0.0.17:443
TCP 00:45 FIN_WAIT 192.168.10.6:39482 172.16.0.100:80 10.0.0.17:80
TCP 00:47 FIN_WAIT 192.168.10.6:39502 172.16.0.100:80 10.0.0.17:80
TCP 00:46 FIN_WAIT 192.168.10.6:39490 172.16.0.100:80 10.0.0.17:80
TCP 00:46 FIN_WAIT 192.168.10.6:39494 172.16.0.100:80 10.0.0.17:80
TCP 00:47 FIN_WAIT 192.168.10.6:51230 172.16.0.100:443 10.0.0.17:443
IP 15:27 NONE 192.168.10.6:0 0.0.0.10:0 10.0.0.17:0
TCP 00:46 FIN_WAIT 192.168.10.6:51214 172.16.0.100:443 10.0.0.17:443
TCP 00:47 FIN_WAIT 192.168.10.6:39498 172.16.0.100:80 10.0.0.17:80
4.LVS 实战案例
4.1 LVS-NAT模式案例
环境:
共四台主机
一台: internet client:192.168.10.6/24 GW:无 仅主机
一台:lvs
eth1 仅主机 192.168.10.100/24
eth0 NAT 10.0.0.8/24
两台RS:
RS1: 10.0.0.7/24 GW:10.0.0.8 NAT
RS2: 10.0.0.17/24 GW:10.0.0.8 NAT
配置过程:
[root@internet ~]#cat /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
NAME=eth0
BOOTPROTO=static
IPADDR=192.168.10.6
PREFIX=24
ONBOOT=yes
[root@lvs network-scripts]#cat ifcfg-eth0
DEVICE=eth0
NAME=eth0
BOOTPROTO=static
IPADDR=10.0.0.8
PREFIX=24
ONBOOT=yes
[root@lvs network-scripts]#cat ifcfg-eth1
DEVICE=eth1
NAME=eth1
BOOTPROTO=static
IPADDR=192.168.10.100
PREFIX=24
ONBOOT=yes
#nat模式RS网关需指向Director
[root@rs1 ~]#cat /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
NAME=eth0
BOOTPROTO=static
IPADDR=10.0.0.7
PREFIX=24
GATEWAY=10.0.0.8
ONBOOT=yes
[root@rs2 ~]#cat /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
NAME=eth0
BOOTPROTO=static
IPADDR=10.0.0.17
PREFIX=24
GATEWAY=10.0.0.8
ONBOOT=yes
#配置后端RS服务器web页面内容,用以区别分配到哪台RS服务器
[root@rs1 ~]#curl 10.0.0.7
10.0.0.7 RS1
[root@rs2 ~]#curl 10.0.0.17
10.0.0.17 RS2
#修改内核参数,支持forward转发
[root@lvs-server ~]#vim /etc/sysctl.conf
net.ipv4.ip_forward = 1
[root@lvs-server ~]#sysctl -p
net.ipv4.ip_forward = 1
#配置lvs nat规则并查看
[root@lvs-server ~]#ipvsadm -A -t 192.168.10.100:80 -s wrr
[root@lvs-server ~]#ipvsadm -a -t 192.168.10.100:80 -r 10.0.0.7:80 -m
[root@lvs-server ~]#ipvsadm -a -t 192.168.10.100:80 -r 10.0.0.17:80 -m
[root@lvs-server ~]#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.10.100:80 wrr
-> 10.0.0.7:80 Masq 1 1 0
-> 10.0.0.17:80 Masq 1 0 0
#编写while循环,使用curl测试轮询情况
[root@internet ~]#while :;do curl 192.168.10.100;sleep 0.5;done
rs1.magedu.org
rs2.magedu.org
rs1.magedu.org
rs2.magedu.org
rs1.magedu.org
rs2.magedu.org
#查看统计信息
[root@lvs-server ~]#ipvsadm -Ln --stats
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Conns InPkts OutPkts InBytes OutBytes
-> RemoteAddress:Port
TCP 192.168.10.100:80 46 281 194 18104 21031
-> 10.0.0.7:80 23 141 98 9134 10609
-> 10.0.0.17:80 23 140 96 8970 10422
#查看ipvs规则
[root@lvs-server ~]#cat /proc/net/ip_vs
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP C0A80A64:0050 wrr
-> 0A000011:0050 Masq 1 0 98
-> 0A000007:0050 Masq 1 0 97
#当前IPVS连接输出
[root@lvs-server ~]#ipvsadm -Lnc
IPVS connection entries
pro expire state source virtual destination
TCP 01:01 TIME_WAIT 192.168.10.6:48644 192.168.10.100:80 10.0.0.7:80
TCP 01:08 TIME_WAIT 192.168.10.6:45620 192.168.10.100:80 10.0.0.17:80
TCP 01:00 TIME_WAIT 192.168.10.6:48612 192.168.10.100:80 10.0.0.17:80
TCP 00:57 TIME_WAIT 192.168.10.6:48562 192.168.10.100:80 10.0.0.17:80
TCP 01:05 TIME_WAIT 192.168.10.6:48706 192.168.10.100:80 10.0.0.7:80
TCP 00:57 TIME_WAIT 192.168.10.6:48570 192.168.10.100:80 10.0.0.7:80
TCP 01:08 TIME_WAIT 192.168.10.6:45628 192.168.10.100:80 10.0.0.7:80
TCP 00:58 TIME_WAIT 192.168.10.6:48598 192.168.10.100:80 10.0.0.7:80
TCP 00:59 TIME_WAIT 192.168.10.6:48608 192.168.10.100:80 10.0.0.17:80
TCP 01:02 TIME_WAIT 192.168.10.6:48672 192.168.10.100:80 10.0.0.7:80
TCP 01:01 TIME_WAIT 192.168.10.6:48630 192.168.10.100:80 10.0.0.17:80
TCP 00:58 TIME_WAIT 192.168.10.6:48586 192.168.10.100:80 10.0.0.17:80
TCP 01:02 TIME_WAIT 192.168.10.6:48660 192.168.10.100:80 10.0.0.17:80
TCP 01:04 TIME_WAIT 192.168.10.6:48694 192.168.10.100:80 10.0.0.17:80
TCP 01:03 TIME_WAIT 192.168.10.6:48692 192.168.10.100:80 10.0.0.7:80
TCP 01:03 TIME_WAIT 192.168.10.6:48680 192.168.10.100:80 10.0.0.17:80
TCP 00:59 TIME_WAIT 192.168.10.6:48610 192.168.10.100:80 10.0.0.7:80
#查看ipvs连接
[root@lvs-server ~]#cat /proc/net/ip_vs_conn
Pro FromIP FPrt ToIP TPrt DestIP DPrt State Expires PEName PEData
TCP C0A80A06 91C0 C0A80A64 0050 0A000011 0050 TIME_WAIT 116
TCP C0A80A06 919C C0A80A64 0050 0A000007 0050 TIME_WAIT 114
TCP C0A80A06 9190 C0A80A64 0050 0A000011 0050 TIME_WAIT 114
TCP C0A80A06 91CC C0A80A64 0050 0A000007 0050 TIME_WAIT 116
TCP C0A80A06 BA60 C0A80A64 0050 0A000007 0050 TIME_WAIT 119
TCP C0A80A06 BA42 C0A80A64 0050 0A000011 0050 TIME_WAIT 118
TCP C0A80A06 91B2 C0A80A64 0050 0A000007 0050 TIME_WAIT 115
TCP C0A80A06 BA3C C0A80A64 0050 0A000007 0050 TIME_WAIT 117
TCP C0A80A06 BA34 C0A80A64 0050 0A000011 0050 TIME_WAIT 117
TCP C0A80A06 BA46 C0A80A64 0050 0A000007 0050 TIME_WAIT 118
TCP C0A80A06 91A8 C0A80A64 0050 0A000011 0050 TIME_WAIT 115
TCP C0A80A06 BA52 C0A80A64 0050 0A000011 0050 TIME_WAIT 119
#保存规则,开启自启动生效
[root@lvs-server ~]#ipvsadm -Sn > /etc/sysconfig/ipvsadm
[root@lvs-server ~]#systemctl enable --now ipvsadm.service
#问题:LVS 打开监听VIP相关的端口吗?
LVS 监听端口是在内核层面进行的,在使用ss命令查看端口时,无法直接看到LVS监听的端口。ss命令只能查看用户空间服务所监听端口
范例2:
- Director 服务器采用双网卡,一个是桥接网卡连接外网,一个是仅主机网卡与后端Web服务器相连
- Web服务器采用仅主机网卡与director相连
- Web服务器网关指向10.0.0.8
- 后端web服务器不需要连接外网
环境:
共四台主机
一台: internet client :172.20.200.6/16 GW:无
一台:lvs
eth1 桥接 172.20.200.200/16
eth0 NAT 10.0.0.8/24
两台RS:
RS1: 10.0.0.7/24 GW: 10.0.0.200
RS2: 10.0.0.17/24 GW: 10.0.0.200
配置过程
#LVS启用IP_FORWORD功能
[root@lvs ~]#vim /etc/sysctl.conf
net.ipv4.ip_forward = 1
[root@LVS ~]#sysctl -p
[root@lvs ~]#ipvsadm -A -t 172.20.200.200:80 -s rr
[root@lvs ~]#ipvsadm -a -t 172.20.200.200:80 -r 10.0.0.7 -m
[root@lvs ~]#ipvsadm -a -t 172.20.200.200:80 -r 10.0.0.17 -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.20.200.200:80 rr
-> 10.0.0.7:80 Masq 1 0 0
-> 10.0.0.17:80 Masq 1 0 0
#测试
[root@client ~]#curl 172.20.200.200
RS2 Server on 10.0.0.17
[root@client ~]#curl 172.20.200.200
RS1 Server on 10.0.0.7
[root@client ~]#curl 172.20.200.200
RS2 Server on 10.0.0.17
[root@client ~]#curl 172.20.200.200
RS1 Server on 10.0.0.7
[root@lvs ~]#cat /proc/net/ip_vs_conn
Pro FromIP FPrt ToIP TPrt DestIP DPrt State Expires PEName PEData
TCP AC14C806 88B6 AC14C8C8 0050 0A000007 0050 TIME_WAIT 73
TCP AC14C806 889A AC14C8C8 0050 0A000011 0050 TIME_WAIT 70
TCP AC14C806 88A2 AC14C8C8 0050 0A000007 0050 TIME_WAIT 71
TCP C0A80A7F 0000 C0A80A80 0050 0A000011 0050 NONE 2219
TCP AC14C806 88AE AC14C8C8 0050 0A000011 0050 TIME_WAIT 72
#保存规则
[root@LVS ~]#ipvsadm -Sn > /etc/sysconfig/ipvsadm
[root@lvs ~]#cat /etc/sysconfig/ipvsadm
-A -t 172.20.200.200:80 -s rr
-a -t 172.20.200.200:80 -r 10.0.0.7:80 -m -w 1
-a -t 172.20.200.200:80 -r 10.0.0.17:80 -m -w 1
#清除规则
[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 -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.20.200.200:80 rr
-> 10.0.0.7:80 Masq 1 0 0
-> 10.0.0.17:80 Masq 1 0 0
#开机加载ipvs规则
[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 ~]#systemctl enable --now ipvsadm.service
[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.20.200.200:80 rr
-> 10.0.0.7:80 Masq 1 0 0
-> 10.0.0.17:80 Masq 1 0 0
[root@rs1 ~]#tail /var/log/httpd/access_log
172.20.200.6 - - [11/Oct/2023:04:03:22 -0400] "GET / HTTP/1.1" 200 13 "-" "curl/7.61.1"
172.20.200.6 - - [11/Oct/2023:04:03:22 -0400] "GET / HTTP/1.1" 200 13 "-" "curl/7.61.1"
172.20.200.6 - - [11/Oct/2023:04:03:22 -0400] "GET / HTTP/1.1" 200 13 "-" "curl/7.61.1"
172.20.200.6 - - [11/Oct/2023:04:03:22 -0400] "GET / HTTP/1.1" 200 13 "-" "curl/7.61.1"
172.20.200.6 - - [11/Oct/2023:04:03:22 -0400] "GET / HTTP/1.1" 200 13 "-" "curl/7.61.1"
172.20.200.6 - - [11/Oct/2023:04:03:22 -0400] "GET / HTTP/1.1" 200 13 "-" "curl/7.61.1"
172.20.200.6 - - [11/Oct/2023:04:03:22 -0400] "GET / HTTP/1.1" 200 13 "-" "curl/7.61.1"
172.20.200.6 - - [11/Oct/2023:04:03:22 -0400] "GET / HTTP/1.1" 200 13 "-" "curl/7.61.1"
172.20.200.6 - - [11/Oct/2023:04:03:22 -0400] "GET / HTTP/1.1" 200 13 "-" "curl/7.61.1"
172.20.200.6 - - [11/Oct/2023:04:03:22 -0400] "GET / HTTP/1.1" 200 13 "-" "curl/7.61.1"
#修改调度算法为 WRR 和后端服务器的端口
[root@LVS ~]#ipvsadm -E -t 172.20.200.200:80 -s wrr
[root@LVS ~]#ipvsadm -d -t 172.20.200.200:80 -r 10.0.0.7
[root@LVS ~]#ipvsadm -a -t 172.20.200.200:80 -r 10.0.0.7:8080 -m -w 3
[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.20.200.200:80 wrr
-> 10.0.0.7:8080 Masq 3 0 0
-> 10.0.0.17:80 Masq 1 0 157
[root@rs1 ~]#vim /etc/httpd/conf/httpd.conf
Listen 8080
[root@rs1 ~]#systemctl restart httpd
[root@client ~]#curl 172.20.200.200
RS1 Server on 10.0.0.7
[root@client ~]#curl 172.20.200.200
RS1 Server on 10.0.0.7
[root@client ~]#curl 172.20.200.200
RS1 Server on 10.0.0.7
[root@client ~]#curl 172.20.200.200
RS2 Server on 10.0.0.17
4.2 LVS-DR模式单网段案例
DR模型中各主机上均需要配置VIP,解决地址冲突的方式有三种:
(1) 在前端网关做静态绑定
(2) 在各RS使用arptables
(3) 在各RS修改内核参数,来限制arp响应和通告的级别
限制响应级别:arp_ignore
- 0:默认值,表示可使用本地任意接口上配置的任意地址进行响应
- 1:仅在请求的目标IP配置在本地主机的接收到请求报文的接口上时,才给予响应
限制通告级别:arp_announce
- 0:默认值,把本机所有接口的所有信息向每个接口的网络进行通告
- 1:尽量避免将接口信息向非直接连接网络进行通告
- 2:必须避免将接口信息向非本网络进行通告
配置要点
- Director 服务器采用双IP桥接网络,一个是VIP,一个DIP
- Web服务器采用和DIP相同的网段和Director连接
- 每个Web服务器配置VIP
- 每个web服务器可以出外网
范例:
环境:五台主机
一台:客户端 eth0:仅主机 192.168.10.6/24 GW:192.168.10.200
一台:ROUTER
eth0 :NAT 10.0.0.200/24
eth1: 仅主机 192.168.10.200/24
启用 IP_FORWARD
一台:LVS
eth0:NAT:DIP:10.0.0.8/24 GW:10.0.0.200
两台RS:
RS1:eth0:NAT:10.0.0.7/24 GW:10.0.0.200
RS2:eth0:NAT:10.0.0.17/24 GW:10.0.0.200
4.2.1 LVS的网络配置
#所有主机禁用iptables和SELinux
#internet主机环境
[root@internet ~]#hostname
internet
[root@internet ~]#hostname -I
192.168.10.6
[root@internet ~]#route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.10.200 0.0.0.0 UG 100 0 0 eth0
192.168.10.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0
[root@internet ~]#ping 10.0.0.7 -c1
PING 10.0.0.7 (10.0.0.7) 56(84) bytes of data.
64 bytes from 10.0.0.7: icmp_seq=1 ttl=63 time=0.565 ms
[root@internet ~]#ping 10.0.0.17 -c1
PING 10.0.0.7 (10.0.0.17) 56(84) bytes of data.
64 bytes from 10.0.0.17: icmp_seq=1 ttl=63 time=0.565 ms
################################################################################
######
#路由器的网络配置
[root@router ~]#echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf
[root@router ~]#sysctl -p
[root@router network-scripts]#pwd
/etc/sysconfig/network-scripts
[root@router network-scripts]#cat ifcfg-eth0
DEVICE=eth0
NAME=eth0
BOOTPROTO=static
IPADDR=10.0.0.200
PREFIX=24
ONBOOT=yes
[root@router network-scripts]#cat ifcfg-eth1
DEVICE=eth1
NAME=eth1
BOOTPROTO=static
IPADDR=192.168.10.200
PREFIX=24
ONBOOT=yes
################################################################################
######
#RS1的网络配置
[root@rs1 ~]#hostname
rs1.magedu.org
[root@rs1 ~]#hostname -I
10.0.0.7
[root@rs1 ~]#cat /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
NAME=eth0
BOOTPROTO=static
IPADDR=10.0.0.7
PREFIX=24
GATEWAY=10.0.0.200
ONBOOT=yes
[root@rs1 ~]#route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.0.0.200 0.0.0.0 UG 100 0 0 eth0
10.0.0.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0
[root@rs1 ~]#yum -y install httpd
[root@rs1 ~]#systemctl enable --now httpd
[root@rs1 ~]#hostname -I > /var/www/html/index.html
[root@rs1 ~]#ping 192.168.10.6 -c1
PING 192.168.10.6 (192.168.10.6) 56(84) bytes of data.
64 bytes from 192.168.10.6: icmp_seq=1 ttl=63 time=0.419 ms
[root@rs1 ~]#curl 10.0.0.7
10.0.0.7
################################################################################
######
#RS2 的网络配置
[root@rs2 ~]#cat /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
NAME=eth0
BOOTPROTO=static
IPADDR=10.0.0.17
PREFIX=24
GATEWAY=10.0.0.200
ONBOOT=yes
[root@rs2 ~]#route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.0.0.200 0.0.0.0 UG 100 0 0 eth0
10.0.0.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0
[root@rs2 ~]#yum -y install httpd
[root@rs2 ~]#systemctl enable --now httpd
[root@rs2 ~]#hostname -I > /var/www/html/index.html
[root@rs2 ~]#curl 10.0.0.17
10.0.0.17
[root@rs2 ~]#ping 192.168.10.6 -c1
PING 192.168.10.6 (192.168.10.6) 56(84) bytes of data.
64 bytes from 192.168.10.6: icmp_seq=1 ttl=63 time=0.659 ms
[root@rs2 ~]#curl 10.0.0.17
10.0.0.17
################################################################################
######
#LVS的网络配置
[root@lvs ~]#hostname
lvs-server
[root@lvs ~]#hostname -I
10.0.0.8
[root@lvs ~]#cat /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
NAME=eth0
BOOTPROTO=static
IPADDR=10.0.0.8
PREFIX=24
GATEWAY=10.0.0.200
ONBOOT=yes
[root@lvs ~]#route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.0.0.200 0.0.0.0 UG 100 0 0 eth0
10.0.0.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0
root@lvs ~]#ping 192.168.10.6 -c1
PING 192.168.10.6 (192.168.10.6) 56(84) bytes of data.
64 bytes from 192.168.10.6: icmp_seq=1 ttl=63 time=0.463 ms
4.2.2 后端RS的IPVS配置
#RS1的IPVS配置
#all和lo都需要修改,配合使用。默认重启会丢失,永久生效需要修改/etc/sysctl.conf文件
[root@rs1 ~]#echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
[root@rs1 ~]#echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
[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 ~]#ifconfig lo:1 10.0.0.100/32
[root@rs1 ~]#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 10.0.0.100/0 scope global lo:1
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 pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:96:02:6f brd ff:ff:ff:ff:ff:ff
inet 10.0.0.7/24 brd 10.0.0.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe96:26f/64 scope link
valid_lft forever preferred_lft forever
#RS2的IPVS配置
[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
[root@rs2 ~]#ifconfig lo:1 10.0.0.100/32
[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 10.0.0.100/0 scope global lo:1
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 pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:b3:54:59 brd ff:ff:ff:ff:ff:ff
inet 10.0.0.17/24 brd 10.0.0.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:feb3:5459/64 scope link
valid_lft forever preferred_lft forever
4.2.3 LVS主机的配置
#在LVS上添加VIP
[root@lvs ~]#ifconfig lo:1 10.0.0.100/32
[root@lvs ~]#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 10.0.0.100/0 scope global lo:1
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 fq_codel state UP group default qlen 1000
link/ether 00:0c:29:39:57:a5 brd ff:ff:ff:ff:ff:ff
altname enp3s0
altname ens160
inet 10.0.0.8/24 brd 10.0.0.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe39:57a5/64 scope link
valid_lft forever preferred_lft forever
#实现LVS 规则
[root@lvs ~]#dnf -y install ipvsadm
[root@lvs ~]#ipvsadm -A -t 10.0.0.100:80 -s rr
[root@lvs ~]#ipvsadm -a -t 10.0.0.100:80 -r 10.0.0.7:80 -g
[root@lvs ~]#ipvsadm -a -t 10.0.0.100:80 -r 10.0.0.17:80 -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 10.0.0.100:80 rr
-> 10.0.0.7:80 Route 1 0 0
-> 10.0.0.17:80 Route 1 0 0
4.2.4 测试访问
[root@internet ~]#curl 10.0.0.100
10.0.0.17
[root@internet ~]#curl 10.0.0.100
10.0.0.7
[root@rs1 ~]#tail -f /var/log/httpd/access_log -n0
192.168.10.6 - - [11/Oct/2023:09:42:13 -0400] "GET / HTTP/1.1" 200 10 "-" "curl/7.61.1"
下方截图标记处可以看到TCP三次握手中第一次握手的SYN和第三次握手的ACK报文均有两次,可以证明只要是请求报文都会经过lvs,响应报文不需要经过lvs服务器
4.2.5 思考
4.2.5.1 LVS的eth0的网关可否不配置?如果随便配置,发现什么问题?如果不配置,怎么解决?
LVS服务器没有网关的情况下,默认会做反向地址检测,发现请求源地址和LVS不在同一网段,所以没法通讯,从而导致收到数据包不进行转发。只要LVS服务器配置网关都可正常转发到后端。以下修改rp_filter内核参数可关闭反向地址检查
#默认值为1
[root@centos8 ~]#cat /proc/sys/net/ipv4/conf/all/rp_filter
1
#修改内核参数为0
[root@lvs ~]#echo "0" > /proc/sys/net/ipv4/conf/all/rp_filter
#说明:参数rp_filter用来控制系统是否开启对数据包源地址的校验。
#0标示不开启地址校验
#1表开启严格的反向路径校验。对每一个收到的数据包,校验其反向路径是否是最佳路径。如果反向路径不是最佳路径,则直接丢弃该数据包;
#2表示开启松散的反向路径校验,对每个收到的数据包,校验其源地址是否可以到达,即反向路径是否可以ping通,如反向路径不通,则直接丢弃该数据包
4.2.5.2 LVS的VIP可以配置到lo网卡,但必须使用32位的netmask,为什么?
在LVS的DR(Direct Routing)模式下,VIP(Virtual IP)绑定在回环网卡上,并且可以配置不同的IP掩码(子网掩码)来影响其行为。下面是24位和32位掩码的区别:
-
24位掩码:当将VIP配置为10.0.0.100/24时,24位掩码表示使用24位来标识网络部分和主机部分。在这种情况下,VIP被认为是本地网络的一部分,不会被路由器转发到物理网络。其他设备在物理网络上无法直接访问VIP,只有本地主机上的进程或服务可以访问VIP。
-
32位掩码:当将VIP配置为10.0.0.100/32时,32位掩码表示只有该具体的IP地址被视为有效。在这种情况下,VIP不会被视为本地网络的一部分,而是一个独立的IP地址。其他设备在物理网络上可以通过路由器将数据包传递给VIP,使其可达。这允许其他设备直接访问VIP,而不仅仅限于本地主机上的进程或服务。
因此,配置为24位掩码的VIP将被视为本地网络的一部分,只能通过本地主机访问。而配置为32位掩码的VIP将在物理网络中可达,其他设备可以直接访问。选择合适的掩码取决于您的网络需求和配置。
VIP配置为非32位掩码,假设掩码是24位的情况下,意味着只要是10网段24位的掩码都认为是回环网卡,与10.0.0.0/24网段的网络就不通了。
可参考下方截图,192.16.10.6上ping10.0.0.200,通过默认路由找192.168.10.200网关发出,可以看到10.0.0.200和192.168.10.200为一台机器,正常情况下是可以通信的,由于回环网卡配置的24位掩码,所以在访问10.0.0.200时都是在回环网卡上发生的,ping该网段任意不存在的ip都是在回环网卡上产生的,通过在10.0.0.200抓包也未能成功抓取到数据。当回环网卡配置掩码位32位时,表示只有10.0.0.2这个ip在回环网卡上有效,在192.16.10.6上ping10.0.0.200,通过10.0.0.200抓包可以正常收到报文并回应。
范例:
环境:五台主机
一台:客户端 172.20.200.6/16 GW:172.20.200.200
一台:ROUTER
eth0 :NAT 10.0.0.200/24 VIP
eth1: 桥接 172.20.200.200/16
启用 IP_FORWARD
一台:LVS
eth0: 10.0.0.8/24 GW:10.0.0.200
两台RS:
RS1:10.0.0.7/24 GW:10.0.0.200
RS2:10.0.0.17/24 GW:10.0.0.200
配置:
[root@client ~]#cat /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
NAME=eth0
BOOTPROTO=static
IPADDR=172.20.200.6
PREFIX=16
GATEWAY=172.20.200.200
ONBOOT=yes
[root@Router ~]#cat /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
NAME=eth0
BOOTPROTO=static
IPADDR=10.0.0.200
PREFIX=24
ONBOOT=yes
[root@Router ~]#cat /etc/sysconfig/network-scripts/ifcfg-eth1
DEVICE=eth1
NAME=eth1
BOOTPROTO=static
IPADDR=172.20.200.200
PREFIX=16
ONBOOT=yes
[root@Router ~]#cat /etc/sysctl.conf
net.ipv4.ip_forward=1
[root@Router ~]#sysctl -p
[root@rs1 ~]#cat /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
NAME=eth0
BOOTPROTO=static
IPADDR=10.0.0.7
PREFIX=24
GATEWAY=10.0.0.200
ONBOOT=yes
[root@rs1 ~]#echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
[root@rs1 ~]#echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
[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 ~]#ifconfig lo:1 10.0.0.100/32
[root@rs2 ~]#cat /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
NAME=eth0
BOOTPROTO=static
IPADDR=10.0.0.17
PREFIX=24
GATEWAY=10.0.0.200
ONBOOT=yes
[root@rs2 ~]#echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
[root@rs2 ~]#echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
[root@rs2 ~]#echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
[root@rs2 ~]#echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
[root@rs2 ~]#ifconfig lo:1 10.0.0.100/32
[root@LVS ~]#cat /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
NAME=eth0
BOOTPROTO=static
IPADDR=10.0.0.8
PREFIX=24
GATEWAY=10.0.0.200
ONBOOT=yes
[root@LVS ~]#ifconfig lo:1 10.0.0.100/32
[root@LVS ~]#ipvsadm -A -t 10.0.0.100:80 -s wrr
[root@LVS ~]#ipvsadm -a -t 10.0.0.100:80 -r 10.0.0.7 -g -w 3
[root@LVS ~]#ipvsadm -a -t 10.0.0.100:80 -r 10.0.0.17 -g
4.3 LVS-DR模式多网段案例
单网段的DR模式容易暴露后端RS服务器地址信息,可以使用跨网段的DR模型,实现更高的安全性
范例:
#internet主机的网络配置和4.2一样
[root@internet ~]#hostname -I
192.168.10.6
#router的网络配置在4.2基础上添加172.16.0.200/24的地址
[root@router ~]#ip addr add 172.16.0.200/24 dev eth0
[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 fq_codel state UP group default qlen 1000
link/ether 00:0c:29:a7:56:a6 brd ff:ff:ff:ff:ff:ff
altname enp3s0
altname ens160
inet 10.0.0.200/24 brd 10.0.0.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet 172.16.0.200/24 brd 172.16.0.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fea7:56a6/64 scope link
valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:a7:56:b0 brd ff:ff:ff:ff:ff:ff
altname enp19s0
altname ens224
inet 192.168.10.200/24 brd 192.168.10.255 scope global noprefixroute eth1
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fea7:56b0/64 scope link
valid_lft forever preferred_lft forever
[root@router ~]#hostname -I
10.0.0.200 172.16.0.200 192.168.10.200
#LVS主机的网络配置和4.2一样
[root@lvs ~]#hostname -I
10.0.0.8
[root@lvs ~]#route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.0.0.2 0.0.0.0 UG 100 0 0 eth0
10.0.0.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0
#RS主机的网络配置和4.2一样
[root@rs1~]#hostname -I
10.0.0.7
[root@rs1~]#route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.0.0.200 0.0.0.0 UG 100 0 0 eth0
10.0.0.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0
[root@rs2 ~]#hostname -I
10.0.0.17
[root@rs2 ~]#route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.0.0.200 0.0.0.0 UG 100 0 0 eth0
10.0.0.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0
#在LVS主机运行的脚本
#注意:VIP如果配置在LO网卡上,必须使用32bit子网掩码,如果VIP绑定在eth0上,可以是其它netmask
[root@lvs ~]#cat lvs_dr_vs.sh
#!/bin/bash
#Author:douxijie
#Date:2023-08-13
vip='172.16.0.100'
iface='lo:1'
mask='255.255.255.255'
port='80'
rs1='10.0.0.7'
rs2='10.0.0.17'
scheduler='wrr'
type='-g'
rpm -q ipvsadm &> /dev/null || yum -y install ipvsadm &> /dev/null
case $1 in
start)
ifconfig $iface $vip netmask $mask #broadcast $vip up
iptables -F
ipvsadm -A -t ${vip}:${port} -s $scheduler
ipvsadm -a -t ${vip}:${port} -r ${rs1} $type -w 1
ipvsadm -a -t ${vip}:${port} -r ${rs2} $type -w 1
echo "The VS Server is Ready!"
;;
stop)
ipvsadm -C #清除lvs规则
ifconfig $iface down #删除lo:1的ip
echo "The VS Server is Canceled!"
;;
*)
echo "Usage: $(basename $0) start|stop" #$(basename $0)只提取当前脚本文件名不包括路径,如果写$0则包括路径
exit 1
;;
esac
[root@lvs ~]#bash lvs_dr_vs.sh start
The VS Server is Ready!
#在RS后端服务器运行的脚本
[root@rs1 ~]#cat lvs_dr_rs.sh
#!/bin/bash
#Author:douxijie
#Date:2023-08-13
vip=172.16.0.100
mask='255.255.255.255'
dev=lo:1
case $1 in
start)
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
ifconfig $dev $vip netmask $mask
echo "The RS Server is Ready!"
;;
stop)
ifconfig $dev down
echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 0 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce
echo 0 > /proc/sys/net/ipv4/conf/lo/arp_announce
echo "The RS Server is Canceled!"
;;
*)
echo "Usage: $(basename $0) start|stop"
exit 1
;;
esac
[root@rs1 ~]#bash lvs_dr_rs.sh start
The RS Server is Ready!
#在RS2后端服务器运行的脚本和RS1是一样的
[root@rs2 ~]#bash lvs_dr_rs.sh start
The RS Server is Ready!
#测试访问
[root@internet ~]#curl 172.16.0.100
10.0.0.7
[root@internet ~]#curl 172.16.0.100
10.0.0.17
范例2
RS 的配置脚本
#!/bin/bash
vip=10.0.0.100
mask='255.255.255.255'
dev=lo:1
case $1 in
start)
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
ifconfig $dev $vip netmask $mask
echo "The RS Server is Ready!"
;;
stop)
ifconfig $dev down
echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 0 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce
echo 0 > /proc/sys/net/ipv4/conf/lo/arp_announce
echo "The RS Server is Canceled!"
;;
*)
echo "Usage: $(basename $0) start|stop"
exit 1
;;
esac
VS的配置脚本
#!/bin/bash
vip='10.0.0.100'
iface='lo:1'
mask='255.255.255.255'
port='80'
rs1='192.168.8.101'
rs2='192.168.8.102'
scheduler='wrr'
type='-g'
rpm -q ipvsadm &> /dev/null || yum -y install ipvsadm &> /dev/null
case $1 in
start)
ifconfig $iface $vip netmask $mask #broadcast $vip up
iptables -F
ipvsadm -A -t ${vip}:${port} -s $scheduler
ipvsadm -a -t ${vip}:${port} -r ${rs1} $type -w 1
ipvsadm -a -t ${vip}:${port} -r ${rs2} $type -w 1
echo "The VS Server is Ready!"
;;
stop)
ipvsadm -C
ifconfig $iface down
echo "The VS Server is Canceled!"
;;
*)
echo "Usage: $(basename $0) start|stop"
exit 1
;;
esac
范例3: 跨网段DR模型案例
配置
[root@rs1 ~]#cat lvs_dr_rs.sh
#!/bin/bash
#Author:douxijie
#Date:2023-08-13
vip=192.168.0.100
mask='255.255.255.255'
dev=lo:1
#rpm -q httpd &> /dev/null || yum -y install httpd &>/dev/null
#service httpd start &> /dev/null && echo "The httpd Server is Ready!"
#echo "<h1>`hostname`</h1>" > /var/www/html/index.html
case $1 in
start)
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
ifconfig $dev $vip netmask $mask #broadcast $vip up
#route add -host $vip dev $dev
echo "The RS Server is Ready!"
;;
stop)
ifconfig $dev down
echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 0 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce
echo 0 > /proc/sys/net/ipv4/conf/lo/arp_announce
echo "The RS Server is Canceled!"
;;
*)
echo "Usage: $(basename $0) start|stop"
exit 1
;;
esac
[root@rs1 ~]#bash lvs_dr_rs.sh start
[root@rs2 ~]#bash lvs_dr_rs.sh start
[root@LVS ~]#cat lvs_dr_vs.sh
#!/bin/bash
#Author:douxijie
#Date:2023-08-13
vip='192.168.0.100'
iface='lo:1'
mask='255.255.255.255'
port='80'
rs1='10.0.0.7'
rs2='10.0.0.17'
scheduler='wrr'
type='-g'
rpm -q ipvsadm &> /dev/null || yum -y install ipvsadm &> /dev/null
case $1 in
start)
ifconfig $iface $vip netmask $mask #broadcast $vip up
iptables -F
ipvsadm -A -t ${vip}:${port} -s $scheduler
ipvsadm -a -t ${vip}:${port} -r ${rs1} $type -w 1
ipvsadm -a -t ${vip}:${port} -r ${rs2} $type -w 1
echo "The VS Server is Ready!"
;;
stop)
ipvsadm -C
ifconfig $iface down
echo "The VS Server is Canceled!"
;;
*)
echo "Usage: $(basename $0) start|stop"
exit 1
;;
esac
[root@LVS ~]#bash lvs_dr_vs.sh start
s
[root@Router ~]#nmcli connection modify eth0 +ipv4.addresses 192.168.0.200/24
[root@Router ~]#nmcli connection reload
[root@Router ~]#nmcli connection up eth0
4.4 LVS-TUNNEL隧道模式案例
4.4.1 LVS服务器配置
[root@lvs ~]#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 fq_codel state UP group default qlen 1000
link/ether 00:0c:29:39:57:a5 brd ff:ff:ff:ff:ff:ff
altname enp3s0
altname ens160
inet 10.0.0.8/24 brd 10.0.0.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe39:57a5/64 scope link tentative
valid_lft forever preferred_lft forever
#开启tunnel网卡并配置VIP
[root@lvs ~]#ifconfig tunl0 10.0.0.100 netmask 255.255.255.255 up
#或者下面方法,注意设备名必须为tunl0
[root@lvs ~]#ip addr add 10.0.0.100/32 dev tunl0
[root@lvs ~]#ip link set up tunl0
#自动加载ipip模块
[root@lvs ~]#lsmod |grep ipip
ipip 16384 0
tunnel4 16384 1 ipip
ip_tunnel 28672 1 ipip
[root@lvs ~]#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 fq_codel state UP group default qlen 1000
link/ether 00:0c:29:39:57:a5 brd ff:ff:ff:ff:ff:ff
altname enp3s0
altname ens160
inet 10.0.0.8/24 brd 10.0.0.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe39:57a5/64 scope link
valid_lft forever preferred_lft forever
3: tunl0@NONE: <NOARP,UP,LOWER_UP> mtu 1480 qdisc noqueue state UNKNOWN group default qlen 1000
link/ipip 0.0.0.0 brd 0.0.0.0
inet 10.0.0.100/32 scope global tunl0
valid_lft forever preferred_lft forever
[root@lvs ~]#yum -y install ipvsadm
[root@lvs ~]#ipvsadm -A -t 10.0.0.100:80 -s rr
[root@lvs ~]#ipvsadm -a -t 10.0.0.100:80 -r 10.0.0.7 -i
[root@lvs ~]#ipvsadm -a -t 10.0.0.100:80 -r 10.0.0.17 -i
[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 10.0.0.100:80 rr
-> 10.0.0.7:80 Tunnel 1 0 0
-> 10.0.0.17:80 Tunnel 1 0 0
4.4.2 RS服务器配置
#RS服务器配置,RS1和RS2配置相同
[root@rs1 ~]#hostname
rs1
[root@rs1 ~]#hostname -I
10.0.0.7
[root@rs1 ~]#route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.0.0.200 0.0.0.0 UG 100 0 0 eth0
10.0.0.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0
#开启tunnel网卡并配置VIP
[root@rs1 ~]#ifconfig tunl0 10.0.0.100 netmask 255.255.255.255 up
[root@rs1 ~]#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 pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:96:02:6f brd ff:ff:ff:ff:ff:ff
inet 10.0.0.7/24 brd 10.0.0.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe96:26f/64 scope link
valid_lft forever preferred_lft forever
3: tunl0@NONE: <NOARP,UP,LOWER_UP> mtu 1480 qdisc noqueue state UNKNOWN group default qlen 1000
link/ipip 0.0.0.0 brd 0.0.0.0
inet 10.0.0.100/32 scope global tunl0
valid_lft forever preferred_lft forever
#修改内核参数,由于本实验lvs和rs中间是交换机,也会产生arp冲突所以还需要修改内核参数,生产中路由器的情况下不需要加
[root@rs1 ~]#echo "1" > /proc/sys/net/ipv4/conf/tunl0/arp_ignore
[root@rs1 ~]#echo "2" > /proc/sys/net/ipv4/conf/tunl0/arp_announce
[root@rs1 ~]#echo "1" > /proc/sys/net/ipv4/conf/all/arp_ignore
[root@rs1 ~]#echo "2" > /proc/sys/net/ipv4/conf/all/arp_announce
#以下参数用来控制系统是否开启对数据包源地址的校验。0标示不开启地址校验;1表开启严格的反向路径校验。对每一个进行的数据包,校验其反向路径是否是最佳路径。如果反向路径不是最佳路径,则直接丢弃该数据包;2标示开启松散的反向路径校验,对每个进行的数据包,校验其源地址是否可以到达,即反向路径是否可以ping通,如反向路径不通,则直接丢弃该数据包。
#默认值为1
[root@rs1 ~]#cat /proc/sys/net/ipv4/conf/all/rp_filter
ip
[root@rs1 ~]#echo "0" > /proc/sys/net/ipv4/conf/tunl0/rp_filter
[root@rs1 ~]#echo "0" > /proc/sys/net/ipv4/conf/all/rp_filter
[root@rs1 ~]#yum -y install httpd
[root@rs1 ~]#systemctl enable --now httpd
[root@rs1 ~]#hostname > /var/www/html/index.html
4.4.3 测试
[root@internet ~]#while :;do curl 10.0.0.100;sleep 0.3;done
rs2.magedu.org
rs1.magedu.org
rs2.magedu.org
rs1.magedu.org
通过上方抓包截图可以看到LVS往RS上转发的包有两个ip头,可以看到外层的ip头协议为ipip协议。RS接收时拆开外层头可以发现有用户请求到VIP,回应时使用VIP回应客户端
5. LVS 高可用性实现
LVS 不可用时:
Director不可用,整个系统将不可用;SPoF Single Point of Failure
解决方案:高可用,keepalived、heartbeat/corosync
RS 不可用时:
某RS不可用时,Director依然会调度请求至此RS
解决方案: 由Director对各RS健康状态进行检查,失败时禁用,成功时启用
常用解决方案:
- keepalived
- heartbeat/corosync
- ldirectord
检测方式:
- 网络层检测,icmp
- 传输层检测,端口探测
- 应用层检测,请求某关键资源
RS全不用时:backup server, sorry server
6. 常见面试题
- Linux 集群有哪些
- LVS的工作模式有哪些,有什么特点
- LVS的调度算法
- LVS和nginx,haproxy的区别