33-haproxy

2020-05-21  本文已影响0人  Liang_JC

本章内容

◆ Web架构介绍
◆ 负载均衡介绍
◆ 反向代理介绍
◆ HAProxy介绍
◆ HAProxy结构
◆ HAProxy配置、调度算法及ACL

image.png image.png image.png

什么是负载均衡

为什么使用负载均衡

常见有哪些负载均衡

典型应用场景

HAProxy介绍

HAProxy功能

HAProxy 应用

image.png

HAProxy安装

编译安装HAProxy

1、安装依赖
yum install gcc gcc-c++ glibc glibc-devel pcre pcre-devel openssl openssl-devel systemd-devel net-tools vim iotop bc zip unzip zlib-devel lrzsz tree screen lsof tcpdump wget ntpdate

2、编译安装
tar xvf haproxy-1.8.16.tar.gz && cd haproxy-1.8.16
make ARCH=x86_64 TARGET=linux2628 USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 USE_SYSTEMD=1 USE_CPU_AFFINITY=1 PREFIX=/usr/local/haproxy
make install PREFIX=/usr/local/haproxy
cp haproxy /usr/sbin/

3、创建启动脚本
cat /usr/lib/systemd/system/haproxy.service
[Unit]
Description=HAProxy Load Balancer
After=syslog.target network.target
[Service]
ExecStartPre=/usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -c -q
ExecStart=/usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid
ExecReload=/bin/kill -USR2 $MAINPID
[Install]
WantedBy=multi-user.target

4、创建目录和用户
mkdir /etc/haproxy
useradd haproxy -s /sbin/nologin
mkdir /var/lib/haproxy
chown haproxy.haproxy /var/lib/haproxy/ -R
systemctl restart haproxy
#配置文件
cat /etc/haproxy/haproxy.cfg
global
maxconn 100000      
chroot /usr/local/haproxy
#stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin
uid 99
gid 99
daemon
nbproc 4            
cpu-map 1 0 
cpu-map 2 1
cpu-map 3 2
cpu-map 4 3
pidfile /run/haproxy.pid
log 127.0.0.1 local3 info

defaults
option http-keep-alive
option  forwardfor
maxconn 100000
mode http
timeout connect 300000ms
timeout client  300000ms
timeout server  300000ms

listen stats
 mode http
 bind 0.0.0.0:9999
 stats enable
 log global
 stats uri     /haproxy-status
 stats auth    haadmin:q1w2e3r4ys

listen  web_port
 bind 0.0.0.0:80
 mode http
 log global
 server web1  127.0.0.1:8080  check inter 3000 fall 2 rise 5
 
#haproxy.cfg文件中定义了chroot、 pidfile、 user、 group等参数,如果系统没有相应的资源会导致haproxy无法启动,具体参考日志文件/var/log/messages

5、启动HAProxy
systemctl start haproxy

HAProxy组成

Haproxy 配置-global

HAProxy Proxies配置

• defaults [<name>] #默认配置项,针对以下的frontend、 backend和lsiten生效,可以多个name
• frontend <name> #前端servername,类似于Nginx的一个虚拟主机 server。
• backend <name> #后端服务器组,等于nginx的upstream
• listen <name> #将frontend和backend合并在一起配置
• 注: name字段只能使用”-”、 ”_”、 ”.”、和”:”,并且严格区分大小写,例如: Web和web是完全不同的两组服务器。

Proxies配置- defaults

Proxies配置- frontend配置参数

Proxies配置- backend配置参数

• mode http/tcp #指定负载协议类型
• option #配置选项
• server #定义后端real server
• 注意: option后面加httpchk, smtpchk, mysql-check, pgsql-check, ssl-hello-chk方法,可用于实现更多应用层检测功能。

后端服务器状态监测及相关配置

• check #对指定real进行健康状态检查,默认不开启
• addr IP #可指定的健康状态监测IP
• port num #指定的健康状态监测端口
• inter num #健康状态检查间隔时间,默认2000 ms
• fall num #后端服务器失效检查次数,默认为3
• rise num #后端服务器从下线恢复检查次数,默认为2
• weight #默认为1,最大值为256, 0表示不参与负载均衡
• backup #将后端服务器标记为备用状态
• disabled #将后端服务器标记为不可用状态
• redirect prefix http://www.magedu.com/ #将请求临时重定向至其它URL,只适用于http模式
• maxconn <maxconn>:当前后端server的最大并发连接数
• backlog <backlog>:当server的连接数达到上限后的后援队列长度

frontend/ backend 配置案例

#官网业务访问入口===========================
frontend WEB_PORT_80
 bind 192.168.7.248:80
 mode http
 use_backend web_prot_http_nodes
 
backend web_prot_http_nodes
 mode http
 option forwardfor
 server 192.168.7.101 192.168.7.101:8080 check inter 3000 fall 3 rise 5
 server 192.168.7.102 192.168.7.102:8080 check inter 3000 fall 3 rise 5  

Proxies配置- listen

使用listen替换frontend和backend的配置方式:

#官网业务访问入口===========================
listen WEB_PORT_80
 bind 192.168.7.102:80
 mode http
 option forwardfor
 server web1 192.168.7.101:8080 check inter 3000 fall 3 rise 5
 server web2 192.168.7.101:8080 check inter 3000 fall 3 rise 5

小笔记:配置文件

vim /etc/haproxy/haproxy.cfg
global
maxconn 100000                  #单个进程最大连接数
chroot /usr/local/haproxy       #禁锢目录
#stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin
#uid 99
#gid 99
user haproxy
group haproxy
daemon                          #守护进程方式
#nbthread 2                     #指定每个haproxy进程开启的线程数,默认为每个进程一个线程(1.8以后支持)
nbproc 4                        #核心数, 开启多进程
cpu-map 1 0                     #绑定haproxy 进程至指定CPU
cpu-map 2 1
cpu-map 3 2
cpu-map 4 3
#spread-checks 2                    #后端server状态check随机提前或延迟百分比时间
pidfile /run/haproxy.pid
log 127.0.0.1 local3 info

defaults
option http-keep-alive          #session 会话保持超时时间,范围内会转发到相同的后端服务器
option forwardfor               #客户端源地址
option redispatch               #当server Id对应的服务器挂掉后,强制定向到其他健康的服务器
option abortonclose             #当服务器负载很高的时候,自动结束掉当前队列处理比较久的链接
maxconn 100000
mode http
timeout connect 60s     #转发客户端请求到后端server的最长连接时间(TCP之前)
timeout client  120s        #转发客户端请求到后端服务端的超时超时时长(TCP之后)
timeout server  120s        #与客户端的最长空闲时间

listen stats
 mode http
 bind 0.0.0.0:9999
 stats enable
 log global
 stats uri     /haproxy-status
 stats auth    haadmin:q1w2e3r4ys

listen  web_port
 bind 0.0.0.0:8080
 mode http                  #工作模式,默认http|tcp
 log global
 server web1  127.0.0.1:8080  check inter 3000 fall 2 rise 5
 
#frontend web   #定义一个前端 
# bind 192.168.37.7:80
# use_backend web_host

#backend web_host   #定义一个后端
# server web1 192.168.37.37:80
# server web2 192.168.37.47:80 

listen  web_port
 bind 192.168.37.7:80,172.16.0.7:82
 server web1 192.168.37.37:80
 #server web1 192.168.37.37:80 check inter 3000 fall 3 rise 5   #健康状态监测
 server web2 192.168.37.47:80
 
systemctl restart haproxy

#配置日志路径
vim /etc/rsyslog.conf
local3.* /var/log/haproxy.log
$ModLoad imudp
$UDPServerRun 514
systemctl restart rsyslog haproxy

#rs1
yum install httpd -y
mkdir /var/www/html/app{1,2}
echo "192.168.37.37" > /var/www/html/app1/index.html
echo "app2" > /var/www/html/app2/index.html

HAProxy 静态调度算法

HAProxy 动态调度算法

HAProxy 调度算法-source

HAProxy 调度算法-uri

HAProxy 调度算法-url_param

HAProxy 调度算法-hdr

HAProxy 调度算法- rdp-cookie

• rdp-cookie对远程桌面的负载,使用cookie保持会话
• rdp-cookie(<name>)
示例:

listen RDP
  bind 192.168.7.101:3389
  balance rdp-cookie
  mode tcp
  server rdp0 172.18.139.20:3389 check fall 3 rise 5 inter 2000 weight 1
  server rdp1 172.18.139.21:3389 check fall 3 rise 5 inter 2000 weight 1

• 基于iptables实现目标地址转换:

iptables -t nat -A PREROUTING -d 192.168.7.101 -p tcp --dport 3389 -j DNAT --to-destination 172.18.139.20:3389
iptables -t nat -A POSTROUTING -s 192.168.0.0/21 -j SNAT --to-source 192.168.7.101

算法总结

• roundrobin-------->tcp/http 动态 #四层,配合session共享
• leastconn----------->tcp/http 动态 #四层,用于后端服务器上mysql
• static-rr-------------->tcp/http 静态 #静态轮询, 等于roundrobin
• first-------------------->tcp/http 静态 #很少使用

以下取决于hash_type是否consistent

• source---------------->tcp/http #后端服务器没有做session共享,但是还要实现会话保持
• Uri---------------------->http #缓存场景,CDN缓存服务器
• url_param---------->http #缓存场景
• hdr--------------------->http #基于请求头部指定的信息调度,七层模式
• rdp-cookie--------->tcp #windows远程桌面,很少使用,四层

小笔记:调度

#静态调度
vim /etc/haproxy/haproxy.cfg
listen  webs
 mode http
 balance first          #静态调度
 bind 192.168.37.7:80
 server web1 192.168.37.37:80 maxconn 2 weight 1 check inter 3000 fall 3 rise 5 #访问超过2次调度web2
 server web2 192.168.37.47:80 check weight 1 inter 3000 fall 3 rise 5
 
#动态调度
vim /etc/haproxy/haproxy.cfg
 global
 stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin        #开启动态调度

listen  webs
 mode http
 balance leastconn      #默认roundrobin
 bind 192.168.37.7:80
 server web1 192.168.37.37:80 check weight 1 inter 3000 fall 3 rise 5
 server web2 192.168.37.47:80 check weight 1 inter 3000 fall 3 rise 5
 
mkdir /var/lib/haproxy
yum install socat -y            #修改动态调度命令
echo "show info" | socat stdio /var/lib/haproxy/haproxy.sock
echo "get weight webs/web1" | socat stdio /var/lib/haproxy/haproxy.sock     #查看调度器权重
echo "set weight webs/web1 5" | socat stdio /var/lib/haproxy/haproxy.sock   #设置权重
echo "disable server webs/web1" | socat stdio /var/lib/haproxy/haproxy.sock     #下线服务器,1.8版不好使

#source调度
vim /etc/haproxy/haproxy.cfg
listen  webs
 mode http
 balance source
 hash-type consistent
 bind 192.168.37.7:80
 server web1 192.168.37.37:80 check weight 1 inter 3000 fall 3 rise 5
 server web2 192.168.37.47:80 check weight 1 inter 3000 fall 3 rise 5

#uri调度算法
vim /etc/haproxy/haproxy.cfg
listen  webs
 mode http
 balance uri
 #balance url_param name        #基于参数name做hash
 hash-type consistent
 bind 192.168.37.7:80
 server web1 192.168.37.37:80 check weight 1 inter 3000 fall 3 rise 5
 server web2 192.168.37.47:80 check weight 1 inter 3000 fall 3 rise 5
 
#hdr调度算法
vim /etc/haproxy/haproxy.cfg
listen  webs
 mode http
 balance hdr(User-Agent)        #hdr( Cookie、 User-Agent、 host )
 hash-type consistent
 bind 192.168.37.7:80
 server web1 192.168.37.37:80 check weight 1 inter 3000 fall 3 rise 5
 server web2 192.168.37.47:80 check weight 1 inter 3000 fall 3 rise 5  

四层与七层的区别

四层:
• 在四层负载设备中,把client发送的报文目标地址(原来是负载均衡设备的IP地址),根据均衡设备设置的选择web服务器的规则选择对应的web服务器IP地址,这样client就可以直接跟此服务器建立TCP连接并发送数据。

四层IP透传:

#haproxy 配置:
 listen web_prot_http_nodes
 bind 192.168.7.101:80
 mode tcp
 balance roundrobin
 server web1 blogs.studylinux.net:80 send-proxy check inter 3000 fall 3 rise 5
 
#nginx配置:
 server {
    listen 80 proxy_protocol;
    server_name blogs.studylinux.net;
    ......
 }

七层:

• 七层负载均衡服务器起了一个代理服务器的作用,服务器建立一次TCP连接要三次握手,而client要访问webserver要先与七层负载设备进行三次握手后建立TCP连接,把要访问的报文信息发送给七层负载均衡;然后七层负载均衡再根据设置的均衡规则选择特定的webserver,然后通过三次握手与此台webserver建立TCP连接,然后webserver把需要的数据发送给七层负载均衡设备,负载均衡设备再把数据发送给client;所以,七层负载均衡设备起到了代理服务器的作用。
• tcpdump tcp -i eth0 -nn port ! 22 -w dump-tcp.pcap -v

七层ip透传:

#haproxy 配置:
 defaults
 option forwardfor
#或者:
 option forwardfor header X-Forwarded-xxx #自定义传递IP参数,后端web服务器写X-Forwarded-xxx,如果写option forwardfor则后端服务器web格式为X-Forwarded-For

#listen配置:
 listen web_host
 bind 192.168.7.101:80
 mode http
 log global
 balance random
 server web1 192.168.7.103:80 weight 1 check inter 3000 fall 2 rise 5
 server web2 192.168.7.104:80 weight 1 check inter 3000 fall 2 rise 5

小笔记:四层与七层

#七层
vim /etc/haproxy/haproxy.cfg
listen  webs
 mode http
 #hash-type consistent
 bind 192.168.37.7:80
 option forwardfor
 server web1 blogs.studylinux.net:80 check weight 1 inter 3000 fall 3 rise 5

#四层
vim /etc/haproxy/haproxy.cfg
listen  webs
 mode tcp
 bind 192.168.37.7:80
 server web1  blogs.studylinux.net:80 send-proxy check weight 1 inter 3000 fall 3 rise 5

Cookie 配置

小笔记:Cookie 配置

#记录cookie,把相同的IP往同一台机器调度
vim /etc/haproxy/haproxy.cfg
listen  webs
 mode http
 balance roundrobin
 #hash-type consistent
 bind 192.168.37.7:80
 cookie SERVER-COOKIE insert indirect nocache
 server web1 192.168.37.37:80 cookie web1 check weight 1 inter 3000 fall 3 rise 5
 server web2 192.168.37.47:80 cookie web2 check weight 1 inter 3000 fall 3 rise 5 
 
 #client
 curl --cookie "SERVER-COOKIE=web1" http://192.168.37.7/index.html

配置HAProxy状态页:

• stats enable #基于默认的参数启用stats page
• stats hide-version # 隐藏版本
• stats refresh <delay> # 设定自动刷新时间间隔
• stats uri <prefix> #自定义stats page uri,默认值: /haproxy?stats
• stats realm <realm> #账户认证时的提示信息,示例: stats realm : HAProxy\ Statistics
• stats auth <user>:<passwd> #认证时的账号和密码,可使用多次,默认: no authentication
• stats admin { if | unless } <cond> #启用stats page中的管理功能

listen stats
  bind 192.168.37.7:9009
  stats enable
  #stats hide-version
  stats uri /haproxy-status
  stats realm HAPorxy\ Stats\ Page
  stats auth haadmin:123456
  stats auth admin:123456
  stats refresh 30s
  stats admin if TRUE
  
#client
http://192.168.37.7:9009/haproxy-status
pid = 3698 (process #2, nbproc = 2, nbthread = 2) #pid为当前pid号,process为当前进程号,
nbproc和nbthread为一共多少进程和每个进程多少个线程
uptime = 0d 0h00m08s #启动了多长时间
system limits: memmax = unlimited; ulimit-n = 131124 #系统资源限制:内存/最大打开文件数/
maxsock = 131124; maxconn = 65536; maxpipes = 0 #最大socket连接数/单进程最大连接数/最大管道数
maxpipes
current conns = 1; current pipes = 0/0; conn rate = 1/sec #当前连接数/当前管道数/当前连接速率
Running tasks: 1/9; idle = 100 % #运行的任务/当前空闲率
active UP:#在线服务器
backup UP:#标记为backup的服务器
active UP, going down:#监测未通过正在进入down过程
backup UP, going down:#备份服务器正在进入down过程
active DOWN, going up:#down的服务器正在进入up过程
backup DOWN, going up:#备份服务器正在进入up过程
active or backup DOWN:#在线的服务器或者是backup的服务器已经转换成了down状态
not checked:#标记为不监测的服务器
active or backup DOWN for maintenance (MAINT) #active或者backup服务器人为下线的
active or backup SOFT STOPPED for maintenance #active或者backup被人为软下线(人为将weight改成0)

backend server信息:

session rate(每秒的连接会话信息): Errors(错误统计信息):
cur:每秒的当前会话数量 Req:错误请求量
max:每秒新的最大会话数量 conn:错误链接量
limit:每秒新的会话限制量 Resp:错误响应量
sessions(会话信息): Warnings(警告统计信息):
cur:当前会话量 Retr:重新尝试次数
max:最大会话量 Redis:再次发送次数
limit: 限制会话量
Total:总共会话量 Server(real server信息):
LBTot:选中一台服务器所用的总时间 Status:后端机的状态,包括UP和D
Last:和服务器的持续连接时间 LastChk:持续检查后端服务器的时
Wght:权重
Bytes(流量统计): Act:活动链接数量
In:网络的字节输入总量 Bck:备份的服务器数量
Out:网络的字节输出总量 Chk:心跳检测时间
Dwn:后端服务器连接后都是DOWN的数量
Denied(拒绝统计信息): Dwntme:总的downtime时间
Req:拒绝请求量 Thrtle:server 状态
Resp:拒绝回复量

修改报文首部

HAProxy 日志配置

重启syslog服务并访问haproxy状态页

自定义记录日志

压缩功能

• compression algo #启用http协议中的压缩机制,常用算法有gzip deflate
• compression type #要压缩的类型
示例:

compression algo gzip
compression type compression type text/plain text/html text/css text/xml text/javascript application/javascript  

Web服务器状态监测

小笔记:web监控

vim /etc/haproxy/haproxy.cfg
listen  webs
 mode http
 bind 192.168.37.7:80
 capture request header Host len 256                
 capture request header User-Agent len 512  
 #option httpchk GET /monitor_page/index.html HTTP/1.0      #不推荐,消耗磁盘IO
 option httpchk HEAD /monitor_page/index.html HTTP/1.0      #推荐,减少磁盘IO
 server web1 192.168.37.37:80 check weight 1 inter 3000 fall 3 rise 5
 server web2 192.168.37.47:80 check weight 1 inter 3000 fall 3 rise 5 
 
#rs1、rs2
mkdir /var/www/html/monitor_page
echo ok > /var/www/html/monitor_page/index/html

ACL

• acl:对接收到的报文进行匹配和过滤,基于请求报文头部中的源地址、源端口、目标地址、目标端口、请求方法、 URL、文件后缀等信息内容进行匹配并执行进一步操作。
• acl <aclname> <criterion> [flags] [operator] [<value>]
• acl 名称 条件 条件标记位 具体操作符 操作对象类型
• acl image_service hdr_dom(host) -i img.magedu.com
• ACL名称,可以使用大字母A-Z、小写字母a-z、数字0-9、冒号:、点.、中横线和下划线,并且严格区分大小写,必须Image_site和image_site完全是两个acl。

Criterion-acl

• <criterion> :匹配条件
• dst 目标IP
• dst_port 目标PORT
• src 源IP
• src_port 源PORT

flags

operator

整数比较: eq、 ge、 gt、 le、 lt

Acl定义与调用

小笔记:acl

#acl-域名
vim /etc/haproxy/haproxy.cfg
#listen web
frontend web
  bind :80
  mode http
  log global
  acl pc_web_page hdr_dom(host) -i www.magedu.net
  acl mobile_web_page hdr_dom(host) -i mobile.magedu.net
  use_backend pc_web_host if www_web_page
  use_backend mobile_web_host if mobile_web_page
  default_backend backup_web_host       #以上都没有匹配到的时候使用默认backend
  
backend pc_web_host
  mode http
  server web1 192.168.37.37:80 check weight 1 inter 3000 fall 3 rise 5
  
backend mobile_web_host
  mode http  
  server web2 192.168.37.47:80 check weight 1 inter 3000 fall 3 rise 5
  
backend backup_web_host
  server web1 192.168.37.7:8080 check weight 1 inter 3000 fall 3 rise 5
  
#client
curl www.magedu.net
curl mobile.magedu.net
  
#acl-源地址子网匹配
vim /etc/haproxy/haproxy.cfg
frontend web
  bind :80
  mode http
  log global
  acl ip_range_test src 192.168.37.0/24     #匹配网段
  use_backend web2 if ip_range_test
  #block web2 if ip_range_test          #拒绝访问
  default_backend backup_web_host       #以上都没有匹配到的时候使用默认backend
  
backend web2
  mode http
  server web1 192.168.37.37:80 check weight 1 inter 3000 fall 3 rise 5
  
backend backup_web_host
  server web1 192.168.37.7:8080 check weight 1 inter 3000 fall 3 rise 5
  
#client  
curl 192.168.37.7
curl 172.16.0.7

#acl-匹配浏览器
vim /etc/haproxy/haproxy.cfg
frontend web
  bind :80
  mode http
  log global
  acl pc_web hdr(User-Agent) -m sub -i "chrome"     #匹配谷歌浏览器
  acl ip_range_test src 192.168.37.0/24     #匹配网段
  use_backend web2 if ip_range_test
  use_backend pc_web_host if pc_web
  #redirect prefix http://www.magedu.com if pc_web  #重定向
  default_backend backup_web_host       #以上都没有匹配到的时候使用默认backend

backend pc_web_host
  mode http
  server web1 192.168.37.37:80 check weight 1 inter 3000 fall 3 rise 5

backend web2
  mode http
  server web1 192.168.37.47:80 check weight 1 inter 3000 fall 3 rise 5
  
backend backup_web_host
  server web1 192.168.37.7:8080 check weight 1 inter 3000 fall 3 rise 5

自定义错误页面

• errorfile 500 /usr/local/haproxy/html/500.html #自定义错误页面跳转
• errorfile 502 /usr/local/haproxy/html/502.html
• errorfile 503 /usr/local/haproxy/html/503.html

自定义错误跳转

• errorloc 503 http://192.168.7.103/error_page/503.html

小笔记

#错误页面
mkdir /usr/local/haproxy/html
vim /usr/local/haproxy/html/500.html
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>错误</title>
    </head>
    <body>
        <h1>页面维护中</h1>
        <h2>500</h2>
    </body>
</html>
vim /usr/local/haproxy/html/502.html
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>错误</title>
    </head>
    <body>
        <h1>页面维护中</h1>
        <h2>502</h2>
    </body>
</html>
vim /usr/local/haproxy/html/503.html
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>错误</title>
    </head>
    <body>
        <h1>页面维护中</h1>
        <h2>503</h2>
    </body>
</html>

vim /etc/haproxy/haproxy.cfg
default
errorfile 503 /usr/local/haproxy/html/503.html
#errorloc 503 http://192.168.37.57/error_page/503.html 

基于acl+文件后缀实现动静分离

listen web_port
  bind 192.168.7.102:80
  mode http
  acl php_server path_end -i .php
  use_backend php_server_host if php_server
  acl image_server path_end -i .jpg .png .jpeg .gif
  use_backend image_server_host if image_server
  default_backend default_host
  backend default_host
  mode http
  server web1 192.168.7.101:8080 check inter 2000 fall 3 rise 5
  backend php_server_host
  mode http
  server web1 192.168.7.101:8080 check inter 2000 fall 3 rise 5
  backend image_server_host
  mode http
  server web1 192.168.7.102:8080 check inter 2000 fall 3 rise 5

小笔记:动静分离

#haproxy
vim /etc/haproxy/haproxy.cfg
default
errorfile 503 /usr/local/haproxy/html/503.html

frontend web
  bind :80
  mode http
  log global
  #php
  acl php_server path_end -i .php
  acl image_server path_end -i .jpg .png .jpeg .gif
  use_backend php_server_host if php_server
  use_backend image_server_host if image_server
  
  default_backend backup_web_host       #以上都没有匹配到的时候使用默认backend

backend php_server_host
  mode http
  server web1 192.168.37.37:80 check weight 1 inter 3000 fall 3 rise 5

backend image_server_host
  mode http
  server web1 192.168.37.47:80 check weight 1 inter 3000 fall 3 rise 5
  
backend backup_web_host
  server web1 192.168.37.7:8080 check weight 1 inter 3000 fall 3 rise 5

#rs1
yum install nginx php-fpm
vim /etc/nginx/nginx.conf
http {
    location ~ \.php$ {
        root    html;
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name
        include fastcgi_params;
    }
}
vim /usr/share/nginx/html/info.php
<?php
    phpinfo();
?>
systemctl start nginx php-fpm

#rs2
cp 1.jpg /var/www/html

curl www.magedu.net/info.php
curl www.magedu.net/1.jpg

acl-匹配访问路径

listen web_port
  bind 192.168.7.102:80
  mode http
  acl static_path path_beg -i /static /images /javascript
  use_backend static_path_host if static_path

default_backend default_host
  backend default_host
  mode http
  server web1 192.168.7.101:8080 check inter 2000 fall 3 rise 5
backend static_path_host
  mode http
  server web1 192.168.7.101:8080 check inter 2000 fall 3 rise 5  

http 基于策略的访问控制

listen web_port
  bind 192.168.7.102:80
  mode http
  acl badguy_deny src 192.168.4.1
  http-request deny if badguy_deny
  http-request allow
  
default_backend default_host
  backend default_host
  mode http
  server web1 192.168.7.102:8080 check inter 2000 fall 3 rise 5
backend static_path_host
  mode http
  server web1 192.168.7.101:8080 check inter 2000 fall 3 rise 5
backend image_server_host
  mode http
  server web1 192.168.7.102:8080 check inter 2000 fall 3 rise 5

预定义acl

• ACL name Equivalent to Usage
• FALSE always_false never match
• HTTP req_proto_http match if protocol is valid HTTP
• HTTP_1.0 req_ver 1.0 match HTTP version 1.0
• HTTP_1.1 req_ver 1.1 match HTTP version 1.1
• HTTP_CONTENT hdr_val(content-length) gt 0 match an existing content-length
• HTTP_URL_ABS url_reg ^[^/:]*:// match absolute URL with scheme
• HTTP_URL_SLASH url_beg / match URL beginning with "/"
• HTTP_URL_STAR url * match URL equal to "*"
• LOCALHOST src 127.0.0.1/8 match connection from local host
• METH_CONNECT method CONNECT match HTTP CONNECT method
• METH_DELETE method DELETE match HTTP DELETE method
• METH_GET method GET HEAD match HTTP GET or HEAD method
• METH_HEAD method HEAD match HTTP HEAD method
• METH_OPTIONS method OPTIONS match HTTP OPTIONS method
• METH_POST method POST match HTTP POST method
• METH_PUT method PUT match HTTP PUT method
• METH_TRACE method TRACE match HTTP TRACE method
• RDP_COOKIE req_rdp_cookie_cnt gt 0 match presence of an RDP cookie
• REQ_CONTENT req_len gt 0 match data in the request buffer
• TRUE always_true always match
• WAIT_END wait_end wait for end of content analysis

预定义acl使用

listen web_port
  bind 192.168.7.102:80
  mode http
  acl static_path path_beg -i /static /images /javascript
  use_backend static_path_host if HTTP_1.1 TRUE static_path
  default_backend default_host
  backend default_host
  mode http
  server web1 192.168.7.102:8080 check inter 2000 fall 3 rise 5
  backend static_path_host
  mode http
  server web1 192.168.7.101:8080 check inter 2000 fall 3 rise 5

四层负载

Memcache
Redis
MySQL
RabbitMQ
……

listen redis-port
  bind 192.168.7.102:6379
  mode tcp
  balance leastconn
  server server1 192.168.7.104:6379 check
  server server1 192.168.7.103:6379 check backup

四层访问控制

tcp-request connection {accept|reject} [{if | unless} <condition>] 根据第4层
条件对传入连接执行操作

listen redis-port
  bind 192.168.7.102:6379
  mode tcp
  balance leastconn
  acl invalid_src src 192.168.1.0/24 192.168.7.101
  tcp-request connection reject if invalid_src
  server server1 192.168.7.104:6379 check
  server server1 192.168.7.103:6379 check backup

小笔记:四层

#haproxy
vim /etc/haproxy/haproxy.cfg
listen mysql_port
  mode http
  bind 192.168.37.7:80
  server web1 192.168.37.37:80 check weight 1 inter 3000 fall 3 rise 5

listen mysql_port
  mode tcp
  bind 192.168.37.7:3306
  server web1 192.168.37.37:3306 check weight 1 inter 3000 fall 3 rise 5
  
#rs1
yum install mariadb-server -y
systemctl start mariadb
mysql -e "grant all privileges on *.* to user1@'192.168.37.%' identified by 'centos';flush privileges"

HAProxy-https协议

配置HAProxy支持https协议:
• 支持ssl会话;
bind *:443 ssl crt /PATH/TO/SOME_PEM_FILE
crt 后证书文件为PEM格式,且同时包含证书和所有私钥
cat demo.crt demo.key > demo.pem
• 把80端口的请求重向定443
bind *:80
redirect scheme https if !{ ssl_fc }
• 向后端传递用户请求的协议和端口(frontend或backend)
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwared-Proto https if { ssl_fc }

https-证书制作

mkdir /usr/local/haproxy/certs
cd /usr/local/haproxy/cert
openssl genrsa -out haproxy.key 2048
openssl req -new -x509 -key haproxy.key -out haproxy.crt -subj "/CN=www.magedu.net"
cat haproxy.key haproxy.crt > haproxy.pem
openssl x509 -in haproxy.pem -noout -text #查看证书

https 示例

#web server http
frontend web_server-http
  bind 172.18.200.101:80
  redirect scheme https if !{ ssl_fc }
  mode http
  use_backend web_host
  
#web server https
frontend web_server-https
  bind 172.18.200.101:443 ssl crt /usr/local/haproxy/certs/haproxy.pem
  mode http
  use_backend web_host
  
backend default_host
  mode http
  server web1 192.168.7.101:8080 check inter 2000 fall 3 rise 5
  server web2 192.168.7.102:8080 check inter 2000 fall 3 rise 5

backend web_host
  mode http
  http-request set-header X-Forwarded-Port %[dst_port]
  http-request add-header X-Forwarded-Proto https if { ssl_fc }
  server web1 192.168.7.101:8080 check inter 2000 fall 3 rise 5
  server web2 192.168.7.102:8080 check inter 2000 fall 3 rise 5  

小笔记:https

#创建证书
mkdir /usr/local/haproxy/certs
cd /usr/local/haproxy/cert
openssl genrsa -out haproxy.key 2048
openssl req -new -x509 -key haproxy.key -out haproxy.crt -subj "/CN=www.magedu.net"
cat haproxy.key haproxy.crt > haproxy.pem
openssl x509 -in haproxy.pem -noout -text #查看证书

#配置haproxy
vim /etc/haproxy/haproxy.cfg
listen web_80
  bind 192.168.37.7:80
  mode http
  redirect scheme https if !{ ssl_fc }
  server web1 192.168.37.37:80 check inter 2000 fall 3 rise 5

listen web_443
  bind 192.168.37.7:443 ssl crt /usr/local/haproxy/certs/haproxy.pem
  mode http
  http-request set-header X-Forwarded-Port %[dst_port]
  http-request add-header X-Forwared-Proto https if { ssl_fc }  
  server web1 192.168.37.37:80 check inter 2000 fall 3 rise 5
  server web2 192.168.37.47:80 check inter 2000 fall 3 rise 5

小笔记:自定义配置文件路径

vim /usr/lib/systemd/system/haproxy.service
[Service]
ExecstartPre=/usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -f /etc/haproxy/conf -c -q
Execstart=/usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -f /etc/haproxy/conf -p /run/haproxy.pid

systemctl daemon-reload

HAProxy-服务器动态上下线

yum install socat
echo "show info" | socat stdio /var/lib/haproxy/haproxy.sock
echo "get weight web_host/192.168.7.101" | socat stdio /var/lib/haproxy/haproxy.sock
echo "disable server web_host/192.168.7.101" | socat stdio /var/lib/haproxy/haproxy.sock
echo "enable server web_host/192.168.7.101" | socat stdio /var/lib/haproxy/haproxy.sock

小笔记:多线程动态上下线

#多线程
vim /etc/haproxy/haproxy.cfg
global
stats socket /var/lib/haproxy/haproxy.sock1 mode 600 level admin process 1
stats socket /var/lib/haproxy/haproxy.sock2 mode 600 level admin process 2
nbproc 2                        
cpu-map 1 0                     
cpu-map 2 1

systemctl restart haproxy

echo "disable server web_host/192.168.7.101" | socat stdio /var/lib/haproxy/haproxy.sock1
echo "disable server web_host/192.168.7.101" | socat stdio /var/lib/haproxy/haproxy.sock2
echo "enable server web_host/192.168.7.101" | socat stdio /var/lib/haproxy/haproxy.sock1
echo "enable server web_host/192.168.7.101" | socat stdio /var/lib/haproxy/haproxy.sock2

KeepAlived与IPVS

虚拟服务器配置参数:
virtual server (虚拟服务)的定义:
virtual_server IP port #定义虚拟主机IP地址及其端口
virtual_server fwmark int #ipvs的防火墙打标,实现基于防火墙的负载均衡集群
virtual_server group string #将多个虚拟服务器定义成组,将组定义成虚拟服务

virtual_server IP port
{
    ...
    real_server {
        ...
    } 
    ...
}  

delay_loop <INT>:检查后端服务器的时间间隔
lb_algo rr|wrr|lc|wlc|lblc|sh|dh:定义调度方法
lb_kind NAT|DR|TUN:集群的类型
persistence_timeout <INT>:持久连接时长
protocol TCP|UDP|SCTP:指定服务协议
sorry_server <IPADDR> <PORT>:所有RS故障时,备用服务器地址

real_server <IPADDR> <PORT>
{
  weight <INT> RS权重
  notify_up <STRING>|<QUOTED-STRING> RS上线通知脚本
  notify_down <STRING>|<QUOTED-STRING> RS下线通知脚本
  HTTP_GET|SSL_GET|TCP_CHECK|SMTP_CHECK|MISC_CHEC K { ... }:定义当前主机的健康状态检测方法
}

应用层监测

TCP监测

Keepalived案例一:实现LVS-DR模式

virtual_server 172.18.200.248 80 {
    delay_loop 3        #监听间隔
    lb_algo wrr         #定义调度
    lb_kind DR          #定义集群
    #persistence_timeout 120 #会话保持时间
    protocol TCP
    sorry_server 192.168.37.101 80
    real_server 192.168.37.103 80 {
        weight 1
        TCP_CHECK {
            connect_timeout 5       #连接请求的超时时长
            nb_get_retry 3          #重试次数
            delay_before_retry 3    #重试之前的延迟时长
            connect_port 80
        } 
    }
    real_server 172.18.200.104 80 {
        weight 1
            TCP_CHECK {
            connect_timeout 5
            nb_get_retry 3
            delay_before_retry 3
            connect_port 80
        } 
    } 
}

while true;do curl http://192.168.7.248 && sleep 1;done

real_server http监测

real_server 192.168.7.103 80 {
    weight 1
    HTTP_GET {
        url {
            path /index.html
            status_code 200
        }
    }
    connect_timeout 5
    nb_get_retry 3
    delay_before_retry 3
}

VRRP script

• keepalived调用外部的辅助脚本进行资源监控,并根据监控的结果状态能实现优先动态调整
• vrrp_script:自定义资源监控脚本, vrrp实例根据脚本返回值进行下一步操作,脚本可被多个实例调用。
track_script:调用vrrp_script定义的脚本去监控资源,定义在实例之内,调用事先定义的vrrp_script
• 分两步: (1) 先定义一个脚本; (2) 调用此脚本

vrrp_script <SCRIPT_NAME> {
    script <STRING>|<QUOTED-STRING>
    OPTIONS
}
track_script {
    SCRIPT_NAME_1
    SCRIPT_NAME_2
}

vrrp_script <SCRIPT_NAME> { #定义一个检测脚本,在global_defs 之外配置
    script <STRING>|<QUOTED-STRING> # shell命令或脚本路径
    interval <INTEGER> # 间隔时间,单位为秒,默认1秒
    timeout <INTEGER> # 超时时间
    weight <INTEGER:-254..254> # 权重,监测失败后会执行权重+操作
    fall <INTEGER> #脚本几次失败转换为失败
    rise <INTEGER> # 脚本连续监测成果后,把服务器从失败标记为成功的次数
    user USERNAME [GROUPNAME] # 执行监测的用户或组
    init_fail # 设置默认标记为失败状态,监测成功之后再转换为成功状态
}

vrrp_script chk_down { #基于第三方仲裁设备
    script "/bin/bash -c '[[ -f /etc/keepalived/down ]]' && exit 7 || exit 0"
    interval 1
    weight -80
    fall 3
    rise 5
    timeout 2
}
vrrp_instance VI_1 {
    …
    track_script {
        chk_down
    }
}   

高可用HAProxy

vrrp_script chk_haproxy {
    script "/etc/keepalived/chk_haproxy.sh"
    interval 1
    weight -80
    fall 3
    rise 5
    timeout 2
}
track_script {
    chk_haproxy
}
[root@s1 ~]# yum install psmisc -y
[root@s1 ~]# cat /etc/keepalived/chk_haproxy.sh
#!/bin/bash
/usr/bin/killall -0 haproxy
[root@s1 ~]# chmod a+x /etc/keepalived/chk_haproxy.sh

高可用Nginx

vrrp_script chk_nginx {
    script "/etc/keepalived/chk_nginx.sh"
    interval 1
    weight -80
    fall 3
    rise 5
    timeout 2
}
track_script {
    chk_haproxy
}
[root@s1 ~]# yum install psmisc -y
[root@s1 ~]# cat /etc/keepalived/chk_nginx.sh
#!/bin/bash
/usr/bin/killall -0 nginx
[root@s1 ~]# chmod a+x /etc/keepalived/chk_nginx.sh

小笔记:keepalived+haproxy

vim /etc/mail.rc
set from=184116857@qq.com
set smtp=smtp.qq.com
set smtp-auth-user=184116857@qq.com
set smtp-auth-password=mfcjxxjezawgdgee
set smtp-auth=login
set ssl-verify=ignore

cat /etc/keepalived/notify.sh
#!/bin/bash
contact='184116857@qq.com'
notify() {
mailsubject="$(hostname) to be $1, vip 转移"
mailbody="$(date +'%F %T'): vrrp transition, $(hostname) changed to be $1"
echo "$mailbody" | mail -s "$mailsubject" $contact
}
case $1 in
    master)
        notify master
    ;;
    backup)
        notify backup
    ;;
    fault)
        notify fault
    ;;
    *)
        echo "Usage: $(basename $0) {master|backup|fault}"
        exit 1
    ;;
esac

#ha1
yum install keepalived psmisc
vim /etc/keepalived/keepalived.conf
global_defs {
    notification_email {
        root@localhost                  #发给本机root邮件
    }
    notification_email_from keepalived@localhost    #以什么身份发邮件
    smtp_server 127.0.0.1               #发邮件的地址
    smtp_connect_timeout 30
    router_id ha1                       #主机名
    #vrrp_strict #严格遵守VRRP协议,不允许状况:1,没有VIP地址,2.单播邻居,3.在VRRP版本2中有IPv6地址.
    vrrp_garp_interval 0 #ARP报文发送延迟
    vrrp_gna_interval 0 #消息发送延迟
    #vrrp_mcast_group4 224.0.0.18 #默认组播IP地址, 224.0.0.0到239.255.255.255
    #vrrp_iptables
}
vrrp_script chk_haproxy {
    script "/etc/keepalived/chk_haproxy.sh"
    interval 1
    weight -80
    fall 3          #脚本几次失败转换为失败
    rise 5          #脚本连续监测成果后,把服务器从失败标记为成功的次数
    timeout 2
}
vrrp_script chk_down {
    script "/bin/bash -c '[[ -f /etc/keepalived/down ]]' && exit 7 || exit 0"
    interval 1
    weight -80
    fall 3
    rise 5
    timeout 2
}
vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 81
    priority 100
    advert_int 1
    autherntication {
        auth_type PASS
        auth_pass 123456
    }
    virtual_ipaddress {
        192.168.37.100 dev eth0 label eth0:1
    }
    track_script {
        chk_haproxy
        chk_down
    }
    track_interface {
        eth0   
    }
    notify_master "/etc/keepalived/notify.sh master"
    notify_backup "/etc/keepalived/notify.sh backup"
    notify_fault "/etc/keepalived/notify.sh fault
}
cat /etc/keepalived/chk_haproxy.sh
#!/bin/bash
/usr/bin/killall -0 haproxy
chmod +x /etc/keepalived/chk_haproxy.sh
vim /etc/sysctl.conf
net.ipv4.ip_nonlocal_bind = 1   #是否允许服务绑定一个本机不存在的IP地址
net.ipv4.ip_forward = 1
sysctl -p

#ha2
yum install keepalived psmisc
vim /etc/keepalived/keepalived.conf
global_defs {
    notification_email {
        root@localhost                  #发给本机root邮件
    }
    notification_email_from keepalived@localhost    #以什么身份发邮件
    smtp_server 127.0.0.1               #发邮件的地址
    smtp_connect_timeout 30
    router_id ha2                       #主机名
    #vrrp_mcast_group4 224.100.100.100      #D类地址,多播
}
vrrp_script chk_haproxy {
    script "/etc/keepalived/chk_haproxy.sh"
    interval 1
    weight -80
    fall 3
    rise 5
    timeout 2
}
vrrp_script chk_down {
    script "/bin/bash -c '[[ -f /etc/keepalived/down ]]' && exit 7 || exit 0"
    interval 1
    weight -80
    fall 3
    rise 5
    timeout 2
}
vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 81
    priority 80
    advert_int 1
    autherntication {
        auth_type PASS
        auth_pass 123456
    }
    virtual_ipaddress {
        192.168.37.100 dev eth0 label eth0:1
    }
    track_script {
        chk_haproxy
        chk_down
    }
    track_interface {
        eth0   
    }   
    notify_master "/etc/keepalived/notify.sh master"
    notify_backup "/etc/keepalived/notify.sh backup"
    notify_fault "/etc/keepalived/notify.sh fault
}
cat /etc/keepalived/chk_haproxy.sh
#!/bin/bash
/usr/bin/killall -0 haproxy
chmod +x /etc/keepalived/chk_haproxy.sh
vim /etc/sysctl.conf
net.ipv4.ip_nonlocal_bind = 1   #是否允许服务绑定一个本机不存在的IP地址
net.ipv4.ip_forward = 1
sysctl -p
上一篇下一篇

猜你喜欢

热点阅读