從零開始掌握 HAProxy,也不難嘛!!!

HAProxy 是什麼

HAProxy 是一個免費的負載均衡軟件,可以運行於大部分主流的 Linux 操作系統上。

HAProxy 提供了 L4(TCP) 和 L7(HTTP) 兩種負載均衡能力,具備豐富的功能。HAProxy 的社區非常活躍,版本更新快速(最新穩定版 1.7.2 於 2017/01/13 推出)。最關鍵的是,HAProxy 具備媲美商用負載均衡器的性能和穩定性。

因爲 HAProxy 的上述優點,它當前不僅僅是免費負載均衡軟件的首選,更幾乎成爲了唯一選擇。

HAProxy 的核心功能

HAProxy 的關鍵特性

性能

穩定性

作爲建議以單進程模式運行的程序,HAProxy 對穩定性的要求是十分嚴苛的。按照作者的說法,HAProxy 在 13 年間從未出現過一個會導致其崩潰的 BUG,HAProxy 一旦成功啓動,除非操作系統或硬件故障,否則就不會崩潰(我覺得可能多少還是有誇大的成分)。

在上文中提到過,HAProxy 的大部分工作都是在操作系統內核完成的,所以 HAProxy 的穩定性主要依賴於操作系統,作者建議使用 2.6 或 3.x 的 Linux 內核,對 sysctls 參數進行精細的優化,並且確保主機有足夠的內存。這樣 HAProxy 就能夠持續滿負載穩定運行數年之久。

個人的建議:

net.ipv4.tcp_tw_reuse = 1
net.ipv4.ip_local_port_range = 1024 65023
net.ipv4.tcp_max_syn_backlog = 10240
net.ipv4.tcp_max_tw_buckets = 400000
net.ipv4.tcp_max_orphans = 60000
net.ipv4.tcp_synack_retries = 3
net.core.somaxconn = 10000

HAProxy 的安裝和運行

下面介紹在 CentOS7 中安裝和運行 HAProxy 最新穩定版 (1.7.2) 的方法

安裝

爲 HAProxy 創建用戶和用戶組,此例中用戶和用戶組都是 "ha"。注意,如果想要讓 HAProxy 監聽 1024 以下的端口,則需要以 root 用戶來啓動

下載並解壓

wget http://www.haproxy.org/download/1.7/src/haproxy-1.7.2.tar.gz
tar -xzf haproxy-1.7.2.tar.gz

編譯並安裝

make PREFIX=/home/ha/haproxy TARGET=linux2628
make install PREFIX=/home/ha/haproxy

PREFIX 爲指定的安裝路徑,TARGET 則根據當前操作系統內核版本指定:

- linux22     for Linux 2.2
- linux24     for Linux 2.4 and above (default)
- linux24e    for Linux 2.4 with support for a working epoll (> 0.21)
- linux26     for Linux 2.6 and above
- linux2628   for Linux 2.6.28, 3.x, and above (enables splice and tproxy)

此例中,我們的操作系統內核版本爲 3.10.0,所以 TARGET 指定爲 linux2628

創建 HAProxy 配置文件

mkdir -p /home/ha/haproxy/conf
vi /home/ha/haproxy/conf/haproxy.cfg

我們先創建一個最簡單配置文件:

global #全局屬性
    daemon  #以daemon方式在後臺運行
    maxconn 256  #最大同時256連接
    pidfile /home/ha/haproxy/conf/haproxy.pid  #指定保存HAProxy進程號的文件

defaults #默認參數
    mode http  #http模式
    timeout connect 5000ms  #連接server端超時5s
    timeout client 50000ms  #客戶端響應超時50s
    timeout server 50000ms  #server端響應超時50s

frontend http-in #前端服務http-in
    bind *:8080  #監聽8080端口
    default_backend servers  #請求轉發至名爲"servers"的後端服務

backend servers #後端服務servers
    server server1 127.0.0.1:8000 maxconn 32  #backend servers中只有一個後端服務,名字叫server1,起在本機的8000端口,HAProxy同時最多向這個服務發起32個連接

注意:HAProxy 要求系統的 ulimit -n 參數大於 [maxconn*2+18],在設置較大的 maxconn 時,注意檢查並修改 ulimit -n 參數

將 HAProxy 註冊爲系統服務

在 / etc/init.d 目錄下添加 HAProxy 服務的啓停腳本:

vi /etc/init.d/haproxy

#! /bin/sh
set -e

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/home/ha/haproxy/sbin
PROGDIR=/home/ha/haproxy
PROGNAME=haproxy
DAEMON=$PROGDIR/sbin/$PROGNAME
CONFIG=$PROGDIR/conf/$PROGNAME.cfg
PIDFILE=$PROGDIR/conf/$PROGNAME.pid
DESC="HAProxy daemon"
SCRIPTNAME=/etc/init.d/$PROGNAME

# Gracefully exit if the package has been removed.
test -x $DAEMON || exit 0

start()
{
       echo -e "Starting $DESC$PROGNAME\n"
       $DAEMON -f $CONFIG
       echo "."
}

stop()
{
       echo -e "Stopping $DESC$PROGNAME\n"
       haproxy_pid="$(cat $PIDFILE)"
       kill $haproxy_pid
       echo "."
}

restart()
{
       echo -e "Restarting $DESC$PROGNAME\n"
       $DAEMON -f $CONFIG -p $PIDFILE -sf $(cat $PIDFILE)
       echo "."
}

case "$1" in
 start)
       start
       ;;
 stop)
       stop
       ;;
 restart)
       restart
       ;;
 *)
       echo "Usage: $SCRIPTNAME {start|stop|restart}" >&2
       exit 1
       ;;
esac

exit 0

運行

啓動、停止和重啓:

service haproxy start
service haproxy stop
service haproxy restart

添加日誌

HAProxy 不會直接輸出文件日誌,所以我們要藉助 Linux 的 rsyslog 來讓 HAProxy 輸出日誌

修改 haproxy.cfg

在 global 域和 defaults 域中添加:

global
    ...
    log 127.0.0.1 local0 info
    log 127.0.0.1 local1 warning
    ...

defaults
    ...
    log global
    ...

意思是將 info 級(及以上)的日誌推送到 rsyslog 的 local0 接口,將 warn 級(及以上)的日誌推送到 rsyslog 的 local1 接口,並且所有 frontend 都默認使用 global 中的日誌配置。

注:info 級的日誌會打印 HAProxy 處理的每一條請求,會佔用很大的磁盤空間,在生產環境中,建議將日誌級別調整爲 notice

爲 rsyslog 添加 haproxy 日誌的配置

vi /etc/rsyslog.d/haproxy.conf
$ModLoad imudp
$UDPServerRun 514
$FileCreateMode 0644  #日誌文件的權限
$FileOwner ha  #日誌文件的owner
local0.*     /var/log/haproxy.log  #local0接口對應的日誌輸出文件
local1.*     /var/log/haproxy_warn.log  #local1接口對應的日誌輸出文件

修改 rsyslog 的啓動參數

vi /etc/sysconfig/rsyslog
# Options for rsyslogd
# Syslogd options are deprecated since rsyslog v3.
# If you want to use them, switch to compatibility mode 2 by "-c 2"
# See rsyslogd(8) for more details
SYSLOGD_OPTIONS="-c 2 -r -m 0"

重啓 rsyslog 和 HAProxy

service rsyslog restart
service haproxy restart

此時就應該能在 / var/log 目錄下看到 haproxy 的日誌文件了

用 logrotate 進行日誌切分

通過 rsyslog 輸出的日誌是不會進行切分的,所以需要依靠 Linux 提供的 logrotate(Linux 系統 Logrotate 服務介紹) 來進行切分工作

使用 root 用戶,創建 haproxy 日誌切分配置文件:

mkdir /root/logrotate
vi /root/logrotate/haproxy
/var/log/haproxy.log /var/log/haproxy_warn.log {  #切分的兩個文件名
    daily        #按天切分
    rotate 7     #保留7份
    create 0644 ha ha  #創建新文件的權限、用戶、用戶組
    compress     #壓縮舊日誌
    delaycompress  #延遲一天壓縮
    missingok    #忽略文件不存在的錯誤
    dateext      #舊日誌加上日誌後綴
    sharedscripts  #切分後的重啓腳本只運行一次
    postrotate   #切分後運行腳本重載rsyslog,讓rsyslog向新的日誌文件中輸出日誌
      /bin/kill -HUP $(/bin/cat /var/run/syslogd.pid 2>/dev/null) &>/dev/null
    endscript
}

並配置在 crontab 中運行:

0 0 * * * /usr/sbin/logrotate /root/logrotate/haproxy

HAProxy 搭建 L7 負載均衡器

總體方案

本節中,我們將使用 HAProxy 搭建一個 L7 負載均衡器,應用如下功能

架構如下:

架構中共有 6 個後端服務,劃分爲 3 組,每組中 2 個服務:

搭建後端服務

部署 6 個後端服務,可以使用任意的 Web 服務,如 Nginx、Apache HTTPD、Tomcat、Jetty 等,具體 Web 服務的安裝過程省略。

此例中,我們在 192.168.8.111 和 192.168.8.112 兩臺主機上分別安裝了 3 個 Nginx:

ms1.srv1 - 192.168.8.111:8080
ms1.srv2 - 192.168.8.112:8080
ms2.srv1 - 192.168.8.111:8081
ms2.srv2 - 192.168.8.112:8081
def.srv1 - 192.168.8.111:8082
def.srv2 - 192.168.8.112:8082

在這 6 個 Nginx 服務分別部署健康檢查頁面 healthCheck.html,頁面內容任意。確保通過 http://ip:port/healthCheck.html 可以訪問到這個頁面

接下來在 6 個 Nginx 服務中部署服務頁面:

demo.html 的內容,以部署在 192.168.8.111:8080 上的爲例:

Hello! This is ms1.srv1!

部署在 192.168.8.112:8080 上的就應該是

Hello! This is ms1.srv2!

以此類推

搭建 HAProxy

在 192.168.8.110 主機安裝 HAProxy,HAProxy 的安裝和配置步驟如上一章中描述,此處略去。

HAProxy 配置文件:

global
    daemon
    maxconn 30000   #ulimit -n至少爲60018
    user ha
    pidfile /home/ha/haproxy/conf/haproxy.pid
    log 127.0.0.1 local0 info
    log 127.0.0.1 local1 warning

defaults
    mode http
    log global
    option http-keep-alive   #使用keepAlive連接
    option forwardfor        #記錄客戶端IP在X-Forwarded-For頭域中
    option httplog           #開啓httplog,HAProxy會記錄更豐富的請求信息
    timeout connect 5000ms
    timeout client 10000ms
    timeout server 50000ms
    timeout http-request 20000ms    #從連接創建開始到從客戶端讀取完整HTTP請求的超時時間,用於避免類DoS攻擊
    option httpchk GET /healthCheck.html    #定義默認的健康檢查策略

frontend http-in
    bind *:9001
    maxconn 30000                    #定義此端口上的maxconn
    acl url_ms1 path_beg -i /ms1/    #定義ACL,當uri以/ms1/開頭時,ACL[url_ms1]爲true
    acl url_ms2 path_beg -i /ms2/    #同上,url_ms2
    use_backend ms1 if url_ms1       #當[url_ms1]爲true時,定向到後端服務羣ms1中
    use_backend ms2 if url_ms2       #當[url_ms2]爲true時,定向到後端服務羣ms2中
    default_backend default_servers  #其他情況時,定向到後端服務羣default_servers中

backend ms1    #定義後端服務羣ms1
    balance roundrobin    #使用RR負載均衡算法
    cookie HA_STICKY_ms1 insert indirect nocache    #會話保持策略,insert名爲"HA_STICKY_ms1"的cookie
    #定義後端server[ms1.srv1],請求定向到該server時會在響應中寫入cookie值[ms1.srv1]
    #針對此server的maxconn設置爲300
    #應用默認健康檢查策略,健康檢查間隔和超時時間爲2000ms,兩次成功視爲節點UP,三次失敗視爲節點DOWN
    server ms1.srv1 192.168.8.111:8080 cookie ms1.srv1 maxconn 300 check inter 2000ms rise 2 fall 3
    #同上,inter 2000ms rise 2 fall 3是默認值,可以省略
    server ms1.srv2 192.168.8.112:8080 cookie ms1.srv2 maxconn 300 check

backend ms2    #定義後端服務羣ms2
    balance roundrobin
    cookie HA_STICKY_ms2 insert indirect nocache
    server ms2.srv1 192.168.8.111:8081 cookie ms2.srv1 maxconn 300 check
    server ms2.srv2 192.168.8.112:8081 cookie ms2.srv2 maxconn 300 check

backend default_servers    #定義後端服務羣default_servers
    balance roundrobin
    cookie HA_STICKY_def insert indirect nocache
    server def.srv1 192.168.8.111:8082 cookie def.srv1 maxconn 300 check
    server def.srv2 192.168.8.112:8082 cookie def.srv2 maxconn 300 check

listen stats    #定義監控頁面
    bind *:1080                   #綁定端口1080
    stats refresh 30s             #每30秒更新監控數據
    stats uri /stats              #訪問監控頁面的uri
    stats realm HAProxyStats    #監控頁面的認證提示
    stats auth admin:admin        #監控頁面的用戶名和密碼

修改完成後,啓動 HAProxy

service haproxy start

測試

首先,訪問一下監控頁面 http://192.168.8.110:1080/stats 並按提示輸入用戶名密碼

接下來就能看到監控頁面:

監控頁面中列出了我們配置的所有 frontend 和 backend 服務,以及它們的詳細指標。如連接數,隊列情況,session rate,流量,後端服務的健康狀態等等

接下來,我們一一測試在 HAProxy 中配置的功能

健康檢查

從監控頁面中就可以直接看出健康檢查配置的是否正確,上圖中可以看到,backend ms1、ms2、default_servers 下屬的 6 個後端服務的 Status 都是 20h28m UP,代表健康狀態已持續了 20 小時 28 分鐘,而 LastChk 顯示 L7OK/200 in 1ms 則代表在 1ms 前進行了 L7 的健康檢查(即 HTTP 請求方式的健康檢查),返回碼爲 200

此時我們將 ms1.srv1 中的 healthCheck.html 改名

mv healthCheck.html healthCheck.html.bak

然後再去看監控頁面:

ms1.srv1 的狀態變成了 2s DOWN,LastChk 則是 L7STS/404 in 2ms,代表上次健康檢查返回了 404,再恢復 healthCheck.html,很快就能看到 ms1.srv1 重新恢復到 UP 狀態。

通過 URI 前綴轉發請求:訪問 http://192.168.8.110:9001/ms1/demo.html

可以看到成功定向到了 ms1.srv1 上

訪問 http://192.168.8.110:9001/ms2/demo.html :

訪問 http://192.168.8.110:9001/def/demo.html :

負載均衡和會話保持策略

在分別訪問過 ms1/demo.html, ms2/demo.html, m3/demo.html 後,查看一下瀏覽器的 Cookie

可以看到 HAProxy 已經回寫了三個用於會話保持的 cookie,此時反覆刷新這三個頁面,會發現總是被定向到 *.srv1 上

接下來我們刪除 HA_STICKY_ms1 這條 cookie,然後再訪問 ms1/demo.html,會看到

同時也被新寫入了一條 Cookie

如果發現仍然被定位到 ms1.srv1,同時也沒有寫入新的 HA_STICKY_ms1 Cookie,那麼可能是瀏覽器緩存了 ms1/demo.html 頁面,請求並沒有到達 HAProxy。F5 刷新一下應該就可以了。

HAProxy 搭建 L4 負載均衡器

HAProxy 作爲 L4 負載均衡器工作時,不會去解析任何與 HTTP 協議相關的內容,只在傳輸層對數據包進行處理。也就是說,以 L4 模式運行的 HAProxy,無法實現根據 URL 向不同後端轉發、通過 cookie 實現會話保持等功能。

同時,在 L4 模式下工作的 HAProxy 也無法提供監控頁面。

但作爲 L4 負載均衡器的 HAProxy 能夠提供更高的性能,適合於基於套接字的服務(如數據庫、消息隊列、RPC、郵件服務、Redis 等),或不需要邏輯規則判斷,並已實現了會話共享的 HTTP 服務。

總體方案

本例中,我們使用 HAProxy 以 L4 方式來代理兩個 HTTP 服務,不提供會話保持。

global
    daemon
    maxconn 30000   #ulimit -n至少爲60018
    user ha
    pidfile /home/ha/haproxy/conf/haproxy.pid
    log 127.0.0.1 local0 info
    log 127.0.0.1 local1 warning

defaults
    mode tcp
    log global
    option tcplog            #開啓tcplog
    timeout connect 5000ms
    timeout client 10000ms
    timeout server 10000ms   #TCP模式下,應將timeout client和timeout server設置爲一樣的值,以防止出現問題
    option httpchk GET /healthCheck.html    #定義默認的健康檢查策略

frontend http-in
    bind *:9002
    maxconn 30000                    #定義此端口上的maxconn
    default_backend default_servers  #請求定向至後端服務羣default_servers

backend default_servers    #定義後端服務羣default_servers
    balance roundrobin
    server def.srv1 192.168.8.111:8082 maxconn 300 check
    server def.srv2 192.168.8.112:8082 maxconn 300 check

L4 模式下的會話保持

雖然 TCP 模式下的 HAProxy 無法通過 HTTP Cookie 實現會話保持,但可以很方便的實現基於客戶端 IP 的會話保持。只需將

    balance roundrobin
改爲
    balance source

此外,HAProxy 提供了強大的 stick-table 功能,HAProxy 可以從傳輸層的數據包中採樣出大量的屬性,並將這些屬性作爲會話保持的策略寫入 stick-table 中。

HAProxy 關鍵配置詳解

總覽

HAProxy 的配置文件共有 5 個域

global:用於配置全局參數
default:用於配置所有frontend和backend的默認屬性
frontend:用於配置前端服務(即HAProxy自身提供的服務)實例
backend:用於配置後端服務(即HAProxy後面接的服務)實例組
listen:frontend+backend的組合配置,可以理解成更簡潔的配置方法

global 域的關鍵配置

daemon:指定HAProxy以後臺模式運行,通常情況下都應該使用這一配置
user [username] :指定HAProxy進程所屬的用戶
group [groupname] :指定HAProxy進程所屬的用戶組
log [address] [device] [maxlevel] [minlevel]:日誌輸出配置,如log 127.0.0.1 local0 info warning,即向本機rsyslog或syslog的local0輸出info到warning級別的日誌。其中[minlevel]可以省略。HAProxy的日誌共有8個級別,從高到低爲emerg/alert/crit/err/warning/notice/info/debug
pidfile :指定記錄HAProxy進程號的文件絕對路徑。主要用於HAProxy進程的停止和重啓動作。
maxconn :HAProxy進程同時處理的連接數,當連接數達到這一數值時,HAProxy將停止接收連接請求

frontend 域的關鍵配置

acl [name] [criterion] [flags] [operator] [value]:定義一條ACL,ACL是根據數據包的指定屬性以指定表達式計算出的true/false值。如"acl url_ms1 path_beg -i /ms1/"定義了名爲url_ms1的ACL,該ACL在請求uri以/ms1/開頭(忽略大小寫)時爲true
bind [ip]:[port]:frontend服務監聽的端口
default_backend [name]:frontend對應的默認backend
disabled:禁用此frontend
http-request [operation] [condition]:對所有到達此frontend的HTTP請求應用的策略,例如可以拒絕、要求認證、添加header、替換header、定義ACL等等。
http-response [operation] [condition]:對所有從此frontend返回的HTTP響應應用的策略,大體同上
log:同global域的log配置,僅應用於此frontend。如果要沿用global域的log配置,則此處配置爲log global
maxconn:同global域的maxconn,僅應用於此frontend
mode:此frontend的工作模式,主要有http和tcp兩種,對應L7和L4兩種負載均衡模式
option forwardfor:在請求中添加X-Forwarded-For Header,記錄客戶端ip
option http-keep-alive:以KeepAlive模式提供服務
option httpclose:與http-keep-alive對應,關閉KeepAlive模式,如果HAProxy主要提供的是接口類型的服務,可以考慮採用httpclose模式,以節省連接數資源。但如果這樣做了,接口的調用端將不能使用HTTP連接池
option httplog:開啓httplog,HAProxy將會以類似Apache HTTP或Nginx的格式來記錄請求日誌
option tcplog:開啓tcplog,HAProxy將會在日誌中記錄數據包在傳輸層的更多屬性
stats uri [uri]:在此frontend上開啓監控頁面,通過[uri]訪問
stats refresh [time]:監控數據刷新週期
stats auth [user]:[password]:監控頁面的認證用戶名密碼
timeout client [time]:指連接創建後,客戶端持續不發送數據的超時時間
timeout http-request [time]:指連接創建後,客戶端沒能發送完整HTTP請求的超時時間,主要用於防止DoS類攻擊,即創建連接後,以非常緩慢的速度發送請求包,導致HAProxy連接被長時間佔用
use_backend [backend] if|unless [acl]:與ACL搭配使用,在滿足/不滿足ACL時轉發至指定的backend

backend 域的關鍵配置

acl:同frontend域
balance [algorithm]:在此backend下所有server間的負載均衡算法,常用的有roundrobin和source,完整的算法說明見官方文檔configuration.html#4.2-balance
cookie:在backend server間啓用基於cookie的會話保持策略,最常用的是insert方式,如cookie HA_STICKY_ms1 insert indirect nocache,指HAProxy將在響應中插入名爲HA_STICKY_ms1的cookie,其值爲對應的server定義中指定的值,並根據請求中此cookie的值決定轉發至哪個server。indirect代表如果請求中已經帶有合法的HA_STICK_ms1 cookie,則HAProxy不會在響應中再次插入此cookie,nocache則代表禁止鏈路上的所有網關和緩存服務器緩存帶有Set-Cookie頭的響應。
default-server:用於指定此backend下所有server的默認設置。具體見下面的server配置。
disabled:禁用此backend
http-request/http-response:同frontend域
log:同frontend域
mode:同frontend域
option forwardfor:同frontend域
option http-keep-alive:同frontend域
option httpclose:同frontend域
option httpchk [METHOD] [URL] [VERSION]:定義以http方式進行的健康檢查策略。如option httpchk GET /healthCheck.html HTTP/1.1
option httplog:同frontend域
option tcplog:同frontend域
server [name] [ip]:[port] [params]:定義backend中的一個後端server,[params]用於指定這個server的參數,常用的包括有:
check:指定此參數時,HAProxy將會對此server執行健康檢查,檢查方法在option httpchk中配置。同時還可以在check後指定inter, rise, fall三個參數,分別代表健康檢查的週期、連續幾次成功認爲server UP,連續幾次失敗認爲server DOWN,默認值是inter 2000ms rise 2 fall 3
cookie [value]:用於配合基於cookie的會話保持,如cookie ms1.srv1代表交由此server處理的請求會在響應中寫入值爲ms1.srv1的cookie(具體的cookie名則在backend域中的cookie設置中指定)
maxconn:指HAProxy最多同時向此server發起的連接數,當連接數到達maxconn後,向此server發起的新連接會進入等待隊列。默認爲0,即無限
maxqueue:等待隊列的長度,當隊列已滿後,後續請求將會發至此backend下的其他server,默認爲0,即無限
weight:server的權重,0-256,權重越大,分給這個server的請求就越多。weight爲0的server將不會被分配任何新的連接。所有server默認weight爲1

timeout connect [time]:指HAProxy嘗試與backend server創建連接的超時時間
timeout check [time]:默認情況下,健康檢查的連接+響應超時時間爲server命令中指定的inter值,如果配置了timeout check,HAProxy會以inter作爲健康檢查請求的連接超時時間,並以timeout check的值作爲健康檢查請求的響應超時時間
timeout server [time]:指backend server響應HAProxy請求的超時時間

default 域

上文所屬的frontend和backend域關鍵配置中,除acl、bind、http-request、http-response、use_backend外,其餘的均可以配置在default域中。default域中配置了的項目,如果在frontend或backend域中沒有配置,將會使用default域中的配置。

listen 域

listen域是frontend域和backend域的組合,frontend域和backend域中所有的配置都可以配置在listen域下

使用 Keepalived 實現 HAProxy 高可用

儘管 HAProxy 非常穩定,但仍然無法規避操作系統故障、主機硬件故障、網絡故障甚至斷電帶來的風險。所以必須對 HAProxy 實施高可用方案。

下文將介紹利用 Keepalived 實現的 HAProxy 熱備方案。即兩臺主機上的兩個 HAProxy 實例同時在線,其中權重較高的實例爲 MASTER,MASTER 出現問題時,另一臺實例自動接管所有流量。

原理

在兩臺 HAProxy 的主機上分別運行着一個 Keepalived 實例,這兩個 Keepalived 爭搶同一個虛 IP 地址,兩個 HAProxy 也嘗試去綁定這同一個虛 IP 地址上的端口。顯然,同時只能有一個 Keepalived 搶到這個虛 IP,搶到了這個虛 IP 的 Keepalived 主機上的 HAProxy 便是當前的 MASTER。Keepalived 內部維護一個權重值,權重值最高的 Keepalived 實例能夠搶到虛 IP。同時 Keepalived 會定期 check 本主機上的 HAProxy 狀態,狀態 OK 時權重值增加。

搭建 HAProxy 主備集羣

環境準備

在兩臺物理機上安裝並配置 HAProxy,本例中,將在 192.168.8.110 和 192.168.8.111 兩臺主機上上安裝兩套完全一樣的 HAProxy,具體步驟省略,請參考 “使用 HAProxy 搭建 L7 負載均衡器” 一節。

安裝 Keepalived

下載,解壓,編譯,安裝:

wget http://www.keepalived.org/software/keepalived-1.2.19.tar.gz
tar -xzf keepalived-1.2.19.tar.gz
./configure --prefix=/usr/local/keepalived
make
make install

註冊爲系統服務:

cp /usr/local/keepalived/sbin/keepalived /usr/sbin/
cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
cp /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/
chmod +x /etc/init.d/keepalived

注意:Keepalived 需要使用 root 用戶進行安裝和配置

配置 Keepalived

創建並編輯配置文件

mkdir -p /etc/keepalived/
cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/
vi /etc/keepalived/keepalived.conf

配置文件內容:

global_defs {
    router_id LVS_DEVEL  #虛擬路由名稱
}

#HAProxy健康檢查配置
vrrp_script chk_haproxy {
    script "killall -0 haproxy"  #使用killall -0檢查haproxy實例是否存在,性能高於ps命令
    interval 2   #腳本運行週期
    weight 2   #每次檢查的加權權重值
}

#虛擬路由配置
vrrp_instance VI_1 {
    state MASTER           #本機實例狀態,MASTER/BACKUP,備機配置文件中請寫BACKUP
    interface enp0s25      #本機網卡名稱,使用ifconfig命令查看
    virtual_router_id 51   #虛擬路由編號,主備機保持一致
    priority 101           #本機初始權重,備機請填寫小於主機的值(例如100)
    advert_int 1           #爭搶虛地址的週期,秒
    virtual_ipaddress {
        192.168.8.201      #虛地址IP,主備機保持一致
    }
    track_script {
        chk_haproxy        #對應的健康檢查配置
    }
}

如果主機沒有 killall 命令,則需要安裝 psmisc 包:

yum intall psmisc

分別啓動兩個 Keepalived

service keepalived start

驗證

啓動後,先分別在兩臺主機查看虛 IP 192.168.8.201 由誰持有,執行命令:

ip addr sh enp0s25   (將enp0s25替換成主機的網卡名)

持有虛 IP 的主機輸出會是這樣的:

另一臺主機輸出則是這樣的:

如果你先啓動備機的 Keepalived,那麼很有可能虛 IP 會被備機搶到,因爲備機的權重配置只比主機低 1,只要執行一次健康檢查就能把權重提高到 102,高於主機的 101。

此時訪問 http://192.168.8.201:9001/ms1/demo.html ,可以看到我們先前部署的網頁。

此時,檢查 / var/log/haproxy.log,能看到此請求落在了搶到了虛 IP 的主機上。

接下來,我們停掉當前 MASTER 主機的 HAProxy 實例(或者 Keepalive 實例,效果一樣)

service haproxy stop

再次訪問 http://192.168.8.201:9001/ms1/demo.html ,並查看備機的 / var/log/haproxy.log,會看到此請求落在了備機上,主備自動切換成功。

也可以再次執行 ip addr sh enp0s25 命令,會看到虛 IP 被備機搶去了。

在 / var/log/message 中,也能夠看到 keepalived 輸出的切換日誌:

作者:kelgon

鏈接:https://www.jianshu.com/p/c9f6d55288c0

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/6MxP3fZ0aHz-0e4SXQMFiA