HAProxy状态页配置

stats enable #基于默认的参数启用stats page
 stats hide-version # 隐藏版本
 stats refresh # 设定自动刷新时间间隔
 stats uri #自定义stats page uri,默认值:/haproxy?stats
 stats realm #账户认证时的提示信息
 stats auth : #认证时的账号和密码,可使用多次,默认:no authentication
 stats admin { if | unless } #启用stats page中的管理功能

示例:

listen stats
  bind 8877 #绑定地址端口
  stats enable #状态页启用
  stats hide-version #隐藏版本
  stats uri /haproxy-status #指定URL
  stats realm HAPorxy\ Stats\ Page #指定认证信息
  stats auth haadmin:123456 #指定认证账号密码,可以写多个
  stats auth admin:123456
  stats refresh 30s #刷新间隔
  stats admin if TRUE #只要登录就能获得管理权限

状态页说明

pid = 3698 (process #2, nbproc = 2, nbthread = 2) #pid为当前pid号,process为当前进程号,nbproc和nbthread为一共多少进程和每个进程多少个线程
uptime = 0d 0h00m08s #启动了多长时间
system limits: memmax = unlimited; ulimit-n = 131124 #系统资源限制:内存/最大打开文件数/
maxsock = 131124; maxconn = 65536; maxpipes = 0 #最大socket连接数/单进程最大连接数/最大管道数maxpipes
current conns = 1; current pipes = 0/0; conn rate = 1/sec #当前连接数/当前管道数/当前连接速率
Running tasks: 1/9; idle = 100 % #运行的任务/当前空闲率
active UP:#在线服务器 backup UP:#标记为backup的服务器
active UP, going down: #监测未通过正在进入down过程 backup UP, going down:#备份服务器正在进入down过程
active DOWN, going up: #down的服务器正在进入up过程 backup DOWN, going up:#备份服务器正在进入up过程
active or backup DOWN: #在线的服务器或者是backup的服务器已经转换成了down状态 not checked:#标记为不监测的服务器
active or backup DOWN for maintenance (MAINT) #active或者backup服务器认为下线的
active or backup SOFT STOPPED for maintenance #active或者backup被认为软下线(人为将weight改成0)

session rate(每秒的连接会话信息):
cur:每秒的当前会话数量
max:每秒新的最大会话数量
limit:每秒新的会话限制量

sessions(会话信息):
cur:当前会话量
max:最大会话量
limit:限制会话量
Total:总共会话量
LBTot:选中一台服务器所用的总时间
Last:和服务器的持续连接时间

Bytes(流量统计):
In:网络的字节输入总量
Out:网络的字节输出总量

Denied(拒绝统计信息):
Req:拒绝请求量
Resp:拒绝回复量

Errors(错误统计信息):
Req:错误请求量
conn:错误链接量
Resp:错误响应量

Warnings(警告统计信息):
Retr:重新尝试次数
Redis:再次发送次数

Server(real server信息):
Status:后端机的状态,包括UP和DOWN
LastChk:持续检查后端服务器的时间
Wght:权重
Act:活动链接数量
Bck:备份的服务器数量
Chk:心跳检测时间
Dwn:后端服务器连接后都是DOWN的数量
Dwntme:总的downtime时间
Thrtle:server状态

修改报文

报文修改支持正则
在请求报文尾部添加指定报文:
reqadd [{if | unless} ]

在响应报文尾部添加指定报文:
rspadd [{if | unless} ]
示例:

在响应报文中添加test:a111
listen test
  bind 192.168.1.10:80
  mode http 
  rspadd test:\ a111
  server testweb1 192.168.1.12:80
  server testweb2 192.168.1.13:80

从请求报文中删除匹配正则表达式的首部
reqdel [{if | unless} ]
reqidel [{if | unless} ] 不分大小写

从响应报文中删除匹配正则表达式的首部
rspdel [{if | unless} ]
rspidel [{if | unless} ]

示例:

从报文中删除test
listen test
  bind 192.168.1.10:80
  mode http 
  rspidel test:.*
  server testweb1 192.168.1.12:80
  server testweb2 192.168.1.13:80



日志配置和自定义

在default配置项定义:
log 127.0.0.1 local{1-7} info #基于syslog记录日志到指定设备,级别有(err、warning、info、debug)

配置rsyslog:
$ModLoad imudp
$UDPServerRun 514
local2.* /var/log/haproxy.log

配置HAProxy:
listen web_port
bind 127.0.0.1:80
mode http
log global
option tcplog
server test 127.0.0.1:8080 check inter 3000 fall 2 rise 5

配置完需要重启haproxy和syslog服务

自定义记录

capture cookie len #捕获请求和响应报文中的 cookie并记录日志
capture request header len #捕获请求报文中指定的首部内容和长度并记录日志
capture response header len #捕获响应报文中指定的内容和长度首部并记录日志

示例:

记录host和浏览器类型
listen test
  bind 192.168.1.10:80
  mode http 
  capture request header Host len 256
  capture request header User-Agent len 512
  server testweb1 192.168.1.12:80
  server testweb2 192.168.1.13:80

压缩设置

compression algo #启用http协议中的压缩机制,常用算法有gzip deflate
compression type #要压缩的类型
示例:

记录host和浏览器类型
listen test
  bind 192.168.1.10:80
  mode http 
  compression algo gzip deflate
  compression type text/plain text/html text/css text/xml text/javascript application/javascript
  server testweb1 192.168.1.12:80
  server testweb2 192.168.1.13:80

状态监测

三种状态监测方式:
基于四层的传输端口做状态监测,可用TCP模式

listen test
  bind 192.168.1.10:80
  mode http 
  server testweb1 192.168.1.12:80 check inter 3000 fall 3 rise 5

基于指定URI 做状态监测

listen test
  bind 192.168.1.10:80
  mode http 
  option httpchk GET /a.html HTTP/1.0
  server testweb1 192.168.1.12:80
  server testweb2 192.168.1.13:80

基于指定URI的request请求头部内容做状态监测

listen test
  bind 192.168.1.10:80
  mode http 
  #option httpchk GET /a.html HTTP/1.0
  #还可以添加其他信息比如声明发起请求的地址
  option httpchk GET /a.html HTTP/1.0\r\nHost:\192.168.1.10
  server testweb1 192.168.1.12:80
  server testweb2 192.168.1.13:80

ACL

ACL:对接收到的报文进行匹配和过滤,基于请求报文头部中的源地址、源端口、目标地址、目标端口、请求方法、URL、文件后缀等信息内容进行匹配并执行进一步操作。

acl <aclname> <criterion> [flags] [operator] [<value>]
acl 名称 条件 条件标记位 具体操作符 操作对象类型

ACL名称,可以使用大字母A-Z、小写字母a-z、冒号:、点.、中横线和下划线,并且严格区分大小写,必须Image_site和image_site完全是两个acl。

ACL derivatives :
hdr([<name> [,<occ>]]):完全匹配字符串
hdr_beg([<name> [,<occ>]]):前缀匹配
hdr_dir([<name> [,<occ>]]):路径匹配
hdr_dom([<name> [,<occ>]]):域匹配
hdr_end([<name> [,<occ>]]):后缀匹配
hdr_len([<name> [,<occ>]]):长度匹配
hdr_reg([<name> [,<occ>]]):正则表达式匹配
hdr_sub([<name> [,<occ>]]):子串匹配

[criterion]匹配条件:
dst 目标IP
dst_port 目标PORT
src 源IP
src_port 源PORT
hdr <string>用于测试请求头部首部指定内容
hdr_dom(host) 请求的host名称,如 www.test.com
hdr_beg(host) 请求的host开头,如 www. img. video. download. ftp.
hdr_end(host) 请求的host结尾,如 .com .net .cn
path_beg 请求的URL开头,如/static、/images、/img、/css
path_end 请求的URL中资源的结尾,如 .gif .png .css .js .jpg .jpeg

[flags]条件标记:
-i 不区分大小写
-m 使用指定的pattern匹配方法
-n 不做DNS解析
-u 禁止acl重名,否则多个同名ACL匹配或关系

[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进行匹配

[value]的类型:
Boolean #布尔值false,true
integer or integer range #整数或整数范围,比如用于匹配端口范围,1024~32768
IP address / network #IP地址或IP范围, 192.168.0.1 ,192.168.0.1/24
string
exact #精确比较
substring #子串 例如www.test.com不论匹配www还是test或者com都生效
suffix #后缀比较
prefix #前缀比较
subdir #路径
domain #域名
regular expression #正则表达式
hex block #16进制

示例:

listen test
  bind 192.168.1.10:80
  mode http 
  acl www_test hdr_dom(host) www.test.com #多个匹配可用空格隔开
  acl m_test hdr_dom(host) m.test.com
  use_backend pc_web if www_test
  use_backend m_web if m_test
  #或的写法
  use_backend m_web if www_test || m_test

backend pc_web
  mode http 
  server testweb1 192.168.1.11:80 check port 80 inter 3000 fall 3 rise 5

backend m_web
  mode http 
  server testweb1 192.168.1.12:80 check port 80 inter 3000 fall 3 rise 5



ACL域名匹配
listen test
  bind 192.168.1.10:80
  mode http 
  acl test_host hdr_dom(host) -i www.test.com
  use_backend pc_web if test_host
  default_backend m_web

backend pc_web
  mode http 
  server testweb1 192.168.1.11:80 check port 80 inter 3000 fall 3 rise 5

backend m_web
  mode http 
  server testweb1 192.168.1.12:80 check port 80 inter 3000 fall 3 rise 5



ACL源地址子网匹配
listen test
  bind 192.168.1.10:80
  mode http 
  acl ip_test src 192.168.0.0/24
  use_backend pc_web if ip_test
  default_backend m_web


backend pc_web
  mode http 
  server testweb1 192.168.1.11:80 check port 80 inter 3000 fall 3 rise 5

backend m_web
  mode http 
  server testweb1 192.168.1.12:80 check port 80 inter 3000 fall 3 rise 5



ACL源地址访问控制
listen test
  bind 192.168.1.10:80
  mode http 
  acl ip_test src 192.168.1.100 192.168.1.101
  block if ip_test
  default_backend pc_web


backend pc_web
  mode http 
  server testweb1 192.168.1.11:80 check port 80 inter 3000 fall 3 rise 5



ACL匹配浏览器重定向
listen test
  bind 192.168.1.10:80
  mode http 
  acl redirect_test hdr(User-Agent) -m sub -i "Chrome"
  redirect prefix http://192.168.1.101 if redirect_test
  #也可以根据域名重定向
  acl test_host hdr_dom(host) -i www.test.com
  redirect prefix http://www.text.net if test_host
  default_backend pc_web
  

backend pc_web
  mode http 
  server testweb1 192.168.1.11:80 check port 80 inter 3000 fall 3 rise 5



使用ACL和文件后缀实现动静分离

listen test
  bind 192.168.1.10:80
  mode http 
  acl php_server path_end -i .php
  acl image_server path_end -i .jpg .png .jpeg .gif
  use_backend php_web if php_server
  use_backend img_web if image_server


backend php_web
  mode http 
  server testweb1 192.168.1.11:80 check port 80 inter 3000 fall 3 rise 5

backend img_web
  mode http 
  server testweb1 192.168.1.12:80 check port 80 inter 3000 fall 3 rise 5



ACL匹配访问路径

listen test
  bind 192.168.1.10:80
  mode http 
  acl php_server path_end -i .php
  acl static_path path_beg -i /static /images /javascript
  use_backend php_web if php_server
  use_backend img_web if static_path


backend php_web
  mode http 
  server testweb1 192.168.1.11:80 check port 80 inter 3000 fall 3 rise 5

backend img_web
  mode http 
  server testweb1 192.168.1.12:80 check port 80 inter 3000 fall 3 rise 5



ACL基于策略的访问控制

listen test
  bind 192.168.1.10:80
  mode http 
  acl badguy_deny src 192.168.1.101
  http-request deny if badguy_deny
  http-request allow
  default_backend pc_web 


backend pc_web
  mode http 
  server testweb1 192.168.1.11:80 check port 80 inter 3000 fall 3 rise 5



自定义错误页面

配置通常放在defaults中

default
errorfile 500 /usr/local/haproxy/html/500.html #重定向到本地错误页面文件
errorloc 403 http://192.168.1.101/error_page/403.html #重定向到某个服务器的错误页面



HTTPS配置

由于haproxy证书文件只能使用一个,需要先合并成一个文件
cat demo.crt demo.key > demo.pem

listen test_80
  bind 192.168.1.10:80
  mode http 
  redirect scheme https if !{ ssl_fc }
  server testweb1 192.168.1.11:80 check port 80 inter 3000 fall 3 rise 5

listen test_443
  bind 192.168.1.10:443 ssl ctr /usr/local/haproxy/certs/demo.pem
  mode http #这里改成TCP也不影响访问,但如果要在头部添加信息只能是HTTP
  server testweb1 192.168.1.11:80 check port 80 inter 3000 fall 3 rise 5
 
 向后端服务器传递端口和协议
  listen test_443
  bind 192.168.1.10:443 ssl ctr /usr/local/haproxy/certs/demo.pem
  mode http
  http-request set-header X-Forwarded-Port %[dst_port]
  http-request add-header X-Forwarded-Proto https if { ssl_fc }
  server testweb1 192.168.1.11:80 check port 80 inter 3000 fall 3 rise 5



动态上下线

需要安装socat工具
yum install socat

测试显示状态
echo "show info" | socat stdio /var/lib/haproxy/haproxy.sock

服务器下线

示例配置
backend pc_web
  mode http 
  server testweb1 192.168.1.11:80 check port 80 inter 3000 fall 3 rise 5
  server testweb1 192.168.1.12:80 check port 80 inter 3000 fall 3 rise 5
  
其中pc_web对应上面组的名称,testweb1对应服务器的名称
可以把服务器名称直接写IP方便动态上下线时使用
echo "disable server pc_web/testweb1" | socat stdio /var/lib/haproxy/haproxy.sock

backend pc_web
  mode http 
  server 192.168.1.11 192.168.1.11:80 check port 80 inter 3000 fall 3 rise 5
  server 192.168.1.12 192.168.1.12:80 check port 80 inter 3000 fall 3 rise 5
echo "disable server pc_web/192.168.1.11" | socat stdio /var/lib/haproxy/haproxy.sock

在多线程的配置下,会出现其中一个进程里服务器已下线而其他进程还没下线的情况。
需要给每一个进程绑定一个sock文件
示例:
stats socket /var/lib/haproxy/haproxy.sock1 mode 600 level admin process 1
stats socket /var/lib/haproxy/haproxy.sock2 mode 600 level admin process 2

绑定虚拟IP需要的设置

绑定虚拟IP时可能会因为IP不存在而无法启动,需要编辑文件添加选项

vim /etc/sysctl.conf
写入
net.ipv4.ip_nonlocal_bing = 1 #允许绑定不存在的IP
net.ipv4.ip_forward = 1 #开启IP转发