暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

负载均衡——LVS DR模式

运维家 2022-06-22
1142
背景

相比于nginx
只能用于7层负载均衡,LVS
就比较强大了,能在4层做负载均衡。而且性能和稳定性上LVS
也比较占优,毕竟是合入内核模块,不稳定肯定不行。

关于LVS

LVS
通过工作于内核的ipvs
模块来实现功能,其主要工作于netfilter
INPUT
链上。除此之外,还需要一个用户态工具,ipvdadm
,用于用户负载集群定义和集群服务管理。

1、核心组件

LVS的管理工具和内核模块 ipvsadm/ipvs

ipvsadm
:用户空间的命令行工具,用于管理集群服务及集群服务上的RS
等;

ipvs
:工作于内核上的程序,可根据用户定义的集群实现请求转发;

2、专业术语

VS
Virtual Server
                       #虚拟服务

Director, Balancer
                        #负载均衡器、分发器

RS
Real Server
                              #后端请求处理服务器

CIP
: Client IP
                                  #用户端IP

VIP
Director Virtual IP
           #负载均衡器虚拟IP

DIP
Director IP
                            #负载均衡器真实IP

RIP
Real Server IP
                      #后端请求处理服务器IP

LVS DR模式工作原理

LVS DR
模式的流程大概如下:

1、客户端发送请求至VIP
,也就是访问服务,请求报文源地址是CIP
,目标地址为VIP

2、LVS
调度器接收到请求,报文在PREROUTING
链检查,确定目的IP
是本机,于是将报文发送至INPUT
链,ipvs
内核模块确定请求的服务是我们配置的LVS
集群服务,然后根据用户设定的均衡策略选择某台后端RS
,并将目标MAC
地址修改RIP
MAC
地址。因为调度器和后端服务器RS
在同个网段,因此直接二层互通,将请求发给选择的RS处理;

3、因为报文目的mac
是本机,且RS
上有配置VIP
,因此RS
能接收该报文。后端服务处理完请求后,将响应直接发往客户端,此时源IP
地址为VIP
,目标IP
CIP

LVS DR模式配置

1、环境准备

如下,准备三台服务器,

机器 作用

  • 192.168.0.100 VIP,LVS调度器对外服务IP
  • 192.168.0.200 RIP,后端web服务器之一
  • 192.168.0.300 RIP,后端web服务器之二

2、LVS调度器配置

上面我们说过lvs
依赖于ipvs
内核模块,和ipvsadm
用户态工具。因为centos 7
已经默认加载ipvs
模块,因此这一步我们不需要配置。我们只需要安装ipvsadm
工具即可,

yum install -y ipvsadm

然后在LVS调度器上配置VIP,这里我们采用虚拟网卡,当然也可以使用独立网卡配置,

ifconfig eth0:0 192.168.0.100/24 up

接着配置LVS集群服务,代码如下:

[root@CentOS-7-2 ~]# ipvsadm -C
[root@CentOS-7-2 ~]# ipvsadm -A -t 192.168.0.100:80 -s rr
[root@CentOS-7-2 ~]# ipvsadm -a -t 192.168.0.100:80 -r 192.168.0.200:80 -g
[root@CentOS-7-2 ~]# ipvsadm -a -t 192.168.0.100:80 -r 192.168.0.300:80 -g

命令解释:

第一条命令是清空所有规则;

第二条命令是定义LVS服务,并指定负责均衡策略为rr,即轮询;

第三、四条命令各添加一台后端web服务器,作为负载均衡节点,并指定为DR模式。

ipvsadm基本命令参数如下:

-A  指定添加的LVS负载均衡虚拟服务
-t  指定虚拟服务器的IP地址和端口
-s  指定调度算法,ss为轮询,wrr为加权轮询,dh为目标地址散列,sh为源地址散列,lc为最少链接等
-a  在对应的VIP下添加RS节点
-g  指定LVS的工作模式为DR模式
-l  指定LVS的工作模式为tunnel模式
-m  指定LVS的工作模式为NAT模式

添加完后端RS,我们可以查看此LVS对应的均衡规则,

[root@CentOS-7-2 ~]# 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.100:80 rr
 -> 192.168.0.200:80      Route  1   0     0    
 -> 192.168.0.300:80      Route  1   0     0

3、后端RS配置

这里web
服务器使用nginx
搭建,因此在两台RS
上安装nginx

yum install -y nginx

同时为了后面测试,我们修改web
服务器的index.html
内容,

[root@192_168_0_200 ~]# cat /usr/share/nginx/html/index.html
This is 192.168.0.200
[root@192_168_0_300 ~]# cat /usr/share/nginx/html/index.html
This is 192.168.0.300

接着开始进行LVS
相关配置,以下内容需要在两台RS
上分别执行;

首先将VIP配置在lo接口上,(注意掩码要配置成32位,不然RS通信会出问题)

ifconfig lo:0 192.168.0.100/32 up

接着配置对应路由;

route add -host 192.168.0.100 dev lo

然后设置相关系统参数;

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

其实严格意义上只要配置出口网卡的对应参数就可以了,配置all
也只是为了保险而已,文章最后面会有说明。

4、测试

使用curl命令对vip进行访问,

[root@CentOS-7-3 /home]# curl http://192.168.0.100:80
This is 192.168.0.200
[root@CentOS-7-3 /home]# curl http://192.168.0.100:80
This is 192.168.0.300
[root@CentOS-7-3 /home]# curl http://192.168.0.100:80
This is 192.168.0.200
[root@CentOS-7-3 /home]# curl http://192.168.0.100:80
This is 192.168.0.300

可见结果符合我们设置的轮询策略。

几点思考

1、为什么所有RS上都要配置VIP

因为当调度器把请求转发给对应RS时,并没有修改报文目的IP
,因此请求报文目的IP
仍为VIP
,所以如果RS
没有配置VIP
,那么报文到达RS
后就会被丢弃。

2、为什么所有RS要设置arp_ignore=1
arp_announce=2

arp_ignore=1
:只响应目的IP
地址为接收网卡上的本地地址的arp
请求;

因为我们在RS
上都配置了VIP
,因此此时是存在IP
冲突的,当外部客户端向VIP
发起请求时,会先发送arp
请求,此时调度器和RS
都会响应这个请求。如果某个RS
响应了这个请求,则之后该客户端的请求就都发往该RS
,并没有经过LVS
,因此也就没有真正的负载均衡,LVS
也就没有存在的意义。因此我们需要设置RS
不响应对VIP
arp
请求,这样外部客户端的所有对VIP
arp
请求才会都解析到调度器上,然后经由LVS
的调度器发往各个RS

系统默认arp_ignore=0
,表示响应任意网卡上接收到的对本机IP
地址的arp
请求(包括环回网卡上的地址),而不管该目的IP
是否在接收网卡上。也就是说,如果机器上有两个网卡设备A
B
,即使在A网卡上收到对B_IP
arp
请求,也会回应。而arp_ignore
设置成1
,则不会对B_IP
arp
请求进行回应。由于lo
肯定不会对外通信,所以如果只有一个对外网口,其实只要设置这个对外网口即可,不过为了保险,很多时候都对all
也进行设置。

arp_announce=2
:网卡在发送arp
请求时使用出口网卡IP
作为源IP

RS
处理完请求,想要将响应发回给客户端,此时想要获取目的IP
对应的目的MAC
地址,那么就要发送arp
请求。arp
请求的目的IP
就是想要获取MAC
地址的IP
,那arp
请求的源IP
呢?自然而然想到的是响应报文的源IP
地址,但也不是一定是这样,arp
请求的源IP
是可以选择的,而arp_announce
的作用正是控制这个地址如何选择。系统默认arp_announce=0
,也就是源ip
可以随意选择。这就会导致一个问题,如果发送arp
请求时使用的是其他网口的IP
,达到网络后,其他机器接收到这个请求就会更新这个IP
mac
地址,而实际上并不该更新,因此为了避免arp
表的混乱,我们需要将arp
请求的源ip
限制为出口网卡ip
,因此需要设置arp_announce=2

3、为什么RS上的VIP要配置在lo上

由上可知,只要RS
上的VIP
不响应arp
请求就可以了,因此不一定要配置在lo
上,也可以配置在其他网口。由于lo
设备不会直接接收外部请求,因此只要设置机器上的出口网卡不响应非本网卡上的arp
请求接口。但是如果VIP
配置在其他网口上,除了上面的配置,还需要配置该网口不响应任何arp
请求,也就是arp_ignore
要设置为8

4、为什么RS上lo配置的VIP掩码为32位

这是由于lo
设备的特殊性导致, 如果lo
绑定192.168.0.200/24
,则该设备会响应该网段所有IP(192.168.0.1~192.168.0.254)
的请求,而不是只响应192.168.0.200
这一个地址。

5、为什么调度器与RS要在同一网段中

根据DR
模式的原理,调度器只修改请求报文的目的mac
,也就是转发是在二层进行,因此调度器和RS
需要在同一个网段,从而ip_forward
也不需要开启。

至此,本文结束,相关内容每日更新。

长按以识别二维码关注运维家~
微信号:yunweijia0909

往期推荐

03-docker系列-docker容器的基本操作

06-docker系列-使用dockerfile构建nginx、redis镜像

01-docker系列-linux下的docker安装

文章转载自运维家,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论