keepalived同时配置:vip + lvs负载均衡

1、使用keepalived实现vip,同时在keepalived配置生成lvs负载均衡规则

实现高可用架构如下:

DS1(MASTER):172.17.13.120
DS1(BACKUP):172.17.13.123
RS1:172.17.13.142:80 Nginx
RS1:172.17.13.173:80 Nginx
VIP:172.17.13.252

|
             +----------------+-----------------+
             |                                  |
172.17.13.120|----     VIP:172.17.13.252    ----|172.17.13.123
     +-------+--------+                +--------+-------+
     | 	    DS1       |                |       DS2      |
     | LVS+Keepalived |                | LVS+Keepalived |
     +-------+--------+                +--------+-------+
             |			                |
             +----------------+-----------------+
                              |
  +------------+              |               +------------+
  |     RS1    |172.17.13.142 |  172.17.13.173|     RS2    |
  | Web Server +--------------+---------------+ Web Server |
  +------------+                              +------------+

2、keepalived配置:

DS1(MASTER) 节点:

[root@localhost ~]# vi /etc/keepalived/keepalived.conf

! Configuration File for keepalived
global_defs {
   router_id LVS_DEVEL
}

vrrp_instance VI_1 {
    state MASTER            # 两个 DS,一个为 MASTER 一个为 BACKUP
    interface enp1s0        # 当前 IP 对应的网络接口,通过 ifconfig 查询
    virtual_router_id 62    # 虚拟路由 ID(0-255),在一个 VRRP 实例中主备服务器 ID 必须一样
    priority 200            # 优先级值设定:MASTER 要比 BACKUP 的值大
    advert_int 1            # 通告时间间隔:单位秒,主备要一致
    authentication {        # 认证机制,主从节点保持一致即可
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        172.17.13.252       # VIP,可配置多个
    }
}

# LB 配置
virtual_server 172.17.13.252 80  {
    delay_loop 3                    # 设置健康状态检查时间
    lb_algo rr                      # 调度算法,这里用了 rr 轮询算法
    lb_kind DR                      # 这里测试用了 Direct Route 模式
    persistence_timeout 50          # 持久连接超时时间
    protocol TCP
	real_server 172.17.13.173 80 {
        weight 1
        TCP_CHECK {
            connect_timeout 10   
            retry 3            # 旧版本为 nb_get_retry 
            delay_before_retry 3   
            connect_port 80
        }
    }
	 real_server 172.17.13.142 80 {
        weight 1
        TCP_CHECK {
            connect_timeout 10
            retry 3
            delay_before_retry 3
            connect_port 80
        }
    }
}

DS2(BACKUP) 节点:

按照DS1的配置文件,修改 vrrp_instance VI_1 中的 state 为 BACKUP。

配置 RS节点:

网络配置脚本:

#!/bin/bash 
SNS_VIP=172.17.13.252
case "$1" in
start)
       ifconfig lo:0 $SNS_VIP netmask 255.255.255.255 broadcast $SNS_VIP
       /sbin/route add -host $SNS_VIP dev lo:0
       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
       sysctl -p >/dev/null 2>&1
       echo "RealServer Start OK"
       ;;
stop)
       ifconfig lo:0 down
       route del $SNS_VIP >/dev/null 2>&1
       echo "0" >/proc/sys/net/ipv4/conf/lo/arp_ignore
       echo "0" >/proc/sys/net/ipv4/conf/lo/arp_announce
       echo "0" >/proc/sys/net/ipv4/conf/all/arp_ignore
       echo "0" >/proc/sys/net/ipv4/conf/all/arp_announce
       echo "RealServer Stoped"
       ;;
*)
       echo "Usage: $0 {start|stop}"
       exit 1
esac
exit 0

执行:

chmod a+x lvs-web.sh
./lvs-web.sh start

3、配置原理解析:

1、DR模式下,Realserver 和LVS需要在同一个vlan或者局域网下

原因: lvs改写的是mac地址的,基于mac地址的通讯方式是2层的,所以需要限制在一个vlan或者局域网下。

2、DR模式下的ARP广播问题

在DR模式下时,会存在一个问题,所有的realserver和director都配置了VIP,从网络模型中,我们知道,最终传输的是mac地址,那么这个时候,到底谁的mac地址是准确的呢? 我们要保证请求的VIP必须是director,这样我们的负载均衡才是生效的,因此要在realserver上进行ARP抑制配置,禁止它处理外部的arp请求,也不允许自己向外部广播ARP数据

需要配置:

## 忽略收到的ARP请求
## lo接口不对外广播ARP数据
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


arp_ignore: 定义接收到ARP请求时的相应级别
   0 -- 只要本地配置有相应地址,就给予响应
   1 -- 仅回应目标IP地址为接收网卡本地地址的ARP请求
   2 -- 只响应目标IP地址为接收网卡本地地址的ARP请求,并且arp请求的源IP必须和接收网卡同网段
   4~7 -- 保留未使用
   8 -- 不回应所有ARP请求


arp_announce: 定义将自己的地址向外通告时的通告级别
   0 -- 将本地任何接口上的任何地址向外通告
   1 -- 试图仅向目标网络通告与其网络匹配的地址
   2 -- 仅向与本地接口上地址匹配的网络进行通告

3、为什么要在网卡上绑定vip

原因: 如果不这么做,对于vip的代理流量,本机网卡上没有这个vip,那么本机不认为这属于访问本机器的流量,不会被本机处理并上送协议栈到上层app,而是会被转发出去