一 LVS IP tunnel 模式介绍

IP隧道(IP tunneling)是将一个IP报文封装在另一个IP报文的技术,这可以使得目标为一个IP地址的数据报文能被封装和转发到另一个IP地址。IP隧道技术亦称为IP封装技术(IP encapsulation)。IP隧道主要用于移动主机和虚拟私有网络(Virtual Private Network),在其中隧道都是静态建立的,隧道一端有一个IP地址,另一端也有唯一的IP地址。它的连接调度和管理与VS/NAT中的一样,只是它的报文转发方法不同。调度器根据各个服务器的负载情况,动态地选择一台服务器,将请求报文封装在另一个IP报文中,再将封装后的IP报文转发给选出的服务器;服务器收到报文后,先将报文解封获得原来目标地址为 VIP 的报文,服务器发现VIP地址被配置在本地的IP隧道设备上,所以就处理这个请求,然后根据路由表将响应报文直接返回给客户。
Linux学习总结(五十五)keepalived+lvs 双机热备负载均衡架构

二 LVS DR 模式介绍

DR模式也就是用直接路由技术实现虚拟服务器。它的连接调度和管理与VS/NAT和VS/TUN中的一样,但它的报文转发方法又有不同,VS/DR通过改写请求报文的MAC地址,将请求发送到Real Server,而Real Server将响应直接返回给客户,免去了VS/TUN中的IP隧道开销。这种方式是三种负载调度机制中性能最高最好的,但是必须要求Director Server与Real Server都有一块网卡连在同一物理网段上。Director和RealServer必需在物理上有一个网卡通过不间断的局域网相连。 RealServer上绑定的VIP配置在各自Non-ARP的网络设备上(如lo或tunl),Director的VIP地址对外可见,而RealServer的VIP对外是不可见的。RealServer的地址即可以是内部地址,也可以是真实地址。
Linux学习总结(五十五)keepalived+lvs 双机热备负载均衡架构
具体实现过程为:
DR模式将报文直接路由给目标真实服务器。在DR模式中,调度器根据各个真实服务器的负载情况,连接数多少等,动态地选择一台服务器,不修改目标IP地址和目标端口,也不封装IP报文,而是将请求报文的数据帧的目标MAC地址改为真实服务器的MAC地址。然后再将修改的数据帧在服务器组的局域网上发送。因为数据帧的MAC地址是真实服务器的MAC地址,并且又在同一个局域网。那么根据局域网的通讯原理,真实复位是一定能够收到由LB发出的数据包。真实服务器接收到请求数据包的时候,解开IP包头查看到的目标IP是VIP。(此时只有自己的IP符合目标IP才会接收进来,所以我们需要在本地的回环借口上面配置VIP。另:由于网络接口都会进行ARP广播响应,但集群的其他机器都有这个VIP的lo接口,都响应就会冲突。所以我们需要把真实服务器的lo接口的ARP响应关闭掉。)然后真实服务器做成请求响应,之后根据自己的路由信息将这个响应数据包发送回给客户,并且源IP地址还是VIP。

三 lvs DR 模式搭建

结构框图如下
Linux学习总结(五十五)keepalived+lvs 双机热备负载均衡架构

Linux学习总结(五十五)keepalived+lvs 双机热备负载均衡架构
上图是客户端发过来的请求报文,我们知道DR模式中,LB和RS上都绑定了vip,那么客户是如何请求到LB而不是直接到RS呢?我们知道IP数据包其实是通过数据链路层发过来的,只要确定上面问号处的mac地址为LB的mac地址即可,如何办到呢,这里使用了ARP协议,简单来说就是通过ip解析出mac地址的一个协议,我们把vip地址给广播出去,具有此ip的机器就会回复自己的mac地址,然而这里LB和RS均有vip,因此需要抑制住RS对于该vip地址的arp相应。这样一来,就能确定唯一的LB mac 地址。
既然Load Balancer得到了这个IP数据包, 它就可以用某个策略从RS1, RS2,RS3中选取一个服务器,例如RS1(192.168.226.130),把IP数据报原封不动, 封装成数据链路层的包(目的地是RS1的MAC地址),直接转发就可以了,请看下图

Linux学习总结(五十五)keepalived+lvs 双机热备负载均衡架构
RS1(192.168.226.130)这个服务器收到了数据包,拆开一看,目的地IP是192.168.226.100,是自己的IP, 那就可以处理了。
处理完了以后,RS1可以直接响应发回给客户端,完全不用再通过Load Balancer。因为自己的地址就是192.168.226.100。
对于客户端来说,它看到的还是那个唯一的vip地址192.168.226.100, 并不知道后台发生了什么事情。
由于Load Balancer 根本不会修改IP数据报,其中的TCP的端口号自然也不会修改,这就要求RS1, RS2,RS3上的端口号必须得和Load Balancer一致才行
数据的流向为:
客户端 --> Load Balancer --> RS --> 客户端
下面跟据具体实例来理解整个过程
准备三台机器
DIR ens33 192.168.226.129 ens37
RS1 ens33 192.168.226.130
RS2 ens33 192.168.226.131
指定vip 为 192.168.226.100,DIR vip 绑定在ens37 上,当然可以直接绑定一个虚拟网卡,比如ens33:2
以上每台机器都需要一个公网ip
dir上编写脚本 vim /usr/local/sbin/lvs_dr.sh //内容如下

#! /bin/bash
echo 1 > /proc/sys/net/ipv4/ip_forward
ipv=/usr/sbin/ipvsadm
vip=192.168.226.100
rs1=192.168.226.130
rs2=192.168.226.131
#注意这里的网卡名字
ifconfig ens37 $vip broadcast $vip netmask 255.255.255.255 up
route add -host $vip dev ens37
$ipv -C
$ipv -A -t $vip:80 -s wrr
$ipv -a -t $vip:80 -r $rs1:80 -g -w 1
$ipv -a -t $vip:80 -r $rs2:80 -g -w 1

两台rs上也编写脚本 vim /usr/local/sbin/lvs_rs.sh//内容如下

#/bin/bash
vip=192.168.226.100
#把vip绑定在lo上,是为了实现rs直接把结果返回给客户端
ifconfig lo:0 $vip broadcast $vip netmask 255.255.255.255 up
route add -host $vip lo:0
#以下操作为更改arp内核参数,目的是为了让rs顺利发送mac地址给客户端
#参考文档www.cnblogs.com/lgfeng/archive/2012/10/16/2726308.html
echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce
echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce

分别运行以上脚本后,在浏览器测试
Linux学习总结(五十五)keepalived+lvs 双机热备负载均衡架构
刷新后
Linux学习总结(五十五)keepalived+lvs 双机热备负载均衡架构

四 keepalived +lvs

之前我们试验过lvs的nat 和dr 两种模型的负载均衡,keepalived 不光可以基于vrrp((Virtual Router Redundancy Protocol)协议实现高可用,他本身集成有lvs功能,可以实现负载均衡。下面我们用四台机器做下实验,基本拓扑结构如下
Linux学习总结(五十五)keepalived+lvs 双机热备负载均衡架构
我们先准备四台服务器
LB1 LB2 RS1 RS2
LB1 两网卡 :ens33 192.168.226.129
ens37 192.168.199.200
LB2 两网卡:ens33 192.168.226.132
ens37 192.168.199.201
RS1 一网卡 ens33 192.168.226.130
RS2 一网卡 ens33 192.168.226.131
准备工作:
四台机器都关闭selinux ,清空防火墙规则
两台调度器上安装好keepalived,两台RS上安装好web nginx
1 LB1 作为主调度器
编辑keepalived 配置文件
vim /etc/keepalived/keepalived.conf

vrrp_instance VI_1 {
    //备用服务器上为 BACKUP
    state MASTER
    //绑定vip的网卡为ens37,
    interface ens37
    virtual_router_id 51
    //备用服务器上为90
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass lvlinux
    }
    virtual_ipaddress {
        192.168.226.100
    }
}
virtual_server 192.168.226.100 80 {
   //(每隔10秒查询realserver状态)
    delay_loop 10
    //(lvs 算法)
    lb_algo wrr
    //(DR模式)
    lb_kind DR
    //(同一IP的连接60秒内被分配到同一台realserver)
    persistence_timeout 60
    //(用TCP协议检查realserver状态)
    protocol TCP
    real_server 192.168.226.130 80 {
        //(权重)
        weight 100
        TCP_CHECK {
        //(10秒无响应超时)
        connect_timeout 10
        nb_get_retry 3
        delay_before_retry 3
        connect_port 80
        }
    }
    real_server 192.168.226.131 80 {
        weight 100
        TCP_CHECK {
        connect_timeout 10
        nb_get_retry 3
        delay_before_retry 3
        connect_port 80
        }
     }
}

备注:上面我们定义了vip 为192.168.226.100,并且绑定在网卡ens37

LB2 操作
vim /etc/keepalived/keepalived.conf

vrrp_instance VI_1 {
    //备用服务器上为 BACKUP
    state BACKUP
    //绑定vip的网卡为ens37
    interface ens37
    virtual_router_id 51
    //备用服务器上为90
    priority 90
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass lvlinux
    }
    virtual_ipaddress {
        192.168.226.100
    }
}
virtual_server 192.168.226.100 80 {
    //(每隔10秒查询realserver状态)
    delay_loop 10
    //(lvs 算法)
    lb_algo wrr
    //(DR模式)
    lb_kind DR
    //(同一IP的连接60秒内被分配到同一台realserver)
      persistence_timeout 60    
    //(用TCP协议检查realserver状态)
    protocol TCP
    real_server 192.168.226.130 80 {
        #(权重)
        weight 100
        TCP_CHECK {
        #(10秒无响应超时)
        connect_timeout 10
        nb_get_retry 3
        delay_before_retry 3
        connect_port 80
        }
    }
    real_server 192.168.226.131 80 {
        weight 100
        TCP_CHECK {
        connect_timeout 10
        nb_get_retry 3
        delay_before_retry 3
        connect_port 80
        }
     }
}

也就是将state master 更改为backup , priority 100 改为90
RS1 和RS2 上编辑脚本
vim /usr/local/sbin/lv_dr_rs.sh

#/bin/bash
vip=192.168.226.100
#把vip绑定在lo上,是为了实现rs直接把结果返回给客户端
ifconfig lo:0 $vip broadcast $vip netmask 255.255.255.255 up
route add -host $vip lo:0
#以下操作为更改arp内核参数,目的是为了让rs顺利发送mac地址给客户端
#参考文档www.cnblogs.com/lgfeng/archive/2012/10/16/2726308.html
echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce
echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce

RS 上 sh 运行脚本后, 在LB1上和LB2上 启动keepalived
ipvsadm -ln 查看RS链接状态
ip add 查看vip 绑定情况
LB1上关闭keepalived 后发现,LB2上重新绑定了vip 接管了服务,在/var/log/messages中可以看到vrrp 主从变更
LB2 上ipvsadem -ln 查看RS链接状态
关闭一台RS nginx ,测试高可用