Haproxy+Keepalived實現負載均衡


HAProxy介紹

????反向代理服務器,支持雙機熱備支持虛擬主機,但其配置簡單,擁有非常不錯的服務器健康檢查功能,當其代理的后端服務器出現故障, HAProxy會自動將該服務器摘除,故障恢復后再自動將該服務器加入新的1.3引入了frontend,backend;frontend根據任意 HTTP請求頭內容做規則匹配,然后把請求定向到相關的backend.

????HAProxy 提供高可用性、負載均衡以及基于 TCP 和 HTTP 應用的代理,支持虛擬主機,它是免費、快速并且可靠的一種解決方案。HAProxy 特別適用于那些負載特大的 web 站點, 這些站點通常又需要會話保持或七層處理。HAProxy 運行在當前的硬件上,完全可以支持數以萬計的并發連接。并且它的運行模式使得它可以很簡單安全的整 合進您當前的架構中, 同時可以保護你的 web 服務器不被暴露到網絡上。


Keepalived 介紹

????Keepalived 的作用是檢測web服務器的狀態,如果有一臺web服務器死機,或工作出現故障,Keepalived將檢測到,并將有故障的web服務器從系統中剔除, 當web服務器工作正常后Keepalived自動將web服務器加入到服務器群中,這些工作全部自動完成,不需要人工干涉,需要人工做的只是修復故障的 web服務器。


????在上篇中,我使用了nginx反向代理加上keepalived,來達到雙機主主模式的高可用。Haproxy也是一種反向代理的軟件,故本次實驗也將實現 haproxy 加上 keepalived 來實現主主模式的高可用。


一、環境說明

????本次試驗依舊使用的是2臺 haproxy代理服務器 加上 keepalived,后端為了方便,使用apache來發布網頁,達到測試的目的。


操作系統:centos7 64位

軟件源:阿里云

2臺服務器(haproxy1、haproxy2)安裝 keepalived 和安裝 haproxy 來反向代理

2臺服務器(web1、web2)安裝 apache 來提供服務

服務器的防火墻selinux全部關閉


haproxy1? IP:192.168.163.166

haproxy2? IP:192.168.163.167

nginx1? IP:192.168.163.164

nginx2? IP:192.168.163.165

虛擬IP:192.168.163.100 和 192.168.163.200


拓撲圖如下:

ce60d4dd072f1862fa97513c2c77126e.jpg-wh_

二、環境安裝


先安裝好web服務器

1、首先為后端的2臺web服務器安裝apache

[root@web1 ~]# yum install -y httpd

[root@web2 ~]# yum install -y httpd


2、修改web1的域名為img.xhk.com? web2的域名為test.xhk.com

ServerName img.xhk.com:80

ServerName test.xhk.com:80


3、創建各自的網頁

[root@web1 ~]# echo "web1" > /var/www/html/index.html

[root@web2 ~]# echo "web2" > /var/www/html/index.html


4、啟動服務

[root@web1 ~]# systemctl start httpd

[root@web2 ~]# systemctl start httpd


5、在Client修改hosts文件并測試網頁

[root@client ~]# curl img.xhk.com

web1

[root@client ~]# curl test.xhk.com

web2

????

接下來,就是安裝haproxy服務器的 haproxy 和 keepalived

1、為了方便,在2臺haproxy服務器都使用 yum 安裝

[root@haproxy ~]# yum install -y haproxy keepalived


2、先修改haproxy文件

[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg

globallog?????????127.0.0.1?local2chroot??????/var/lib/haproxypidfile?????/var/run/haproxy.pidmaxconn?????4000user????????haproxygroup???????haproxydaemonstats?socket?/var/lib/haproxy/stats
defaultsmode????????????????????httplog?????????????????????globaloption??????????????????httplogoption??????????????????dontlognulloption?http-server-closeoption?forwardfor???????except?127.0.0.0/8option??????????????????redispatchretries?????????????????3timeout?http-request????10stimeout?queue???????????1mtimeout?connect?????????10stimeout?client??????????1mtimeout?server??????????1mtimeout?http-keep-alive?10stimeout?check???????????10smaxconn?????????????????3000
frontend??main?*:80
option?forwardfor??except?127.0.0.0/8
rspadd?X-via:\?haproxy/www.xhk.com
rspidel?Server.*?stats?enable????????????????????#在frontend添加監控頁面stats?uri?/xhk?stats????????????#自定義監控頁面的urlstats?realm?Stats\?Page\?Area???#去掉空格轉譯stats?authxhk:xhk?????????????#配置帳號密碼stats?refresh?5s????????????????#每5s刷新一次監控頁面stats?hide-version??????????????#隱藏版本信息stats?admin?if?TRUEmaxconn?10000????????????????????#定義最大并發為10000
acl?url_img?hdr(host)?-i?img.xhk.com
acl?url_test?hdr(host)?-i?test.xhk.com
use_backend?img_web?if?url_img
use_backend?test_web?if?url_test
backend?img_web
balance?roundrobin
server?web1?192.168.163.164:80?check
backend?test_web
balance?roundrobin
server?web2?192.168.163.165:80?check

保存退出


3、重啟 haproxy 服務

[root@haproxy haproxy]# systemctl restart haproxy

[root@haproxy haproxy]# systemctl status haproxy

● haproxy.service - HAProxy Load Balancer

? ?Loaded: loaded (/usr/lib/systemd/system/haproxy.service; disabled; vendor preset: disabled)

? ?Active: active (running) since Sat 2017-10-21 22:31:03 EDT; 5s ago

?Main PID: 2265 (haproxy-systemd)

? ?CGroup: /system.slice/haproxy.service

? ? ? ? ? ?├─2265 /usr/sbin/haproxy-systemd-wrapper -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid

? ? ? ? ? ?├─2266 /usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid -Ds

? ? ? ? ? ?└─2267 /usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid -Ds


Oct 21 22:31:03 haproxy systemd[1]: Started HAProxy Load Balancer.

Oct 21 22:31:03 haproxy systemd[1]: Starting HAProxy Load Balancer...

Oct 21 22:31:03 haproxy haproxy-systemd-wrapper[2265]: haproxy-systemd-wrapper: executing /usr/sbin/haproxy -f /et... -Ds

Hint: Some lines were ellipsized, use -l to show in full.


訪問 haproxy 自帶的監控頁面,用戶名密碼為配置文件中設置的

url為haproxy服務器的IP地址加上自定義的url

http://192.168.163.166/xhk?stats

f70922ac8e1cd66bb0cafe0257e2ab71.png-wh_


4、接下來安裝keepalived

[root@haproxy haproxy]# yum install -y keepalived


5、編輯 keepalived 的配置文件

[root@haproxy haproxy]# vim /etc/keepalived/keepalived.conf?

global_defs?{notification_email?{???#?郵件接收者root@localhost}notification_email_from?keepalived@localhost?????#郵件發送者smtp_server?127.0.0.1			????#郵件服務器地址smtp_connect_timeout?30			????#超時時限router_id?xhk		????????????????????#此處注意router_id為負載均衡標識vrrp_mcast_group4?224.0.100.19		????#添加ipv4的多播地址,并確保多播功能啟用
}vrrp_script?check_haproxy?{?script?/root/check_haproxy.sh	#檢測腳本,該路徑就是你腳本存放的位置interval?2				#每隔2秒鐘檢測一次#?weight?-2				#優先級減去2?
}vrrp_instance?VI_1?{state?MASTER			#狀態只有MASTER和BACKUP兩種interface?ens32			#網絡接口virtual_router_id?51		#虛擬路由標識priority?100			#優先級advert_int?1			#MASTER?與BACKUP?之間同步檢查的時間間隔,單位為秒authentication?{auth_type?PASS			#驗證authentication。包含驗證類型和驗證密碼auth_pass?xhk			#AH?使用時有問題。驗證密碼為明文}virtual_ipaddress?{192.168.163.100?dev?ens32	#虛擬ip地址,可以有多個地址}track_script?{??????????????#運行上面所寫的檢測腳本check_haproxy}
}vrrp_instance?VI_2?{state?BACKUPinterface?ens32virtual_router_id?52priority?99advert_int?1authentication?{auth_type?PASSauth_pass?123456}virtual_ipaddress?{192.168.163.200?dev?ens32}track_script?{	check_haproxy}?
}

保存退出


6、編寫檢測haproxy服務狀態的腳本

vim /root/check_haproxy.sh

#!/bin/bashps?-C?haproxy?-o?pid
if?[?$??!=?0?];thensystemctl?stop?keepalived
fi

添加執行權限

[root@haproxy2 ~]# chmod +x check_haproxy.sh?


第二臺 haproxy 服務器也執行上述這些操作,不同的是 keepalived 配置文件,下面貼出第二臺 haproxy 的 keepalived?

[root@haproxy2 ~]# vim /etc/keepalived/keepalived.conf?

global_defs?{notification_email?{???????????????????????????#?郵件接收者root@localhost}notification_email_from?keepalived@localhost?#郵件發送者smtp_server?127.0.0.1			#郵件服務器地址smtp_connect_timeout?30			#超時時限router_id?xhk				#此處注意router_id為負載均衡標識vrrp_mcast_group4?224.0.100.19		#添加ipv4的多播地址,并確保多播功能啟用
}vrrp_script?check_haproxy?{?script?/root/check_haproxy.sh	#檢測腳本interval?2				#每隔2秒鐘檢測一次#?weight?-2				#優先級減去2?
}vrrp_instance?VI_1?{state?BACKUP			#狀態只有MASTER和BACKUP兩種。interface?ens32			#網絡接口virtual_router_id?51		#虛擬路由標識priority?99				#優先級advert_int?1			#MASTER?與BACKUP?之間同步檢查的時間間隔,單位為秒。authentication?{auth_type?PASS			#驗證authenticationauth_pass?xhk			#AH?使用時有問題。驗證密碼為明文}virtual_ipaddress?{192.168.163.100?dev?ens32	#虛擬ip地址,可以有多個地址}track_script?{??????????????#運行上面所寫的檢測腳本check_haproxy}
}vrrp_instance?VI_2?{state?MASTERinterface?ens32virtual_router_id?52priority?100advert_int?1authentication?{auth_type?PASSauth_pass?123456}virtual_ipaddress?{192.168.163.200?dev?ens32}track_script?{	check_haproxy}?
}

不同之處也不過就是,各個 instance 的優先級要互為主備


7、開啟 keepalived 服務

[root@haproxy ~]# systemctl start keepalived

[root@haproxy2 ~]# systemctl start keepalived

查看keepalived狀態

????[root@haproxy ~]# systemctl status keepalived

● keepalived.service - LVS and VRRP High Availability Monitor

? ?Loaded: loaded (/usr/lib/systemd/system/keepalived.service; disabled; vendor preset: disabled)

? ?Active: active (running) since Sat 2017-10-21 22:44:46 EDT; 4min 5s ago

? Process: 2278 ExecStart=/usr/sbin/keepalived $KEEPALIVED_OPTIONS (code=exited, status=0/SUCCESS)

?Main PID: 2279 (keepalived)

? ?CGroup: /system.slice/keepalived.service

? ? ? ? ? ?├─2279 /usr/sbin/keepalived -D

? ? ? ? ? ?├─2280 /usr/sbin/keepalived -D

? ? ? ? ? ?└─2281 /usr/sbin/keepalived -D


Oct 21 22:45:04 haproxy Keepalived_vrrp[2281]: Sending gratuitous ARP on ens32 for 192.168.163.100

Oct 21 22:45:06 haproxy Keepalived_vrrp[2281]: Sending gratuitous ARP on ens32 for 192.168.163.200

Oct 21 22:45:06 haproxy Keepalived_vrrp[2281]: VRRP_Instance(VI_2) Sending/queueing gratuitous ARPs on ens32 for ...3.200

Oct 21 22:45:06 haproxy Keepalived_vrrp[2281]: Sending gratuitous ARP on ens32 for 192.168.163.200

Oct 21 22:45:06 haproxy Keepalived_vrrp[2281]: Sending gratuitous ARP on ens32 for 192.168.163.200

Oct 21 22:45:06 haproxy Keepalived_vrrp[2281]: Sending gratuitous ARP on ens32 for 192.168.163.200

Oct 21 22:45:06 haproxy Keepalived_vrrp[2281]: Sending gratuitous ARP on ens32 for 192.168.163.200

Oct 21 22:45:36 haproxy Keepalived_vrrp[2281]: VRRP_Instance(VI_2) Received advert with higher priority 100, ours 99

Oct 21 22:45:36 haproxy Keepalived_vrrp[2281]: VRRP_Instance(VI_2) Entering BACKUP STATE

Oct 21 22:45:36 haproxy Keepalived_vrrp[2281]: VRRP_Instance(VI_2) removing protocol VIPs.

Hint: Some lines were ellipsized, use -l to show in full.


[root@haproxy ~]# ip addr show

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1

? ? link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

? ? inet 127.0.0.1/8 scope host lo

? ? ? ?valid_lft forever preferred_lft forever

? ? inet6 ::1/128 scope host?

? ? ? ?valid_lft forever preferred_lft forever

2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000

? ? link/ether 00:0c:29:4a:86:70 brd ff:ff:ff:ff:ff:ff

? ? inet 192.168.163.166/24 brd 192.168.163.255 scope global ens32

? ? ? ?valid_lft forever preferred_lft forever

? ? inet 192.168.163.100/32 scope global ens32

? ? ? ?valid_lft forever preferred_lft forever

? ? inet6 fe80::20c:29ff:fe4a:8670/64 scope link?

? ? ? ?valid_lft forever preferred_lft forever


可以發現,因為第一臺服務器的 VI_1 的優先級高,所以haproxy拿到了vip為192.168.163.100

而 VI_2 的優先級低,所以讓 haproxy2 拿到了192.168.163.200,自己降為backup


三、測試環節


在Client綁定域名,讓Client訪問img.xhk.com、test.xhk.com 時分別去到192.168.163.100、192.168.163.200

[root@client ~]# cat /etc/hosts

127.0.0.1? ?localhost localhost.localdomain localhost4 localhost4.localdomain4

::1? ? ? ? ?localhost localhost.localdomain localhost6 localhost6.localdomain6

192.168.163.100 img.xhk.com test.xhk.com

192.168.163.200 img.xhk.com test.xhk.com



訪問網頁

[root@client ~]# curl img.xhk.com

web1

[root@client ~]# curl test.xhk.com

web2


停掉第一臺的haproxy服務

[root@haproxy ~]# systemctl stop haproxy

[root@haproxy ~]# systemctl status haproxy

haproxy.service - HAProxy Load Balancer

? ?Loaded: loaded (/usr/lib/systemd/system/haproxy.service; disabled; vendor preset: disabled)

? ?Active: inactive (dead)


Oct 21 22:31:03 haproxy systemd[1]: Stopping HAProxy Load Balancer...

Oct 21 22:31:03 haproxy haproxy-systemd-wrapper[2253]: haproxy-systemd-wrapper: SIGTERM -> 2256.

Oct 21 22:31:03 haproxy haproxy-systemd-wrapper[2253]: haproxy-systemd-wrapper: exit, haproxy RC=0

Oct 21 22:31:03 haproxy systemd[1]: Started HAProxy Load Balancer.

Oct 21 22:31:03 haproxy systemd[1]: Starting HAProxy Load Balancer...

Oct 21 22:31:03 haproxy haproxy-systemd-wrapper[2265]: haproxy-systemd-wrapper: executing /usr/sbin/haproxy -f /et... -Ds

Oct 21 23:17:19 haproxy systemd[1]: Stopping HAProxy Load Balancer...

Oct 21 23:17:19 haproxy haproxy-systemd-wrapper[2265]: haproxy-systemd-wrapper: SIGTERM -> 2267.

Oct 21 23:17:19 haproxy haproxy-systemd-wrapper[2265]: haproxy-systemd-wrapper: exit, haproxy RC=0

Oct 21 23:17:19 haproxy systemd[1]: Stopped HAProxy Load Balancer.

Hint: Some lines were ellipsized, use -l to show in full.



[root@haproxy ~]# systemctl status keepalived?

● keepalived.service - LVS and VRRP High Availability Monitor

? ?Loaded: loaded (/usr/lib/systemd/system/keepalived.service; disabled; vendor preset: disabled)

? ?Active: inactive (dead)


Oct 21 22:45:06 haproxy Keepalived_vrrp[2281]: Sending gratuitous ARP on ens32 for 192.168.163.200

Oct 21 22:45:06 haproxy Keepalived_vrrp[2281]: Sending gratuitous ARP on ens32 for 192.168.163.200

Oct 21 22:45:36 haproxy Keepalived_vrrp[2281]: VRRP_Instance(VI_2) Received advert with higher priority 100, ours 99

Oct 21 22:45:36 haproxy Keepalived_vrrp[2281]: VRRP_Instance(VI_2) Entering BACKUP STATE

Oct 21 22:45:36 haproxy Keepalived_vrrp[2281]: VRRP_Instance(VI_2) removing protocol VIPs.

Oct 21 23:17:20 haproxy Keepalived[2279]: Stopping

Oct 21 23:17:20 haproxy systemd[1]: Stopping LVS and VRRP High Availability Monitor...

Oct 21 23:17:20 haproxy Keepalived_vrrp[2281]: VRRP_Instance(VI_1) sent 0 priority

Oct 21 23:17:20 haproxy Keepalived_vrrp[2281]: VRRP_Instance(VI_1) removing protocol VIPs.

Oct 21 23:17:21 haproxy systemd[1]: Stopped LVS and VRRP High Availability Monitor.


停掉第一臺的 haproxy 之后,keepalived的檢測腳本檢測到 haproxy 服務停止,執行腳本,停掉自身的keepalived進程


查看第二臺 haproxy 服務器(haproxy2)的keepalived狀態

[root@haproxy2 ~]# systemctl status keepalived

● keepalived.service - LVS and VRRP High Availability Monitor

? ?Loaded: loaded (/usr/lib/systemd/system/keepalived.service; disabled; vendor preset: disabled)

? ?Active: active (running) since Sat 2017-10-21 22:45:35 EDT; 35min ago

? Process: 2451 ExecStart=/usr/sbin/keepalived $KEEPALIVED_OPTIONS (code=exited, status=0/SUCCESS)

?Main PID: 2452 (keepalived)

? ?CGroup: /system.slice/keepalived.service

? ? ? ? ? ?├─2452 /usr/sbin/keepalived -D

? ? ? ? ? ?├─2453 /usr/sbin/keepalived -D

? ? ? ? ? ?└─2454 /usr/sbin/keepalived -D


Oct 21 23:17:21 haproxy2 Keepalived_vrrp[2454]: Sending gratuitous ARP on ens32 for 192.168.163.100



[root@haproxy2 ~]# ip addr show

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1

? ? link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

? ? inet 127.0.0.1/8 scope host lo

? ? ? ?valid_lft forever preferred_lft forever

? ? inet6 ::1/128 scope host?

? ? ? ?valid_lft forever preferred_lft forever

2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000

? ? link/ether 00:0c:29:d5:fc:a2 brd ff:ff:ff:ff:ff:ff

? ? inet 192.168.163.167/24 brd 192.168.163.255 scope global dynamic ens32

? ? ? ?valid_lft 1369sec preferred_lft 1369sec

? ? inet 192.168.163.200/32 scope global ens32

? ? ? ?valid_lft forever preferred_lft forever

? ? inet 192.168.163.100/32 scope global ens32

? ? ? ?valid_lft forever preferred_lft forever

? ? inet6 fe80::20c:29ff:fed5:fca2/64 scope link?

? ? ? ?valid_lft forever preferred_lft forever


2個VIP都已經漂移到 haproxy2 上


進行網頁訪問

[root@client ~]# curl img.xhk.com

web1

[root@client ~]# curl test.xhk.com

web2


實驗成功!!!!!!!!!!!!!!!!!!!!!!!