介绍

为什么需要高可用

高可用(High Availability, HA),通过设计减少系统不能提供服务的时间。

在日常业务场景中,容易因为某个服务故障导致功能出错、用户无法访问。高可用的核心思想就是提供冗余的资源,当某个服务故障后其他服务可以顶替,保障服务能够持续使用。在数据层面就是冗余备份,在服务层面就是故障转移。

很多服务自身有提供高可用的能力,如果服务本身没提供此能力,我们也不是束手无措,还能通过其他工具来实现故障转移能力,例如 Keepalived、Heartbeat。

Keepalived

Keepalived 目标是为 Linux 和基于 Linux 的系统提供简单而强大的负载平衡和高可用设施。相对于 Heartbeat 来说,Keepalived 更加的轻量易用。

Keepalived 的负载均衡能力是通过 Linux 内核模块中的 LVS (Linux Virtual Server, Linux虚拟服务器) 实现。高可用是通过 VRRP(virtual router redundancy protocol, 虚拟路由冗余协议)实现。

VRRP 主要实现功能:虚拟路由器、虚拟IP,Master 广播 ARP、Backup选举。Keepalived 可以提供一个虚IP,这个虚拟IP绑定在 Master 节点上。Master 会定期向所有 Backup 节点发送 VRRP 广播心跳,当未收到心跳时,Backup 会竞选出新的 Master 节点,将虚拟IP绑定在此节点上,可以做到外部无感。

配置流程

Ambari-Server

Ambari-Server(网页管理端)自身没提供高可用的方案,所以我们不得不借助外部服务来实现,Keepalived 就是一个很不错的选择。

安装

ambar-server setup

安装过程照旧,Ambari-Server 数据库初始化是手动进行的,setup 时无需担心,按正常流程操作。

也可以将之前的那份配置文件复制到 /etc/ambari-server/conf/ambari.properties ,setup的时候会自动读取其中配置,可以省一些操作。

启动

ambar-server start

正常启动确认可用后,可以开始 Keepalived 的配置了。

Keepalived

安装

yum install -y keepalived

检查安装是否成功

keepalived -v

其他一些控制命令

# 重启
systemctl restart keepalived.service

# 停止
systemctl stop keepalived.service

# 当前状态
systemctl status keepalived.service

# 设置开机启动
chkconfig keepalived on

# 查看进程
ps -ef | grep keepalived

配置

配置文件位置:/etc/keepalived/keepalived.conf

默认全局配置:/etc/sysconfig/keepalived (不存在则自行创建)

日志位置:/var/log/messages

每台服务都得配置,主要是当前路由ID、本机IP、网卡得变更,其他像是密码、虚拟路由ID、虚拟IP之类都需要保持一样才能互通,具体看注释。

所有配置时间单位是,精度可到微秒。布尔值支持好几种表达方式:on | off | true | false | yes | no

! Configuration File for keepalived

global_defs {
   # notification_email {             # 邮件通知
   #   test1@mail.com
   # }
   # notification_email_from test@mail.com
   router_id hostname1                # 路由id 设置为hostname即可
}

vrrp_script chk_ambari {
       script "/etc/keepalived/check.sh"
       interval 2                     # 检测间隔 单位秒
       weight -20                     # 失败一次扣除的优先级值
       # rise 1                       # 几次转为成功状态 
       # fall 1                       # 几次转为失败状态 
       # init_fail                    # 初始状态为失败状态 
       # user USERNAME [GROUPNAME]    # 运行的用户名与用户组
}

vrrp_instance VI_1 {
    state MASTER                     # 标识节点服务 MASTER BACKUP 
    interface eth0                     # 绑定的网卡
    virtual_router_id 10             # 虚拟路由id 需要和备节点保持一致
    priority 100                      # 优先级(0 ~ 255) 主节点时需要比备节点高
    # nopreempt                         # 不抢占模式
    # smtp_alert                     # 激活故障时发送邮件告警
    mcast_src_ip 10.20.10.100         # 本机IP
    advert_int 1                     # 节点之间的同步检查时间间隔 单位秒
    authentication {                 # 验证类型和验证密码
        auth_type PASS                 # 认证方式 简单密码 PASS(推荐,最大八位) IPSEC认证头 AH 
        auth_pass ambari             # 使用相同明文才可以互通
    }
    virtual_ipaddress {                 # 虚拟IP池
        10.20.10.200                 # 虚拟IP1
    }
    track_script {                   # 状态检测脚本
       chk_ambari
    }
}

上面是主节点,备节点基本一样,除了本机IP、网卡等专属信息需要改,其他配置差异在:state 值为 BACKUP、priority 值需要比主节点低。

priority 和 weight

  • priority 和 weight 值

    priority 值与主服务选举密切相关,可以按以下公式配置:

    abs(MASTER priority - BAKCUP priority) < abs(weight)

    如果主服务 priority 值太高、备服务值太小,或者 weight 值过小,可能主服务失效很久但因为扣除 weight 值还是比备服务高,导致无法切换成功。

  • priority 值复原

    当主节点 priority 值到 0 或过小时,又是非抢占模式,此时如果主节点再次启动也因为 priority 值问题无法选举成功。

抢占模式/非抢占模式

抢占模式:默认的模式。主节点故障后,备节点会选举出新的主节点。当主节点故障恢复后,会重新接替继续变成主节点。

非抢占模式:配置中使用 nopreempt,并且 state 必须设置为 BACKUP 。当前配置使用的就是非抢占模式。

另外还能配置多主模式:需要在配置中将所有 vrrp_instance 写出,然后将当前主机需要的节点配置 MASTER 即可。

添加检测脚本

配置文件中依赖 vrrp_script来添加我们的检测逻辑,在vrrp_instance中添加track_script指定使用检测规则的名称。上面配置中 shell 是我们的检测脚本,脚本执行返回0代表服务正常,返回非0代表服务异常。

ambari-server 有提供 api 接口返回服务信息

curl -u admin:admin -X GET http://192.168.99.60:8080/api/v1/check

更简单的,ambari-server 默认会在目录下生成 pid,找到这个文件路径读取文件就能判断服务是否正常。

#!/bin/bash

PID_FILE="/var/run/ambari-server/ambari-server.pid"

if [ -f "$PID_FILE" ]; then
    PID=$(cat "$PID_FILE")
    echo "Ambari Server is running with PID: $PID"
    exit 0
else
    echo "Ambari Server is stopped."
    exit 1
fi

如果要自动启动,但由于 Ambari-Server 启动比较慢,所以增加了二次检测,并且更换了存活状态的判断

#!/bin/bash

# CURL检测 1启用 0禁用
CURL_CHECK_ENABLE=1
AMBARI_USERNAME="admin"
AMBARI_PASSWORD="admin"
HOST=$(hostname -I | awk '{print $1}')
PORT=8080


# CURL检查函数
check_status() {
    log "curl -u \"$AMBARI_USERNAME:$AMBARI_PASSWORD\" -s -X GET \"http://$HOST:$PORT/api/v1/check\""
    RESPONSE=$(curl -u "$AMBARI_USERNAME:$AMBARI_PASSWORD" -s -X GET "http://$HOST:$PORT/api/v1/check")
    # 判断返回数据是否包含RUNNING
    if echo "$RESPONSE" | grep -q "RUNNING"; then
        log "Ambari Server api check: success."
        return 0
    else
        log "Ambari Server api check failed."
        return 1
    fi
}

# 日志
LOG_ENABLED=0
LOG_FILE="/etc/keepalived/check-ambari.log"
log() {
    if [ "$LOG_ENABLED" -eq 1 ] && [ -d "$(dirname "$LOG_FILE")" ]; then
        echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
    fi
}

# 重启服务
LOCK_FILE="/etc/keepalived/ambari.lock"
ambari_restart() {
    # 检查锁是否存在
    if [ -f "$LOCK_FILE" ]; then
        log "Ambari Server is already restarting. Exiting."
        exit 1
    fi

    touch "$LOCK_FILE"

    # ambari restart
    log "Ambari Server is restarting..."
    ambari-server restart

    # 删除锁文件
    rm -f "$LOCK_FILE"
}

# 检查
PID=$(pgrep -f AmbariServer)
if [ -n "$PID" ]; then
    rm -f "$LOCK_FILE"
    log "Ambari Server is running with PID: $PID"
    
    # 是否启用curl检测
    if [ "$CURL_CHECK_ENABLE" -eq 1 ]; then
        exit $(check_status)
    else
        exit 0  # 服务正常
    fi
else
    log "Ambari Server is stopped."
    ambari_restart
    exit 1  # 服务异常
fi

检测

  • 检查虚拟IP是否生效

    ip addr show

    查看生效节点配置的网卡是否增加了指定的IP,此时其他节点不会绑定虚拟IP,当主节点失效时,虚拟IP会漂移到新选举出来的节点上。

  • IP自动漂移

    可以手动让服务失效,来检测IP自动漂移是否成功。

    ambari-server stop

    此时再输入命令可以看到 IP 绑定到新选举出的节点上,并且服务也能正常访问,说明检测脚本与IP漂移都成功了。

在调研时有查到一些方案,但相对的都更加复杂,维护的脚本也需要更多的逻辑才能保证服务的健壮性。引入 Keepalived 后,得益于 Keepalived 的简单易用,我们可以非常快速的完成服务的搭建。

Keepalived 除了高可用,另一大功能就是负载均衡,配置中通过 virtual_server 来定制,这块与当前无关,具体的可以查看相关文档了解。


LnEoi
707 声望17 粉丝

引用和评论

0 条评论