最近我在負責一個統一接入層的建設項目,涉及到 Haproxy 和 ospf 的運維部署,本文分享一下我在部署 Haproxy 之后整理的運維部署規范,並實現了Haproxy 的多配置文件管理方案。
一、部署安裝
1、下載源碼包
最新 stable 版本下載地址:http://www.haproxy.org/download/1.7/src/haproxy-1.7.9.tar.gz
2、編譯安裝
tar zxf haproxy-1.7.9.tar.gz cd haproxy-1.7.9 make TARGET=linux31 prefix=/usr/local/haproxy make install PREFIX=/usr/local/haproxy
3、創建目錄
mkdir-p/usr/local/haproxy/conf/ready/tcp mkdir-p/usr/local/haproxy/conf/ready/http mkdir-p/usr/local/haproxy/conf/enabled/tcp mkdir-p/usr/local/haproxy/conf/enabled/http mkdir-p/usr/local/haproxy/logs mkdir-p/data/wwwlogs/logs
二、軟件配置
熟悉 Nginx 和 Apache 的朋友都知道,這兩個 Webservice 都支持 include 加載多個配置文件的語法,但是 Haproxy 並不支持!如果現網映射規則非常多,那么 haproxy.cfg 這個配置文件就跟臭襪子一樣,又臭又長!
因此,我也是翻遍了國外的各種論壇帖子,終於發現一種變相實現 Haproxy 多配置文件的方案。其實,Hparoxy 是支持多配置文件的,但是不是 include 語法,而是在啟動的時候多次使用-f 拼接配置文件,比如:
cd/usr/local/haproxy/sbin
./haproxy-f../conf/haproxy.cfg-f../conf/ext1.cfg-f../conf/ext2.cfg
因此,我們可以在配置文件目錄以及啟動腳本上做點改變,讓 Haproxy 支持多配置文件。
1、路徑約定:
- 待上線的 tcp 映射規則存放目錄:/usr/local/haproxy/conf/ready/tcp
- 待上線的 http 映射規則存放目錄:/usr/local/haproxy/conf/ready/http
- 已上線的 tcp 映射規則存放目錄:/usr/local/haproxy/conf/enabled/tcp
- 已上線的 http 映射規則存放目錄:/usr/local/haproxy/conf/enabled/http
- Ps:本文為多配置模式,enabled 里面的配置為軟鏈接形式,軟鏈接至 ready 對應配置文件,方便管理。
2、配置模板
①、主配置:haproxy.cfg
#configure haproxy.cfg global log127.0.0.1 local0 maxconn4096 #最大連接數 chroot/usr/local/haproxy#安裝目錄 uid99 #用戶nobody gid99 #組nobody daemon #守護進程運行 nbproc1 #進程數量 pidfile/usr/local/haproxy/logs/haproxy.pid#haproxy pid defaults log global mode http #7層 http;4層tcp 如果要讓haproxy支持虛擬主機,mode 必須設為http option httplog #http 日志格式 log127.0.0.1local6 option httpclose #主動關閉http通道 option redispatch #serverId對應的服務器掛掉后,強制定向到其他健康的服務器 retries1 option dontlognull maxconn2000 #最大連接數 timeout connect 3600000 #連接超時(毫秒) timeout client 3600000 #客戶端超時(毫秒) timeout server 3600000 #服務器超時(毫秒) frontend default option httplog option httpclose bind0.0.0.0:80 # 狀態頁面規則 acl haproxy_stats path_beg/haproxy use_backend haproxy_stats ifhaproxy_stats # 其他 # default_backend default_server # 提升失敗的時候的用戶體驗 #errorfile 502 /usr/local/haproxy/html/maintain.html #errorfile 503 /usr/local/haproxy/html/maintain.html #errorfile 504 /usr/local/haproxy/html/maintain.html # 狀態頁面 backend haproxy_stats stats uri/haproxy stats enable stats refresh60s #stats auth admin:admin # 狀態頁面認證配置 stats admin ifTRUE
②、http 擴展配置文件模板
frontend demo option httplog option httpclose bind192.168.1.10:80# 擴展 # 域名匹配范例 acl is_demo hdr_beg(host)-idemo.oa.com # 正則范例范例 acl is_demo_rex hdr_reg(host)-i^demo[0-9].oa.com$ # 路徑匹配范例 acl is_demo_path path_beg/demo/path use_backend demo_oa_com ifis_demo||is_demo_rex|| is_demo_path backend http_demo_ext mode http # 額外的一些設置,按需使用 option forwardfor option forwardfor header Client-IP option http-server-close option httpclose #balance roundrobin #負載均衡的方式,輪詢方式 #balance leastconn #負載均衡的方式,最小連接 balance source #負載均衡的方式,根據請求的源IP cookie SERVERID insert nocache indirect # 插入serverid到cookie中,serverid后面可以定義 # 健康檢查 option httpchk HEAD/index.html HTTP/1.1\r\nHost:\demo.oa.com serverx.x.x.xx.x.x.x:80cookie server1 check inter2srise3fall3weight3 serverx.x.x.xx.x.x.x:80cookie server1 check inter2srise3fall3weight3
③、tcp 擴展配置文件模板
listen tcp_demo_ext bind0.0.0.0:3306 mode tcp serverx.x.x.xx.x.x.x:3306weight1check inter1srise2fall2 serverx.x.x.xx.x.x.x:3306weight1check inter1srise2fall2
Ps:多配置模式中,多個 frontend 必須綁定不同的 IP 或者端口,否則數據會串,導致映射到不同的后端而報錯。因此,同一個 IP+端口下的映射務必配置到同一個 frontend 模塊內。
三、系統服務
1、服務腳本
對比已有的 Haproxy 腳本,我編寫的時候新增了如下實用功能:
- 支持配置文件語法測試
- 支持進程的監控(自拉起)功能
- 重啟之前會先檢測配置語法,規避因配置錯誤導致重啟后進程掛掉
- 支持多配置文件模式(按照前文約定目錄存放拓展配置,腳本將自動識別)
下面是服務腳本代碼:
#!/bin/bash ################################################################### # Haproxy Service Script 1.0.0 Author: Jager <im@zhang.ge> # # Common Operations(start|stop|restart|mon|test) # #-----------------------------------------------------------------# # For more information please visit https://zhang.ge/5125.html # # Copyright @2017 zhang.ge. All rights reserved. # ################################################################### # chkconfig: 35 10 90 export PATH=/sbin:/usr/sbin:/usr/local/sbin:/usr/local/bin:/usr/bin:/bin:$PATH PROCESS_NAME=haproxy BASE_DIR=/usr/local/haproxy EXEC=$BASE_DIR/sbin/haproxy PID_FILE=$BASE_DIR/logs/haproxy.pid DEFAULT_CONF=$BASE_DIR/conf/haproxy.cfg MONLOG_PATH="$BASE_DIR/logs/${PROCESS_NAME}_mon.log" # COLOR print COLOR_RED=$( echo-e"\e[31;49m") COLOR_GREEN=$( echo-e"\e[32;49m") COLOR_RESET=$( echo-e"\e[0m" ) info(){echo"${COLOR_GREEN}$*${COLOR_RESET}" ;} warn(){echo"${COLOR_RED}$*${COLOR_RESET}" ;} do_log() { local log_fpath=$1 local log_content=$2 echo"$(date '+%F %T') $log_content">>$log_fpath } print_usage() { echo info" Usage: $(basename $0) [start|stop|restart|mon|test]" echo } #get Expanding configuration ext_configs() { CONFIGS= if[[-d$BASE_DIR/conf/enabled]];then forFILEin$(find$BASE_DIR/conf/enabled-typel|sort-n) do CONFIGS="$CONFIGS -f $FILE"; done echo$CONFIGS else echo fi } # check process status check_process() { PID=`get_pid` ifpsaux|awk'{print $2}'|grep-qw$PID2>/dev/null;then true else false fi } # check Configuration file check_conf() { $EXEC-c-f$DEFAULT_CONF`ext_configs`>/dev/null2>&1 return$? } get_pid() { if[[-f$PID_FILE]];then cat$PID_FILE else warn" $PID_FILE not found!" exit1 fi } start() { echo ifcheck_process;then warn" ${PROCESS_NAME} is already running!" else $EXEC-f$DEFAULT_CONF`ext_configs`&&\ echo-e" ${PROCESS_NAME} start [ `info OK` ]"||\ echo-e" ${PROCESS_NAME} start [ `warn Failed` ]" fi echo } stop() { echo ifcheck_process;then PID=`get_pid` kill-9$PID>/dev/null2>&1 echo-e" ${PROCESS_NAME} stop [ `info OK` ]" else warn" ${PROCESS_NAME} is not running!" fi echo } restart() { echo ifcheck_process;then : else warn" ${PROCESS_NAME} is not running! Starting Now..." fi if`check_conf`;then PID=`get_pid` $EXEC-f$DEFAULT_CONF`ext_configs`-st$PID&&\ echo-e" ${PROCESS_NAME} restart [ `info OK` ]"||\ echo-e" ${PROCESS_NAME} restart [ `warn Failed` ]" else warn" ${PROCESS_NAME} Configuration file is not valid, plz check!" echo-e" ${PROCESS_NAME} restart [ `warn Failed` ]" fi echo } mon() { ifcheck_process;then info"${PROCESS_NAME} is running OK!" do_log$MONLOG_PATH"${PROCESS_NAME} is running OK!" else start warn" ${PROCESS_NAME} not running, start it!" do_log$MONLOG_PATH"${PROCESS_NAME} not running, plz check" fi } if[[$# != 1 ]]; then print_usage exit1 else case$1in "start"|"START") start ;; "stop"|"STOP") stop ;; "restart"|"RESTART"|"-r") restart ;; "status"|"STATUS") ifcheck_process;then info"${PROCESS_NAME} is running OK!" else warn" ${PROCESS_NAME} not running, plz check" fi ;; "test"|"TEST"|"-t") echo ifcheck_conf;then info" Configuration file test Successfully." else warn" Configuration file test failed." fi echo ;; "mon"|"MON"|"-m") mon ;; *) print_usage exit1 esac fi
保存為 /usr/local/haproxy/sbin/ctrl.sh,賦可執行權限,如下注冊系統服務:
chmod+x/usr/local/haproxy/sbin/ctrl.sh ln-sf/usr/local/haproxy/sbin/ctrl.sh /etc/init.d/haproxy chkconfig haproxy on
服務控制:
啟動:service haproxy start
停止:service haproxy stop
重載:service haproxy restart
狀態:service haproxy status
檢查:service haproxy test
監控:service haproxy mon # 進程自拉起,如有告警通道可自行加入
2、配置自拉起
*****bash/usr/local/haproxy/ctrl.sh mon>/dev/null2>&1
全部完成后,最終目錄結構如下:
[root@locahost:/usr/local/haproxy]# tree . ├──conf │ ├──enabled # 正式使用的拓展配置 │ │ ├──http │ │ │ └──demo.cfg->/usr/local/haproxy/conf/ready/http/demo.cfg# 此處軟鏈到可以上線的配置 │ │ └──tcp │ │ └──demo.cfg->/usr/local/haproxy/conf/ready/tcp/demo.cfg │ ├──haproxy.cfg │ └──ready # 存在預發布的拓展配置 │ ├──http │ │ └──demo.cfg │ │ └──other.cfg │ └──tcp │ └──demo.cfg │ └──other.cfg ├──doc │ ..... ├──logs │ └──haproxy.pid ├──sbin │ ├──ctrl.sh │ └──haproxy └──share └─... 14directories,24files
四、日志配置
配置 rsyslog
mkdir-p/data/wwwlogs vim/etc/rsyslog.conf 或/etc/syslog.conf #新增配置 local6.*/data/wwwlogs/haproxy.log #取消如下2行注釋 $ModLoad imudp $UDPServerRun514 #重啟syslog服務 service rsyslog restart
五、小結
以上內容就是我對 Haproxy 部署規范的整理,並通過拼接方式變相實現了 Haproxy 的多配置文件管理。當然,略遺憾的是未能實現 Haproxy 的 WEB 管理方案,這個有待繼續研究實現,敬請期待!
轉自:https://zhang.ge/5125.html