Pound+keepalivedでHTTPロードバランス&冗長化

VIP:192.168.10.200 VIP (Client接続先)
SV1:192.168.10.201 Pound Master
SV2:192.168.10.202 Pound Backup
HTTP1:192.168.10.211 Apache
HTTP2:192.168.10.212 Apache


上記のようにVIPでClientからの接続を受けます。
MasterになっているPoundからHTTP1、HTTP2へロードバランスをします。


keepalivedが停止する。もしくはローカルのPound経由のHTTPチェックに失敗すると
keepalivedがBackupに切り替わります。Masterが復旧すると処理がMasterに
切り替わります。


※HTTP監視は5秒サイクルで設定例として記述してありますが、
 サーバ負荷に気をつけながら運用上の最適化が必要です。
 インターバルが長ければ長いほど障害時のMaster切り替え時間に影響します。


※MasterもBackupもHTTPコネクト出来ないとVIPが停止してしまいます。
 この状態は重度の障害という事でここに記述してある自動化では
 対処しないで手動で対処するという考えでの設定例になっています。


SV1 /etc/pound/pound.cfg
pound設定ファイル

User "nobody"
Group "nobody"
RootJail "/usr/share/pound"
Control "/var/run/pound/ctl_socket"
Daemon 1
Alive 15

# Main listening ports
ListenHTTP
    Address 0.0.0.0
    Port    80
    xHTTP   1
    Client  300
    TimeOut 310
End
ListenHTTPS
    Address 0.0.0.0
    Port    443
    Cert    "/etc/pki/pound/pound.pem"
    Ciphers "ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL"
    xHTTP   1
End

# Catch-all server(s)
Service
    BackEnd
        Address 192.168.10.211
        Port    80
    End
    BackEnd
        Address 192.168.10.212
        Port    80
    End
    Session
        Type    Cookie
        ID      "JSESSIONID"
        TTL     1800
    End
End

SV1 /etc/keepalived/keepalived.conf
keepalived設定ファイル
※メール通知を省略してます。

! Configuration File for keepalived

global_defs {
   notification_email {
   }
}

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass passworddayo
    }
    virtual_ipaddress {
        192.168.10.200
    }
    notify_master "/etc/keepalived/checkStart.sh"
    notify_backup "/etc/keepalived/checkStart.sh"
}

SV1 /etc/keepalived/checkStart.sh
keepalived 動作時Pound正常動作監視起動シェル

#!/bin/sh

CHECK_SHELL=/etc/keepalived/check.sh
 
#チェック用シェルが起動されていたらkillする
CHEK_SHELL_PS=`ps -ef | grep $CHECK_SHELL | grep -v grep`
if [ -n "$CHEK_SHELL_PS" ] ; then
    for PID in `echo $CHEK_SHELL_PS | awk '{print $2}'` ; do
        echo "kill -9 $PID"
        kill -9 $PID
    done
fi

$CHECK_SHELL &
exit

SV1 /etc/keepalived/check.sh
keepalived 動作時Pound正常動作監視シェル
自分自身のPound経由でHTTP出来ない場合、keepalivedを停止してVRRP切替発動

#!/bin/sh

#監視開始直後のチェック無視時間
sleep 5

#チェックIP
CHECK_IP=192.168.10.201

#チェックPATH
CHECK_PATH=/index.html

#チェックURL
CHECK_URL=http://$CHECK_IP$CHECK_PATH

#STOPフラグ
STOP_FLAG=0

#STOPフラグしきい値
STOP_FLAG_LIMIT=5

while true ; do

    #監視インターバル
    sleep 5

    CODE=`/usr/bin/curl -s --head $CHECK_URL | head -n 1 | cut -f 2 -d ' '`

    if [ "$CODE" != "200" ]  ; then
         STOP_FLAG=`expr $STOP_FLAG + 1`
    else
         STOP_FLAG=0
    fi

    if [ "$STOP_FLAG" = "$STOP_FLAG_LIMIT" ] ; then
        echo "stop keepalived"
        /etc/rc.d/init.d/keepalived stop
        exit
    fi
done


SV2 /etc/pound/pound.cfg
pound設定ファイル

User "nobody"
Group "nobody"
RootJail "/usr/share/pound"
Control "/var/run/pound/ctl_socket"
Daemon 1
Alive 15

# Main listening ports
ListenHTTP
    Address 0.0.0.0
    Port    80
    xHTTP   1
    Client  300
    TimeOut 310
End
ListenHTTPS
    Address 0.0.0.0
    Port    443
    Cert    "/etc/pki/pound/pound.pem"
    Ciphers "ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL"
    xHTTP   1
End

# Catch-all server(s)
Service
    BackEnd
        Address 192.168.10.211
        Port    80
    End
    BackEnd
        Address 192.168.10.212
        Port    80
    End
    Session
        Type    Cookie
        ID      "JSESSIONID"
        TTL     1800
    End
End

SV2 /etc/keepalived/keepalived.conf
keepalived設定ファイル
※メール通知を省略してます。

! Configuration File for keepalived

global_defs {
   notification_email {
   }
}

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 50
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass passworddayo
    }
    virtual_ipaddress {
        192.168.10.200
    }
    notify_master "/etc/keepalived/checkStart.sh"
    notify_backup "/etc/keepalived/checkStart.sh"
}

SV2 /etc/keepalived/checkStart.sh
keepalived 動作時Pound正常動作監視起動シェル

#!/bin/sh

CHECK_SHELL=/etc/keepalived/check.sh
 
#チェック用シェルが起動されていたらkillする
CHEK_SHELL_PS=`ps -ef | grep $CHECK_SHELL | grep -v grep`
if [ -n "$CHEK_SHELL_PS" ] ; then
    for PID in `echo $CHEK_SHELL_PS | awk '{print $2}'` ; do
        "echo kill $PID"
        kill -9 $PID
    done
fi

$CHECK_SHELL &
exit

SV2 /etc/keepalived/check.sh
keepalived 動作時Pound正常動作監視シェル
Pound経由で5回HTTP通信に失敗した場合にkeepalivedを停止してVRRP切替発動

#!/bin/sh

#監視開始直後のチェック無視時間
sleep 5

#チェックIP
CHECK_IP=192.168.10.202

#チェックPATH
CHECK_PATH=/index.html

#チェックURL
CHECK_URL=http://$CHECK_IP$CHECK_PATH

#STOPフラグ
STOP_FLAG=0

#STOPフラグしきい値
STOP_FLAG_LIMIT=5

while true ; do

    #監視インターバル
    sleep 5

    CODE=`/usr/bin/curl -s --head $CHECK_URL | head -n 1 | cut -f 2 -d ' '`

    if [ "$CODE" != "200" ]  ; then
         STOP_FLAG=`expr $STOP_FLAG + 1`
    else
         STOP_FLAG=0
    fi

    if [ "$STOP_FLAG" = "$STOP_FLAG_LIMIT" ] ; then
        echo "stop keepalived"
        /etc/rc.d/init.d/keepalived stop
        exit
    fi
done


※Pound経由でのバックエンドのApacheへのアクセスは
 X-Forwarded-ForヘッダのIPアドレスにクライアントのIPアドレスが格納され、
 通常のIPアドレスはPoundのサーバのIPになるのでログやIPチェックのロジックで
 注意が必要です。