Keepalived 實現 Ambari-Server 高可用

LnEoi發表於2024-10-30

介紹

為什麼需要高可用

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

相關文章