标签:haproxy
haproxy安装:
yum -y install haproxy
HAProxy工作模式
tcp:
haproxy的默认模式;该模式下,haproxy在客户端和upstream server之间建立一个全双工连接;这种模式不会对应用层协议做任何检查;SSL、MySQL、SSH、https等都应该使用此模式。
http:
工作在http协议下,对应用层数据做深度分析,因此支持7层的过滤、出来、转换等机制。
CentOS6.5的haproxy RPM包在defaults配置段中定义了mode为http。
指定日志:
haproxy日志配置可以在 defaults、frontend、listen、backend4个配置段中定义。也可以使用global全局配置。
haproxy配置日志有以下两种方式
1、log global:使用全局配置中的日志服务器
2、log <address> <facility> [<level> [<minlevel>] ] :自定义日志配置
注意:haproxy最多只能使用2个日志配置,如果global中配置了两个日志服务器,那么在使用了全局配置后,如果还有其他自定义的日志配置,则不会生效
global # local2.* /var/log/haproxy.log log 127.0.0.1 local2 frontend websrv log 127.0.0.1 local3
haproxy日志配置还需要修改/etc/rsyslog.conf文件,
$ModLoad imudp //启用 $UDPServerRun 514 //启用 $ModLoad imtcp //启用 $InputTCPServerRun 514 //启用 local3.* /var/log/websrv.log //指定日志路径
配置完成后,要重启rsyslog服务
/etc/init.d/rsyslog restart
log相关的参数:
capture cookie:抓取请求和响应报文中的cookie信息并记录到日志文件中。可在frontend 和 listen中配置
capture cookie <name> len <length>
capture request header <name> len <length>
捕获并记录指定的请求首部最近一次出现时的第一个值,仅能用于“frontend”和“listen”区段。捕获的首部值使用花括号{}括起来后添加进日志中。如果需要捕获多个首部值,它们将以指定的次序出现在日志文件中,并以竖线“|”作为分隔符。不存在的首部记录为空字符串,最常需要捕获的首部包括在虚拟主机环境中使用的“Host”、上传请求首部中的“Content-length”、快速区别真实用户和网络机器人的“User-agent”,以及代理环境中记录真实请求来源的“X-Forward-For”。
<name>:要捕获的首部的名称,此名称不区分字符大小写,但建议与它们出现在首部中的格式相同,比如大写首字母。需要注意的是,记录在日志中的是首部对应的值,而非首部名称。
<length>:指定记录首部值时所记录的精确长度,超出的部分将会被忽略。
可以捕获的请求首部的个数没有限制,但每个捕获最多只能记录64个字符。为了保证同一个frontend中日志格式的统一性,首部捕获仅能在frontend中定义。
例如:
capture request header X-Forwarded-For len 15 capture request header Referrer len 15
测试:
我在haproxy配置中加入capture request header Host len 15的配置,如下:
frontend websrv *:80 capture request header Host len 15 default_backend webservers backend webservers cookie node insert nocache balance roundrobin server node1 172.16.42.131:80 check cookie node1 server node2 172.16.42.135:80 check cookie node2
对比前后日志格式:
Apr 6 18:15:54 localhost haproxy[2271]: 172.16.42.165:57495 [06/Apr/2017:18:15:54.605] websrv webservers/node1 177/0/1/2/180 304 149 - - --VN 1/1/0/0/0 0/0 "GET /test3.html HTTP/1.1" Apr 6 18:21:19 localhost haproxy[2351]: 172.16.42.165:57947 [06/Apr/2017:18:21:19.498] websrv webservers/node1 0/0/0/1/1 304 149 - - --VN 1/1/0/1/0 0/0 {172.16.42.128} "GET /test3.html HTTP/1.1"
capture response header <name> len <length> :
捕获并记录响应首部,其格式和要点同请求首部。
例如:
capture response header Content-length len 9 capture response header location len 15
default_backend:
在没有匹配的"use_backend"规则时为实例指定使用的默认后端,因此,其不可应用于backend区段。在"frontend"和"backend"之间进行内容交换时,通常使用"use-backend"定义其匹配规则;而没有被规则匹配到的请求将由此参数指定的后端接收。
<backend>:指定使用的后端的名称;
使用案例:
use_backend dynamic if url_dyn use_backend static if url_css url_img extension_img default_backend dynamic
use_backend:
在listen或frontend中指定使用的条件式后端:
use_backend <backend_name> if <condition>
当满足某条件时,才使用指定的后端
use_backend <backend_name> unless <condition>
只有不满足条件时,才使用指定的后端
Server:
为后端声明一个server,因此不能用于defaults和frontend区段
server <name> <address> [:port] [param*]
为后端声明一个server,因此,不能用于defaults和frontend区段。
server有以下参数
<name>:
为此服务器指定的内部名称,其将出现在日志及警告信息中;如果设定了"http-send-server-name",它还将被添加至发往此服务器的请求首部中;
<address>:
此服务器的的IPv4地址,也支持使用可解析的主机名,只不过在启动时需要解析主机名至相应的IPv4地址;
[:port]:指定将连接请求所发往的此服务器时的目标端口,其为可选项;未设定时,将使用客户端请求时的同一相端口;
[param*]:
为此服务器设定的一系参数;其可用的参数非常多,具体请参考官方文档中的说明,下面仅说明几个常用的参数;
服务器或默认服务器参数:
backup:
设定为备用服务器,仅在负载均衡场景中的其它server均不可用于启用此server;
check:
启动对此server执行健康状态检查,其可以借助于额外的其它参数完成更精细的设定,如:
inter <delay>:
设定健康状态检查的时间间隔,单位为毫秒,默认为2000;也可以使用fastinter和downinter来根据服务器端状态优化此时间延迟;
rise <count>:
设定健康状态检查中,某离线的server从离线状态转换至正常状态需要成功检查的次数;
fall <count>:
确认server从正常状态转换为不可用状态需要检查的次数;
配置示例:
server node1 172.16.42.131:80 check inter 2000 rise 2 fall 5 server node2 172.16.42.135:80 check inter 2000 rise 2 fall 5
解释:设置每2000毫秒(2秒)对后端server做一次健康状态检查,离线的server只要2次(2s*2=4s)检查状态正常则上线,加入集群中。在线的server 5次(2s*5=10s)检查失败,则从集群中下线。
cookie <value>:
为指定server设定cookie值,此处指定的值将在请求入站时被检查,第一次为此值挑选的server将在后续的请求中被选中,其目的在于实现持久连接的功能;
配置示例:
backend webservers cookie node insert nocache balance roundrobin server node1 172.16.42.131:80 check cookie node1 server node2 172.16.42.135:80 check cookie node2
maxconn <maxconn>:
指定此服务器接受的最大并发连接数;如果发往此服务器的连接数目高于此处指定的值,其将被放置于请求队列,以等待其它连接被释放;
maxqueue <maxqueue>:
设定请求队列的最大长度;
observe <mode>:通过观察服务器的通信状况来判定其健康状态,默认为禁用,其支持的类型有“layer4”和“layer7”,“layer7”仅能用于http代理场景;
redir <prefix>:启用重定向功能,将发往此服务器的GET和HEAD请求均以302状态码响应;需要注意的是,在prefix后面不能使用/,且不能使用相对地址,以免造成循环;
例如:
server srv1 172.16.42.6:80 redir http://imageserver.test.com check
解释:将访问172.16.42.6:80的请求转发到 http://imageserver.test.com
weight <weight>:权重,默认为1,最大值为256,0表示不参与负载均衡;
检查方法:
option httpchk option httpchk <uri> option httpchk <method> <uri> option httpchk <method> <uri> <version>:不能用于frontend段,
例如:
backend https_relay mode tcp option httpchk OPTIONS * HTTP/1.1\r\nHost:\ www server apache1 192.168.1.1:443 check port 80
统计页面输出
stats enable
启用基于程序编译时默认设置的统计报告,不能用于“frontend”区段。只要没有另外的其它设定,它们就会使用如下的配置:
- stats uri : /haproxy?stats //默认stats访问页面 - stats realm : "HAProxy Statistics" - stats auth : no authentication - stats scope : no restriction
配置示例:
frontend websrv *:80 capture request header Host len 15 default_backend webservers backend webservers balance roundrobin stats enable server node1 172.16.42.131:80 check inter 2000 rise 2 fall 5 cookie node1 server node2 172.16.42.135:80 check inter 2000 rise 2 fall 5 cookie node2
访问http://172.16.42.128/haproxy?stats
尽管“stats enable”一条就能够启用统计报告,但还是建议设定其它所有的参数,以免其依赖于默认设定而带来非期后果。下面是一个配置案例。
backend public_www server websrv1 172.16.100.11:80 stats enable stats hide-version stats scope . stats uri /haproxyadmin?stats stats realm Haproxy\ Statistics stats auth statsadmin:password stats auth statsmaster:password
stats hide-version
启用统计报告并隐藏HAProxy版本报告,不能用于“frontend”区段。默认情况下,统计页面会显示一些有用信息,包括HAProxy的版本号,然而,向所有人公开HAProxy的精确版本号是非常有风险的,因为它能帮助恶意用户快速定位版本的缺陷和漏洞。尽管“stats hide-version”一条就能够启用统计报告,但还是建议设定其它所有的参数,以免其依赖于默认设定而带来非期后果。具体请参照“stats enable”一节的说明。
stats realm
stats realm <realm>
启用统计报告并高精认证领域,不能用于“frontend”区段。haproxy在读取realm时会将其视作一个单词,因此,中间的任何空白字符都必须使用反斜线进行转义。此参数仅在与“stats auth”配置使用时有意义。
<realm>:实现HTTP基本认证时显示在浏览器中的领域名称,用于提示用户输入一个用户名和密码。
尽管“stats realm”一条就能够启用统计报告,但还是建议设定其它所有的参数,以免其依赖于默认设定而带来非期后果。具体请参照“stats enable”一节的说明。
stats scope
stats scope { <name> | "." }
启用统计报告并限定报告的区段,不能用于“frontend”区段。当指定此语句时,统计报告将仅显示其列举出区段的报告信息,所有其它区段的信息将被隐藏。如果需要显示多个区段的统计报告,此语句可以定义多次。需要注意的是,区段名称检测仅仅是以字符串比较的方式进行,它不会真检测指定的区段是否真正存在。
<name>:可以是一个“listen”、“frontend”或“backend”区段的名称,而“.”则表示stats scope语句所定义的当前区段。
尽管“stats scope”一条就能够启用统计报告,但还是建议设定其它所有的参数,以免其依赖于默认设定而带来非期后果。下面是一个配置案例。
backend private_monitoring stats enable stats uri /haproxyadmin?stats //自定义的stats页面uri stats refresh 10s
stats auth
stats auth <user>:<passwd>
启用带认证的统计报告功能并授权一个用户帐号,其不能用于“frontend”区段。可以有多个。
<user>:授权进行访问的用户名;
<passwd>:此用户的访问密码,明文格式;
此语句将基于默认设定启用统计报告功能,并仅允许其定义的用户访问,其也可以定义多次以授权多个用户帐号。可以结合“stats realm”参数在提示用户认证时给出一个领域说明信息。在使用非法用户访问统计功能时,其将会响应一个“401 Forbidden”页面。其认证方式为HTTP Basic认证,密码传输会以明文方式进行,因此,配置文件中也使用明文方式存储以说明其非保密信息故此不能相同于其它关键性帐号的密码。
尽管“stats auth”一条就能够启用统计报告,但还是建议设定其它所有的参数,以免其依赖于默认设定而带来非期后果。
配置示例:
stats enable stats auth admin:admin
解释:访问stats页面时,需要账号密码,账号密码均为admin
stats admin
stats admin { if | unless } <cond>
在指定的条件满足时启用统计报告页面的管理级别功能,它允许通过web接口启用或禁用服务器,不过,基于安全的角度考虑,统计报告页面应该尽可能为只读的。此外,如果启用了HAProxy的多进程模式,启用此管理级别将有可能导致异常行为。
目前来说,POST请求方法被限制于仅能使用缓冲区减去保留部分之外的空间,因此,服务器列表不能过长,否则,此请求将无法正常工作。因此,建议一次仅调整少数几个服务器。下面是两个案例,第一个限制了仅能在本机打开报告页面时启用管理级别功能,第二个定义了仅允许通过认证的用户使用管理级别功能。
backend stats_localhost stats enable stats admin if LOCALHOST
backend stats_auth stats enable stats auth haproxyadmin:password stats admin if TRUE
配置示例:
frontend websrv *:80 capture request header Host len 15 default_backend webservers backend webservers balance roundrobin stats enable stats auth admin:admin stats admin if TRUE option httpchk /test1.html server node1 172.16.42.131:80 check inter 2000 rise 2 fall 5 cookie node1 server node2 172.16.42.135:80 check inter 2000 rise 2 fall 5 cookie node2
我们还可以将stats 配置在listen区段
listen statspage bind *:8009 stats enable stats auth admin:123456 stats admin if TRUE stats uri /haadmin?stats
自定义错误页面
errorfile <code> <file>
在用户请求不存在的页面时,返回一个页面文件给客户端而非由haproxy生成的错误代码;可用于所有段中。
<code>:指定对HTTP的哪些状态码返回指定的页面;这里可用的状态码有200、400、403、408、500、502、503和504;
<file>:指定用于响应的页面文件;
例如:
errorfile 400 /etc/haproxy/errorpages/400badreq.http errorfile 403 /etc/haproxy/errorpages/403forbid.http errorfile 503 /etc/haproxy/errorpages/503sorry.http
errorloc 和 errorloc302
errorloc <code> <url> errorloc302 <code> <url>
请求错误时,返回一个HTTP重定向至某URL的信息;可用于所有配置段中。
<code>:指定对HTTP的哪些状态码返回指定的页面;这里可用的状态码有200、400、403、408、500、502、503和504;
<url>:Location首部中指定的页面位置的具体路径,可以是在当前服务器上的页面的相对路径,也可以使用绝对路径;需要注意的是,如果URI自身错误时产生某特定状态码信息的话,有可能会导致循环定向;
需要留意的是,这两个关键字都会返回302状态吗,这将使得客户端使用同样的HTTP方法获取指定的URL,对于非GET法的场景(如POST)来说会产生问题,因为返回客户的URL是不允许使用GET以外的其它方法的。如果的确有这种问题,可以使用errorloc303来返回303状态码给客户端。
errorloc303
errorloc303 <code> <url>
请求错误时,返回一个HTTP重定向至某URL的信息给客户端;可用于所有配置段中。
<code>:指定对HTTP的哪些状态码返回指定的页面;这里可用的状态码有400、403、408、500、502、503和504;
<url>:Location首部中指定的页面位置的具体路径,可以是在当前服务器上的页面的相对路径,也可以使用绝对路径;需要注意的是,如果URI自身错误时产生某特定状态码信息的话,有可能会导致循环定向;
例如:
backend webserver server 172.16.100.6 172.16.100.6:80 check maxconn 3000 cookie srv01 server 172.16.100.7 172.16.100.7:80 check maxconn 3000 cookie srv02 errorloc 403 /etc/haproxy/errorpages/sorry.htm errorloc 503 /etc/haproxy/errorpages/sorry.htm
option forwardfor
可以定义在defaults、frontend、backend、listen4个区段
option forwardfor [ except <network> ] [ header <name> ] [ if-none ]
允许在发往服务器的请求首部中插入“X-Forwarded-For”首部。默认情况下,由于客户端的请求是经由haproxy发往后端server的,因此后端server日志中记录的client都是haproxy server的地址,有了
option forwardfor 选项,可以让后端server日志记录真实的client地址,但server端日志格式需要修改。例如apache服务器的日志格式需要改为
LogFormat "%{X-Forwarded-For}iX %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
<network>:可选参数,当指定时,源地址为匹配至此网络中的请求都禁用此功能。
<name>:可选参数,可使用一个自定义的首部,如“X-Client”来替代“X-Forwarded-For”。有些独特的web服务器的确需要用于一个独特的首部。
if-none:仅在此首部不存在时才将其添加至请求报文问道中。
HAProxy工作于反向代理模式,其发往服务器的请求中的客户端IP均为HAProxy主机的地址而非真正客户端的地址,这会使得服务器端的日志信息记录不了真正的请求来源,“X-Forwarded-For”首部则可用于解决此问题。HAProxy可以向每个发往服务器的请求上添加此首部,并以客户端IP为其value。
需要注意的是,HAProxy工作于隧道模式,其仅检查每一个连接的第一个请求,因此,仅第一个请求报文被附加此首部。如果想为每一个请求都附加此首部,请确保同时使用了“option httpclose”、“option forceclose”和“option http-server-close”几个option。
下面是一个例子。
frontend www mode http option forwardfor except 127.0.0.1
option http-server-close / no option http-server-close
启用或者禁用http服务器端关闭连接的功能
解释:在使用长连接的场景中,haproxy一方面要和client端建立连接,一方面要和后端server建立连接。为保证传输效率,一般情况下会在和client连接时启用keepalived建立长连接。而当连接数过多,或者请求超时的时候,服务器端要发起关闭连接的指令。此选项是开启长连接时必须提供的选项。
option httpclose / no option httpclose
如果使用了option httpclose,则haproxy会检查每一个连接的报文首部是否包含“Connection close”,如果没有,则会加一个。换句话说这个选项其实就是禁用keepalived 长连接。
option redispatch(重分发) / no option redispatch
当后端server开启了cookie会话保持时,通常需要加上option redispatch。这样,当后端server宕机时,发送到该server的请求可以被重定向到其他server上。
ACL
haproxy的ACL用于实现基于请求报文的首部、响应报文的内容或其它的环境状态信息来做出转发决策,这大大增强了其配置弹性。其配置法则通常分为两步,首先去定义ACL,即定义一个测试条件,而后在条件得到满足时执行某特定的动作,如阻止请求或转发至某特定的后端。定义ACL的语法格式如下。
acl <aclname> <criterion> [flags] [operator] <value> ...
<aclname>:ACL名称,区分字符大小写,且其只能包含大小写字母、数字、-(连接线)、_(下划线)、.(点号)和:(冒号);haproxy中,acl可以重名,这可以把多个测试条件定义为一个共同的acl;
<criterion>:测试标准,即对什么信息发起测试;测试方式可以由[flags]指定的标志进行调整;而有些测试标准也可以需要为其在<value>之前指定一个操作符[operator];
[flags]:目前haproxy的acl支持的标志位有3个:
-i:不区分<value>中模式字符的大小写;
-f:从指定的文件中加载模式;
--:标志符的强制结束标记,在模式中的字符串像标记符时使用;
<value>:acl测试条件支持的值有以下四类:
整数或整数范围:如1024:65535表示从1024至65535;仅支持使用正整数(如果出现类似小数的标识,其为通常为版本测试),且支持使用的操作符有5个,分别为eq、ge、gt、le和lt;
字符串:支持使用“-i”以忽略字符大小写,支持使用“\”进行转义;如果在模式首部出现了-i,可以在其之前使用“--”标志位;
正则表达式:其机制类同字符串匹配;
IP地址及网络地址
同一个acl中可以指定多个测试条件,这些测试条件需要由逻辑操作符指定其关系。条件间的组合测试关系有三种:“与”(默认即为与操作)、“或”(使用“||”操作符)以及“非”(使用“!”操作符)。
常用的测试标准(criteria)
be_sess_rate <integer>
be_sess_rate(backend) <integer>
用于测试指定的backend上会话创建的速率(即每秒创建的会话数)是否满足指定的条件;常用于在指定backend上的会话速率过高时将用户请求转发至另外的backend,或用于阻止攻击行为。例如:
backend dynamic mode http acl being_scanned be_sess_rate gt 50 redirect location /error_pages/denied.html if being_scanned
fe_sess_rate <integer>
fe_sess_rate(frontend) <integer>
用于测试指定的frontend(或当前frontend)上的会话创建速率是否满足指定的条件;常用于为frontend指定一个合理的会话创建速率的上限以防止服务被滥用。例如下面的例子限定入站邮件速率不能大于50封/秒,所有在此指定范围之外的请求都将被延时50毫秒。
frontend mail bind :25 mode tcp maxconn 500 acl too_fast fe_sess_rate ge 50 tcp-request inspect-delay 50ms tcp-request content accept if ! too_fast tcp-request content accept if WAIT_END
hdr <string>
hdr(header) <string>
用于测试请求报文中的所有首部或指定首部是否满足指定的条件;指定首部时,其名称不区分大小写,且在括号“()”中不能有任何多余的空白字符。测试服务器端的响应报文时可以使用shdr()。例如下面的例子用于测试首部Connection的值是否为close。
hdr(Connection) -i close
method <string>
测试HTTP请求报文中使用的方法。
path_beg <string>
用于测试请求的URL是否以<string>指定的模式开头。下面的例子用于测试URL是否以/static、/images、/javascript或/stylesheets头。
acl url_static path_beg -i /static /images /javascript /stylesheets
path_end <string>
用于测试请求的URL是否以<string>指定的模式结尾。例如,下面的例子用户测试URL是否以jpg、gif、png、css或js结尾。
acl url_static path_end -i .jpg .gif .png .css .js
hdr_beg <string>
用于测试请求报文的指定首部的开头部分是否符合<string>指定的模式。例如,下面的例子用记测试请求是否为提供静态内容的主机img、video、download或ftp。
acl host_static hdr_beg(host) -i img. video. download. ftp.
hdr_end <string>
用于测试请求报文的指定首部的结尾部分是否符合<string>指定的模式。例如,下面的例子用记测试请求是否为
acl示例介绍:
acl clear dst_port 80
所有目标端口为80的连接,定义为clear
acl secure dst_port 8080
所有目标端口为8080的连接,定义为secure
acl login_page url_beg /login
所有url以login开头,定义为login_page(登录页面)
acl logout url_beg /logout
所有url以logout开头,定义为logout_page(logout页面)
acl uid_given url_reg /login?userid=[^&]+
url符合指定正则表达式(login?userid=&以外的任意字符)的定义为url_given
acl cookie_set hdr_sub(cookie) SEEN=1
有cookie信息的定义为cookie_set
超时时长相关设定
timeout http-request <timeout>
设置等待客户端发起http请求的超时时长,单位是毫秒
示例: timeout http-request 10s
timeout queue <timeout>
设置客户端在队列中等待一个连接被释放的最大时长,当连接已满时,新的客户端连接需要在队列中等待,这个配置就是设置的等待的最大时长
实例: timeout queus 1m
timeout connect <timeout>
设定在haproxy尝试向后端server发起请求时等待的超时时长
可以在defaults、listen、backend区段中定义
实例: timeout connect 10s
timeout client <timeout>
客户端非活动状态的超时时长,什么是非活动状态?客户端想haproxy发起请求建立连接后,不断开连接,也不请求新的资源,就是非活动连接
可以在defaults、frontend、listen区段中定义
实例: timeout client 1m
timeout server <timeout>
haproxy等待后端server发送数据的超时时长。haproxy与server建立连接后,等待server发送数据,如果server宕机,则在超时后,自动断开连接
可以在defaults、listen、backend区段中定义
实例: timeout server 1m
timeout http-keep-alive <timeout>
haproxy与client保持连接状态的超时时长。如果后端server非常繁忙,则这个时间不能设置太长
实例:timeout http-keep-alive 10s
timeout check <timeout>
在实现健康状态监测时的超时时长。
可以在defaults、listen、backend区段中定义
实例:timeout check 10s
本文出自 “zengestudy” 博客,请务必保留此出处http://zengestudy.blog.51cto.com/1702365/1913809
标签:haproxy
原文地址:http://zengestudy.blog.51cto.com/1702365/1913809