企业实战(13)LVS负载均衡DR(直接路由)模式实战详解(二)

2022-06-22 14:28:07 浏览数 (1)

什么是集群

  • 一组通过高速网络互连的计算组,并以单一系统的模式加以管理。
  • 将很多服务器集中起来一起,提供同一种服务,在客户端看起来就像是只有一个服务器。
  • 可以在付出较低成本的情况下获得在性能、可靠性、灵活性方面的相对较高的收益。
  • 任务调度是集群系统中的核心技术。

集群分类

  • 高性能计算集群HPC  -通过以集群开发的并行应用程序,解决 复杂的科学问题
  • 负载均衡(LB)集群  -客户端负载在计算机集群中尽可能平均分摊
  • 高可用(HA)集群  -避免单点故障,当一个系统发生故障时,可以快速迁移

负载均衡类型

- DNS 实现负载均衡

 DNS 实现负载均衡是最基础简单的方式。一个域名通过 DNS 解析到多个 IP,每个 IP 对应不同的服务器实例,这样就完成了流量的调度,虽然没有使用常规的负载均衡器,但也的确完成了简单负载均衡的功能。

- 硬件负载均衡

 硬件负载均衡是通过专门的硬件设备来实现负载均衡功能,类似于交换机、路由器,是一个负载均衡专用的网络设备。目前业界典型的硬件负载均衡设备有两款:F5 和 A10。这类设备性能强劲、功能强大,但价格非常昂贵,一般只有 “土豪” 公司才会使用此类设备,普通业务量级的公司一般负担不起,二是业务量没那么大,用这些设备也是浪费。

- 软件负载均衡

 软件负载均衡,可以在普通的服务器上运行负载均衡软件,实现负载均衡功能。目前常见的有 Nginx、HAproxy、LVS。  区别:   -Nginx :是 7 层负载均衡,支持 HTTP、E-mail 协议,貌似也支持 4 层负载均衡了。   -HAproxy :是 7 层负载均衡软件,支持 7 层规则的设置,性能也很不错。OpenStack 默认使用的负载均衡软件就是 HAproxy   -LVS :是纯 4 层的负载均衡,运行在内核态,性能是软件负载均衡中最高的,因为是在四层,所以也更通用一些。

负载均衡LVS简介

 LB集群的架构和原理很简单,就是当用户的请求过来时,会直接分发到Director Server上,然后它把用户的请求根据设置好的调度算法,智能均衡地分发到后端真正服务器(real server)上。为了避免不同机器上用户请求得到的数据不一样,需要用到了共享存储,这样保证所有用户请求的数据是一样的。

 LVS是 Linux Virtual Server 的简称,也就是Linux虚拟服务器。这是一个由章文嵩博士发起的一个开源项目, 现在 LVS 已经是 Linux 内核标准的一部分。使用 LVS 可以达到的技术目标是:通过 LVS 达到的负载均衡技术和 Linux 操作系统实现一个高性能高可用的 Linux 服务器集群,它具有良好的可靠性、可扩展性和可操作性。从而以低廉的成本实现最优的性能。LVS 是一个实现负载均衡集群的开源软件项目,LVS架构从逻辑上可分为调度层、Server集群层和共享存储。

LVS的基本工作原理

在这里插入图片描述  1.当用户向负载均衡调度器(Director Server)发起请求,调度器将请求发往至内核空间

 2.PREROUTING链首先会接收到用户请求,判断目标IP确定是本机IP,将数据包发往INPUT链

  3.IPVS是工作在INPUT链上的,当用户请求到达INPUT时,IPVS会将用户请求和自己已定义好的集群服务进行比对,如果用户请求的就是定义的集群服务,那么此时IPVS会强行修改数据包里的目标IP地址及端口,并将新的数据包发往POSTROUTING链

 4.POSTROUTING链接收数据包后发现目标IP地址刚好是自己的后端服务器,那么此时通过选路,将数据包最终发送给后端的服务器

LVS负载均衡调度算法

  • LVS目前实现了10种调度算法
  • 常用调度算法有4种  -`轮询` -将客户端请求平均分发到Real Server  -`加权轮询` -根据Real Server权重值进行轮询调度  -`最少连接` -选择连接数最少的服务器  -`加权最少连接 ` -根据Real Server权重值,选择连接数最少的服务器  -源地址散列   -根据请求的目标IP地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器

LVS集群组成

- 前端:负载均衡层   -由一台或多台负载调度器构成

- 中间:服务器群组层   -由一组实际运行应用服务的服务器组成

- 底端:数据共享存储层   -提供共享存储空间的存储区域

相关术语

DS Director Server。指的是前端负载均衡器节点。

RS Real Server。后端真实的工作服务器。

CIP Client IP,表示的是客户端 IP 地址。

VIP Virtual IP,表示负载均衡对外提供访问的 IP 地址,一般负载均衡 IP 都会通过 Virtual IP 实现高可用。

RIP RealServer IP,表示负载均衡后端的真实服务器 IP 地址。

DIP Director IP,表示负载均衡与后端服务器通信的 IP 地址。

LVS工作模式

LVS/NAT:网络地址转换

 -通过网络地址转换实现的虚拟服务器

 -大并发访问时,调度器的性能成为瓶颈

-LVS/DR:直接路由

 -直接使用路由技术实现虚拟服务器

 -节点服务器需要配置VIP,注意MAC地址广播

-LVS/TUN:IP隧道

 -通过隧道方式实现虚拟服务器

LVS各工作模式原理

 更详细原理可参考博客:https://blog.csdn.net/liwei0526vip/article/details/103104483

1.网络地址转换(LVS-NAT)

在这里插入图片描述

代码语言:javascript复制
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

2.直接路由(LVS-DR)

在这里插入图片描述

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

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

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

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

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

注意:
 如果没有给RS设置外网IP,RS将ARP广播查找CIP,内网没有就提交给网关,网关直接外网发送出去,会有可能提高网关压力

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

特点: 多了一个Mac地址,作用是让真实服务器可以找到客户端,直接发送响应报文,并且整个过程的客户端IP(CIP)和负载均衡器的IP都没有改变,只是Mac地址变了,目的是让客户端知道,你发送请求的报文,和响应你报文的是一个人。

3.IP隧道(LVS-TUN)

在这里插入图片描述

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

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

3.IPVS比对数据包请求的服务是否为集群服务,若是,在请求报文的首部再次封装一层IP报文,封装源IP为为DIP,目标IP为RIP。然后发至POSTROUTING链。 此时源IP为DIP,目标IP为RIP ④、POSTROUTING链根据最新封装的IP报文,将数据包发至RS(因为在外层封装多了一层IP首部,所以可以理解为此时通过隧道传输)。 此时源IP为DIP,目标IP为RIP

4.RS接收到报文后发现是自己的IP地址,就将报文接收下来,拆除掉最外层的IP后,会发现里面还有一层IP首部,而且目标是自己的lo接口VIP,那么此时RS开始处理此请求,处理完成之后,通过lo接口送给eth0网卡,然后向外传递。 此时的源IP地址为VIP,目标IP为CIP

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

三种工作模式比较

在这里插入图片描述

ipvsadm命令选项

代码语言:javascript复制
  ipvsadm -A   创建虚拟服务器
  ipvsadm -E   修改虚拟服务器
  ipvsadm -D   删除虚拟服务器

  ipvsadm -t   设置集群地址(VIP,Virtual IP)
  ipvsadm -s   指定集群算法     ----> rr(轮询)、wrr(加权轮询)、lc(最少连接)、wlc(加权最少连接)、sh(ip_hash)

  ipvsadm -a   添加真实服务器
  ipvsadm -e   修改真实服务器
  ipvsadm -d   删除真实服务器

  ipvsadm -r   指定真实服务器的地址
  ipvsadm -w   为节点服务器设置权重,默认为1

  ipvsadm -C   清空所有
  ipvsadm -L   查看LVS规则表   ---> 一般跟n一起用,以数字形式输出(-Ln)

  ipvsadm -m   使用NAT模式
  ipvsadm -g   使用DR模式
  ipvsadm -i   使用TUN模式

LVS-DR模式实战

环境介绍

客户端:192.168.2.132/24

负载均衡服务器: ens33:0(VIP):192.168.2.133/24 ens33(DIP):192.168.2.130/24(test3)

后端服务器1:192.168.2.128/24(localhost) lo:0:192.168.2.133/32

后端服务器2:192.168.2.129/24(test2) lo:0:192.168.2.133/32

内核版本:3.10.0-862.el7.x86_64

系统版本:CentOS 7.5

说明:

 CIP是客户端的IP地址;

 VIP是对客户端提供服务的IP地址;

 RIP是后端服务器的真实IP地址;

 DIP是调度器与后端服务器通信的IP地址(VIP必须配置在虚拟接口)

网卡含义:

代码语言:javascript复制
cat /etc/sysconfig/network-scripts/ifcfg-ens33
  TYPE=Ethernet        #网卡类型
  DEVICE=ens33          #网卡接口名称
  ONBOOT=yes            #系统启动时是否激活 yes|no
  BOOTPROTO=static      #启用地址协议 –static:静态协议 –bootp:协议 –dhcp:协议 -none:不指定协议[最好指定]
  IPADDR=192.168.2.130  #网卡IP地址
  NETMASK=255.255.255.0    #子网掩码
  GATEWAY=192.168.2.1      #网卡网关地址
  DNS1=8.8.8.8     #网卡DNS地址
  PREFIX="24"     #掩码位数
  BROADCAST=********     #网卡广播地址
  HWADDR=00:0C:29:13:5D:74    #网卡设备MAC地址

一、基础环境配置

1.两台后端服务器128/129分别安装Nginx

代码语言:javascript复制
[root@localhost ~]# wget http://nginx.org/download/nginx-1.16.1.tar.gz

[root@localhost ~]# yum -y install gcc pcre-devel openssl-devel

[root@localhost ~]# useradd -s /sbin/nologin nginx   //创建禁止登陆解释器的用户(为了安全)

[root@localhost ~]# id nginx
uid=1001(nginx) gid=1001(nginx) 组=1001(nginx)

[root@localhost ~]# tar -xf nginx-1.16.1.tar.gz

[root@localhost ~]# cd nginx-1.16.1

[root@localhost nginx-1.16.1]# ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module

         --prefix=/usr/local/nginx                   //指定安装路径
         --user=nginx                               //指定用户
         --group=nginx                              //指定组
         --with-http_ssl_module                    //安装ssl模块,开启其中的SSL加密功能(需要什么模块就安装什么模块)
  ......
  ......
  nginx modules path: "/usr/local/nginx/modules"
  nginx configuration prefix: "/usr/local/nginx/conf"
  nginx configuration file: "/usr/local/nginx/conf/nginx.conf"
  nginx pid file: "/usr/local/nginx/logs/nginx.pid"
  nginx error log file: "/usr/local/nginx/logs/error.log"
  nginx http access log file: "/usr/local/nginx/logs/access.log"
  nginx http client request body temporary files: "client_body_temp"
  nginx http proxy temporary files: "proxy_temp"
  nginx http fastcgi temporary files: "fastcgi_temp"
  nginx http uwsgi temporary files: "uwsgi_temp"
  nginx http scgi temporary files: "scgi_temp"

[root@localhost nginx-1.16.1]#  make && make install    //编译并且安装
......
    '/usr/local/nginx/conf/scgi_params.default'
test -f '/usr/local/nginx/conf/nginx.conf' 
    || cp conf/nginx.conf '/usr/local/nginx/conf/nginx.conf'
cp conf/nginx.conf '/usr/local/nginx/conf/nginx.conf.default'
test -d '/usr/local/nginx/logs' 
    || mkdir -p '/usr/local/nginx/logs'
test -d '/usr/local/nginx/logs' 
    || mkdir -p '/usr/local/nginx/logs'
test -d '/usr/local/nginx/html' 
    || cp -R html '/usr/local/nginx'
test -d '/usr/local/nginx/logs' 
    || mkdir -p '/usr/local/nginx/logs'
make[1]: 离开目录“/root/nginx-1.16.1”

[root@localhost ~]# /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.16.1
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)
built with OpenSSL 1.0.2k-fips  26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module

[root@test2 ~]# /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.16.1
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)
built with OpenSSL 1.0.2k-fips  26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module

2.创建测试页面

代码语言:javascript复制
[root@localhost ~]# echo "I am 192.168.2.128" > /usr/local/nginx/html/index.html

[root@test2 ~]# echo "I am 192.168.2.129" > /usr/local/nginx/html/index.html

3.启动Nginx

代码语言:javascript复制
[root@localhost nginx-1.16.1]# /usr/local/nginx/sbin/nginx 

[root@localhost nginx-1.16.1]# netstat -antulp | grep :80
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      6079/nginx: master

或者[root@localhost nginx-1.16.1]# netstat -antulp | grep nginx
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      6079/nginx: master

3.关闭防火墙与selinux

两台后端服务器都需要操作。

代码语言:javascript复制
[root@test2 ~]# systmctl stop firewalld

[root@test2 ~]# setenforce 0

[root@test2 ~]# getenforce
Disabled

[root@test2 ~]# vim /etc/sysconfig/selinux     //永久关闭selinux
SELINUX=disabled

二、网络相关配置

1.负载均衡调度器网络配置(VIP和DIP)

注意:为了防止冲突,VIP必须要配置在网卡的虚拟接口!!!

代码语言:javascript复制
[root@test3 ~]# cd /etc/sysconfig/network-scripts/

[root@test3 network-scripts]# cp ifcfg-ens33 ifcfg-ens33:0    //复制网卡ens33改名为ens33:0

[root@test3 network-scripts]# vim ifcfg-ens33:0
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO="static"
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=ens33:0          //修改
UUID=2d899e46-1b9d-40d5-9fed-8a88cb181d55
DEVICE=ens33:0       //修改
ONBOOT=yes
IPADDR="192.168.2.133"     //IP地址
PREFIX="24"
GATEWAY="192.168.2.1"
DNS1="8.8.8.8"

[root@test3 network-scripts]# systemctl restart network

[root@test3 network-scripts]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.2.130  netmask 255.255.255.0  broadcast 192.168.2.255
        inet6 fe80::2c27:a02c:731a:2219  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:53:71:a2  txqueuelen 1000  (Ethernet)
        RX packets 76415  bytes 15971247 (15.2 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 16427  bytes 1491040 (1.4 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ens33:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.2.133  netmask 255.255.255.0  broadcast 192.168.2.255

        ether 00:0c:29:53:71:a2  txqueuelen 1000  (Ethernet)
lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 52  bytes 4117 (4.0 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 52  bytes 4117 (4.0 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

2.两台后端服务器配置VIP地址

注意:这里的子网掩码必须是32(也就是全255),网络地址与IP地址一样,广播地址与IP地址也一样。

代码语言:javascript复制
-后端128服务器 
[root@localhost ~]# cd /etc/sysconfig/network-scripts/

[root@localhost network-scripts]# cp ifcfg-lo ifcfg-lo:0

[root@localhost network-scripts]# vim ifcfg-lo:0
DEVICE=lo:0            //网卡名称lo:0
IPADDR=192.168.2.133      //这里为VIP地址
NETMASK=255.255.255.255      //必须是32位掩码(即全255)
NETWORK=192.168.2.133      
BROADCAST=192.168.2.133     //为VIP地址
ONBOOT=yes
NAME=lo:0

[root@localhost ~]#  systemctl restart network

[root@localhost ~]# ifconfig lo:0    //查看配置的VIP地址
lo:0: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 192.168.2.133  netmask 255.255.255.255
        loop  txqueuelen 1000  (Local Loopback)

-后端129服务器
[root@test2 ~]# cd /etc/sysconfig/network-scripts/
[root@test2 network-scripts]# cp ifcfg-lo ifcfg-lo:0
[root@test2 network-scripts]# vim ifcfg-lo:0
DEVICE=lo:0            //网卡名称lo:0
IPADDR=192.168.2.133      //这里为VIP地址
NETMASK=255.255.255.255      //必须是32位掩码(即全255)
NETWORK=192.168.2.133      
BROADCAST=192.168.2.133     //为VIP地址
ONBOOT=yes
NAME=lo:0

[root@test2 ~]#  systemctl restart network

[root@test2 ~]# ifconfig lo:0    //查看配置的VIP地址
lo:0: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 192.168.2.133  netmask 255.255.255.255
        loop  txqueuelen 1000  (Local Loopback)

 以上是防止地址冲突的问题:因为后端服务器也配置与调度器一样的VIP地址,默认肯定会出现地址冲突。

3.后端服务器配置sysctl.conf文件

在这里插入图片描述

在这里插入图片描述

代码语言:javascript复制
-后端128服务器
[root@localhost network-scripts]# cat >> /etc/sysctl.conf <<EOF
> net.ipv4.conf.all.arp_ignore = 1
> net.ipv4.conf.lo.arp_ignore = 1
> net.ipv4.conf.lo.arp_announce = 2
> net.ipv4.conf.all.arp_announce = 2
> EOF

[root@localhost network-scripts]# sysctl -p
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-arptables = 1
net.ipv4.ip_forward = 1
以下4行配置是新添加的:
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2
net.ipv4.conf.all.arp_announce = 2

[root@localhost network-scripts]# systemctl restart NetworkManager
[root@localhost network-scripts]# systemctl restart network

-后端129服务器
[root@test2 network-scripts]# cat >> /etc/sysctl.conf <<EOF
> net.ipv4.conf.all.arp_ignore = 1
> net.ipv4.conf.lo.arp_ignore = 1
> net.ipv4.conf.lo.arp_announce = 2
> net.ipv4.conf.all.arp_announce = 2
> EOF

[root@localhost network-scripts]# sysctl -p
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-arptables = 1
net.ipv4.ip_forward = 1
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2
net.ipv4.conf.all.arp_announce = 2

[root@test2 network-scripts]# systemctl restart NetworkManager
[root@test2 network-scripts]# systemctl restart network

以上配置的含义:

当有arp广播问谁是192.168.2.133(VIP)时,本机忽略该ARP广播,不做任何回应,且本机不要向外宣告自己的lo回环地址是192.168.2.133.

三、部署LVS-DR模式调度器

1.创建集群调度服务器

代码语言:javascript复制
[root@test3 ~]# yum -y install ipvsadm

[root@test3 ~]# ipvsadm -C

[root@test3 ~]# ipvsadm -A -t 192.168.2.133:80 -s wrr  //创建虚拟集群服务器并设置调度算法为加权轮询wrr

2.添加后端真实服务器

-g:参数设置LVS工作模式为DR模式 -w:设置权重

代码语言:javascript复制
[root@test3 ~]# ipvsadm -a -t 192.168.2.133:80 -r 192.168.2.128 -g -w 1

[root@test3 ~]# ipvsadm -a -t 192.168.2.133:80 -r 192.168.2.129 -g -w 2

3.查看规则列表,并保存规则

代码语言:javascript复制
[root@test3 ~]# 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.2.133:80 wrr
  -> 192.168.2.128:80             Route   1      0          0
  -> 192.168.2.129:80             Route   2      0          0

[root@test3 ~]# ipvsadm-save -n > /etc/sysconfig/ipvsadm-config

四、客户端测试

代码语言:javascript复制
[root@VOS3000 ~]# curl  http://192.168.2.133:80
I am 192.168.2.129
[root@VOS3000 ~]# curl  http://192.168.2.133:80
I am 192.168.2.129
[root@VOS3000 ~]# curl  http://192.168.2.133:80
I am 192.168.2.128
[root@VOS3000 ~]# curl  http://192.168.2.133:80
I am 192.168.2.129
[root@VOS3000 ~]# curl  http://192.168.2.133:80
I am 192.168.2.129
[root@VOS3000 ~]# curl  http://192.168.2.133:80
I am 192.168.2.128
[root@VOS3000 ~]# curl  http://192.168.2.133:80
I am 192.168.2.129
[root@VOS3000 ~]# curl  http://192.168.2.133:80
I am 192.168.2.129
[root@VOS3000 ~]# curl  http://192.168.2.133:80
I am 192.168.2.128
[root@VOS3000 ~]# curl  http://192.168.2.133:80
I am 192.168.2.129

 可以看到每当我们执行一次curl命令(相当于刷新一次网页),调度器都会根据权重值轮询到不同的后端真实服务器。

` 思考`

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也不需要开启。

0 人点赞