HAProxy簡介
HAProxy提供高可用性、負載均衡以及基於TCP和HTTP應用的代理,支持虛擬主機,它是免費、快速並且可靠的一種解決方案。根據官方數據,其最高極限支持10G的併發。HAProxy特別適用於那些負載特大的web站點,這些站點通常又需要會話保持或七層處理。其支持從4層至7層的網絡交換,即覆蓋所有的TCP協議。就是說,Haproxy甚至還支持Mysql的均衡負載。
它專門是一款的用於均衡負載的應用代理,其自身並不能提供http服務,而Nginx,ApacheProxy,lighttpd,Cheroke也是帶反向代理均衡負載的產品,但它們同時也是WEB服務器。並且它的運行模式使得它可以很簡單安全的整合進您當前的架構中,同時可以保護你的web服務器不被暴露到網絡上。
HAProxy實現了一種事件驅動, 單一進程模型,此模型支持非常大的併發連接數。多進程或多線程模型受內存限制 、系統調度器限制以及無處不在的鎖限制,很少能處理數千併發連接。事件驅動模型因爲在有更好的資源和時間管理的用戶端(User-Space) 實現所有這些任務,所以沒有這些問題。此模型的弊端是,在多核系統上,這些程序通常擴展性較差。這就是爲什麼他們必須進行優化以使每個CPU時間片(Cycle)做更多的工作。
HAProxy配置主要有五部分:
global
參數是進程級的,通常和操作系統(OS)相關,這些參數一般只設置一次,如果配置無誤,就不需要再次配置進行修改
defaults
配置默認參數的,這些參數可以被利用配置到frontend,backend,listen組件
frontend
接收請求的前端虛擬節點,Frontend可以根據規則直接指定具體使用後端的backend(可動態選擇)。
backend
後端服務集羣的配置,是真實的服務器,一個Backend對應一個或者多個實體服務器。
listen
Frontend和Backend的組合體。
安裝簡單配置
https://src.fedoraproject.org/repo/pkgs/haproxy/ 軟件包下載
[root@k8snode01 yum.repos.d]# cd /var/www/html/ #配置web1
[root@k8snode01 html]# ll
total 0
[root@k8snode01 html]# echo "node1" >index.html
[root@k8snode02 yum.repos.d]# cd /var/www/html/
[root@k8snode02 html]# ll
total 0
[root@k8snode02 html]# echo "node2">index.html #配置web2
[root@k8snode02 html]# curl "http://192.168.23.102:80" #正常訪問web2
node2
[root@k8snode02 html]# curl "http://192.168.23.101:80" #正常訪問web1
node1
[root@k8snode02 html]#
[root@k8smaster haproxy]# tar -xvf haproxy-2.1.3.tar.gz #解壓軟件包
[root@k8smaster haproxy]# ls -lrt
total 2620
-rw-r--r-- 1 zhaiky zhaiky 2675529 Feb 12 02:41 haproxy-2.1.3.tar.gz
drwxrwxr-x 12 root root 4096 Feb 12 2020 haproxy-2.1.3
[root@k8smaster haproxy]# ln -s haproxy-2.1.3 haproxy #建立軟鏈接
[root@k8smaster haproxy]# ls -lrt
total 2620
-rw-r--r-- 1 zhaiky zhaiky 2675529 Feb 12 02:41 haproxy-2.1.3.tar.gz
lrwxrwxrwx 1 root root 13 Feb 12 02:52 haproxy -> haproxy-2.1.3
drwxrwxr-x 12 root root 4096 Feb 12 2020 haproxy-2.1.3
[root@k8smaster haproxy]# cd haproxy
[root@k8smaster haproxy]# pwd
/data/haproxy/haproxy
[root@k8smaster haproxy]# make TARGET=generic PREFIX=/data/haproxyinstall #T編譯 ARGET variable :
- 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)
- solaris for Solaris 8 or 10 (others untested)
- freebsd for FreeBSD 5 to 10 (others untested)
- netbsd for NetBSD
- osx for Mac OS/X
- openbsd for OpenBSD 3.1 and above
- aix51 for AIX 5.1
- aix52 for AIX 5.2
- cygwin for Cygwin
- generic for any other OS or version.
- custom to manually adjust every setting
CC src/ev_poll.o
CC src/mux_h2.o
CC src/stream.o
CC src/mux_fcgi.o
CC src/cfgparse-listen.o
CC src/http_ana.o
CC src/stats.o
CC src/mux_h1.o
CC src/flt_spoe.o
CC src/server.o
CC src/cfgparse.o
CC src/checks.o
CC src/backend.o
CC src/log.o
CC src/peers.o
CC src/cli.o
CC src/haproxy.o
CC src/stick_table.o
CC src/standard.o
CC src/sample.o
CC src/proxy.o
CC src/stream_interface.o
CC src/pattern.o
CC src/dns.o
CC src/proto_tcp.o
CC src/listener.o
CC src/cfgparse-global.o
CC src/h1.o
CC src/http_rules.o
CC src/http_fetch.o
CC src/cache.o
CC src/session.o
CC src/fcgi-app.o
CC src/connection.o
CC src/tcp_rules.o
CC src/filters.o
CC src/task.o
CC src/mworker.o
CC src/map.o
CC src/h1_htx.o
CC src/trace.o
CC src/flt_trace.o
CC src/acl.o
CC src/http_htx.o
CC src/flt_http_comp.o
CC src/payload.o
CC src/vars.o
CC src/debug.o
CC src/mux_pt.o
CC src/http_act.o
CC src/h2.o
CC src/queue.o
CC src/fd.o
CC src/proto_uxst.o
CC src/lb_chash.o
CC src/ring.o
CC src/frontend.o
CC src/raw_sock.o
CC src/xprt_handshake.o
CC src/htx.o
CC src/memory.o
CC src/applet.o
CC src/channel.o
CC src/signal.o
CC src/lb_fwrr.o
CC src/ev_select.o
CC src/sink.o
CC src/http_conv.o
CC src/proto_sockpair.o
CC src/mworker-prog.o
CC src/activity.o
CC src/lb_fwlc.o
CC src/http.o
CC src/lb_fas.o
CC src/uri_auth.o
CC src/hathreads.o
CC src/regex.o
CC src/auth.o
CC src/buffer.o
CC src/compression.o
CC src/proto_udp.o
CC src/lb_map.o
CC src/chunk.o
CC src/wdt.o
CC src/hpack-dec.o
CC src/action.o
CC src/xxhash.o
CC src/pipe.o
CC src/shctx.o
CC src/hpack-tbl.o
CC src/http_acl.o
CC src/sha1.o
CC src/time.o
CC src/hpack-enc.o
CC src/fcgi.o
CC src/arg.o
CC src/base64.o
CC src/protocol.o
CC src/freq_ctr.o
CC src/lru.o
CC src/hpack-huff.o
CC src/dict.o
CC src/hash.o
CC src/mailers.o
CC src/version.o
CC ebtree/ebtree.o
CC ebtree/eb32sctree.o
CC ebtree/eb32tree.o
CC ebtree/eb64tree.o
CC ebtree/ebmbtree.o
CC ebtree/ebsttree.o
CC ebtree/ebimtree.o
CC ebtree/ebistree.o
LD haproxy
[root@k8smaster haproxy]#
[root@k8smaster haproxy]# make install PREFIX=/data/haproxyinstall #安裝PREFIX參數與編譯要一致
install: creating directory ‘/data/haproxyinstall’
install: creating directory ‘/data/haproxyinstall/sbin’
‘haproxy’ -> ‘/data/haproxyinstall/sbin/haproxy’
install: creating directory ‘/data/haproxyinstall/share’
install: creating directory ‘/data/haproxyinstall/share/man’
install: creating directory ‘/data/haproxyinstall/share/man/man1’
‘doc/haproxy.1’ -> ‘/data/haproxyinstall/share/man/man1/haproxy.1’
install: creating directory ‘/data/haproxyinstall/doc’
install: creating directory ‘/data/haproxyinstall/doc/haproxy’
‘doc/configuration.txt’ -> ‘/data/haproxyinstall/doc/haproxy/configuration.txt’
‘doc/management.txt’ -> ‘/data/haproxyinstall/doc/haproxy/management.txt’
‘doc/seamless_reload.txt’ -> ‘/data/haproxyinstall/doc/haproxy/seamless_reload.txt’
‘doc/architecture.txt’ -> ‘/data/haproxyinstall/doc/haproxy/architecture.txt’
‘doc/peers-v2.0.txt’ -> ‘/data/haproxyinstall/doc/haproxy/peers-v2.0.txt’
‘doc/regression-testing.txt’ -> ‘/data/haproxyinstall/doc/haproxy/regression-testing.txt’
‘doc/cookie-options.txt’ -> ‘/data/haproxyinstall/doc/haproxy/cookie-options.txt’
‘doc/lua.txt’ -> ‘/data/haproxyinstall/doc/haproxy/lua.txt’
‘doc/WURFL-device-detection.txt’ -> ‘/data/haproxyinstall/doc/haproxy/WURFL-device-detection.txt’
‘doc/proxy-protocol.txt’ -> ‘/data/haproxyinstall/doc/haproxy/proxy-protocol.txt’
‘doc/linux-syn-cookies.txt’ -> ‘/data/haproxyinstall/doc/haproxy/linux-syn-cookies.txt’
‘doc/SOCKS4.protocol.txt’ -> ‘/data/haproxyinstall/doc/haproxy/SOCKS4.protocol.txt’
‘doc/network-namespaces.txt’ -> ‘/data/haproxyinstall/doc/haproxy/network-namespaces.txt’
‘doc/DeviceAtlas-device-detection.txt’ -> ‘/data/haproxyinstall/doc/haproxy/DeviceAtlas-device-detection.txt’
‘doc/51Degrees-device-detection.txt’ -> ‘/data/haproxyinstall/doc/haproxy/51Degrees-device-detection.txt’
‘doc/netscaler-client-ip-insertion-protocol.txt’ -> ‘/data/haproxyinstall/doc/haproxy/netscaler-client-ip-insertion-protocol.txt’
‘doc/peers.txt’ -> ‘/data/haproxyinstall/doc/haproxy/peers.txt’
‘doc/close-options.txt’ -> ‘/data/haproxyinstall/doc/haproxy/close-options.txt’
‘doc/SPOE.txt’ -> ‘/data/haproxyinstall/doc/haproxy/SPOE.txt’
‘doc/intro.txt’ -> ‘/data/haproxyinstall/doc/haproxy/intro.txt’
[root@k8smaster haproxy]#
[root@k8smaster haproxy]# cp /data/haproxyinstall/sbin/haproxy /usr/sbin/ #建立軟鏈接
[root@k8smaster haproxy]# haproxy -version
HA-Proxy version 2.1.3 2020/02/12 - https://haproxy.org/
Status: stable branch - will stop receiving fixes around Q1 2021.
Known bugs: http://www.haproxy.org/bugs/bugs-2.1.3.html
[root@k8smaster haproxy]#
[root@k8smaster config]# pwd
/data/haproxyinstall/config
[root@k8smaster config]#
[root@k8smaster config]# more haproxy.cfg #簡單haproxy配置
global
daemon
maxconn 2048
defaults
mode http
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
frontend web
bind *:8888
default_backend servers
backend servers
server web1 192.168.23.101:80 maxconn 32
server web2 192.168.23.102:80 maxconn 32
[root@k8smaster config]# haproxy -f /data/haproxyinstall/config/haproxy.cfg #啓動haproxy
[root@k8smaster config]# ps -ef|grep haproxy #查看haproxy進行
root 15149 1 0 03:24 ? 00:00:00 haproxy -f /data/haproxyinstall/config/haproxy.cfg
root 15151 13170 0 03:25 pts/2 00:00:00 grep --color=auto haproxy
[root@k8smaster config]# netstat -apn|grep 15149 #查看監聽端口
tcp 0 0 0.0.0.0:8888 0.0.0.0:* LISTEN 15149/haproxy
[root@k8smaster config]# curl "192.168.23.100:8888" #正常輪詢負載
node1
[root@k8smaster config]# curl "192.168.23.100:8888"
node2
[root@k8smaster config]#
[root@k8snode01 html]# systemctl stop httpd #停止web1服務
[root@k8smaster config]# curl "192.168.23.100:8888" #由於沒有加check檢查,不好的服務不會驅除
<html><body><h1>503 Service Unavailable</h1>
No server is available to handle this request.
</body></html>
負載均衡算法
1)roundrobin,表示簡單的輪詢,每個服務器根據權重輪流使用,在服務器的處理時間平均分配的情況下這是最流暢和公平的算法。該算法是動態的,對於實例啓動慢的服務器權重會在運行中調整。
2)static-rr,表示根據權重,建議關注;每個服務器根據權重輪流使用,類似roundrobin,但它是靜態的,意味着運行時修改權限是無效的。另外,它對服務器的數量沒有限制。
3)leastconn,新的連接請求被派發至具有最少連接數目的後端服務器;在有着較長時間會話的場景中推薦使用此算法,如LDAP、SQL等,其並不太適用於較短會話的應用層協議,如HTTP;此算法是動態的,可以在運行時調整其權重;
4)source,將請求的源地址進行hash運算,並由後端服務器的權重總數相除後派發至某匹配的服務器;這可以使得同一個客戶端IP的請求始終被派發至某特定的服務器;不過,當服務器權重總數發生變化時,如某服務器宕機或添加了新的服務器,許多客戶端的請求可能會被派發至與此前請求不同的服務器;常用於負載均衡無cookie功能的基於TCP的協議;其默認爲靜態,不過也可以使用hash-type修改此特性;
5)uri,表示根據請求的URI;表示根據請求的URI左端(問號之前)進行哈希,用可用服務器的權重總數除以哈希值,根據結果進行分配。只要服務器正常,同一個URI地址總是訪問同一個服務器。 一般用於代理緩存和反病毒代理,以最大限度的提高緩存的命中率。該算法只能用於HTTP後端;該算法一般用於後端是緩存服務器; 該算法默認是靜態的,所以運行時修改服務器的權重是無效的,但是算法會根據“hash-type”的變化做調整。
6)url_param,通過<argument>爲URL指定的參數在每個HTTP GET請求中將會被檢索;如果找到了指定的參數且其通過等於號“=”被賦予了一個值,那麼此值將被執行hash運算並被服務器的總權重相除後派發至某匹配的服務器;此算法可以通過追蹤請求中的用戶標識進而確保同一個用戶ID的請求將被送往同一個特定的服務器,除非服務器的總權重發生了變化;如果某請求中沒有出現指定的參數或其沒有有效值,則使用輪叫算法對相應請求進行調度;此算法默認爲靜態的,不過其也可以使用hash-type修改此特性;
7)hdr(name),對於每個HTTP請求,通過<name>指定的HTTP首部將會被檢索;如果相應的首部沒有出現或其沒有有效值,則使用輪叫算法對相應請求進行調度;其有一個可選選項“use_domain_only”,可在指定檢索類似Host類的首部時僅計算域名部分(比如通過www.magedu.com來說,僅計算magedu字符串的hash值)以降低hash算法的運算量;此算法默認爲靜態的,不過其也可以使用hash-type修改此特性;
8)rdp-cookie(name),表示根據據cookie(name)來鎖定並哈希每一次TCP請求。爲每個進來的TCP請求查詢並哈希RDP cookie<name>; 該機制用於退化的持久模式,可以使同一個用戶或者同一個會話ID總是發送給同一臺服務器。 如果沒有cookie,則使用roundrobin算法代替; 該算法默認是靜態的,所以運行時修改服務器的權重是無效的,但是算法會根據“hash-type”的變化做調整。
#其實這些算法各有各的用法,我們平時應用得比較多的應該是roundrobin、source和lestconn。
配置說明
[root@k8smaster config]# more haproxy.cfg
###########全局配置#########
global
log 127.0.0.1 local3
daemon #以後臺形式運行harpoxy
nbproc 1 #設置進程數量
maxconn 4096 #默認最大連接數,需考慮ulimit-n限制
#user haproxy #運行haproxy的用戶
#group haproxy #運行haproxy的用戶所在的組
#pidfile /var/run/haproxy.pid #haproxy 進程PID文件
#ulimit-n 819200 #ulimit 的數量限制
#chroot /usr/share/haproxy #chroot運行路徑
#debug #haproxy 調試級別,建議只在開啓單進程的時候調試
#quiet
########默認配置############
defaults
log global #全局日誌
mode http
option dontlognull #不記錄健康檢查日誌信息
retries 2 #兩次連接失敗就認爲是服務器不可用,也可以通過後面設置
#option forwardfor #如果後端服務器需要獲得客戶端真實ip需要配置的參數,可以從Http Header中獲得客戶端ip
option httpclose #每次請求完畢後主動關閉http通道,haproxy不支持keep-alive,只能模擬這種模式的實現
#option redispatch #當serverId對應的服務器掛掉後,強制定向到其他健康的服務器,以後將不支持
option abortonclose #當服務器負載很高的時候,自動結束掉當前隊列處理比較久的鏈接
maxconn 4096 #默認的最大連接數
timeout connect 5000ms #連接超時
timeout client 30000ms #客戶端超時
timeout server 30000ms #服務器超時
#timeout check 2000 #心跳檢測超時
#timeout http-keep-alive10s #默認持久連接超時時間
#timeout http-request 10s #默認http請求超時時間
#timeout queue 1m #默認隊列超時時間
balance roundrobin #設置默認負載均衡方式,輪詢方式
#balance source #設置默認負載均衡方式,類似於nginx的ip_hash
#balnace leastconn #設置默認負載均衡方式,最小連接數
########統計頁面配置########
listen stats
bind 0.0.0.0:1080 #設置Frontend和Backend的組合體,監控組的名稱,按需要自定義名稱
mode http #http的7層模式
maxconn 10 #默認的最大連接數
stats refresh 30s #統計頁面自動刷新時間
stats uri /stats #統計頁面url
stats realm XingCloud\ Haproxy #統計頁面密碼框上提示文本
stats auth admin:admin #設置監控頁面的用戶和密碼:admin,可以設置多個用戶名
stats hide-version #隱藏統計頁面上HAProxy的版本信息
stats admin if TRUE #設置手工啓動/禁用,後端服務器(haproxy-1.4.9以後版本)
########frontend前端配置##############
frontend web
bind *:80
option httplog #啓用http的log
option forwardfor except 127.0.0.1 #啓用X-Forwarded-Fo,except來自於127.0.0.1不記錄
acl node1 hdr(host) -i node1.com #acl後面是規則名稱,-i爲忽略大小寫,後面跟的是要訪問的域名,如果訪問www.node1.com這個域名,就
觸發node1規則
acl node2 hdr(host) -i node2.com #如果訪問img.node2.com這個域名,就觸發node2規則
use_backend node1server if node1 #如果上面定義的node1規則被觸發,即訪問node1.com,就將請求分發到node1server這個作用域。
use_backend node2server if node2 #如果上面定義的node2規則被觸發,即訪問node2.com,就將請求分發到node2server這個作用域。
default_backend dynamic #不滿足則響應backend的默認頁面
########backend後端配置##############
backend dynamic
mode http
#option httpchk get /index.html
balance roundrobin
server web1 192.168.23.101:80 maxconn 32 weight 5 check inter 2000 rise 2 fall 3
server web2 192.168.23.102:80 maxconn 32 weight 3 check inter 2000 rise 2 fall 3
#check inter 1500 是檢測心跳頻率
##rise 2是2次正確認爲服務器可用,fall 3是3次失敗認爲服務器不可用,weight代表權重
backend node1server
mode http
#option httpchk get /index.html
balance roundrobin
server web1 192.168.23.101:80 maxconn 32 check inter 2000 rise 2 fall 3
backend node2server
mode http
#option httpchk get /index.html
balance roundrobin
server web2 192.168.23.102:80 maxconn 32 check inter 2000 rise 2 fall 3
[root@k8smaster config]#
[root@k8smaster config]# more /etc/hosts #設置hosts,進行域名訪問
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 k8smaster
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.23.100 k8smaster
192.168.23.101 k8snode01
192.168.23.102 k8snode02
192.168.23.100 node1.com
192.168.23.100 node2.com
[root@k8smaster config]# curl "node1.com" #正常訪問到node1
node1
[root@k8smaster config]# curl "node1.com"
node1
[root@k8smaster config]# curl "node2.com" curl "node1.com" #正常訪問到node2
node2
[root@k8smaster config]# curl "node2.com"
node2
[root@k8smaster config]# curl "192.168.23.100"
node2
[root@k8smaster config]# curl "192.168.23.100"
node1
[root@k8smaster config]#
http://192.168.23.100:1080/stats