介紹
為什麼需要高可用
高可用(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 來定製,這塊與當前無關,具體的可以查看相關文檔瞭解。