haproxy实现负载均衡详解 之 (高级功能配置)

目录

一、基于cookie的会话保持

1.1语法

[1.2 配置](#1.2 配置)

[二、haproxy 状态页](#二、haproxy 状态页)

[2.1 状态页配置项](#2.1 状态页配置项)

[2.2 配置](#2.2 配置)

三、IP透传

[3.1 七层透传](#3.1 七层透传)

[3.1.1 web1上利用httpd进行IP透传](#3.1.1 web1上利用httpd进行IP透传)

[​3.2 四层透传](#3.2 四层透传)

[3.2.1 在web2上利用nginx进行IP透传](#3.2.1 在web2上利用nginx进行IP透传)

四、ACL---访问控制列表

[4.1 ACL配置选项](#4.1 ACL配置选项)

4.1.1ACL-Name名称

4.1.2ACL-criterion匹配规范:判断条件

[4.1.3 ACL-flags 匹配模式](#4.1.3 ACL-flags 匹配模式)

[4.1.4 ACL-operator 具体操作符](#4.1.4 ACL-operator 具体操作符)

[4.1.5 ACL-value 操作对象](#4.1.5 ACL-value 操作对象)

[4.1.6 多个ACL的组合调用方式](#4.1.6 多个ACL的组合调用方式)

[4.2 示例](#4.2 示例)

[4.2.1 hdr_dom 请求的host名称](#4.2.1 hdr_dom 请求的host名称)

[4.2.2 hdr_beg](#4.2.2 hdr_beg)

[4.2.3 基于IP](#4.2.3 基于IP)

[4.2.4 拒绝访问](#4.2.4 拒绝访问)

[4.2.5 基于浏览器](#4.2.5 基于浏览器)

[4.2.6 基于使用php------后缀名动静分离](#4.2.6 基于使用php------后缀名动静分离)

[4.2.7 访问路径名实现动静分离](#4.2.7 访问路径名实现动静分离)

五、自定义错误页面

在haproxy上面编写定义错误页面

然后在配置文件中添加错误页面配置。

[六、haproxy 四层负载](#六、haproxy 四层负载)

修改数据库id:

修改haproxy配置文件

最后我们要放行用户权限

七、haproxy的https实现

在haproxy上配置证书密钥

修改haproxy配置文件:


前言:本章实验的环境与上一篇一样。如果环境不知道的可以查看上一篇哦。

一、基于cookie的会话保持

cookie value :为当前 server 指定 cookie 值,实现基于 cookie 的会话黏性,相对于基于 source 地址hash 调度算法对客户端的粒度更精准,但同时也加大了 haproxy 负载,目前此模式使用较少, 已经被session 共享服务器代替。
注意:不支持 tcp mode ,使用 http mode

1.1语法

语法:

bash 复制代码
cookie name [ rewrite | insert | prefix ][ indirect ] [ nocache ][ postonly ] [
preserve ][ httponly ] [ secure ][ domain ]* [ maxidle <idle> ][ maxlife ]
name:        #cookie 的 key名称,用于实现持久连接
insert:      #插入新的cookie,默认不插入cookie
indirect:    #如果客户端已经有cookie,则不会再发送cookie信息
nocache:     #当client和hapoxy之间有缓存服务器(如:CDN)时,不允许中间缓存器缓存cookie,
              #因为这会导致很多经过同一个CDN的请求都发送到同一台后端服务器

1.2 配置

在配置文件/etc/haproxy/haproxy.cfg中配置下面的标红地方:

然后我们可以指定cookie值进行访问看是否实现负载均衡。结果如下所示

还可以在浏览器中查看,就可以查看到cookie值。

二、haproxy 状态页

通过web界面,显示当前HAProxy的运行状态。

2.1 状态页配置项

bash 复制代码
stats enable #基于默认的参数启用stats page
stats hide-version #将状态页中haproxy版本隐藏
stats refresh <delay> #设定自动刷新时间间隔,默认不自动刷新
stats uri <prefix> #自定义stats page uri,默认值:/haproxy?stats
stats auth <user>:<passwd> #认证时的账号和密码,可定义多个用户,每行指定一个用户
#默认:no authentication
stats admin { if | unless } <cond> #启用stats page中的管理功能

2.2 配置

在配置文件添加配置页:

bash 复制代码
listen stats
    mode http
    bind *:9999
    stats enable
    stats refresh 3
    stats uri /status
    stats auth lee:lee

测试:

我们设置了刷新之就可以自动刷新。

三、IP透传

3.1 七层透传

web 服务器中需要记录客户端的真实 IP 地址,用于做访问统计、安全防护、行为分析、区域排行等场景。
在全局中通过option forward for 实现IP透传

3.1.1 web1上利用httpd进行IP透传

然后我们利用 在web1上面配置httpd服务查看测试:

bash 复制代码
#先停止nginx
[root@web1 ~]# systemctl disable nginx
[root@web1 ~]# systemctl stop nginx
#下载httpd
[root@web1 ~]# dnf install httpd -y
[root@web1 ~]# echo webserver1 - 172.25.254.10 > /var/www/html/index.html
[root@web1 ~]# systemctl restart httpd

在没有设置前通过curl712.25.254.100测试,再其其日志里默认是看不到IP的。

然后我们通过在httpd的配置文件中日志那一部分添加内容来进行IP透传

再来测试通过curl712.25.254.100完再查看日志:就出现了IP,这个就是httpd的七层IP透传

3.2 四层透传

3.2.1 在web2上利用nginx进行IP透传

修改配置文件:

然后修改nginx配置文件来实现透窗,添加如下标红圈起的地方

再来测试通过curl712.25.254.100完再查看日志:相比之前就出现了IP

四、ACL---访问控制列表

是一种基于包过滤的访问控制技术。
它可以根据设定的条件对经过服务器传输的数据包进行过滤 ( 条件匹配 )即对接收到的报文进行匹配和过滤,基于请求报文头部中的源地址、源端口、目标地址、目标端口、请求方法、 URL、文件后缀等信息内容进行匹配并执行进一步操作,比如允许其通过或丢弃。

4.1 ACL配置选项

bash 复制代码
#用acl来定义或声明一个acl
acl <aclname> <criterion> [flags] [operator] [<value>]
acl 名称 匹配规范 匹配模式 具体操作符 操作对象类型

4.1.1ACL-Name名称

bash 复制代码
acl test path_end -m sub /a
#ACL名称,可以使用大字母A-Z、小写字母a-z、数字0-9、冒号:、点.、中横线和下划线,并且严格区分大小写,比如:my_acl和My_Acl就是两个完全不同的acl5.8.1.2 ACL-criterion

4.1.2ACL-criterion匹配规范:判断条件

bash 复制代码
hdr string,提取在一个HTTP请求报文的首部
hdr([<name> [,<occ>]]):完全匹配字符串,header的指定信息,<occ> 表示在多值中使用的值的出
现次数
hdr_beg([<name> [,<occ>]]):前缀匹配,header中指定匹配内容的begin
hdr_end([<name> [,<occ>]]):后缀匹配,header中指定匹配内容end
hdr_dom([<name> [,<occ>]]):域匹配,header中的dom(host)
hdr_dir([<name> [,<occ>]]):路径匹配,header的uri路径
hdr_len([<name> [,<occ>]]):长度匹配,header的长度匹配
hdr_reg([<name> [,<occ>]]):正则表达式匹配,自定义表达式(regex)模糊匹配
hdr_sub([<name> [,<occ>]]):子串匹配,header中的uri模糊匹配 模糊匹配c 报文中a/b/c也会匹
配
#示例:
hdr(<string>) 用于测试请求头部首部指定内容
hdr_dom(host) 请求的host名称,如 www.timinglee.org
hdr_beg(host) 请求的host开头,如 www. img. video. download. ftp.
hdr_end(host) 请求的host结尾,如 .com .net .cn
#示例:
acl bad_agent hdr_sub(User-Agent) -i curl wget
http-request deny if bad_agent
#有些功能是类似的,比如以下几个都是匹配用户请求报文中host的开头是不是www
acl short_form hdr_beg(host) www.
acl alternate1 hdr_beg(host) -m beg www.
acl alternate2 hdr_dom(host) -m beg www.
acl alternate3 hdr(host) -m beg www.
base : string
#返回第一个主机头和请求的路径部分的连接,该请求从主机名开始,并在问号之前结束,对虚拟主机有用
<scheme>://<user>:<password>@#<host>:<port>/<path>;<params>#?<query>#<frag>
base : exact string match
base_beg : prefix match
base_dir : subdir match
base_dom : domain match
base_end : suffix match
base_len : length match
base_reg : regex match
base_sub : substring match
path : string
#提取请求的URL路径,该路径从第一个斜杠开始,并在问号之前结束(无主机部分)
<scheme>://<user>:<password>@<host>:<port>#/<path>;<params>#?<query>#<frag>
path : exact string match
path_beg : prefix match #请求的URL开头,如/static、/images、/img、/css
path_end : suffix match #请求的URL中资源的结尾,如 .gif .png .css .js .jpg .jpeg
path_dom : domain match
path_dir : subdir match
path_len : length match
path_reg : regex match
path_sub : substring match
#示例:
path_beg -i /haproxy-status/
path_end .jpg .jpeg .png .gif
path_reg ^/images.*\.jpeg$
path_sub image
path_dir jpegs
path_dom timinglee
url : string
#提取请求中的整个URL。
url :exact string match
url_beg : prefix match
url_dir : subdir match
url_dom : domain match
url_end : suffix match
url_len : length match
url_reg : regex match
url_sub : substring match
dst #目标IP
dst_port #目标PORT
src #源IP
src_port #源PORT
#示例:
acl invalid_src src 10.0.0.7 192.168.1.0/24
acl invalid_src src 172.16.0.0/24
acl invalid_port src_port 0:1023
status : integer #返回在响应报文中的状态码
#七层协议
acl valid_method method GET HEAD
http-request deny if ! valid_method

4.1.3 ACL-flags****匹配模式

bash 复制代码
-i 不区分大小写
-m 使用指定的正则表达式匹配方法
-n 不做DNS解析
-u 禁止acl重名,否则多个同名ACL匹配或关系

4.1.4 ACL-operator****具体操作符

bash 复制代码
整数比较:eq、ge、gt、le、lt
字符比较:
- exact match (-m str) :字符串必须完全匹配模式
- substring match (-m sub) :在提取的字符串中查找模式,如果其中任何一个被发现,ACL将匹配
- prefix match (-m beg) :在提取的字符串首部中查找模式,如果其中任何一个被发现,ACL将匹配
- suffix match (-m end) :将模式与提取字符串的尾部进行比较,如果其中任何一个匹配,则ACL进行
匹配
- subdir match (-m dir) :查看提取出来的用斜线分隔("/")的字符串,如其中任一个匹配,则ACL
进行匹配
- domain match (-m dom) :查找提取的用点(".")分隔字符串,如果其中任何一个匹配,则ACL进行
匹配

4.1.5 ACL-value****操作对象

bash 复制代码
The ACL engine can match these types against patterns of the following types :
- Boolean #布尔值
- integer or integer range #整数或整数范围,比如用于匹配端口范围
- IP address / network #IP地址或IP范围, 192.168.0.1 ,192.168.0.1/24
- string--> www.timinglee.org
exact #精确比较
substring #子串
suffix #后缀比较
prefix #前缀比较
subdir #路径, /wp-includes/js/jquery/jquery.js
domain #域名,www.timinglee.org
- regular expression #正则表达式
- hex block #16进制

4.1.6 多个ACL的组合调用方式

bash 复制代码
#多个ACL的逻辑处理
与:隐式(默认)使用
或:使用"or" 或 "||"表示
否定:使用 "!" 表示

#多个ACL调用方式:
#示例:
if valid_src valid_port #与关系,ACL中A和B都要满足为true,默认为与
if invalid_src || invalid_port #或,ACL中A或者B满足一个为true
if ! invalid_src #非,取反,不满足ACL才为true

4.2 示例

4.2.1 hdr_dom 请求的host名称

在配置文件中配置如下,

注意要在windows下面修改本地解析才能访问。

在windows下测试成功:

bash 复制代码
[C:\~]$ curl www.timinglee.org
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    23  100    23    0     0   9837      0 --:--:-- --:--:-- --:--:-- 11500
web2 - 172.25.254.20

[C:\~]$ curl www.timinglee.org
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    23  100    23    0     0   9837      0 --:--:-- --:--:-- --:--:-- 11500
web1 - 172.25.254.10

4.2.2 hdr_beg

在本地解析中添加

访问测试内容以上差不多:

bash 复制代码
[C:\~]$ curl bbs.timinglee.org
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    23  100    23    0     0   9837      0 --:--:-- --:--:-- --:--:-- 11500
web2 - 172.25.254.20

[C:\~]$ curl bbs.timinglee.org
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    23  100    23    0     0   9837      0 --:--:-- --:--:-- --:--:-- 11500
web1 - 172.25.254.10

下面这些原理与上面的相似就不一一讲解了。

4.2.3 基于IP

配置如下:

4.2.4 拒绝访问

4.2.5 基于浏览器

4.2.6 基于使用php------后缀名动静分离

在web1上面下载php,并写配置文件。

重启httpd服务。

其配置文件如下:

4.2.7 访问路径名实现动静分离

先创建文件做测试准备

bash 复制代码
将配置文件复制过来
[root@web1 ~]# mkdir -p /var/www/html/php
[root@web1 ~]# cp /var/www/html/index.php  /var/www/html/php/

#在web2上面
[root@web2 ~]# mkdir /usr/share/nginx/html/static -p
[root@web2 ~]# echo static - 172.25.254.20 > /usr/share/nginx/html/static/index.tml

在浏览器里测试 :

注意以上设置修改完配置文件一定要重启服务。

在终端里面测试

bash 复制代码
[C:\~]$ curl 172.25.254.100/php/
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    17    0    17    0     0   6383      0 --:--:-- --:--:-- --:--:--  8500
php 192.168.0.10

[C:\~]$ curl 172.25.254.100/static/
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    23  100    23    0     0   9837      0 --:--:-- --:--:-- --:--:-- 11500
static - 172.25.254.20

五、自定义错误页面

首先先stop 两台realserver服务器上面的服务,以便测试。

5.1在haproxy上面编写定义错误页面

注意路径,配置文件里面写的也要一样。

bash 复制代码
[root@haproxy ~]# mkdir /etc/haproxy/errorpage -p
[root@haproxy ~]# vim /etc/haproxy/errorpage/503.http
HTTP/1.0 503 Service Unavailable 
Cache-Control: no-cache 
Connection: close 
Content-Type: text/html;charset=UTF-8 
<html><body><h1>什么动物生气最安静</h1>
大猩猩!!
</body></html>

5.2然后在配置文件中添加错误页面配置。


关闭后端的 RS 主机
然后用浏览器去访问 172.25.254.100,就会出现错误页面。
也可以添加错误链接,就是上面的错误配置下一行。链接到百度。

六、haproxy 四层负载

本次主要实验mariadb来进行测试,需要在两台real server 的web服务器上下载mariadb服务。

bash 复制代码
[root@web1 ~]# dnf install mariadb-server -y

[root@web2 ~]# dnf install mariadb-server -y

6.1修改数据库id:

bash 复制代码
[root@web1 ~]# vim /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
server-id=1
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mariadb/mariadb.log
pid-file=/run/mariadb/mariadb.pid


[root@web2 ~]# vim /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
server-id=2
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mariadb/mariadb.log
pid-file=/run/mariadb/mariadb.pid

然后要重启服务:

bash 复制代码
[root@web1 ~]# systemctl restart mariadb

[root@web2 ~]# systemctl restart mariadb

然后我们可以进数据库查看id:

6.2修改haproxy配置文件

6.3最后我们要放行用户权限

web1上面:

web2上面:

然后我们选一个主机来多次测试:查看一下其id是否一样 。

第一次其id为1:

第二次 id就为2 :

以上就说明haproxy的四层MySQL负载均衡实现了。

七、haproxy的https实现

7.1在haproxy上配置证书密钥

bash 复制代码
[root@haproxy ~]# mkdir -p /etc/haproxy/certs
[root@haproxy ~]# openssl req -newkey rsa:2048 -nodes -sha256 -keyout /ekeyout /etc/haproxy/certs/timinglee.org.key -x509 -days 365 -out /etc/haproxy/certs/timinglee.org.crt


[root@haproxy ~]# ls /etc/haproxy/certs
timinglee.org.crt  timinglee.org.key
[root@haproxy ~]# cat /etc/haproxy/certs/timinglee.org.key /etc/haproxy/certs/timinglee.org.crt > /etc/haproxy/certs/timinglee.pem
[root@haproxy ~]# cat /etc/haproxy/certs/timinglee.pem 

7.2修改haproxy配置文件:

注意要重启haproxy服务。

在浏览器里面测试:

在终端里面测试:

以上就是haproxy的全部内容啦

相关推荐
zhd15306915625ff几秒前
化工厂主要涉及的自动化备件有哪些?
运维·自动化·化工厂
Jason-河山几秒前
利用API返回值实现商品信息自动化更新:技术与实践
运维·自动化
wowocpp1 小时前
查看 linux ubuntu 分区 和 挂载 情况 lsblk
linux·运维·ubuntu
wowocpp1 小时前
查看 磁盘文件系统格式 linux ubuntu blkid ext4
linux·数据库·ubuntu
龙鸣丿2 小时前
Linux基础学习笔记
linux·笔记·学习
耶啵奶膘4 小时前
uniapp-是否删除
linux·前端·uni-app
_.Switch4 小时前
高级Python自动化运维:容器安全与网络策略的深度解析
运维·网络·python·安全·自动化·devops
2401_850410834 小时前
文件系统和日志管理
linux·运维·服务器
JokerSZ.4 小时前
【基于LSM的ELF文件安全模块设计】参考
运维·网络·安全
XMYX-05 小时前
使用 SSH 蜜罐提升安全性和记录攻击活动
linux·ssh