33.0 haproxy
[aaa@qq.com ~ ]#yum info haproxy
Loaded plugins: fastestmirror, langpacks
Loading mirror speeds from cached hostfile
Installed Packages
Name : haproxy
Arch : x86_64
Version : 1.5.18 #base repository
Release : 7.el7
Size : 2.6 M
Repo : installed
From repo : base
Summary : TCP/HTTP proxy and load balancer for high availability environments
URL : http://www.haproxy.org/
License : GPLv2+
Description : HAProxy is a TCP/HTTP reverse proxy which is particularly suited for high
: availability environments. Indeed, it can:
: - route HTTP requests depending on statically assigned cookies
: - spread load among several servers while assuring server persistence
: through the use of HTTP cookies
: - switch to backup servers in the event a main server fails
: - accept connections to special ports dedicated to service monitoring
: - stop accepting connections without breaking existing ones
: - add, modify, and delete HTTP headers in both directions
: - block requests matching particular patterns
: - report detailed status to authenticated users from a URI
: intercepted by the application
haproxy
默认http
支持http反向代理
支持动态程序的反向代理
支持基于数据的反向代理(一般数据库不用haproxy,数据库有读写分离技术)
HAProxy是TCP / HTTP反向代理服务器,尤其适合于高可用性环境
可以针对HTTP请求添加cookie,进行路由后端服务器
可平衡负载至后端服务器,并支持持久连接
支持基于cookie进行调度
支持所有主服务器故障切换至备用服务器
支持专用端口实现监控服务
支持不影响现有连接情况下停止接受新连接请求
可以在双向添加,修改或删除HTTP报文首部
支持基于pattern实现连接请求的访问控制
通过特定的URI为授权用户提供详细的状态信息
haproxy的调度算法(1.5版本)
balance参数
balance <algorithm> [ <arguments> ]
balance url_param <param> [check_post]
Define the load balancing algorithm to be used in a backend.
<algorithm> is the algorithm used to select a server when doing load
balancing. This only applies when no persistence information
is available, or when a connection is redispatched to another
server. <algorithm> may be one of the following :
算法
balance
roundrobin
static-rr
leastconn
first
source
uri
url_param
hdr(<name>) 如hdr(user-agent)
rdp-cookie
rdp-cookie(<name>)
hash-type:哈希算法
hash-type <method> <function> <modifier>
method:
map-based:除权取余法,哈希数据结构是静态数组
consistent:一致性哈希,哈希数据结构是一棵树
function : 哈希函数,取值:sdbm,djb2,wt6
modifier: 取值avalanche时,将修改哈希值,而非直接使用
default_backend <backend>
无use_backend 匹配时,使用默认的backend,用于frontend中
default-server [param*]
为backend中的各server设定默认选项
配置段
代理配置段:
- defaults
- frontend
- backend
- listen
Frontend段:指定接收客户端连接侦听套接字设置
ackend段:指定将连接请求转发至后端服务器的相关设置
Listen段:指定完整的前后端设置
proxy 名称:使用字母 数字 - _ . : 并区分字符大小写
性能调整
性能调整:
maxconn :设置每个haproxy进程所能接受的最大并发连接数
maxconnrate :设置每个进程每秒种所能建立的最大连接数量 #传输层
maxsessrate :设置每个进程每秒种所能建立的最大会话数量 #会话层
maxsslconn : 每进程支持SSL的最大连接数量
spread-checks <0..50, in percent> 健康检测延迟时长百分比,建议2-5之间
日志
日志系统
log:
log global
log <address> [len <length>] <facility> [<level> [<minlevel>]]
length 日志行的长度,默认1024
no log
注意:
默认发往本机的日志服务器
(1) local2.* /var/log/local2.log
(2) $ModLoad imudp
$UDPServerRun 514
log-format <string>:
参考文档实现combined格式的记录
日志管理
将特定信息记录在日志中
capture cookie <name> len <length>
捕获请求和响应报文中的 cookie并记录日志
capture request header <name> len <length>
捕获请求报文中指定的首部并记录日志
示例:
capture request header X-Forwarded-For len 15
capture response header <name> len <length>
捕获响应报文中指定的首部并记录日志
示例:
capture response header Content-length len 9
capture response header Location len 15
[aaa@qq.com ~ ]#vim /etc/haproxy/haproxy.cfg
frontend web #多对多
bind *:80
default_backend websrvs
backend websrvs
balance roundrobin
server srv1 192.168.31.17:80 check
server srv2 192.168.31.27:80 check
或者用如下
listen http
bind 192.168.31.7:80 #一对一
frontend web
bind *:80
default_backend websrvs
backend websrvs
default-server inter 1000 weight 10
balance roundrobin
server srv1 192.168.31.17:80 check weight 2
server srv2 192.168.31.27:80 check maxconn 5000 backlog 100
server backupsrv 192.168.31.7:8080 check #sorry server
[aaa@qq.com ~ ]#for i in {1..100};do curl 192.168.31.7;sleep .5;done
<h1>rs2</h1>
<h1>rs2</h1>
<h1>rs2</h1>
<h1>rs2</h1>
<h1>rs2</h1>
<h1>rs1</h1>
<h1>rs2</h1>
把rs1和rs2服务都停了,则会显示自定义的道歉页面
server srv1 192.168.31.17:80 check disabled #可以用来灰度发布
server srv1 192.168.31.17:80 check redir http://www.baidu.com
curl -L 192.168.31.7
如果调度到192.168.1.17,则会把http://www.baidu.com网址返回给客户端,让客户端去访问此网址
check选项实现后台服务器(upstream)健康性检测
backlog 后援队列,即等待连接的客户端数量
健康状态检测
check:对当前server做健康状态检测,只用于四层检测
注意:httpchk,“smtpchk”, “mysql-check”, “pgsql-check” and “ssl-hello-chk” 用于定义应用层检测方法
addr :检测时使用的IP地址
port :针对此端口进行检测
inter <delay>:检测之间的时间间隔,默认为2000ms
rise <count>:连续多少次检测结果为“成功”才标记为可用;默认为2
fall <count>:连续多少次检测结果为“失败”才标记为不可用;默认为3
disabled:标记为不可用
redir <prefix>:将发往此server的所有GET和HEAD类的请求重定向至指定的URL
cookie配置
实现session会话绑定
cookie <value>:为当前server指定cookie值,实现基于cookie的会话黏性
cookie <name> [ rewrite | insert | prefix ] [ indirect ] [ nocache ]
[ postonly ] [ preserve ] [ httponly ] [ secure ] [ domain <domain> ]*
[ maxidle <idle> ] [ maxlife <life> ]
<name>:cookie名称,用于实现持久连接
rewrite:重写
insert:插入
prefix:前缀
nocache:当client和hapoxy之间有缓存时,不缓存cookie
cookie配置示例
基于cookie的session sticky的实现
backend websrvs
cookie WEBSRV insert nocache
server srv1 172.16.0.6:80 weight 2 check rise 1 fall 2 maxconn 3000 cookie srv1
server srv2 172.16.0.7:80 weight 1 check rise 1 fall 2 maxconn 3000 cookie srv2
curl -b WEBSRV cookie=srv1 192.168.31.17
统计接口启用相关的参数
stats enable
启用统计页;基于默认的参数启用stats page
stats hide-version 隐藏版本
stats refresh <delay>
设定自动刷新时间间隔
stats uri <prefix>
自定义stats page uri,默认值:/haproxy?stats
stats realm <realm>
认证时的realm,示例:stats realm : HAProxy\ Statistics
stats auth <user>:<passwd>
认证时的账号和密码,可使用多次,默认:no authentication
stats admin { if | unless } <cond> #staus admin true
启用stats page中的管理功能
配置示例
listen stats
bind :9527
stats enable
stats hide-version
stats uri /hastats
stats realm HAPorxy\ Stats\ Page
stats auth admin1:password1
stats auth admin1:password2
stats refresh 3s
stats admin if TRUE
示例
vim /etc/haproxy/haproxy.cfg
listen haproxy
bind 192.168.31.7:9527 #我做实验用的是80端口
stats enable
stats hide-version
stats refresh 30
stats uri /dhy-ha
stats realm : HAproxy\Statistics
stats auth dhy:dhy1
stats admin if TRUE
frontend web
bind 192.168.31.7:80
default_backend websrvs
backend websrvs
cookie WEBSRV insert nocache
server srv1 192.168.31.17:80 check cookie dhy17 maxconn 5000
server srv2 192.168.31.27:80 check cookie dhy27 maxconn 5000
图
工作模式
maxconn :为指定的frontend定义其最大并发连接数;默认为3000
mode { tcp|http|health }
定义haproxy的工作模式
tcp:基于layer4实现代理;可代理mysql, pgsql, ssh, ssl等协议,https时使用此模式,默认模式
http:仅当代理协议为http时使用,CentOS中haproxy实际的默认模式
health:工作为健康状态检查的响应模式,当连接请求到达时回应“OK”后即断开连接,较少使用
tcp是伪代理,真正的代理是tcp转发,此处是应用层模拟的传输层;后端服务器日志你看到的是代理服务器在访问后端服务器
TCP模式示例
示例:
listen ssh
bind :22022
balance leastconn
mode tcp
server sshsrv1 192.168.31.17:22 check
server sshsrv2 192.168.31.27 check
健康状态检测
对后端服务器做http协议健康状态检测:通常用于backend
option httpchk 默认向后端服务器发请求:OPTIONS / HTTP/1.0
option httpchk <uri>
option httpchk <method> <uri>
option httpchk <method> <uri> <version> #开始行
定义基于http协议的7层健康状态检测机制
http-check expect [!] <match> <pattern>
http协议健康状态检测响应内容或指定响应码
————————————————————
https://cbonte.github.io/haproxy-dconv/1.5/configuration.html#4-option%20httpchk
backend websrvs
#option httpchk GET / HTTP/1.1\r\nhost: #实验未能成功,添加官网如下成功
option httpchk OPTIONS * HTTP/1.1\r\nhost:
http-check expect status 200
server srv1 192.168.31.17:80 check
curl 192.168.31.17 503 服务不可用
curl 192.168.31.17 正常访问
forwardfor配置
option forwardfor [ except <network> ] [ header <name> ] [ if-none ]
在由haproxy发往后端主机的请求报文中添加“X-Forwarded-For”首部,其值为前端客户端的地址;用于向后端主发送真实的客户端IP #在日志中添加X-Forwarded-For
[ except <network> ]:请求报请来自此处指定的网络时不予添加此首部, 如haproxy自身所在网络
[ header <name> ]:使用自定义的首部名称,而非“X-Forwarded-For ”
[ if-none ] 如果没有首部才添加首部,如果有使用默认值
为指定的MIME类型启用压缩传输功能
compression algo <algorithm> ...:启用http协议的压缩机制,指明压缩 算法gzip, deflate
compression type <mime type> ...:指明压缩的MIMI类型
示例
[root@cos7 ~ ]#vim /etc/haproxy/haproxy.cfg
option forwardfor except 127.0.0.0/8 #默认头部是X-Forwarded-For
[root@cos17 ~ ]#vim /etc/httpd/conf/httpd.conf
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" \"%{X-Forwarded-For}i\"" combined
#自定义头部
option forwardfor except 127.0.0.0/8 header dhytest
[root@cos17 ~ ]#vim /etc/httpd/conf/httpd.conf
\"%{dhytest}i\"
[root@cos17 ~ ]#tail -f /var/log/httpd/accss_log
错误页配置
后端服务器宕机,代理服务器错误页面
[proxy-4.1版](https://cbonte.github.io/haproxy-dconv/1.5/configuration.html#4-errorfile)
errorfile <code> <file> 自定义错误页
<code>:HTTP status code.
支持200, 400, 403, 408, 500, 502, 503, 504.
<file>:错误页文件路径
示例:
errorfile 400 /etc/haproxy/errorfiles/400badreq.http
errorfile 408 /dev/null # workaround Chrome pre-connect bug
errorfile 403 /etc/haproxy/errorfiles/403forbid.http
errorfile 503 /etc/haproxy/errorfiles/503sorry.http
errorloc <code> <url>
相当于errorloc302 <code> <url>,利用302重定向至指URL
示例:errorloc 503 http://www.dhy.com/error_pages/503.html #加到backend后端
修改报文首部
在请求报文尾部添加指定首部
reqadd <string> [{if | unless} <cond>]
在响应报文尾部添加指定首部
rspadd <string> [{if | unless} <cond>]
示例:rspadd X-Via:\ HAPorxy
从请求报文中删除匹配正则表达式的首部
reqdel <search> [{if | unless} <cond>]
reqidel <search> [{if | unless} <cond>] 不分大小写
从响应报文中删除匹配正则表达式的首部
rspdel <search> [{if | unless} <cond>]
rspidel <search> [{if | unless} <cond>] 不分大小写 ignore
示例: rspidel server.*
示例
[root@cos7 ~ ]#vim /etc/haproxy/haproxy.cfg
listen ssh
bind :22222
balance leastconn
mode tcp
server sshsrv1 192.168.31.17:22 check
server sshsrv2 192.168.31.27:22 check
listen haproxy
bind 192.168.31.7:9527
stats enable
stats hide-version
stats refresh 30
stats uri /dhy-ha
stats realm : haproxy:dhy
stats auth dhy:dhy1
stats admin if TRUE
frontend web
bind 192.168.31.7:80
default_backend websrvs
rspidel server.*
rspadd server:\ dhy-nginx
reqadd dhyheader:\ requestheader-dhy
errorfile 503 /etc/haproxy/errorfiles/503.html
backend websrvs
cookie WEBSRV insert nocache
server srv1 192.168.31.17:80 check cookie dhy17 maxconn 5000
server srv2 192.168.31.27:80 check cookie dhy27 maxconn 5000
[root@cos7 ~ ]#systemctl reload haproxy
[root@cos17 ~ ]#vim /etc/httpd/conf/httpd.conf
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{dhyheader}i\"" combined
[root@cos6 ~ ]#curl -I 192.168.31.7
HTTP/1.1 200 OK
Date: Fri, 14 Sep 2018 09:14:29 GMT
Last-Modified: Fri, 14 Sep 2018 07:44:58 GMT
ETag: "10-575d0000e1342"
Accept-Ranges: bytes
Content-Length: 16
Content-Type: text/html; charset=UTF-8
server: dhy-nginx #"国产"nginx
Set-Cookie: WEBSRV=dhy17; path=/
Cache-control: private
[aaa@qq.com ~ ]#for i in {1..100};do curl 192.168.31.7;sleep 0.5;done
<h1>rs2-27</h1>
<h1>rs1-17</h1>
<h1>rs2-27</h1>
<h1>rs1-17</h1>
[aaa@qq.com ~ ]#tail -f /var/log/httpd/access_log
192.168.31.7 - - [14/Sep/2018:17:30:43 +0800] "GET / HTTP/1.1" 200 16 "-" "requestheader-dhy"
192.168.31.7 - - [14/Sep/2018:17:30:44 +0800] "GET / HTTP/1.1" 200 16 "-" "requestheader-dhy"
图3
[root@cos7 ~ ]#mkdri -p /etc/haproxy/errorfiles/
[root@cos7 ~ ]#echo "503 error" > /etc/haproxy/errorfiles/503.html
[root@cos17 ~ ]#systemctl stop httpd
[root@cos27 ~ ]#systemctl stop httpd
[root@cos6 ~ ]#for i in {1..100};do curl 192.168.31.7;sleep 0.5;done
503 error
503 error
503 error
acl:access control list
acl:访问控制列表(ACL)的使用提供了一个灵活的解决方案来执行内容交换,并且通常基于从请求中提取的内容、响应或任何环境状态进行决策 #类似dns的智能dns
acl <aclname> <criterion> [flags] [operator] [<value>] ...
<aclname>:ACL名称,可使用字母 数字 : . - _ ,区分字符大小写
<criterion>: 比较的标准和条件
<value>的类型:
- boolean
- integer or integer range
- IP address / network
- string (exact, substring, suffix, prefix, subdir, domain)
- regular expression
- hex block
<flags>
-i 不区分大小写
-m 使用指定的pattern匹配方法
-n 不做DNS解析
-u 强制每个ACL必须唯一ID,否则多个同名ACL或关系
-- 强制flag结束. 当字符串和某个flag相似时使用
[operator]
匹配整数值:eq、ge、gt、le、lt
匹配字符串:
- exact match (-m str) :字符串必须完全匹配模式
- substring match (-m sub) :在提取的字符串中查找模式,如果其中任何一个被发现,ACL将匹配
- prefix match (-m beg) :在提取的字符串首部中查找模式,如果其中任何一个被发现,ACL将匹配
- suffix match (-m end) :将模式与提取字符串的尾部进行比较,如果其中任何一个匹配,则ACL进行匹配
- subdir match (-m dir) :查看提取出来的用斜线分隔(“/”)的字符串,如果其中任何一个匹配,则ACL进行匹配
- domain match (-m dom) :查找提取的用点(“.”)分隔字符串,如果其中任何一个匹配,则ACL进行匹配
ACL 逻辑
acl作为条件时的逻辑关系:
- 与:隐式(默认)使用
- 或:使用“or ” 或 “||”表示
- 否定:使用“!“ 表示
示例:if invalid_src invalid_port 与关系
if invalid_src || invalid_port 或
if ! invalid_src 非
<criterion> :各种条件
dst 目标IP
dst_port 目标PORT
src 源IP
src_port 源PORT
示例:acl invalid_src src 192.168.31.1
[root@cos7 ~ ]#vim /etc/haproxy/haproxy.cfg
listen haproxy
bind 192.168.31.7:9527
acl valid_src src 192.168.31.1
stats enable
stats hide-version
stats refresh 30
stats uri /dhy-ha
stats realm : haproxy:dhy
stats auth dhy:dhy1
stats admin if ! valid_src
图4
[root@cos7 ~ ]#vim /etc/haproxy/haproxy.cfg
frontedn web
bind 192.168.31.7:80
block if METH_HEAD
acl image_acl path_end .jpg .png #图片服务器
default_backedn websrvs
use_backend appsrvs if image_acl #图片服务器
backend websrvs
srvser srv1 192.168.31.17:80 check
backend appsrvs
srvser srv2 192.168.31.27:80 check #图片服务器
支持https协议
配置HAProxy支持https协议:
支持ssl会话;
bind *:443 ssl crt /PATH/TO/SOME_PEM_FILE
crt 后证书文件为PEM格式,且同时包含证书和所有私钥
cat demo.crt demo.key > demo.pem
把80端口的请求重向定443
bind *:80
redirect scheme https if !{ ssl_fc }
向后端传递用户请求的协议和端口(frontend或backend)
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwared-Proto https if { ssl_fc }
frontend web
bind 172.18.0.7:80
bind 172.18.0.7:443 ssl crt /etc/haproxy/a.pem
mod tcp
-----------------------
cd /etc/pki/tls/certs/
make a.pem
cat a.pem #包含了证书和私钥,如果是自己手动创建的则,cat a.crt a.key > a.pem
Privacy Enhanced Mail 私有,加强,邮件
上一篇: CentOS 7 firewalld 配置详解 (转)
下一篇: Firewalld