目录
[1.2 配置](#1.2 配置)
[二、haproxy 状态页](#二、haproxy 状态页)
[2.1 状态页配置项](#2.1 状态页配置项)
[2.2 配置](#2.2 配置)
[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透传)
[4.1 ACL配置选项](#4.1 ACL配置选项)
[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 四层负载)
前言:本章实验的环境与上一篇一样。如果环境不知道的可以查看上一篇哦。
一、基于cookie的会话保持
cookie value :为当前 server 指定 cookie 值,实现基于 cookie 的会话黏性,相对于基于 source 地址hash 调度算法对客户端的粒度更精准,但同时也加大了 haproxy 负载,目前此模式使用较少, 已经被session 共享服务器代替。
注意:不支持 tcp mode ,使用 http mode
1.1语法
语法:
bashcookie 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的全部内容啦