Linux部署运维系统运维专家

Keepalived LVS+DR合设配置方法以及存在的问题

2019-03-16  本文已影响7人  Mr萝卜

  使用Keepalived可以很方便的配置LVS,而Keepalived实现高可用往往都是一主多从的模式,这样的话备机就处于standby状态,浪费了资源。我们可以将LVS和RS节点合设在一起,这样备机虽然不会作为LVS节点转发,但是也可以作为真实服务器提供服务,充分利用资源。

一、Keepalived配置LVS-DR模式

! Configuration File for keepalived

global_defs {
}

vrrp_instance VI_1 {
    state BACKUP              //nopreempt不抢占要求节点都为BACKUP
    interface wlan
    virtual_router_id 51      //同一个集群节点的virtual_router_id要一致
    priority 100              //主节点要比备节点的priority高
    advert_int 1              //vrrp组播时间间隔
    nopreempt                 //主机从故障状态恢复后不抢占备机
    notify_master "/etc/keepalived/master.sh"
    notify_backup "/etc/keepalived/backup.sh"
    notify_fault "/etc/keepalived/fault.sh"
    virtual_ipaddress {
        192.168.1.1/27 dev wlan
    }
    
}

virtual_server 192.168.1.10 80 {
    delay_loop 6
    lb_algo rr
    lb_kind DR
    #persistence_timeout 50
    protocol TCP

    real_server 192.168.1.11 80 {
        weight 100
        HTTP_GET {
            url {
              path /
              digest ff20ad2481f97b1754ef3e12ecd3a9cc
            }
            connect_timeout 3
            retry 3
            delay_before_retry 3
        }
    }
}

  上面是一份常见的Keepalived LVS-DR模式的配置。在LVS不与RS合设的情况下,这份配置是没有问题的。
  但是,如果LVS与RS合设,这个配置就会带来一个非常严重的问题: 乒乓现象

二、乒乓现象

LVS备机请求数

  如上所示,仅仅是一个telnet发起的syn请求,就已经能造成如此巨大的转发量了,如果是生产环境,必然会引起网卡流量风暴。

三、如何解决合设带来的乒乓问题

  要想解决乒乓问题,只需要将引发乒乓现象的必要条件给破坏掉。很显然条件1和2都是不能改变的,不然这个问题本身也没有存在的意义了。那我们只能拿条件3开刀了。
  既然备机加载了LVS转发规则就会引发乒乓,那么能否让备机不加载规则呢?

include /etc/keepalived/*.conf

  而对于备机,我们可以在/etc/keepalived下创建一个目录,如vs_dir,利用notify_backup脚本将virtual_server配置挪到vs_dir中隐藏起来,避免Keepalived加载。当backup节点切换到master状态时,由notify_master节点将目录中隐藏的vs配置挪到/etc/keepalived下,使Keepalived可以正常加载。
  上面的办法虽然能解决问题,但是比较繁琐,也不利于故障快速切换。那么我们换个思路,在备机加载了LVS规则的情况下,要想解决问题,只需保证主机上转发过来的消息不进入备机的LVS转发,而是直接由备机的真实服务进行处理。

# iptables  -t mangle -I PREROUTING -p tcp -m tcp -d $VIP --dport $VPORT -m mac ! --mac-source $MAC_Director_B -j MARK --set-mark 0x1

  LVS备机上配置iptables,其中$MAC_Director_A 表示主机的mac地址

# iptables  -t mangle -I PREROUTING -p tcp -m tcp -d $VIP --dport $VPORT -m mac ! --mac-source $MAC_Director_A -j MARK --set-mark 0x1

  keepalived.conf中virtual_server的配置

virtual_server fwmark 1 {
    delay_loop 6
    lb_algo wrr
    lb_kind DR
    #persistence_timeout 50
    protocol TCP

    real_server 192.168.1.10 80 {
        weight 100
        TCP_CHECK {
            connect_timeout 3
            retry 3
            delay_before_retry 3
        }
    }
    real_server 192.168.1.11 80 {
        weight 100
        TCP_CHECK {
            connect_timeout 3
            retry 3
            delay_before_retry 3
        }
    }
}

  注意,iptables中给数据包打上的mark值只是一个系统内核中数据结构,并不会实际改变数据包的内容,数据包ip头部中也没有mark的字段。所以备机上收到来自主机转发的请求中,是没有mark标记的,而备机的iptables中也限定了来自主机mac的请求不会打标记,所以请求是不会进入备机的LVS虚拟服务中,而是被RS服务直接处理。

MARK target介绍
图片内容参考来自 https://www.frozentux.net/iptables-tutorial/chunkyhtml/x4389.html

  下面介绍的mark标记和lvs工作分别对应netfilter框架中的位置,应该会有助于理解fwmark为什么能解决乒乓问题

netfilter框架
  如上图所示,对数据包打上mark标记是在mangle表的PREROUTING链中,而LVS捕获数据包是在filter表的INPUT链中。在netfilter框架中,数据包的流向是先经过PREROUTING链,再到INPUT链,所以打mark标记会先于LVS处理。
图片内容参考来自 http://www.austintek.com/LVS/LVS-HOWTO/HOWTO/LVS-HOWTO.filter_rules.html
# iptables -t nat -A PREROUTING -p tcp -m tcp -d $VIP --dport $PORT -j REDIRECT

  如果发生了主备切换,则需要在脚本中调整主备机中的这条iptables配置,将新主机中的配置清除,新备机中加上该配置。

  综合来看以上各种方法,更倾向于使用fwmark。方法一实现过于繁琐,也不利于故障快速切换。方法3需要在切换时更改对应角色的iptables配置,增加了切换的不稳定性。而fwmark在部署阶段配置好后则无需再变动,更为可靠。只是要注意防止系统重启导致iptables规则失效。

上一篇 下一篇

猜你喜欢

热点阅读