1勤众、簡述keepalived工作原理
總的來說keepalived的功能主要有兩個:
1、集群中各個服務(wù)節(jié)點的健康狀態(tài)檢查
2酪术、服務(wù)的高可用
原理:
Keepalived高可用對之間是通過 VRRP進行通信的陆盘, VRRP是通過競選機制來確定主備的株汉,主的優(yōu)先級高于備,因此液茎,工作時主會優(yōu)先獲得所有的資源矾削,備節(jié)點處于等待狀態(tài)壤玫,當主宕機的時候,備節(jié)點就會接管主節(jié)點的資源哼凯,然后頂替主節(jié)點對外提供服務(wù)欲间;
在Keepalived服務(wù)對之間,只有作為主的服務(wù)器會一直發(fā)送 VRRP廣播包,告訴備它還活著断部,此時備不會搶占主猎贴,當主不可用時,即備監(jiān)聽不到主發(fā)送的廣播包時蝴光,就會啟動相關(guān)服務(wù)接管資源通過選舉形式來選擇新的主她渴,保證業(yè)務(wù)的連續(xù)性.接管速度最快。
1-2蔑祟、什么是腦裂
在高可用的系統(tǒng)中趁耗,當聯(lián)系的兩個節(jié)點之間的‘心跳線’斷開時,本來為一個整體疆虚、動作協(xié)調(diào)的HA系統(tǒng)苛败,就分裂成為2個獨立的個體。相互之間失去了聯(lián)系径簿,都以為對方出現(xiàn)了故障罢屈。兩個故障節(jié)點上機器,爭搶“共享資源”篇亭、爭起“應用服務(wù)”缠捌,就會出現(xiàn)嚴重的后果,兩邊的服務(wù)都起不來或者兩邊的服務(wù)同時起來译蒂,同時提供讀寫服務(wù)曼月,導致數(shù)據(jù)被破壞。
1-3柔昼、腦裂產(chǎn)生的原因
1十嘿、高可用服務(wù)器(keepalived)之間的心跳線路發(fā)生故障,到時無法正常通信
2岳锁、心跳線壞了(斷了绩衷、或者老化)
3、因網(wǎng)卡及相關(guān)驅(qū)動壞了激率,ip配置及沖突問題(網(wǎng)卡連接)
4咳燕、心跳線之間連接的設(shè)備故障(網(wǎng)卡或者交換機)
5、因仲裁的機器出問題(采用仲裁的方案)
6乒躺、高可用服務(wù)器上開啟了iptables防火墻阻擋了心跳消息傳輸
7招盲、高可用服務(wù)器上心跳網(wǎng)卡地址等信息配置不正確,到時發(fā)送心跳失敗
8嘉冒、其他服務(wù)配置不當曹货,比如心跳方式不同咆繁,心跳廣插沖突,軟件bug等
1-4顶籽、解決腦裂的方案
1玩般、同時使用串行電纜和以太網(wǎng)電纜連接,同時用兩條心跳線路礼饱,這樣一條線路故障之后坏为,另一個依然可以使用
2、當檢測到裂腦時強行關(guān)閉一個心跳節(jié)點(這個功能需特殊設(shè)備支持镊绪,如Stonith匀伏、feyce)。相當于備節(jié)點接收不到心跳消患蝴韭,通過單獨的線路發(fā)送關(guān)機命令關(guān)閉主節(jié)點的電源够颠。
3、做好對裂腦的監(jiān)控報警(如郵件及手機短信等或值班).在問題發(fā)生時人為第一時間介入仲裁榄鉴,降低損失履磨。管理員可以通過手機回復對應數(shù)字或簡單的字符串操作返回給服務(wù)器.讓服務(wù)器根據(jù)指令自動處理相應故障這樣解決故障的時間更短。
1-5牢硅、與heartbeat/corosync等的比較
Heartbeat、Corosync芝雪、Keepalived這三個集群組件我們到底選哪個好减余,Heartbeat、Corosync是屬于同一類型惩系,Keepalived與Heartbeat位岔、Corosync,根本不是同一類型的堡牡。Keepalived使用的vrrp虛擬路由冗余協(xié)議方式抒抬;Heartbeat或Corosync是基于主機或網(wǎng)絡(luò)服務(wù)的高可用方式;簡單的說就是晤柄,Keepalived的目的是模擬路由器的高可用擦剑,Heartbeat或Corosync的目的是實現(xiàn)Service的高可用。
所以一般Keepalived是實現(xiàn)前端高可用芥颈,常用的前端高可用的組合有惠勒,就是我們常見的LVS+Keepalived、Nginx+Keepalived爬坑、HAproxy+Keepalived纠屋。而Heartbeat或Corosync是實現(xiàn)服務(wù)的高可用,常見的組合有Heartbeat v3(Corosync)+Pacemaker+NFS+Httpd 實現(xiàn)Web服務(wù)器的高可用盾计、Heartbeat v3(Corosync)+Pacemaker+NFS+MySQL 實現(xiàn)MySQL服務(wù)器的高可用售担×抟牛總結(jié)一下,Keepalived中實現(xiàn)輕量級的高可用族铆,一般用于前端高可用岩四,且不需要共享存儲,一般常用于兩個節(jié)點的高可用骑素。而Heartbeat(或Corosync)一般用于服務(wù)的高可用炫乓,且需要共享存儲,一般用于多節(jié)點的高可用献丑。
2末捣、編譯安裝haproxy
由于centos7之前自帶的lua版本太低,不適合haproxy要求的最低(5.3)版本的需求创橄,需要下載編譯安裝新版本的lua環(huán)境箩做,才能編譯安裝haproxy等
編譯安裝lua5.4.4
yum install -y gcc readline-devel
wget http://www.lua.org/ftp/lua-5.4.4.tar.gz
tar xvf lua-5.4.4.tar.gz -C /usr/local/src
cd /usr/local/src/lua-5.4.4/
make linux test
src/lua -v
Lua 5.4.4 Copyright (C) 1994-2022 Lua.org, PUC-Rio
編譯安裝haproxy
yum -y install gcc openssl-devel pcre-devel systemd-devel
tar xvf haproxy-2.3.10.tar.gz -C /usr/local/src
cd /usr/local/src/haproxy-2.3.10/
編譯安裝選項:根據(jù)自己的安裝路徑,指定相應的地址妥畏,我這里的lua路徑是/usr/local/src/lua-5.4.4/src/
make ARCH=x86_64 TARGET=linux-glibc USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 USE_SYSTEMD=1 USE_LUA=1 LUA_INC=/usr/local/src/lua-5.4.4/src/ LUA_LIB=/usr/local/src/lua-5.4.4/src/
執(zhí)行編譯安裝
make install PREFIX=/apps/haproxy
創(chuàng)建軟連接
ln -s /apps/haproxy/sbin/haproxy /usr/sbin/
生成的文件
[root@centos7 ~]#tree /apps/haproxy/
/apps/haproxy/
├── doc
│ └── haproxy
│ ├── 51Degrees-device-detection.txt
│ ├── architecture.txt
│ ├── close-options.txt
│ ├── configuration.txt
│ ├── cookie-options.txt
│ ├── DeviceAtlas-device-detection.txt
│ ├── intro.txt
│ ├── linux-syn-cookies.txt
│ ├── lua.txt
│ ├── management.txt
│ ├── netscaler-client-ip-insertion-protocol.txt
│ ├── network-namespaces.txt
│ ├── peers.txt
│ ├── peers-v2.0.txt
│ ├── proxy-protocol.txt
│ ├── regression-testing.txt
│ ├── seamless_reload.txt
│ ├── SOCKS4.protocol.txt
│ ├── SPOE.txt
│ └── WURFL-device-detection.txt
├── sbin
│ └── haproxy
└── share
└── man
└── man1
└── haproxy.1
6 directories, 22 files
查看haproxy的版本
[root@centos7 ~]#haproxy -v
HA-Proxy version 2.3.10-4764f0e 2021/04/23 - https://haproxy.org/
Status: stable branch - will stop receiving fixes around Q1 2022.
Known bugs: http://www.haproxy.org/bugs/bugs-2.3.10.html
Running on: Linux 3.10.0-693.el7.x86_64 #1 SMP Tue Aug 22 21:09:27 UTC 2017 x86_64
創(chuàng)建自定義的service文件
vim /usr/lib/systemd/system/haproxy.service
[Unit]
Description=HAProxy Load Balancer
After=syslog.target network.target
[Service]
ExecStartPre=/usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -c -q
ExecStart=/usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /var/lib/haproxy/hap
roxy.pid
ExecReload=/bin/kill -USR2 $MAINPID
LimitNOFILE=100000
[Install]
WantedBy=multi-user.target
創(chuàng)建haproxy.cfg配置文件
mkdir /etc/haproxy
vim /etc/haproxy/haproxy.cfg
global
maxconn 100000
chroot /apps/haproxy
stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin
#uid 99
#gid 99
user haproxy
group haproxy
daemon
#nbproc 4
#cpu-map 1 0
#cpu-map 2 1
#cpu-map 3 2
#cpu-map 4 3
pidfile /var/lib/haproxy/haproxy.pid
log 127.0.0.1 local2 info
defaults
option http-keep-alive
option forwardfor
maxconn 100000
mode http
timeout connect 300000ms
timeout client 300000ms
timeout server 300000ms
listen stats
mode http
bind 0.0.0.0:9999
stats enable
log global
stats uri /haproxy-status
stats auth haadmin:123456
listen web_port
bind 192.168.1.142:80
mode http
log global
server web1 192.168.1.29:80 check inter 3000 fall 2 rise 5
創(chuàng)建socket文件夾邦邦,并設(shè)置權(quán)限
mkdir /var/lib/haproxy
useradd -r -s /sbin/nologin -d /var/lib/haproxy haproxy
啟動haproxy
systemctl daemon-reload
systemctl enable --now haproxy
[root@centos7 ~]#systemctl status haproxy
● haproxy.service - HAProxy Load Balancer
Loaded: loaded (/usr/lib/systemd/system/haproxy.service; enabled; vendor preset: disabled)
Active: active (running) since Tue 2022-04-12 15:39:37 CST; 3s ago
Process: 12492 ExecStartPre=/usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -c -q (code=exited, status=0/SUCCESS)
Main PID: 12495 (haproxy)
CGroup: /system.slice/haproxy.service
├─12495 /usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /var/lib/haproxy/haproxy.pid
└─12498 /usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /var/lib/haproxy/haproxy.pid
Apr 12 15:39:37 centos7.4-6 systemd[1]: Starting HAProxy Load Balancer...
Apr 12 15:39:37 centos7.4-6 systemd[1]: Started HAProxy Load Balancer.
Apr 12 15:39:37 centos7.4-6 haproxy[12495]: [NOTICE] 101/153937 (12495) : New worker #1 (12498) forked
查看進程
[root@centos7 ~]#pstree | grep haproxy
|-haproxy---haproxy---{haproxy}
3、總結(jié)haproxy各調(diào)度算法的實現(xiàn)方式及其應用場景
HAProxy通過固定參數(shù) balance 指明對后端服務(wù)器的調(diào)度算法醉蚁,該參數(shù)可以配置在listen或backend選項中
3-1燃辖、靜態(tài)算法
按照事先定義好的規(guī)則輪詢進行調(diào)度,不關(guān)心后端服務(wù)器的當前負載网棍、連接數(shù)和響應速度等黔龟,且無法實時動態(tài)修改權(quán)重(只能為0和1,不支持其它值)或者修改后不生效,如果需要修改只能靠重啟HAProxy生效滥玷。
static-rr:
基于權(quán)重的輪詢調(diào)度氏身,不支持運行時利用socat進行權(quán)重的動態(tài)調(diào)整(只支持0和1,不支持其它值)及后端服務(wù)器慢啟動,其后端主機數(shù)量沒有限制惑畴,相當于LVS中的 wrr蛋欣。
first:
根據(jù)服務(wù)器在列表中的位置,自上而下進行調(diào)度如贷,但是其只會當?shù)谝慌_服務(wù)器的連接數(shù)達到上限陷虎,新請求才會分配給下一臺服務(wù),因此會忽略服務(wù)器的權(quán)重設(shè)置杠袱,此方式使用較少泻红。
3-2、動態(tài)算法
roundrobin:
基于權(quán)重的輪詢動態(tài)調(diào)度算法霞掺,支持權(quán)重的運行時調(diào)整谊路,不同于lvs中的rr輪訓模式,
HAProxy中的roundrobin支持慢啟動(新加的服務(wù)器會逐漸增加轉(zhuǎn)發(fā)數(shù))菩彬,其每個后端backend中最多支持4095個real server缠劝,支持對real server權(quán)重動態(tài)調(diào)整潮梯,roundrobin為默認調(diào)度算法,此算法使用廣泛。
leastconn :
加權(quán)的最少連接的動態(tài)惨恭,支持權(quán)重的運行時調(diào)整和慢啟動秉馏,即:根據(jù)當前連接最少的后端服務(wù)器而非權(quán)重進行優(yōu)先調(diào)度(新客戶端連接),比較適合長連接的場景使用脱羡,比如:MySQL等場景萝究。
random:
在1.9版本開始增加 random的負載平衡算法,其基于隨機數(shù)作為一致性hash的key锉罐,隨機負載平衡對于大型服務(wù)器場或經(jīng)常添加或刪除服務(wù)器非常有用帆竹,支持weight的動態(tài)調(diào)整,weight較大的主機有更大概率獲取新請求
3-3脓规、其他算法
source:
源地址hash栽连,基于用戶源地址hash并將請求轉(zhuǎn)發(fā)到后端服務(wù)器,后續(xù)同一個源地址請求將被轉(zhuǎn)發(fā)至同一個后端web服務(wù)器侨舆。此方式當后端服務(wù)器數(shù)據(jù)量發(fā)生變化時秒紧,會導致很多用戶的請求轉(zhuǎn)發(fā)至新的后端服務(wù)器,默認為靜態(tài)方式挨下,但是可以通過hash-type選項進行更改熔恢。
map-base 取模法
對source地址進行hash計算,再基于服務(wù)器總權(quán)重的取模臭笆,最終結(jié)果決定將此
請求轉(zhuǎn)發(fā)至對應的后端服務(wù)器叙淌。此方法是靜態(tài)的,即不支持在線調(diào)整權(quán)重耗啦,不支持慢啟動凿菩,可實現(xiàn)對后端服務(wù)器均衡調(diào)度机杜。缺點是當服務(wù)器的總權(quán)重發(fā)生變化時帜讲,即有服務(wù)器上線或下線,都會因總權(quán)重發(fā)生變化而導致調(diào)度結(jié)果整體改變椒拗,hash-type 指定的默認值為此算法似将。
一致性 hash
一致性哈希,當服務(wù)器的總權(quán)重發(fā)生變化時蚀苛,對調(diào)度結(jié)果影響是局部的在验,不會引起大的變動,hash(o)mod n 堵未,該hash算法是動態(tài)的腋舌,支持使用 socat等工具進行在線權(quán)重調(diào)整,支持慢啟動渗蟹。
uri
基于對用戶請求的URI的左半部分或整個uri做hash块饺,再將hash結(jié)果對總權(quán)重進行取模后赞辩,根據(jù)最終結(jié)果將請求轉(zhuǎn)發(fā)到后端指定服務(wù)器,適用于后端是緩存服務(wù)器場景授艰,默認是靜態(tài)算法辨嗽,也可以通過hash-type指定map-based和consistent,來定義使用取模法還是一致性hash淮腾。
注意:此算法基于應用層糟需,所以只支持 mode http ,不支持 mode tcp
url_param
url_param對用戶請求的url中的 params 部分中的一個參數(shù)key對應的value值作hash計算谷朝,并由服務(wù)器總權(quán)重相除以后派發(fā)至某挑出的服務(wù)器洲押;通常用于追蹤用戶,以確保來自同一個用戶的請求始終發(fā)往同一個real server徘禁,如果無沒key诅诱,將按roundrobin算法。
hdr
針對用戶每個http頭部(header)請求中的指定信息做hash送朱,此處由 name 指定的http首部將會被取出并做hash計算娘荡,然后由服務(wù)器總權(quán)重取模以后派發(fā)至某挑出的服務(wù)器,如果無有效值驶沼,則會使用默認的輪詢調(diào)度炮沐。
rdp-cookie
rdp-cookie對遠windows遠程桌面的負載,使用cookie保持會話回怜,默認是靜態(tài)大年,也可以通過hash-type指定map-based和consistent,來定義使用取模法還是一致性hash玉雾。
3-4翔试、算法總結(jié)
靜態(tài)
static-rr--------->tcp/http
first-------------->tcp/http
動態(tài)
roundrobin-------->tcp/http
leastconn--------->tcp/http
random------------>tcp/http
以下靜態(tài)和動態(tài)取決于hash_type是否consistent
source------------>tcp/http
Uri---------------------->http
url_param------------>http
hdr--------------------->http
rdp-cookie------------>tcp
3-5、各種算法的使用場景
first---------------------------->使用較少
static-rr----------------------->做session共享的 web 集群
roundrobin------------------->同上
random----------------------->同上
leastconn-------------------->數(shù)據(jù)庫
source ----------------------->基于客戶端公網(wǎng) IP 的會話保持
Uri--------------->http,一般用于緩存服務(wù)器复旬,CDN服務(wù)商垦缅,藍汛、百度驹碍、阿里云壁涎、騰訊
url_param--------->http ,一般用于可以實現(xiàn)session保持
hdr ---------------------------->基于客戶端請求報文頭部做下一步處理
4、使用haproxy的ACL實現(xiàn)基于文件后綴名的動靜分離"
添加子配置文件志秃,保存配置
mkdir /etc/haproxy/conf.d/
vim /etc/haproxy/conf.d/srv2.cfg
frontend shenqiqi_http_port
bind 192.168.1.11:80 #haproxy的監(jiān)聽地址
mode http #指定負載協(xié)議類型
log global # 開啟日志功能
balance roundrobin #指定調(diào)度算法
option httplog #啟用日志記錄HTTP請求怔球、會話狀態(tài)和計時器的功能
########################## acl setting ############################
acl acl_static path_end -i .jpg .jpeg .png .gif .css .js .html #以.jpg .jpeg .png .gif .css .js .html為結(jié)尾的訪問,命令為acl_static靜態(tài)資源
acl acl_php path_end -i .php #以.php為結(jié)尾的訪問浮还,命令為acl_php動態(tài)資源
########################## acl hosts ##############################
use_backend mobile_hosts if acl_static #如果訪問的是靜態(tài)資源竟坛,就轉(zhuǎn)向后端mobile_hosts主機組
use_backend app_hosts if acl_php #如果訪問的是動態(tài)資源,就轉(zhuǎn)向后端app_hosts主機組
default_backend pc_hosts #默認訪問的是 pc_hosts主機組
########################## backend hosts ##########################
backend mobile_hosts
mode http #指定負載協(xié)議類型,必須和上面frontend一致
server web1 192.168.1.12:80 check inter 2000 fall 3 rise 5 #后端web1担汤,地址和端口號又官,并且要健康檢查,健康狀態(tài)檢查間隔時間2000 ms漫试,后端服務(wù)器從線上轉(zhuǎn)為線下的檢查的連續(xù)失效次數(shù)六敬,默認為3,
后端服務(wù)器從下線恢復上線的檢查的連續(xù)有效次數(shù)驾荣,默認為5外构。
backend app_hosts
mode http
server web2 192.168.1.13:80 check inter 2000 fall 3 rise 5
▽ackend pc_hosts
mode http
server web2 192.168.1.13:80 check inter 2000 fall 3 rise 5
訪問測試
[root@192.168.1.12 html]#pwd
/var/www/html
[root@192.168.1.12 html]#ls
1.jpg index.html
[root@192.168.1.13 html]#pwd
/var/www/html
[root@192.168.1.13 html]#ls
test.php
測試界面1
測試界面2