美文网首页
KeepAliveD in AWS

KeepAliveD in AWS

作者: 华阳_3bcf | 来源:发表于2018-06-08 22:11 被阅读0次

    KeepAliveD in AWS

    需求

    在AWS环境,已有两台服务器安装Mysql,并配置为主主模式(Active/Active)。要求实现一种方案,当一个Mysql故障后,能自动切换到另一Mysql服务器,提供服务的高可用。

    操作系统要求: ubuntu14.04

    前期调研

    想在AWS 环境实现数据库的高可用,考虑了方案:

    • RDS -- AWS服务,使用DNS 实现服务切换,耗时1分钟-- 时间太长,不满足需求
    • ELB -- AWS服务,本质是实现负载均衡。不能实现Active/Passive 模式 -- 不满足需求
    • Haproxy -- 使用 Active/Passive模式,能够实现Mysql服务的切换,切换耗时15秒。但这个方案需要一个新的VM,在解决一个问题的同时,引入了一个新的单点故障。 -- 放弃
    • Veritas -- 传统的HA方案,是商业软件,需要额外付费。配置的时候需要双网卡来配置心跳检测网络。这种网卡冗余方案在公有云中不合时宜——先跳过,如果其他方案不可行,再回过头来看。
    • HeartBeat -- 需要单独网络做心跳检查 -- 先跳过。
    • KeepAliveD -- 公司其他部门使用KeepAliveD+Apache实现Web高可用,是一套成熟,可靠的方案。而且服务切换只需要3-5秒,效率很高。

    选择方案

    最后考虑 AWS 环境中部署keepalived + Mysql 实现高可用。

    KeepAliveD 工作原理

    Keepalived是一个免费开源的,用C编写的类似于layer3, 4 & 7交换机制软件,具备我们平时说的第3层、第4层和第7层交换机的功能。主要提供loadbalancing(负载均衡)和 high-availability(高可用)功能,负载均衡实现需要依赖Linux的虚拟服务内核模块(ipvs),而高可用是通过VRRP协议实现多台机器之间的故障转移服务。

    简单来说,只需要把它当作路由器即可!

    VRRP协议

    网络在设计的时候必须考虑到冗余容灾,包括线路冗余,设备冗余等,防止网络存在单点故障,那在路由器或三层交换机处实现冗余就显得尤为重要,在网络里面有个协议就是来做这事的,这个协议就是VRRP协议,Keepalived就是巧用VRRP协议来实现高可用性(HA)的。

    遇到的问题:

      1. 通过命令 “apt install keepalived” 安装包不可用。
      1. 亚马逊云不支持KeepAliveD中的组播模式。主备之间的VRRP包互相发不通。
      1. 在AWS环境中,所有的ARP广播都被禁止了。这样KeepAliveD的IP欺骗机制基本上也就不可行了。在资源服务器上配置的Virtual IP,应用服务器没有办法访问。
        VIP的默认配置是不生效的:(AWS 中,只有本机认可,没有广播,其他服务器不知道)

    解决办法:

      1. 需要下载源码包,并针对ubuntu 做修改(源码适用redhat)。
      1. 切换KeepAliveD到单播模式,在配置中增加单播机器的IP:
    
    unicast_src_ip 172.*.*.1 #localIp
    
    unicast_peer {
    172.*.*.124 #Resource-02
    
    }
    
    

    还有一点需要特别注意,VRRP协议既不属于TCP也不属于UDP,在做防火墙策略的时候,在协议类型选项需要选“All traffice”的选项来防止由于防火墙原因造成通信问题。

      1. 用 AWS CLI 来实现 VIP 指向的切换
      • 3.1.1 如果使用private IP作为 VIP,则:两个服务器配置三个IP 地址,其中一个是 Secondary private IP,它作为内网的VIP使用。这个配置是基础配置。也就是说,如果一个IP指向这台服务器,可是这台服务器上的网卡不认为自己拥有这个IP是不行的。

      • 3.1.2 如果Public IP (EIP) 作为 VIP,配置相对简单,可以跳过Secondary private IP

      • 3.2 在两台服务器上安装亚马逊云自己的客户端工具(awscli) 并配置(Authentication,IP 切换时使用)

      • 3.3 在KeepAliveD认为自己获取到Master权限的时候,调用awscli命令让Virtual IP实际指向本服务器。这个逻辑是核心逻辑。亚马逊云虽然不允许广播ARP,但可以用命令行指定网卡(ENI)的Secondary-private-ip-address。这个命令的具体形式如下:

    
    su - ubuntu -c "aws ec2 assign-private-ip-addresses --network-interface-id $ENI --private-ip-addresses $VIP --allow-reassignment"
    ip address add $VIP/20 dev eth0
    
    
    

    $ENI指的是网卡的ID,$VIP是虚拟IP,分配Private IP后,必须用ip命令把它启用(OS 能识别出这个变化) (具体原因的官方解释

    【已知问题】keepalived 被停掉后,因script 无法被调用,导致本机VIP无法被删除,于是本机的VIP连接继续指向本地,其它服务器不受影响。也就是说本机Mysql继续认为自己是主服务器,但由于没有外部数据写入,虽然它是错的,但也没有实质的影响。

    【注】使用EIP无此问题。(直接从AWS云平台获取Public IP,没有到OS这一级)

    如果把外网EIP作为VIP,则:

    aws ec2 disassociate-address --public-ip $EIP
    aws ec2 associate-address --public-ip $EIP --instance-id $INSTANCE_ID
    
    

    EIP(Elastic IP) 是外网IP,先释放,再分给某个instance

    安装步骤

    在ubuntu14平台,两台Mysql Server所在的服务器都安装和配置KeepAliveD。

    安装依赖

    $ sudo apt update
    $ sudo apt install libssl-dev gcc make awscli daemon

    下载源包并编译

    $ wget http://www.keepalived.org/software/keepalived-1.3.9.tar.gz
    $ tar zxf keepalived-1.3.9.tar.gz
    $ cd keepalived-1.3.9
    $ ./configure --prefix=/usr/local/keepalived --sysconf=/etc

    编译结果:

    Keepalived configuration
    ------------------------
    Keepalived version       : 1.3.9
    Compiler                 : gcc
    Preprocessor flags       :
    Compiler flags           : -Wall -Wunused -Wstrict-prototypes -Wextra -g -O2
    Linker flags             :
    Extra Lib                :  -lcrypto  -lssl
    Use IPVS Framework       : Yes
    IPVS use libnl           : No
    IPVS syncd attributes    : No
    IPVS 64 bit stats        : No
    fwmark socket support    : Yes
    Use VRRP Framework       : Yes
    Use VRRP VMAC            : Yes
    Use VRRP authentication  : Yes
    With ip rules/routes     : Yes
    SNMP vrrp support        : No
    SNMP checker support     : No
    SNMP RFCv2 support       : No
    SNMP RFCv3 support       : No
    DBUS support             : No
    SHA1 support             : No
    Use Debug flags          : No
    Use Json output          : No
    Stacktrace support       : No
    Memory alloc check       : No
    libnl version            : None
    Use IPv4 devconf         : No
    Use libiptc              : No
    Use libipset             : No
    init type                : upstart
    Build genhash            : Yes
    Build documentation      : No
    *** WARNING - this build will not support IPVS with IPv6. Please install libnl/libnl-3 dev libraries to support IPv6 with IPVS.
    
    

    Install

    $ make
    $ sudo make install

    针对ubuntu 修改配置:

    $ sudo cp keepalived/etc/init.d/keepalived /etc/init.d
    $ sudo vi /etc/init.d/keepalived

    修改启动脚本 /etc/init.d/keepalived

    . /etc/rc/d/init.d/functions #注释这句,新增下行
    . /lib/lsb/init-functions
    daemon keepalived ${KEEPALIVED_OPTIONS} #注释该行,新增下行
    daemon keepalived start

    $ sudo mkdir -p /var/lock/subsys

    拷贝运行的核心文件

    $ sudo cp /usr/local/keepalived/sbin/keepalived /usr/sbin/

    $ sudo vi /etc/keepalived/keepalived.conf #运行的配置文件

    For master:

    配置分为三部分:
    global_defs 全局配置
    vrrp_script 服务健康检查脚本
    vrrp_instance 完成keepalived 服务健康检查,VIP切换

    global_defs {
        router_id backup_cluster # 标识本节点的字符串,通常为hostname,但不一定非得是hostname,故障发生时,邮件通知会用到
    }
    vrrp_script chk_mysql {
        script "killall -0 mysqld"     # 监控服务脚本,尽量简单,判断返回值0 或非0
        interval 2   # check every 2 seconds
        fall 2       # require 2 failures for KO
        rise 2       # require 2 successes for OK
    }
    vrrp_instance VI_1 {  # 实例名称
        state BACKUP      # 可以是MASTER或BACKUP,不过当其他节点keepalived启动时会将priority比较大的节点选举为MASTER
        interface eth0    # 节点固有IP(非VIP)的网卡,用来发VRRP包做心跳检测
        priority 100      # 用来选举master的,要成为master那么这个选项的值最好高于其他机器50个点,该项取值范围是1-255(在此范围之外会被识别成默认值100)
        nopreempt       # 服务恢复后成为backup, 不会抢回master避免频繁切换
        virtual_router_id 51 # 虚拟路由ID,取值在0-255之间,用来区分多个instance的VRRP组播,同一网段内ID不能重复;主备必须为一样;
        unicast_src_ip 172.31.19.247  # AWS中组播被禁,采用点对点通信。 这是本机IP
        unicast_peer {
        172.31.21.194  # 这是另一台keepalive server IP
        }
        advert_int 1      # 检查间隔默认为1秒,即1秒进行一次master选举
        authentication {  # 认证区域,认证类型有PASS和HA(IPSEC),推荐使用PASS(密码只识别前8位)
            auth_type PASS  # 默认是PASS认证
            auth_pass MrUse # PASS认证密码
        }
        track_script {
            chk_mysql
        }
        notify   /etc/keepalived/failover.sh
     }
    
    

    For Backup:

    
    global_defs {
        router_id backup_cluster # 标识本节点的字符串,通常为hostname,但不一定非得是hostname,故障发生时,邮件通知会用到
    }
    vrrp_script chk_mysql {
        script "killall -0 mysqld"
        interval 2
    }
    vrrp_instance VI_1 {  # 实例名称
        state BACKUP      # 可以是MASTER或BACKUP,不过当其他节点keepalived启动时会将priority比较大的节点选举为MASTER
        interface eth0    # 节点固有IP(非VIP)的网卡,用来发VRRP包做心跳检测
        priority 40      # 用来选举master的,要成为master那么这个选项的值最好高于其他机器50个点,该项取值范围是1-255(在此范围之外会被识别成默认值100)
        virtual_router_id 51 # 虚拟路由ID,取值在0-255之间,用来区分多个instance的VRRP组播,同一网段内ID不能重复;主备必须为一样;
        unicast_src_ip 172.31.21.194  # 跟master 设置反过来
        unicast_peer {
        172.31.19.247
        }
        advert_int 1      # 检查间隔默认为1秒,即1秒进行一次master选举
        authentication {  # 认证区域,认证类型有PASS和HA(IPSEC),推荐使用PASS(密码只识别前8位)
            auth_type PASS  # 默认是PASS认证
            auth_pass MrUse # PASS认证密码
        }
        track_script {
            chk_mysql
        }
        notify   /etc/keepalived/failover.sh
        #notify_master /etc/keepalived/master.sh
        #notify_backup /etc/keepalived/backup.sh
        #notify_fault     /etc/keepalived/fault.sh
        
    }
    
    

    Keepalived notify脚本

    notify脚本是keepalived集群管理脚本,当keepalived角色state状态发生变化时都会执行这个脚本。 AWS中默认方法不可行,只能靠它来实现IP切换。

    例子

    配置aws cli:

    aws cli 认证方法

    获取网卡 eni 信息:

    $ aws ec2 describe-instances --instance-ids i-0f530d6377bcd4db9 --query Reservations[].Instances[].NetworkInterfaces[].NetworkInterfaceId
    [
        "eni-ee4c45c6"
    ]
    
    

    or

     $ aws ec2 describe-instances --instance-ids i-0f530d6377bcd4db9 | grep eni
    

    网页上也能查到:

    Snip20180611_3.png

    VIP 切换脚本:

    failover.sh

    
    #!/bin/bash
    VIP=172.31.31.31
    ENI=eni-8df310ac  ## 这是本机eth0 网卡的ID,另一server不同
    LOG=/etc/keepalived/failover.log
    TYPE=$1
    NAME=$2
    STATE=$3
    echo -e "\n##### failover to $STATE status ######" >> ${LOG}
    date >> ${LOG}
    case $STATE in
        "MASTER")
            su - ubuntu -c "/usr/bin/aws ec2 assign-private-ip-addresses --network-interface-id $ENI --private-ip-addresses $VIP --allow-reassignment" >> ${LOG} 2>&1
            ip address add $VIP/20 dev eth0 >> ${LOG} 2>&1
            echo -e "##### complete master script for ${NAME} ######\n" >> ${LOG}
              ;;
        "BACKUP"|"FAULT")
            ip address del $VIP/20 dev eth0 >> ${LOG} 2>&1
            echo -e "#####  complete $STATE script for VRRP ${TYPE} ${NAME} ######\n" >> ${LOG}
              ;;
        *)
            echo "unknown state ${STATE} for VRRP ${TYPE} ${NAME}"
            exit 1
            ;;
    esac
    
    

    后续服务启动和检查

    添加为系统服务

    $ sudo update-rc.d keepalived defaults

    启动keepalived

    $ sudo /etc/init.d/keepalived start

    查看keepalived 日志

    $ tail -f /var/log/syslog

    查看自定义脚本生成的日志

    $ tail /etc/keepalived/failover.sh

    mysql 连接测试

    $ mysql -uhive -phive -h172.31.31.31

    相关文章

      网友评论

          本文标题:KeepAliveD in AWS

          本文链接:https://www.haomeiwen.com/subject/gyrzsftx.html