HAProxy反向代理

HAProxy的简单配置实现反向代理服务器的功能:(有自动的健康性检查的功能)

程序环境:
主程序:/usr/sbin/haproxy
主配置文件:/etc/haproxy/haproxy.cfg
Unit file:/usr/lib/systemd/system/haproxy.service

官网文档:

http://cbonte.github.io/haproxy-dconv/

 

实验简单实现haproxy的代理服务:

1 .在代理服务器上:(有内网和外网两块网卡)

yum install haproxy  (安装包)

修改配置文件:(添加的内容)

frontend main *:80
default_backend websers   (websers :默认代理的后端服务器组名,自定义的)

backend websers         (定义后端的代理服务器)
balance roundrobin        (调用调度算法:roundrobin:轮询)
server webser1 192.168.60.20:80   (被代理的后端服务器的IP地址及代理服务的端口号)
server webser2 192.168.60.21:80       (webser2:自定义的名称可以随便写)

QQ截图20180709201320

systemctl start haproxy (重启服务)

ss -nult   (查看监听的端口号应该已经打开了)

2 . 在后端web服务器上:(只有内网网卡)

RS1

yum install httpd    (安装包)

echo RS1 > /var/www/html/index.html   (生成测试的主页面文件)

systemctl start httpd   (启动服务)

RS2
yum install httpd (安装包)
echo RS2 > /var/www/html/index.html (生成测试的主页面文件)
systemctl start httpd (启动服务)

3 . 在客户端访问:curl  172.20.20.2   (此为haproxy的外网的IP地址)

这样就实现了简单的代理服务器的功能,下面为具体的介绍各个配置参数及其功能和用法。

 

global:全局参数配置  

1 .log (日志)

log:定义全局的syslog服务器;最多可以定义两个;

格式:log <address> [len <length>] <facility> [max level [min level]]

在haproxy中启用日志记录功能:

vim /etc/rsyslog.conf   (编辑日志的配置文件;在haproxy代理服务器上操作)

添加下面的内容:

QQ截图20180709210059

QQ截图20180709210609

systemctl restart rsyslog   (重新启动日志服务功能)

ss -nult   (查看514端口是否起来)

tail /var/log/haproxy.log  (再次查看日志已经有记录了)

QQ截图20180709211753

此时客户端的IP和调度到后台的哪一台web服务器也有了。

2 . nbproc <number>:

要启动的haproxy的进程数量;(系统默认的是启用两个进程数)

nbproc 4  (在全局配置里添加)

3 . ulimit-n <number>:(在命令行查看ulimit  -n )

每个haproxy进程可打开的最大文件数;(不建议修改,系统的主控进程会根据访问量的大小来自动调节每个子进程haproxy进程打开的文件数)

4 .性能调整:

maxconn <number>:设定每个haproxy进程所能接受的最大并发连接数

nbproc * maxconn:总体的并发连接数(单个进程连接数*开启的进程数)

maxconnrate <number>:每个进程每秒种所能创建的最大连接数量;
maxsessrate <number>:每个进程每秒所能创建的会话速率。
maxsslconn <number>:  设定每个haproxy进程所能接受的ssl的最大并发连接数;
spread-checks <0..50, in percent>

5 .代理配置段:

– defaults <name>  (默认配置段)
– frontend <name>   ()
– backend <name>   (配置后端的web服务器组)
– listen <name>

bind:(配置监听端口)

frontend main
bind :80,:8080
default_backend websers

backend websers
balance roundrobin
server webser1 192.168.60.20
server webser2 192.168.60.21 weight 3

 

balance:后端服务器组内的服务器调度算法

算法:(在配置文件里不能简写;写在balance后面)

roundrobin    (轮询调度)只要给后台的服务器添加权重就能实现加权轮询的调度。

动态算法:支持权重的运行时调整,支持慢启动;每个后端中最多支持4095个server;

一般短连接无状态的服务下使用:例如http服务

QQ截图20180710105938

static-rr:(静态轮询)
静态算法:不支持权重的运行时调整及慢启动;后端主机数量无上限;

leastconn:
推荐使用在具有较长会话的场景中,例如MySQL、LDAP,SSH等;(除非用户断开连接,自己不会主动断开连接的)

first:
根据服务器在列表中的位置,自上而下进行调度;前面服务器的连接数达到上限,新请求才会分配给下一台服务;(当列表中的第一个web服务器连接满了之后,再去调度到下一个web服务器上)

source:

源地址hash算法;
a .将来自同一个的地址请求发往同一个的后端服务器。(静态)

存在的缺点:当后台服务器有一台宕机了,源地址绑定就会无法访问后台的web服务了。无法实现高可用的效果。

b .还有一致性的哈希算法:同nginx的一致性哈希算法相同。(动态)

具体使用那种算法取决于第二个参数:hash-type

source map-based:除权取余法,哈希数据结构是静态的数组;
source  consistent:一致性哈希,哈希数据结构是一个环。

QQ截图20180710144117

uri  :对来自同一个url的请求就绑定到后台同一个服务器上,不论请求来自哪一个IP地址。(提升缓存命中率,如果有缓存服务器,就需要使用这种算法)

对URI的左半部分做hash计算,并由服务器总权重相除以后派发至某挑出的服务器;

具体使用那种算法取决于第二个参数:hash-type

map-based:除权取余法,哈希数据结构是静态的数组;

consistent:一致性哈希,哈希数据结构是一个环。

QQ截图20180710143604

url_param:对用户请求的uri的<params>部分中的参数的值作hash计算,并由服务器总权重相除以后派发至某挑出的服务器;通常用于追踪用户,以确保来自同一个用户的请求始终发往同一个后台服务器。

(当你登陆淘宝时,当打开多个页面后,会出现一段长的字符和数字,其中就包含用户名,然后就对用户名相对应的那一串字符做哈希值计算)

把同一个用户的请求始终发往后台的某一个固定的服务器上。可以对用户做分类或者在发布新版的站点时,对某些不重要的客户所对应的服务器首先更新做测试服务。

具体使用那种算法取决于第二个参数:hash-type
map-based:除权取余法,哈希数据结构是静态的数组;
consistent:一致性哈希,哈希数据结构是一个环

hdr(<name>):对于每个http请求,此处由<name>指定的http首部将会被取出做hash计算; 并由服务器总权重相除以后派发至某挑出的服务器;没有有效值的会被轮询调度; 例如对浏览器进行区分,将PC端和移动端进行区分,代理到后台指定的服务器上去。

具体使用那种算法取决于第二个参数:hash-type
map-based:除权取余法,哈希数据结构是静态的数组;
consistent:一致性哈希,哈希数据结构是一个环

QQ截图20180710144653

 default_backend <backend>
设定默认的backend,用于frontend中;

用于设定后端的服务器的IP地址的设置。

server <name> <address>[:[port]] [param*]
定义后端主机的各服务器及其选项;后面添加的参数选线:

maxconn <maxconn>:当前server的最大并发连接数;

maxcon 4444
backlog <backlog>:当前server的连接数达到上限后的后援队列长度;

backlog 3333
check:对当前server做健康状态检测 (下面为check可以添加的参数)

addr :检测时使用的IP地址;(当有多个网卡时,可以使用另外一个网卡作为检测端口)
port :针对此端口进行检测;
inter <delay>:连续两次检测之间的时间间隔,默认为2000ms;
rise <count>:连续多少次检测结果为“成功”才标记服务器为可用;默认为2次
fall <count>:连续多少次检测结果为“失败”才标记服务器为不可用;默认为3次

QQ截图20180710153825

QQ截图20180710154004

 

disabled:标记为不可用;做灰度发布时使用。

标记为disabled 服务器就下线了。

backup:设定当前server为备用服务器;

QQ截图20180710153427

cookie <value>:为当前server指定其cookie值,用于实现基于cookie的会话黏性;

redir <prefix>:将发往此server的所有GET和HEAD类的请求重定向至指定的URL;

例如:server webser1 192.168.60.20   redir http://www.baidu.com

QQ截图20180710154806

weight <weight>:权重,默认为1;

 

统计接口启用相关的参数:

stats enable
启用统计页;基于默认的参数启用stats page;

在配置文件里添加

QQ截图20180710161935

在浏览器上输入路径:http://172.20.49.2/haproxy?stats (就可以查看了)

此状态页面包括信息较多,为了防止其他人看到可以采取以下方式来避免:

a .  通过设定特别的端口号:(不使用默认的端口号)

QQ截图20180710164218

在浏览器上输入:http://172.20.49.2:9556/haproxy?stats (就可以查看了)

b . 通过设定用户登陆的密码和账号来限制其他人的查看:

QQ截图20180710165209

在浏览器上输入:http://172.20.49.2:9556/haproxy?stats  然后输入用户名和密码就可以查看了。

c . 通过自定义的uri路径别名来控制其他人的登陆:

QQ截图20180710170008

在浏览器上输入:http://172.20.49.2:9556/admin   就可以查看了。

 

开启状态页面的修改参数的端口:

QQ截图20180710170612

然后打开状态页面:

QQ截图20180710170521

set stats to DRAIN  (排干模式):新的用户请求不在接收,老的用户请求继续等待执行完毕。

health: disable checks  :禁止做健康状态检测

 

实验:将后端服务器的ssh服务通过haproxy代理,互联网通过haproxy来连接ssh服务。

添加配置到主配置文件里:

QQ截图20180710174807

在客户端连接代理服务器,通过代理服务的转发,到后台真实连接的主机上去。

ssh root@172.20.49.2 -p  2222     (IP地址为代理服务器的外网地址,-p后面跟的是代理服务器代理的端口号,在配置文件里定义的)

小结:haproxy支持多种服务的代理转发。

 

haproxy代理服务器后端的web服务器如何查看到客户端访问的具体的IP地址

编辑后端服务器的配置文件:

如后端安装的是httpd服务:

vim /etc/httpd/conf/httpd.conf

QQ截图20180710191643

systemctl restart httpd (重新启动HTTP服务)

客户端再次通过haproxy代理访问后端服务器,就可以在后端服务器的日志信息里看到客户端的IP地址了。

tail /var/log/httpd/access_log

QQ截图20180710191527

 

errorfile <code> <file> (代理服务器定义错误界面的文件选择)

它能够代理的错误界面的代码:

403, 408, 500, 502, 503, and 504.

示例:
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

 

haproxy代理服务器的访问控制列表

block { if | unless } <condition>   (可作用于7层连接)

bolck if  (拒绝的意思)

block unless  (除了的意思)

例如: acl invalid_src src 172.16.200.2    (定义源地址及别称;别称可以自定义的)
block if invalid_src            (如果是定义的源地址)
errorfile 403 /etc/fstab    (则返回403代码,转到 /etc/fstab文件下)

精确的访问控制

http-request { allow | deny } [ { if | unless } <condition> ] (可作用于7层应用)

http-request allow if (如果是定义的源的IP则允许)

http-request allow unless (除了是定义的源的IP都允许)

http-request deny  (拒绝)

http-request deny if  (如果是定义的源的IP地址就拒绝)

http-request deny unless  (除了是定义源的IP都拒绝)

tcp-request connection {accept|reject} [{if | unless} <condition>] (可作用于4层应用)

tcp-request connection accept (允许)

tcp-request connection accept if(如果是定义的源的IP则允许)

tcp-request connection accept unless(除了是定义的源的IP都允许)

tcp-request connection  rejiect  (拒绝)

tcp-request connection rejiect if(如果是定义的源的IP地址就拒绝)

tcp-request connection rejiect unless(除了是定义源的IP都拒绝)

src  IP 源地址可以是地址段

示例:
listen ssh
bind :22022  (代理端口号)
balance  leastconn   (调度算法)
acl invalid_src src 172.16.200.2  (定义cal的源IP地址;及别称名,别成名可以自定义)
tcp-request connection reject if invalid_src  (如果是上面定义的源IP地址就拒绝tcp的请求连接)
mode tcp   (使用的协议类型)
server sshsrv1 172.16.100.6:22 check  (后端服务器)
server sshsrv2 172.16.100.7:22 check backup   (后端服务器)

示例:

frontend main
bind :80,:8080
default_backend websers
acl dddd src 172.20.49.1   (dddd自定义的源的别称名)
block if dddd                    (如果是来自ddddIP地址的访问就给于拒绝并返回错误代码,转向错误界面)
errorfile 403 /data/test.html             (此错误界面为自定义的)

示例:

frontend main
bind :80
default_backend websers
acl mmmm src 172.20.0.0/16    (定义源的别名和IP地址)
http-request allow if mmmm  (如果是mmmm的源的话就都允许)
http-request deny if all       (如果是其他的all所有就都拒绝访问)

 

acl作为条件时的逻辑关系

如果定义了两个acl条件:

acl  hhhsrc 172.20.0.0/16
acl  mmm 1:102   (定义的端口1-102的范围)

if hhh mmm   (或的关系)
if hhh || mmm   (与的关系)
if ! hhh mmm (!是取反,只对第一个条件hhh取反然后再对第二个条件或)

 

通过acl条件实现动静分离:

frontend main    (定义的第一个组并且有限定条件)
bind :80
default_backend hhh
acl url_img path_beg /images
acl url_img path_end .jpg .png .jpeg

frontend main   (定义第二个组)
bind :80
default_backend websers

backend hhh           (引用第一个组)
balance roundrobin
server web1 182.168.60.21:80

backend websers   (引用第二个组)
balance roundrobin
server webser1 192.168.60.20
server webser1 192.168.60.20

在上述案例中定义的第一个组然后指定代理到的服务器上,实现了将静态的图片访问只代理到后端的一台服务器上去。

QQ截图20180710212147

 

上述定义中的path的含义

path_beg :  前缀匹配
path_dir :  字串的匹配
path_dom :  子域名匹配
path_end : 路径的后缀匹配
path_len : 路径的长度匹配
path_reg : 路径的正则表达式匹配
path_sub :  字串的匹配

示例:

path_beg /images/
path_end .jpg .jpeg .png .gif
path_reg ^/images.*\.jpeg$
path_sub image
path_dir jpegs
path_dom ilinux
/images/jpegs/20180312/logo.jpg

 

 

 

 

 

 

本文来自投稿,不代表Linux运维部落立场,如若转载,请注明出处:http://www.178linux.com/102520

发表评论

登录后才能评论

This site uses Akismet to reduce spam. Learn how your comment data is processed.

联系我们

400-080-6560

在线咨询:点击这里给我发消息

邮件:1823388528@qq.com

工作时间:周一至周五,9:30-18:30,节假日同时也值班