【002】集群学习笔记-LVS-NAT,LVS-DR,持久性连接(实验)

1 IP负载均衡

在网络层通过修改请求目标地址进行负载均衡

用户请求数据包到达负载均衡服务器后,负载均衡服务器在操作系统内核进程获取网络数据包,根据负载均衡算法计算到一台真实web服务器,然后将数据目的ip地址修改成这台真实web的ip,不需通过用户进程处理。真实web应用服务器处理完成后,响应数据包回到负载均衡服务器,负载均衡服务器再将数据包源地址修改为自身的ip发送给用户浏览器

IP负载均衡在内核进程完成数据分支,较反向代理负载均衡(在应用程序中分发数据)有更好的处理性能。但是由于所有请求响应都需要经过负载均衡服务器,集群的最大响应数据吞吐量不得不受制于负载均衡服务器网卡带宽,对于提供下载服务或者视频服务等需要传输大量数据的网站而言,难以满足需求。

能不能让负载均衡服务器只分发请求,而使响应数据从正式物理服务器直接返回给用户呢?数据链路层负载均衡

1.1 LVS-NAT

原理

在这里插入图片描述

  1. 当用户请求到达Director Server,,时请求的数据报文会先到内核空间的PREROUTING链。 此时报文的源IP为CIP,目标IP为VIP
  2. PREROUTING检查发现数据包的目标IP是本机,将数据包送至INPUT链
  3. IPVS比对数据包请求的服务是否为集群服务,若是,修改数据包的目标IP地址为后端服务器IP,然后将数据包发至POSTROUTING链。 此时报文的源IP为CIP,目标IP为RIP
  4. POSTROUTING链通过选路,将数据包发送给Real Server
  5. Real Server比对发现目标为自己的IP,开始构建响应报文发回给Director Server。 此时报文的源IP为RIP,目标IP为CIP
  6. Director Server在响应客户端前,此时会将源IP地址修改为自己的VIP地址,然后响应给客户端。 此时报文的源IP为VIP,目标IP为CIP

LVS-NAT模型的特性

  1. RS应该使用私有地址,RS的网关必须指向DIP
  2. DIP和RIP必须在同一个网段内
  3. 请求和响应报文都需要经过Director Server,高负载场景中,Director Server易成为性能瓶颈
  4. 支持端口映射
  5. RS可以使用任意操作系统
  6. 缺陷:对Director Server压力会比较大,请求和响应都需经过director server

1.2 LVS-NAT实验

  1. 准备四台虚拟机

外网ip的客户机
client:180.15.100.100
在这里插入图片描述

有内外网ip的LVS
lvs:

  • 180.15.16.17
  • 192.168.23.11
    在这里插入图片描述

两台real server
rs1:192.168.23.12
在这里插入图片描述

rs2:192.168.23.13
在这里插入图片描述

  1. 在两台real server 安装apache并输入如下,并添加LVS的网关
[root@rs1 ~]# yum -y install httpd
[root@rs1 ~]# echo web1 > /var/www/html/index.html
[root@rs1 ~]# route add default gw 192.168.23.11
[root@rs2 ~]# yum -y install httpd
[root@rs2 ~]# echo web2 > /var/www/html/index.html
[root@rs2 ~]# route add default gw 192.168.23.11

不要忘了开启httpd并且
echo web1 /var/www/html/index.html
echo web2 /var/www/html/index.html

  1. LVS端curl测试发现连接成功后开启路由转换
[root@lvs ~]# curl 192.168.23.12
web1
[root@lvs ~]# curl 192.168.23.13
web2
  1. LVS端永久开启路由转换并验证成功
# 更改配置文件
vim /etc/sysctl.conf

在这里插入图片描述

# 验证路由转换是否开启
[root@lvs ~]# cat /proc/sys/net/ipv4/ip_forward
1
  1. LVS端安装ipvsadm
[root@lvs ~]# yum -y install ipvsadm
  1. 添加一台虚拟服务器到IP(180.15.16.17:80),将调度算法(-s)设置为轮叫调度(rr)
[root@lvs ~]# ipvsadm -A -t 180.15.16.17:80 -s rr

# -A  --add-service 在内核的虚拟服务器表中添加一条新的虚拟服务器记录。也就是增加一台新的虚拟服务器
# -t --tcp-service service-address 说明虚拟服务器提供的是tcp 的服务[vip:port] or [real-server-ip:port]
# -s --scheduler scheduler 使用的调度算法,有这样几个选项 rr|wrr|lc|wlc|lblc|lblcr|dh|sh|sed|nq,默认的调度算法是: wlc.
# rr 轮叫调度(Round Robin)(简称rr),调度器通过“轮叫”调度算法将外部请求按顺序轮流分配到集群中的真实服务器

[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  180.15.16.17:80 rr

# -L  --list 显示内核虚拟服务器表
# -n  --numeric  输出IP地址和端口的数字形式
  1. 在内核虚拟服务器里添加两台真实服务器rs1,rs2,并设置为NAT模式(-M)
[root@lvs ~]# ipvsadm -a -t 180.15.16.17:80 -r 192.168.23.12:80 -m
[root@lvs ~]# ipvsadm -a -t 180.15.16.17:80 -r 192.168.23.13:80 -m

# -a  --add-server 在内核虚拟服务器表的一条记录里添加一条新的真实服务器记录。也就是在一个虚拟服务器中增加一台新的真实服务器
# -r --real-server server-address 真实的服务器[Real-Server:port]
# -m --masquerading 指定LVS 的工作模式为NAT 模式
  1. 验证发现rs1与rs2成功添加到虚拟服务器180.15.16.17:80
[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  180.15.16.17:80 rr
  -> 192.168.23.12:80             Masq    1      0          0
  -> 192.168.23.13:80             Masq    1      0          0
  1. 通过client端多次curl验证轮叫有效
    在这里插入图片描述

2 数据链路层负载均衡

2.1 LVS-DR

原理

在这里插入图片描述

  1. 当用户请求到达Director Server,,时请求的数据报文会先到内核空间的PREROUTING链。 此时报文的源IP为CIP,目标IP为VIP

  2. PREROUTING检查发现数据包的目标IP是本机,将数据包送至INPUT链

  3. IPVS比对数据包请求的服务是否为集群服务,若是,将请求报文中的源MAC地址修改为DIP的MAC地址,将目标MAC地址修改RIP的MAC地址,然后将数据包发至POSTROUTING链。 此时的源IP和目的IP均未修改,仅修改了源MAC地址为DIP的MAC地址,目标MAC地址为RIP的MAC地址

  4. 由于DS和RS在同一个网络中,所以是通过二层来传输。POSTROUTING链检查目标MAC地址为RIP的MAC地址,那么此时数据包将会发至Real Server。

  5. RS发现请求报文的MAC地址是自己的MAC地址,就接收此报文。处理完成之后,将响应报文通过lo接口传送给eth0网卡然后向外发出。 此时的源IP地址为VIP,目标IP为CIP

  6. 响应报文最终送达至客户端

LVS-DR模型的特性

  1. 保证前端路由将目标地址为VIP报文统统发给Director Server,而不是RS
  2. RS可以使用私有地址;也可以是公网地址,如果使用公网地址,此时可以通过互联网对RIP进行直接访问
  3. RS跟Director Server必须在同一个物理网络中
  4. 所有的请求报文经由Director Server,但响应报文必须不能进过Director Server
  5. 不支持地址转换,也不支持端口映射
  6. RS可以是大多数常见的操作系统
  7. RS的网关绝不允许指向DIP(因为我们不允许他经过director)
  8. RS上的lo接口配置VIP的IP地址

过程及解决方案:

  1. 客户端要找vip访问80端口,因为是在同一个网段,所以发arp广播找vip的mac地址通信
  2. 因为有RS上也有vip,我们不能直接让RS上的vip回应客户端的广播,所以设置内核参数arp_ignore的内容为1
    将arp_ignore 设置为1,意味着当别人的arp请求过来的时候,如果接收的设备上面没有这个ip,就不做出响应.
    默认是0,只要这台机器上面任何一个设备上面有这个ip,就响应arp请求,并发送mac地址
  3. 当DR的vip收到这个广播之后,回应mac地址,然后得到客户端发来的80端口请求,再通过lvs分发到一个RS
  4. 那么DR如何分发到一个RS?
    dip发出arp广播询问RS的ip地址所对应的mac地址,然后发出一个目标ip为RS_vip,目标mac为RS_eth0_mac的包到RS
  5. RS必须要使用vip把回应包发出去(这样client收到之后一看源地址是vip,他就会相信这是正确的地址发来的包)
  6. 那么怎样让RS使用lo的vip而不使用eth0?
    设置arp_announce文件的内容为2, 2的意思是使用本机最好的本地IP地址把回应包发出去
  7. 最后怎么算是最好的本地IP地址?
    同一个网段下,使用可变长度子网掩码最长的IP地址被认为是好IP,因为他更精确

2.2 LVS-DR实验

  1. 准备4台机器

client

  • CIP: 192.168.10.10

lvs

  • VIP: 192.168.23.100
  • DIP: 192.168.23.11

rs1

  • VIP:192.168.23.100
  • RIP:192.168.23.12

rs2

  • VIP: 192.168.23.100
  • RIP: 192.168.23.13

不要忘了开启httpd并且
echo web1 /var/www/html/index.html
echo web2 /var/www/html/index.html

  1. 在rs1 与 rs2上将VIP配置到lo上(lo网卡不能做收发)
[root@rs1 network-scripts]# ifconfig lo:0 192.168.23.100 netmask 255.255.255.255      

在这里插入图片描述

[root@rs2 network-scripts]# ifconfig lo:0 192.168.23.100 netmask 255.255.255.255   

在这里插入图片描述
3. 为了让两台real server不响应客户端访问vip的请求,我们修改如下内核参数:

[root@rs1 network-scripts]# echo 1 >/proc/sys/net/ipv4/conf/all/arp_ignore

# 不要响应客户端访问请求

[root@rs1 network-scripts]# echo 2 >/proc/sys/net/ipv4/conf/all/arp_announce

# 设置arp_announce文件的内容为2, 2的意思是使用本机最好的本地IP地址把回应包发出去
  1. 在rs2做同样操作
[root@rs2 ~]# echo 1 >/proc/sys/net/ipv4/conf/all/arp_ignore
[root@rs2 ~]# echo 2 >/proc/sys/net/ipv4/conf/all/arp_announce
  1. 在lvs端,当我们客户端收到请求之后,我们要用DIP发送给Real Server(上面原理图中第三步),配置ipvsadm
[root@lvs ~]# ipvsadm -A -t 192.168.23.100:80 -s rr
[root@lvs ~]# ipvsadm -a -t 192.168.23.100:80 -r 192.168.23.12:80
[root@lvs ~]# ipvsadm -a -t 192.168.23.100:80 -r 192.168.23.13:80
[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.23.100:80 rr
  -> 192.168.23.12:80             Route   1      0          0
  -> 192.168.23.13:80             Route   1      0          0
  1. 使用client端访问lvs验证
[root@client ~]# curl 192.168.23.100
  1. 在lvs端验证,发现只有InPkts没有OutPks,OutBytes等于0(不响应客户端),与LVS-NAT形成对比
    在这里插入图片描述

3 持久性链接

3.1 简介

持久连接是什么?

在LVS中,持久连接是为了用来保证当来自同一个用户的请求时能够定位到同一台服务器。

为什么会用到持久连接?

  1. cookie/session机制的简单说明:

    在Web服务通信中,HTTP本身是无状态协议,不能标识用户来源,此时出现了一个问题,当用户在一个网站浏览了A网页并跳转到B网页,此时服务器就认为B网页是一个新的用户请求,你之前的登陆的信息就都丢失了,头疼。为了记录用户的会话信息,我们的开发者就在客户端/服务器端软件提供了cookie/session机制,当你访问网站时,服务器端建立一个session会话区,并建立一个cookie与这个session绑定,将信息发送给你的浏览器。这样,只要你的cookie存在,服务器端的session存在,那么当你打开新页面的时候,服务器依然会认识你!

  2. cookie/session由负载均衡导致的问题:

    上面说服务器需要靠session/cookie来标记用户的会话,这没什么问题。不过,当你在做了负载均衡的时候,就出现了问题。

我们依然假设一个场景:某电商网站为了实现更多用户的访问,提供了A、B两台服务器,并在前面做了LVS负载均衡。于是某用户打开了某购物网站,选中了一件衣服,并加入了购物车(此时背后的操作是:LVS负载均衡器接受了用户请求,并将其分发到了选中的服务器,并将用户添加了一件衣服记录到这个会话的session中)。这时当用户打开了第二个网页,又选中了一件帽子并加入购物车(此时背后的操作是:LVS负载均衡器接受了用户请求,进行计算,将其发送到选中的服务器上,该服务器将用户添加了一件帽子记录到session中)。
到现在可能各位已经发现问题了,由于LVS是一个四层负载均衡器,仅能根据IP:Port对数据报文进行分发,不能确保将同一用户根据session发往同一个服务器,也就是用户第一次被分配到了A服务器,而第二次可能分配到了B服务器,但是B服务器并没有A服务器用户的session记录,直接导致这个例子里的用户发现自己的购物车没有了之前的衣服,而仅有帽子。这是不可接受的。为了避免上面的问题,生产环境中一般有三种方案:

  1. 将来自于同一个用户的请求发往同一个服务器
  2. 将session信息在服务器集群内共享,每个服务器都保存整个集群的session信息
  3. 建立一个session存储池,所有session信息都保存到存储池中

显然,第一种方案是最简单,也是最节约资源的,而持久连接和sh算法就是实现第一种方案的两种方式。由于sh的应用并不是太多,我们仅仅介绍一下其和持久连接的区别,其他的就不讲述了,有兴趣的朋友可以自行查找资料。

LVS的hash算法和持久连接:

hash算法全称为source hash(源地址hash),它和持久连接的作用都是"将来自同一个IP的请求都转发到同一个Server",从而保证了session会话定位的问题。两者的不同是:

  • hash算法:使用hash算法,hash算法在内核中会自动维护一个哈希表,此哈希表中用每一个请求的源IP地址经过哈希计算得出的值作为键,把请求所到达的RS的地址作为值。在后面的请求中,每一个请求会先经过此哈希表,如果请求在此哈希表中有键值,那么直接定向至特定RS,如没有,则会新生成一个键值,以便后续请求的定向。但是此种方法在时间的记录上比较模糊(依据TCP的连接时长计算),而且其是算法本身,所以无法与算法分离,并不是特别理想的方法。
  • 持久连接:此种方法实现了无论使用哪一种调度方法,持久连接功能都能保证在指定时间范围之内,来自于同一个IP的请求将始终被定向至同一个RS,还可以把多种服务绑定后统一进行调度。
    详细一点说:当用户请求到达director时。无论使用什么调度方法,都可以实现对同一个服务的请求在指定时间范围内始终定向为同一个RS。在director内有一个LVS持久连接模板,模板中记录了每一个请求的来源、调度至的RS、维护时长等等,所以,在新的请求进入时,首先在此模板中检查是否有记录(有内置的时间限制,比如限制是300秒,当在到达300秒时依然有用户访问,那么持久连接模板就会将时间增加两分钟,再计数,依次类推,每次只延长2分钟),如果该记录未超时,则使用该记录所指向的RS,如果是超时记录或者是新请求,则会根据调度算法先调度至特定RS,再将调度的记录添加至此表中。这并不与SH算法冲突,lvs持久连接会在新请求达到时,检查后端RS的负载状况,这就是比较精细的调度和会话保持方法。

LVS的三种持久连接方式:

  • PCC:每客户端持久;将来自于同一个客户端的所有请求统统定向至此前选定的RS;也就是只要IP相同,分配的服务器始终相同。
  • PPC:每端口持久;将来自于同一个客户端对同一个服务(端口)的请求,始终定向至此前选定的RS。例如:来自同一个IP的用户第一次访问集群的80端口分配到A服务器,25号端口分配到B服务器。当之后这个用户继续访问80端口仍然分配到A服务器,25号端口仍然分配到B服务器。
  • PFMC:持久防火墙标记连接;将来自于同一客户端对指定服务(端口)的请求,始终定向至此选定的RS;不过它可以将两个毫不相干的端口定义为一个集群服务,例如:合并http的80端口和https的443端口定义为同一个集群服务,当用户第一次访问80端口分配到A服务器,第二次访问443端口时仍然分配到A服务器。

定义LVS持久连接:

LVS的持久连接功能需要定义在集群服务上面,使用-p timeout选项。

  1. 定义PCC:
# ipvsadm -A -t 192.168.1.200:0 -s wrr -p 600
# ipvsadm -a -t 192.168.1.200:0 -r 192.168.1.10 -g -w 2
# ipvsadm -a -t 192.168.1.200:0 -r 192.168.1.20 -g -w 1
  1. 定义PPC:
# ipvsadm -A -t 192.168.10.100:80 -s rr -p 300
  1. 定义PFMC:
# iptables -t mangle -A PREROUTING -d 192.168.1.200 -i eth0 -p tcp --dport 80 -j MARK --set-mark 3
# iptables -t mangle -A PREROUTING -d 192.168.1.200 -i eth0 -p tcp --dport 443 -j MARK --set-mark 3
# ipvsadm -A -f 3 -s wrr -p 600
# ipvsadm -a -f 3 -r 192.168.1.10 -g -w 2
# ipvsadm -a -f 3 -r 192.168.1.20 -g -w 1

3.2 持久性连接实验

(待完善)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值