haproxy是一个代理服务器,他是将用户的多个请求调度到后端服务器时,而不会因为一个后端服务器的故障而导致面向客户端的服务不可用,但是如果是haproxy自身故障了,服务依然不可用

haproxy是一个代理服务器,但是天然就是一个能在代理时做负载均衡调度的服务器

haproxy的特信有两个反代和调度器

1.反代,支持两种反代模式

1.如果工作在http模式下,这是一个七层反代

2.如果工作在tcp模式下,这是一个伪四层反代,之所以称为伪四层是因为还有工作在七层,来模拟四层调度

四层反代和七层反代的区别

1.要根据用户的请求的资源类型做分离调度,只有七层才有这样的功能

2.七层还可以做ssl/tls会话的卸载器。四层反代就无法实现这个功能

ssl/tls会话的卸载器就是,如果我们要构建一个ssl类型的应用,他可以实现客户端与调度器后端的RS服务器二者之间实现ssl会话的建立,拆除等功能

如果我们要做七层调度的话ssl会话可以只在客户端与调度器之间进行,调度器与反代服务器通常都是一个局域网之内的通信,而且是一个防范严密的局域网通信,因此他们之间的明文通常是没有问题的

由于ipvs工作在四层而ssl或tls工作在七层模型中的会话层或应用层,使得他没法卸载,这是七层反代时能获取的功能

七层反代只针对http和https服务

2.调度器

调度器有众多的调度算法

rr轮循 wrr加权轮循 lc最少连接 wlc加权最少连接

还支持七层模型中特有的调度算法,例如:URL

haproxy使用事件驱动模型单进程响应多请求的模式来工作,他也可以同时启用多进程,每个进程响并处理一部分用户请求,但是对haproxy不建议这么做,他们强烈建议将haproxy运行在单进程上,足以处理较大并发数量的用户请求,虽然他也能支持多进程的模式,但建议单进程,这样更容易排查和定义问题

四层和七层调度的区别

四层调度仅仅是一个管道,如果和ipvs一样仅仅工作在内核的话,ipvs不用监听套接字,它只是打开了一个管道,他是把请求原封不动的发到后端服务器上

七层反代是自己要监听在套接字上,所以客户端请求的时候,我们的代理服务器就是服务器端,客户端和代理服务器之间有一个完整的会话,代理服务器发现自己没有对方请求内容,自己在起一个客户端程序,然后向后端服务器发请求,这样一来面向后端服务器的是代理服务器端

所以这是完全独立的两路连接,各自独立

四层是不受套接字数量限制的

七层是受套接字数量限制的

timedatectl set-timezone Asia/Shanghai 更改时间区

haproxy的版本是1.5

haproxy 的配置主要分两段

global 全局配置段,这些都要工作在默认配置下,因为会动态调整

进程及安全配置相关的参数

性能调整相关参数

Debug参数

用户列表

peers 同等端点的其他兄弟服务器彼此间通信

proxies 代理配置段

defaults:为frontend ,backend,listen 提供默认配置

frontend前端 相当于nginx的server {}

backend 后端 相当于nginx的upstream {} 调度器

listen 相对frontend和backend的合体,但是只能实现一对一

安装haproxy

yum install haproxy -y

配置文件

vim /etc/haproxy/haproxy.cfg

global全局中配置

定义前端

frontend main *:80 #要监听的端口

mode http #以http模型为主导

default_backend websrvs #要使用哪个默认后端,websrvs后端的名字自己定义

定义后端

backend websrvs

balance roundrobin #调度算法,roundrobin加强轮循

server websrv1 192.168.63.131:80 check websrv1 代表第一个后端,check代表健康检查

server websrv2 192.168.63.139:80 check websrv2 代表第一个后端,check代表健康检查

clip_image002

启动服务

systemctl restart haproxy

clip_image004

客户端测试

for i in {1..10} ;do curl 192.168.63.140; done

更改调用的权重

frontend main *:80

mode http

default_backend websrvs

backend websrvs

balance roundrobin

server static1 192.168.63.131:80 check weight 2 注:weight 2代表权重改为2

server static2 192.168.63.139:80 check

clip_image006

客户端测试 192.168.63.140是代理服务器haproxy的ip

for i in {1..10} ;do curl 192.168.63.140; done

global是haproxy的全局配置

配置日志文件

vim /etc/rsyslog.conf

在日志文件中加入这一行

local2.* /var/log/haproxy.log

clip_image008

取消两行注释,使用UDP协议,因为性能比较好

# Provides UDP syslog reception

$ModLoad imudp

$UDPServerRun 514

clip_image010

启动日志服务

systemctl restart rsyslog

用ss -unl查看udp协议的端口,查看514监听端口是否启用

clip_image012

查看日志

tail /var/log/haproxy.log

nbproc 要启动的haproxy的进程数量

默认是两个

ps aux 查看

clip_image014

可以用 ulimit-n修改,不过不建议修改,haproxy主控进程会根据子进程所需要打开的描述符自动调整

进程及安全管理:chroot切根,daemon是否以守护进程方式运行, user group uid gid

代理配置阶段

defaults <name>

frontend <name>

用来配置前端,就是接入客户端请求的,监听在某一个套接字上

backend <name>

后端有多少个服务器,我们把它规定成组,并配置调度算法,以便能被前端作为调度或者转 - 发请求目的端

listen <name>

listen包含frontend和backend的

可以的配置参数

bind:用来定义前端服务器用来接收用户请求的套接字

例:

listen http

bind :80,:443 #可以监听两个套接字80,443 只能用在frontend和listen代理中

bind 10.0.0.:1080,10.0.0.1:10443 #也可以用ip加端口的格式

bind /var/run.ssl-frontend.sock user root mode 600 accept-proxy #亦可以说sock文件

监听两个套接字只能用在frontend和listen代理中

clip_image016

uri算法

后端服务器调度到缓存服务器的时候要用到的

vim /etc/haproxy/haproxy.cfg

backend websrvs

balance uri #算法

hash-type consistent  # 用动态方式调度

server static1 192.168.63.131:80 check weight 2 #权重为2,是2比1的调度

server static2 192.168.63.139:80 check

clip_image018

在后端服务器创建测试页面

192.168.63.131 服务器

for i in {1..10};do echo "Test Page $i @Backend Server 1" >/var/www/html/test$i.html; done

192.168.63.139 服务器

for i in {1..10};do echo "Test Page $i @Backend Server 1" >/var/www/html/test$i.html; done

客户端测试

for i in {1..10};do curl http://192.168.63.140/test9.html; done

hdr(User-Agent)算法

把来自同一客户端的请求,始终绑到同一服务器上

vim /etc/haproxy/haproxy.cfg

backend websrvs

balance hdr(User-Agent)

hash-type consistent

server static1 192.168.63.131:80 check weight 2

server static2 192.168.63.139:80 check

将一台服务器标记为backup

下架一台服务器

vim /etc/haproxy/haproxy.cfg

backend websrvs

balance roundrobin

server static1 192.168.63.131:80 check backup

server static2 192.168.63.139:80 check

clip_image020

修改默认检测逻辑

backend websrvs

balance roundrobin

server static1 192.168.63.131:80 check inter 1000 rise 1 fall 2 1秒钟检测一次,上架只要一次,下架要两次

server static2 192.168.63.139:80 check

redir 只要访问这个服务器都调度到其他服务器

如果这个服务器有问题。当客户端访问的时候我吗可以将这条服务器调度到其他可以用的服务器上

backend websrvs

balance roundrobin

server static1 192.168.63.131:80 check inter 1000 rise 1 fall 2

server static2 192.168.63.139:80 check redir https://www.baidu.com/

如果访问的是static2服务器就调度到baidu网站

clip_image022

在客户端浏览器测试

172.20.127.233 ip是haproxy的服务器外网ip

maxconn 定义最大并发连接数

backend websrvs

balance roundrobin

server static1 192.168.63.131:80 check inter 1000 rise 1 fall 2 maxconn 2000

server static2 192.168.63.139:80 check redir maxconn 1500

clip_image024

cookie 做会话绑定

当有请求报文的时候,进程请求报文,发现上一次已经例如到过static1服务器,就将这个报文调度到第一个服务器上

backend websrvs

balance roundrobin

cookie WEBSRV insert nocache indirect 注: WEBSRV名字随便指定,以insert的方式插入已有的cookie中,后面两是补充,nocache 非缓存响应的,以及indirect重定向的

server static1 192.168.63.131:80 check inter 1000 rise 1 fall 2 maxconn 2000 cookie static1

server static2 192.168.63.139:80 check maxconn 1500 cookie static2

clip_image026

在客户端浏览器测试

172.20.127.233 ip是haproxy的服务器外网ip

httpchk http的七层状态安全检测

vim /etc/haproxy/haproxy.cfg

backend websrvs

balance roundrobin

option httpchk GET /test9.html #GET是方法,test9.html是URL

server static1 192.168.63.131:80 check inter 1000 rise 1 fall 2 maxconn 2000

server static2 192.168.63.139:80 check maxconn 1500

检测test9.html网站,如果没有故障两个都调度,如果一个故障,就只调度一个服务器

clip_image028

统计接口的参数

显示web界面

在前端加入 stats enable

vim /etc/haproxy/haproxy.cfg

frontend main

bind :80,:8080

mode http

default_backend websrvs

stats enable

clip_image030

启动服务

systemctl restart haproxy

浏览器测试

http://172.20.127.233/haproxy?stats

clip_image032

clip_image034

我们打开的web界面没有安全装置非常的不安全。我们可以做以下几种安全设置

1.让web界面特定的端口打开,我的可以单独定义

listen stats *:9527 #端口是9527

stats enable

clip_image036

启动服务

systemctl restart haproxy

在客户端访问的时候要加端口

http://172.20.127.233:9527/haproxy?stats

2.输入用户名密码

listen stats *:9527

stats enable

stats realm "HAProxy Stats" #提示用户输入用户名密码

stats auth admin:admin #用户名和密码是admin

clip_image038

启动服务

systemctl restart haproxy

客户端测试

http://172.20.127.233:9527/haproxy?stats

clip_image040

3. 更改URL

vim /etc/haproxy/haproxy.cfg

listen stats *:9527

stats enable

stats uri /admin?mystats

stats realm "HAProxy Stats"

stats auth admin:admin

clip_image042

重新启动服务

systemctl restart haproxy

客户端测试

http://172.20.127.233:9527/admin?mystats

4.打开内建管理接口

vim /etc/haproxy/haproxy.cfg

listen stats *:9527

stats enable

stats uri /admin?mystats

stats realm "HAProxy Stats"

stats auth admin:admin

stats admin if TRUE

clip_image044

启动服务

systemctl restart haproxy

客户端测试

http://172.20.127.233:9527/admin?mystats

clip_image046

选择要在已检查的服务器上执行的操作

例将static1 设置为DRAIN

clip_image048

maxconn的参数

不建议打开

将ssh端口发布到互联网,这样互联网的客户端也可以访问

listen ssh

bind :22222

mode tcp

balance leastconn

server srv1 192.168.63.131 check

server srv2 192.168.63.139 check

option forwardfor 加入这个选项能获取到客户端的真实地址

1. 在haproxy服务器端加入选项

vim /etc/haproxy/haproxy.cfg

backend websrvs

balance roundrobin

option httpchk GET /test8.html

option forwardfor

server static1 192.168.63.131:80 check inter 1000 rise 1 fall 2 maxconn 2000

server static2 192.168.63.139:80 check maxconn 1500

clip_image050

启动服务

systemctl restart haproxy

2.在后端服务器修改httpd的配置

vim /etc/httpd/conf/httpd.conf

找到 LogFormat所在的行

在第一行开头把%h修改为 LogFormat "%{X-Forwarded-For}i

clip_image052

启动服务

systemctl start httpd

3 在日志文件中查看

tail /var/log/httpd/access_log

clip_image054

errorfile 错误页面

服务器有内建的错误页面,可以自定义。注:代理服务不能自定义错误页面404

但是能指定200, 400, 403, 408, 500, 502, 503, and 504.

errorloc

rspdel删除服务器端的一些信息 rspadd是添加信息

在响应报文可以看到server暴露了http的版本信息,非常危险,我们可以删除这个选项

clip_image056

删除server的首部

vim /etc/haproxy/haproxy.cfg

frontend main

bind :80,:8080

mode http

default_backend websrvs

rspidel ^Server:.*

clip_image058

我也可以自己定义一个server的首部

vim /etc/haproxy/haproxy.cfg

frontend main

bind :80,:8080

mode http

default_backend websrvs

rspidel ^Server:.*

rspadd Server:\ Feige

clip_image060

在客户端测试

clip_image062

和facl相关的选项

block 在满足条件的时候拒绝

定义某一个地址拒绝

frontend main

bind :80,:8080

mode http

default_backend websrvs

rspidel ^Server:.*

rspadd Server:\ Feige

acl bad_guys src 192.168.63.137 #拒绝ip

block if bad_guys #如果是bad_guys就拒绝

errorfile 403 /etc/haproxy/errorfiles/403.html  #自定义返回一个错误403,访问指定的文件信息

clip_image064

创建指定的目录

mkdir -p /etc/haproxy/errorfiles/

vim /etc/haproxy/errorfiles/403.html

<h1>403 Forbidden</h1>

客户端浏览器测试

http://172.20.127.233/

clip_image066

http-request 进行精确的访问控制,那些人可以访问,那些人不可以访问

frontend main

bind :80,:8080

mode http

default_backend websrvs

rspidel ^Server:.*

rspadd Server:\ Feige

acl mynet src 172.20.0.0/16 #定义一个网段

http-request allow if mynet #只要是mynet就可以访问

clip_image068

tcp-request 在三次握手的时候就拒绝掉

use_backend 当满足条件时使用指定的客户端,否则默认

ACL

path_beg 路径的前缀,以什么开头

path_end 以什么结尾的

path_reg ^/images.*\.jpeg$ 如果以/images开头,后面跟任何内容,以\.jpeg结尾

path_sub image 搜索字串,包含image

path_dir jpegs 子路径匹配包含 jpegs

path_dom ilinux 只要包含ilinux的字串,就符合条件

-i 不区分字符大小写

-m 使用特点的模式 ,一般不用

-n禁止DNS做用,域名解析

-u 要acl必须使用唯一的名称

多个ACL可以用同一个名字,通常用来做或逻辑

如果有多个ACL,当标准不一样

frontend main *:5000

acl url_static path_beg -i /static /images /javascript /stylesheets #只要是这些开头>的都归类为url_static

acl url_static path_end -i .jpg .gif .png .css .js #以这些结尾的都归类为url_static

use_backend static if url_static #只要满足url_static这些条件就调度到static

default_backend app

backend static #只要满足url_static这些条件就调度到static

balance roundrobin

server static 127.0.0.1:4331 check

clip_image070

进行动态和具体的分离调用

vim /etc/haproxy/haproxy.cfg

frontend main

bind :80,:8080

mode http

acl url_img path_beg /images #以/images开头的文件夹,这个文件夹下面放的是图片

acl url_img path_end .jpg .png .jpeg .gif #以这些格式结尾

use_backend imgsrvs if url_img #如果访问的是图片就访问这个服务器

default_backend websrvs

rspidel ^Server:.*

clip_image072

backend imgsrvs #如果访问的是图片就访问这个服务器

balance roundrobin 轮循算法

server imgsrv1 192.168.63.139:80 check 注:check 健康检测

backend websrvs

balance roundrobin

option httpchk GET /test8.html

option forwardfor

server static1 192.168.63.131:80 check inter 1000 rise 1 fall 2 maxconn 2000

server static2 192.168.63.139:80 check maxconn 1500

clip_image074

在后端192.168.63.139服务器查找图片

find /usr/share -iname "*.jpg" -exec cp {} ./ \; 查找图片并拷贝到当前目录

find /usr/share -iname "*.png" -exec cp {} ./ \; 查找图片并拷贝到当前目录

通过首部报文控制

frontend main

bind :80,:8080

mode http

acl bad_agent hdr_sub(User-Agent) -i curl wget # 用hdr_sub做字串匹配,如果对User-Agen去检测的时候 -i不区分大小写 ,发现curl和wget

block if bad_agent #如果匹配就拒绝访问

default_backend websrvs

rspidel ^Server:.*

后端服务器测试

显示无法访问

[root@RS1 ~]# curl http://172.20.127.233/test1.html

<html><body><h1>403 Forbidden</h1>

Request forbidden by administrative rules.

</body></html>

[root@RS1 ~]# wget -O - -q http://172.20.127.233/test1.html

连接超时时长

timeout client 面向客户端的超时时长

timeout server 面向服务端的超时时长,建立连接以后要多少时间断开的时长

timeout http-keep-alive 持久连接的持久时长

timeout http-request http客户端请求报文传完的时长

timeout connect 客户端发起连接请求时的超时时长

timeout client-fin 在客户端设置半关闭连接的非活动超时

timeout server-fin 在服务器端设置半关闭连接的非活动超时