實驗目的
- 測試基於haproxy的反代和負載均衡配置
- 測試keepalived高可用haproxy的效果
實驗要點
(1) 動靜分離discuzx,動靜都要基於負載均衡實現;
(2) 進一步測試在haproxy和后端主機之間添加varnish緩存;
(3) 給出拓撲設計;
(4) haproxy的設定要求:
(a) 啟動stats;
(b) 自定義403、502和503的錯誤頁;
(c) 各組后端主機選擇合適的調度方法;
(d) 記錄好日志;
(e) 使用keepalived高可用haproxy;
.
拓撲結構
拓撲圖的簡要說明
- node2和node5上同時運行keepalived和haproxy,做高可用,VIP為172.16.47.100
- 在node3和node4上,模擬了2台基於IP的虛擬主機,以減少實驗中機器的數量
- 在node3上,運行nginx的同時,還運行了nfs服務,共享目錄;在node4上把該共享目錄掛載到本地,用於httpd服務存放靜態內容;node3上的nginx將該目錄作為其網頁文件根路徑,從而實現了靜態內容的共享
- haproxy主機負責接受用戶請求,當用戶請求的是圖片資源時,調度至nginx服務器,否則調度請求至httpd服務器
實驗配置
根據實驗拓撲,在node3上部署nginx服務,nfs服務
[root@node3 ~]# rpm -ivh nginx-1.10.0-1.el7.ngx.x86_64.rpm #安裝nginx
[root@node3 ~]# yum install nfs-utils -y #安裝nfs
[root@node3 ~]# mkdir /testdir/nfs -pv #創建nfs服務器的導出目錄
[root@node3 ~]# vim /etc/exports
[root@node3 ~]# cat /etc/exports #授權node4上的2個ip可以訪問
/testdir/nfs 172.16.47.104(rw,no_root_squash) 172.16.47.204(rw,no_root_squash)
[root@node3 ~]# systemctl start rpcbind
[root@node3 ~]# systemctl start nfs #啟動nsf服務,因為nfs服務依賴於rpc服務,因此要先啟動rpc
ssl -tnl
可以看到111端口(rpc)和2049(nfs)都已經起來
修改nginx的配置文件,添加兩個基於IP的虛擬主機,以模擬一組靜態服務器組,將其網頁根文件路徑設置為nfs服務器的導出目錄。
[root@node3 /etc/nginx/conf.d]# egrep -v "#|^$" default.conf
server {
listen 172.16.47.103:80;
server_name www.33love.me;
location / {
root /testdir/nfs;
index index.html index.htm;
rewrite /attachment/(.*)$ /$1; #因為在前端用戶訪問某附件資源時,其訪問路徑是http://172.16.47.100/bbs/data/attachment/XX,而nginx本地只有attachment目錄下的相關資源,因此要對url進行重寫
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
server {
listen 172.16.47.203:80;
server_name www.33love.com;
root /testdir/nfs;
index index.html;
rewrite /attachment/(.*)$ /$1;
}
[root@node3 /etc/nginx/conf.d]#
提供測試主頁,啟動nginx服務,測試nginx服務是否正常
在node4上部署配置amp環境
yum install httpd php php-mysql mariadb-server -y
,啟動mariadb,創建bbs庫,授權用戶訪問,部署用於安裝Discuz論壇所需的數據庫環境
解壓Discuzx至httpd工作目錄/var/www/html/下,改名upload為bbs,解壓目錄下的data/attachment/目錄為用戶上傳附件的目錄,將node3上的共享目錄/testdir/nfs掛載到該目錄下。這樣的話,就需要先將該目錄下的文件先備份處理,待掛載后,再移進來。
注意:得先在node3上創建一個於node4上的apache用戶相同ID號的用戶,並且讓該用戶對nfs導出的目錄有寫權限。
再來配置httpd服務器,創建兩個基於IP的虛擬主機,模擬動態服務器組
兩個IP訪問都沒問題,開始安裝
在node2上安裝部署haproxy和keepalived
yum install haproxy keepalived -y #安裝相應軟件
配置keepalived高可用haproxy,node2為備節點
! Configuration File for keepalived
global_defs {
notification_email {
root@localhost
}
notification_email_from keepalived@localhost
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id Lurker
vrrp_mcast_group4 224.0.100.33
}
vrrp_script chk_haproxy {
script "killall -0 haproxy"
interval 1 #每隔一秒執行一次上面的檢測
weight -5 #權重減5,而主的上面我配置的是權重減10
rise 1
fall 2
}
vrrp_instance VI_1 {
state BACKUP #備
interface eno16777736
virtual_router_id 14
priority 95 #優先級
advert_int 1 #vrrp通告的時間間隔
authentication {
auth_type PASS
auth_pass 3333
}
track_script {
chk_haproxy
}
virtual_ipaddress {
172.16.47.100/16 dev eno16777736
}
track_interface {
eno16777736
}
}
HAProxy的配置
defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
errorfile 403 /tmp/403.html #定義錯誤頁面
errorfile 502 /tmp/502.html
errorfile 503 /tmp/503.html
frontend bbs *:80 #注意備份節點上的監聽地址不能寫出VIP,因為它是Backup狀態時,是沒有VIP的,如果寫出VIP,這時會報錯的
acl fujian path_sub -i /attachment #定義acl,當訪問路徑有attachment時,匹配
use_backend nginxgroup if fujian
default_backend httpdgroup
backend nginxgroup #定義處理靜態內容的nginx服務器組
balance roundrobin
server nginx103 172.16.47.103:80 check maxconn 1000
server nginx203 172.16.47.203:80 check maxconn 2000
backend httpdgroup #定義處理動態內容的httpd服務器組
balance uri
option httpchk /index.html
hash-type consistent
server httpd104 172.16.47.104:80 check maxconn 300
server httpd204 172.16.47.204:80 check maxconn 500
listen statspage #自定義狀態頁面
bind *:3333
stats enable
stats uri /myadmin?stats
stats realm Lurker\ HAProxy \stats \Page
stats auth admin:admin@123
stats admin if TRUE
配置rsyslog
開啟TCP或UDP
# Provides UDP syslog reception
$ModLoad imudp
$UDPServerRun 514
# Provides TCP syslog reception
$ModLoad imtcp
$InputTCPServerRun 514
加上一句定義loacl2的facility日志文件路徑
local12.* /varlog/haproxy.log
node5上的配置也是類似,只不過配置keepalived時要配置成主節點。
重啟rsyslog,啟動keepalived,haproxy,測試訪問。
停掉主節點node5上的haproxy,可以看到VIP,已經到備節點node2上,頁面也仍可以正常訪問
至此,keepalived高可用haproxy成功。不過在這里的時候遇到一個坑,記錄一下。
在配置好keepalived高可用haproxy后,把node5(主)和node3(備)上的haproxy和keepalived都起起來,這時VIP在node5上面,能正常訪問頁面,這沒問題;把node5上的Haproxy停掉之后,它的優先級減了10,成了90,,這也沒問題,但是,node3的優先級按正常來說應該是95,這時node3優先級比node5高,應該成為主,VIP應該在node3上,但是實際上卻沒有。
在node2上抓包'tcpdump -i eno16777736 -nn host 224.0.100.33'
可以看到,仍是node5(172.16.47.105)發的vrrp報文,並且優先級變成了90。
到這里我們來分析一下:node5的優先級降低,都變成了90,而node2卻還沒有變成主,難道是node2的優先級更低?停掉node5上的keepalived讓其優先級變為0,來看看node2的優先級。
node2的優先級不是應該是95嗎,怎么變成90了?於是想到檢查haproxy健康狀態的配置段:
vrrp_script chk_haproxy {
script "killall -0 haproxy"
interval 1 #每隔一秒執行一次上面的檢測
weight -5 #權重減5,而主的上面我配置的是權重減10
rise 1
fall 2
}
killall -0 haproxy
是檢查haproxy進程是否存在,存在返回0。所以檢測的邏輯是:每秒鍾執行一次script "killall -0 haproxy",如果返回碼為0,則不執行下面的weight -5,否則執行。自己手動執行一下killall -0 haproxy
,發現killall命令竟然不存在。
killall命令不存在,那么killall命令肯定執行不成功,返回非0值了。於是就明白為什么node2權重會異常的減5了。安裝上killall所需的包,問題就解決了。
統計頁面如下:
現在來驗證動靜分離是否成功:查看已經上傳的圖片是由誰處理的。
可以看到,是由nignx處理的,再來看看其他資源
可以看到,是由apache處理的。這說明,我們在haproxy上定義的acl生效了,當匹配到/attachment時,請求就被調度至nginx,其他的請求全都送往httpd服務器組,查看我們定義的haproxy的日志,可以看到nginxgroup和httpdgroup都處理過請求。
node4上停掉httpd服務器,systemctl stop httpd.service
,我們自定義的錯誤頁面也出來了
至此,discuz論壇的動靜分離也已經實現。