介绍
为什么需要高可用
高可用(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 来定制,这块与当前无关,具体的可以查看相关文档了解。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。