14.3. haproxy¶
14.3.1. haproxy的安装¶
[root@centos-151 ~]# yum install haproxy
[root@centos-151 ~]# rpm -ql haproxy
/etc/haproxy # 主配置目录
/etc/haproxy/haproxy.cfg # 主配置文件
/etc/logrotate.d/haproxy # 日志滚动
/etc/sysconfig/haproxy # 启动参数
/usr/bin/halog
/usr/bin/iprange
/usr/lib/systemd/system/haproxy.service # 服务脚本
/usr/sbin/haproxy
/usr/sbin/haproxy-systemd-wrapper
/usr/share/doc/haproxy-1.5.18
/usr/share/doc/haproxy-1.5.18/CHANGELOG
/usr/share/doc/haproxy-1.5.18/LICENSE
/usr/share/doc/haproxy-1.5.18/README
/usr/share/doc/haproxy-1.5.18/ROADMAP
/usr/share/doc/haproxy-1.5.18/VERSION
/usr/share/doc/haproxy-1.5.18/acl.fig
/usr/share/doc/haproxy-1.5.18/architecture.txt
/usr/share/doc/haproxy-1.5.18/close-options.txt
/usr/share/doc/haproxy-1.5.18/coding-style.txt
/usr/share/doc/haproxy-1.5.18/configuration.txt
/usr/share/doc/haproxy-1.5.18/cookie-options.txt
/usr/share/doc/haproxy-1.5.18/design-thoughts
/usr/share/doc/haproxy-1.5.18/design-thoughts/backends-v0.txt
/usr/share/doc/haproxy-1.5.18/design-thoughts/backends.txt
/usr/share/doc/haproxy-1.5.18/design-thoughts/be-fe-changes.txt
/usr/share/doc/haproxy-1.5.18/design-thoughts/binding-possibilities.txt
/usr/share/doc/haproxy-1.5.18/design-thoughts/buffer-redesign.txt
/usr/share/doc/haproxy-1.5.18/design-thoughts/buffers.fig
/usr/share/doc/haproxy-1.5.18/design-thoughts/config-language.txt
/usr/share/doc/haproxy-1.5.18/design-thoughts/connection-reuse.txt
/usr/share/doc/haproxy-1.5.18/design-thoughts/cttproxy-changes.txt
/usr/share/doc/haproxy-1.5.18/design-thoughts/entities-v2.txt
/usr/share/doc/haproxy-1.5.18/design-thoughts/how-it-works.txt
/usr/share/doc/haproxy-1.5.18/design-thoughts/http_load_time.url
/usr/share/doc/haproxy-1.5.18/design-thoughts/rate-shaping.txt
/usr/share/doc/haproxy-1.5.18/design-thoughts/sess_par_sec.txt
/usr/share/doc/haproxy-1.5.18/examples # 样例配置目录,下面都是一些特定样例
/usr/share/doc/haproxy-1.5.18/examples/acl-content-sw.cfg
/usr/share/doc/haproxy-1.5.18/examples/auth.cfg
/usr/share/doc/haproxy-1.5.18/examples/build.cfg
/usr/share/doc/haproxy-1.5.18/examples/content-sw-sample.cfg
/usr/share/doc/haproxy-1.5.18/examples/cttproxy-src.cfg
/usr/share/doc/haproxy-1.5.18/examples/examples.cfg
/usr/share/doc/haproxy-1.5.18/examples/haproxy.cfg
/usr/share/doc/haproxy-1.5.18/examples/option-http_proxy.cfg
/usr/share/doc/haproxy-1.5.18/examples/ssl.cfg
/usr/share/doc/haproxy-1.5.18/examples/tarpit.cfg
/usr/share/doc/haproxy-1.5.18/examples/test-section-kw.cfg
/usr/share/doc/haproxy-1.5.18/examples/transparent_proxy.cfg
/usr/share/doc/haproxy-1.5.18/examples/url-switching.cfg
/usr/share/doc/haproxy-1.5.18/gpl.txt
/usr/share/doc/haproxy-1.5.18/haproxy-en.txt
/usr/share/doc/haproxy-1.5.18/haproxy-fr.txt
/usr/share/doc/haproxy-1.5.18/haproxy.1
/usr/share/doc/haproxy-1.5.18/internals
/usr/share/doc/haproxy-1.5.18/internals/acl.txt
/usr/share/doc/haproxy-1.5.18/internals/body-parsing.txt
/usr/share/doc/haproxy-1.5.18/internals/buffer-operations.txt
/usr/share/doc/haproxy-1.5.18/internals/buffer-ops.fig
/usr/share/doc/haproxy-1.5.18/internals/connect-status.txt
/usr/share/doc/haproxy-1.5.18/internals/connection-header.txt
/usr/share/doc/haproxy-1.5.18/internals/connection-scale.txt
/usr/share/doc/haproxy-1.5.18/internals/entities.fig
/usr/share/doc/haproxy-1.5.18/internals/entities.pdf
/usr/share/doc/haproxy-1.5.18/internals/entities.svg
/usr/share/doc/haproxy-1.5.18/internals/entities.txt
/usr/share/doc/haproxy-1.5.18/internals/hashing.txt
/usr/share/doc/haproxy-1.5.18/internals/header-parser-speed.txt
/usr/share/doc/haproxy-1.5.18/internals/header-tree.txt
/usr/share/doc/haproxy-1.5.18/internals/http-cookies.txt
/usr/share/doc/haproxy-1.5.18/internals/http-docs.txt
/usr/share/doc/haproxy-1.5.18/internals/http-parsing.txt
/usr/share/doc/haproxy-1.5.18/internals/naming.txt
/usr/share/doc/haproxy-1.5.18/internals/pattern.dia
/usr/share/doc/haproxy-1.5.18/internals/pattern.pdf
/usr/share/doc/haproxy-1.5.18/internals/polling-states.fig
/usr/share/doc/haproxy-1.5.18/internals/repartition-be-fe-fi.txt
/usr/share/doc/haproxy-1.5.18/internals/sequence.fig
/usr/share/doc/haproxy-1.5.18/internals/stats-v2.txt
/usr/share/doc/haproxy-1.5.18/internals/stream-sock-states.fig
/usr/share/doc/haproxy-1.5.18/internals/todo.cttproxy
/usr/share/doc/haproxy-1.5.18/lgpl.txt
/usr/share/doc/haproxy-1.5.18/proxy-protocol.txt
/usr/share/doc/haproxy-1.5.18/queuing.fig
/usr/share/haproxy
/usr/share/haproxy/400.http # 主要的几个状态页面
/usr/share/haproxy/403.http
/usr/share/haproxy/408.http
/usr/share/haproxy/500.http
/usr/share/haproxy/502.http
/usr/share/haproxy/503.http
/usr/share/haproxy/504.http
/usr/share/haproxy/README
/usr/share/man/man1/halog.1.gz # 帮助文档类
/usr/share/man/man1/haproxy.1.gz
/var/lib/haproxy # haproxy数据库位置
14.3.2. 快速使用案例¶
# 备份工作
[root@centos-151 ~]# cd /etc/haproxy/
[root@centos-151 haproxy]# ls
haproxy.cfg
[root@centos-151 haproxy]# cp haproxy.cfg{,.bak}
[root@centos-151 haproxy]# ll
total 8
-rw-r--r-- 1 root root 3142 May 2 2017 haproxy.cfg
-rw-r--r-- 1 root root 3142 Mar 21 19:47 haproxy.cfg.bak
[root@centos-151 haproxy]# vim haproxy.cfg
# 删除这行(main frontend which proxys to the backends)后面的所有行
# 添加如下几行配置
frontend web *:80
default_backend webservs
backend webservs
balance roundrobin
server web152 192.168.46.152:80 check
server web153 192.168.46.153:80 check
# 准备后端的web服务
[root@centos-152 ~]# yum install nginx
[root@centos-152 ~]# systemctl restart nginx
[root@centos-152 ~]# hostnamectl > /usr/share/nginx/html/index.html
[root@centos-152 ~]# curl localhost
Static hostname: centos-152.linuxpanda.tech
Icon name: computer-vm
Chassis: vm
Machine ID: 8522cb29cf77495dbb9c4ad8f7ca02c4
Boot ID: 6a174ac39912489da3947eb4a2a8bb9a
Virtualization: vmware
Operating System: CentOS Linux 7 (Core)
CPE OS Name: cpe:/o:centos:centos:7
Kernel: Linux 3.10.0-693.el7.x86_64
Architecture: x86-64
[root@centos-153 ~]# yum install nginx
[root@centos-153 ~]# hostnamectl > /usr/share/nginx/html/index.html
[root@centos-153 ~]# systemctl restart nginx
[root@centos-153 ~]# curl localhost
Static hostname: centos-153.linuxpanda.tech
Icon name: computer-vm
Chassis: vm
Machine ID: 8522cb29cf77495dbb9c4ad8f7ca02c4
Boot ID: 065ba5421bc9473eab1202cc23e1a5ba
Virtualization: vmware
Operating System: CentOS Linux 7 (Core)
CPE OS Name: cpe:/o:centos:centos:7
Kernel: Linux 3.10.0-693.el7.x86_64
Architecture: x86-64
# 测试
[root@centos-151 haproxy]# systemctl start haproxy
[root@centos-151 haproxy]# curl 192.168.46.151
Static hostname: centos-152.linuxpanda.tech
Icon name: computer-vm
Chassis: vm
Machine ID: 8522cb29cf77495dbb9c4ad8f7ca02c4
Boot ID: 6a174ac39912489da3947eb4a2a8bb9a
Virtualization: vmware
Operating System: CentOS Linux 7 (Core)
CPE OS Name: cpe:/o:centos:centos:7
Kernel: Linux 3.10.0-693.el7.x86_64
Architecture: x86-64
[root@centos-151 haproxy]# curl 192.168.46.151
Static hostname: centos-153.linuxpanda.tech
Icon name: computer-vm
Chassis: vm
Machine ID: 8522cb29cf77495dbb9c4ad8f7ca02c4
Boot ID: 065ba5421bc9473eab1202cc23e1a5ba
Virtualization: vmware
Operating System: CentOS Linux 7 (Core)
CPE OS Name: cpe:/o:centos:centos:7
Kernel: Linux 3.10.0-693.el7.x86_64
Architecture: x86-64
14.3.3. 日志配置¶
在haproxy的配置文件中,默认已经绑定到local2上了,我们需要在rsyslog上关联下。
[root@centos-151 haproxy]# vim /etc/rsyslog.conf
# 解开如下4行注释内容
$ModLoad imudp
$UDPServerRun 514
# Provides TCP syslog reception
$ModLoad imtcp
$InputTCPServerRun 514
# 添加如下行
local2.* /var/log/haproxy.log
# 重启下服务
[root@centos-151 haproxy]# systemctl restart rsyslog
[root@centos-151 haproxy]# systemctl restart haproxy
# 请求一次
[root@centos-151 haproxy]# !curl
curl 192.168.46.151
Static hostname: centos-152.linuxpanda.tech
Icon name: computer-vm
Chassis: vm
Machine ID: 8522cb29cf77495dbb9c4ad8f7ca02c4
Boot ID: 6a174ac39912489da3947eb4a2a8bb9a
Virtualization: vmware
Operating System: CentOS Linux 7 (Core)
CPE OS Name: cpe:/o:centos:centos:7
Kernel: Linux 3.10.0-693.el7.x86_64
Architecture: x86-64
# 查看日志文件
[root@centos-151 haproxy]# cat /var/log/haproxy.log
Mar 21 20:09:06 localhost haproxy[16857]: Proxy web started.
Mar 21 20:09:06 localhost haproxy[16857]: Proxy webservs started.
Mar 21 20:09:10 localhost haproxy[16858]: 192.168.46.151:53018 [21/Mar/2018:20:09:10.841] web webservs/web152 0/0/0/0/0 200 628 - - ---- 1/1/0/0/0 0/0 "GET / HTTP/1.1"
14.3.4. 主要配置参数¶
global配置项:
chroot: 切换根运行目录
uid,gid: 运行用户和组
user,group:运行用户和组
daemon: 是否守护进程
log: 配置日志和相应的级别
nbproc: 要启动的haproxy的进程数量
ulimit: 每个haproxy进程可打开的最大文件数量
maxconn: 设定每个haproxy进程能接受的最大并发连接数量
maxconnrate: 每个进程每秒能创建的最大连接数量
maxsslconn: 每个haproxy进程所能接受的ssl最大并发连接数量
spread-checks: 散开检查工作
代理配置项:
defaults: 默认的
frontend: 前段
backend: 后端的
listen: 监听
bind: 绑定地址和端口
balance: 指定调度算法类型和算法参数
roundrobin: 轮调
static-rr: 静态轮调
leastconn: 最小连接
first: 前面的达到上限在调度下一个
source: 源地址hash
uri: 对uri左半部分做hash计算,派发到下面服务器
url_param: 对参数做hash计算,然后派发
hdr: 对特定的http首部做hash计算
hash-type: hash类型,map-based,consistent
default_backend: 默认后端
default_server: 默认服务器
name: 名字
address: 地址
port: 端口
maxconn:最大连接
backlog: 后援队列长度
check 健康检查
addr: 检查地址
port: 检查端口
inter: 检查间隔
rise: 多少次检查成功认为可用
fall: 多少次失败标记不可用
cookie: 设置cookie值
disabled: 标记不可用
on-error: 后端服务故障时候的行动策略
统计接口相关参数
states enable ,启动后可以通过ip/haproxy?stats访问
stats uri : /haproxy?stats
stats realm: "认证提示"
stats refresh: 设定自动刷新时间间隔
stats admin: 启用stats page的管理功能
配置样例:
listen stats
bind :9090
stats enable
stats realm " stat page"
stats auth admin:admin
stats admin if TRUE
mode: 工作模式,支持tcp,http,health三种
option forwardfor [except network] : 添加forwardfor信息
erroffile <code> <file>: 错误文件
errorloc302 <code> <url>: 指定一个url地址
reqadd: 请求头添加
rspdel: 响应头删除
rspadd: 响应头添加
option httpchk uri: 特定uri的http检查
use_backend <backup>:使用特定后端
default_backend:默认后端
http-request {allow,deny} {if 条件}: 如果特定条件就执行特定动作
http_request set-header X-Forwarded-Port %{dst_port}
压缩功能
compression algo: 指定http压缩了下
compression type:对特定类型压缩
连接超时相关
timout client : 客户端超时
timeout server: 客户端超时
timeout http-request: 请求的超时时长
timeout connect: 连接超时时长
timout client-fin 等待fin的时间
timeout server-find 等待fin的时间
acl设置
acl invalid_src src ip : 设置一个命名的acl
block if invalid_src: 如果特定条件满足就403返回
14.3.5. 常用配置¶
14.3.5.1. 后台记录真实的客户端ip方法¶
默认default已经有forwardfor配置了。 可以在后端的服务器上面使用X-Forwarded-For头来记录真实的客户端地址。 可以使用命令 “tcpdump -i ens33 port 80 -nn -vv” 去抓取调度到后端的服务器的请求头信息, 这里有一个样例的信息(部分的):
tcpdump -i ens33 port 80 -nn -vv
192.168.46.151.38294 > 192.168.46.152.80: Flags [P.], cksum 0xf70e (correct), seq 1:517, ack 1, win 457, options [nop,nop,TS val 16990545 ecr 23555307], length 516: HTTP, length: 516
GET / HTTP/1.1
Host: 192.168.46.151
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
If-None-Match: "5ab2496d-18b"
If-Modified-Since: Wed, 21 Mar 2018 12:00:45 GMT
X-Forwarded-For: 192.168.46.1
Connection: close
剩下的就是在web的日志格式中添加该变量即可。
14.3.5.2. 动静分离¶
frontend web *:80
acl url_static path_beg -i /static /images/ /javascript /stylesheets /css /js
acl url_static path_end -i .jpg .gif .png .css .js .html .txt .htm
use_backend staticsrvs if url_static
default_backend webservs
backend staticsrvs
balance roundrobin
server static152 192.168.46.152
backend webservs
#balance roundrobin
cookie BACKENDSRV insert nocache indirect
server web153 192.168.46.153:80 cookie web153 check addr 192.168.46.152 port 80 inter 2000 rise 2 fall 3
# 后端的153机器需要构建一个php页面,安装php-fpm包,主要配置如下
location / {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php ;
fastcgi_param SCRIPT_FILENAME /usr/share/nginx/html$fastcgi_script_name;
include fastcgi_params ;
}
# php主页设置
[root@centos-153 ~]# cat /usr/share/nginx/html/index.php
<?php
echo "今天是 " . date("Y/m/d") . "<br>";
?>
# 测试下配置
[root@centos-151 ~]# for i in {1..10} ; do curl http://192.168.46.151/index.html ; curl http://192.168.46.151/index.php; echo "" ; done
centos-152.linuxpanda.tech
今天是 2018/03/22<br>
centos-152.linuxpanda.tech
今天是 2018/03/22<br>
centos-152.linuxpanda.tech
今天是 2018/03/22<br>
centos-152.linuxpanda.tech
今天是 2018/03/22<br>
centos-152.linuxpanda.tech
今天是 2018/03/22<br>
centos-152.linuxpanda.tech
今天是 2018/03/22<br>
centos-152.linuxpanda.tech
今天是 2018/03/22<br>
centos-152.linuxpanda.tech
今天是 2018/03/22<br>
centos-152.linuxpanda.tech
今天是 2018/03/22<br>
centos-152.linuxpanda.tech
今天是 2018/03/22<br>
14.3.5.3. 配置支持https协议¶
# 证书准备
[root@centos-151 certs]# make haproxy.crt
umask 77 ; \
/usr/bin/openssl genrsa -aes128 2048 > haproxy.key
Generating RSA private key, 2048 bit long modulus
............................................+++
..........................................................................+++
e is 65537 (0x10001)
Enter pass phrase:
Verifying - Enter pass phrase:
umask 77 ; \
/usr/bin/openssl req -utf8 -new -key haproxy.key -x509 -days 365 -out haproxy.crt
Enter pass phrase for haproxy.key:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:cn
State or Province Name (full name) []:beijing
Locality Name (eg, city) [Default City]:beijing
Organization Name (eg, company) [Default Company Ltd]:linuxpanda.tech
Organizational Unit Name (eg, section) []:opt
Common Name (eg, your name or your server's hostname) []:*.linuxpanda.tech
Email Address []:
[root@centos-151 certs]# ls
ca-bundle.crt ca-bundle.trust.crt haproxy.crt haproxy.key make-dummy-cert Makefile renew-dummy-cert
[root@centos-151 certs]# openssl rsa -in haproxy.key -out haproxy.key2
Enter pass phrase for haproxy.key:
writing RSA key
[root@centos-151 certs]# cat haproxy.crt haproxy.key2 > haproxy.pem
# 配置
frontend web
bind *:443 ssl crt /etc/pki/tls/certs/haproxy.pem
bind *:80
redirect scheme https if !{ ssl_fc }
#http_request set-header X-Forwarded-Port %{dst_port]
#http_request set-header X-Forward-Porto https if { ssl_fc }
acl url_static path_beg -i /static /images/ /javascript /stylesheets /css /js
acl url_static path_end -i .jpg .gif .png .css .js .html .txt .htm
use_backend staticsrvs if url_static
default_backend webservs
backend staticsrvs
balance roundrobin
server static152 192.168.46.152
backend webservs
#balance roundrobin
cookie BACKENDSRV insert nocache indirect
server web153 192.168.46.153:80 cookie web153 check addr 192.168.46.152 port 80 inter 2000 rise 2 fall 3
# 测试下
[root@centos-152 ~]# curl https://192.168.46.151 -k
今天是 2018/03/22<br>