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

(0)
无所谓无所谓
上一篇 2018-07-09
下一篇 2018-07-10

相关推荐

  • 软硬链接

    软链接和硬链接的区别

    2018-03-31
  • 马哥网络班第31期——第二周作业

    1、Linux上的文件管理类命令都有哪些,其常用的使用方法及其相关示例演示
    2、bash的工作特性之命令执行状态返回值和命令行展开所涉及的内容及其示例演示
    3、请使用命令行展开功能来完成以下练习
    (1)创建/tmp目录下的:a_c,a_d,b_c,b_d
    (2)创建/tmp/mylinux目录下的:
    4、文件的元数据信息有哪些,分别表示什么含义,如何查看?如何修改文件的时间戳信息
    5、如何定义一个命令的别名,如何在命令中引用另一个命令的执行结果?
    6、显示/var目录下所有以l开头,以一个小写字母结尾,且中间至少出现一位数字(可以有其他字符)的文件或目录
    7、显示/etc目录下,以任意一个数字开头,且以非数字结尾的文件或目录
    8、显示/etc目录下,以非字母开头,后面跟了一个字母以及其他任意长度任意字符的文件或目录
    9、在/tmp目录下创建以tfile开头,后跟当前日期和时间的文件,文件名形如:tfile-2016-05-27-09-32-22
    10、复制/etc目录下所有以p开头,以非数字结尾的文件或目录到/tmp/mytest1目录中
    11、复制/etc目录下所有以.d结尾的文件或目录至/tmp/mytest2目录中
    12、复制/etc目录下所有以l或m或n开头,以.conf结尾的文件至/tmp/mytest3目录中

    Linux笔记 2018-07-18
  • 脚本练习题

    1.使用脚本打印出如下图形 ************答案一:#!/bin/bash#1.接受一个参数为星星的个数。num=$1 #2.求出总共要打印的行数let lines=num*2 #3.for 循环处理每一行的数据for i in `seq $lines`;do#4.前半个星星处理逻辑if [ $i -le $num ];thenfor j in `s…

    Linux笔记 2018-03-26
  • Docker容器二

    容器的虚拟化网络;

    2018-08-01
  • linux系统修复报错的方法 .

    如果/etc/fstab文件和boot目录下的文件丢失怎么办
    centos6启动流程

    2018-05-13