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