美文网首页
33-haproxy

33-haproxy

作者: Liang_JC | 来源:发表于2020-05-21 15:16 被阅读0次

    本章内容

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

    image.png image.png image.png

    什么是负载均衡

    • 负载均衡(Load Balance,简称LB)是一种服务或基于硬件设备等实现的高可用反向代理
      技术,负载均衡将特定的业务(web服务、网络流量等)分担给指定的一个或多个后端特
      定的服务器或设备,从而提高了公司业务的并发处理能力、保证了业务的高可用性、方
      便了业务后期的水平动态扩展。
    • https://yq.aliyun.com/articles/1803 #阿里云SLB介绍

    为什么使用负载均衡

    • Web服务器的动态水平扩展
      对用户无感知
    • 增加业务并发访问及处理能力
      解决单服务器瓶颈问题,单机故障
    • 节约公网IP地址
      降低IT支出成本
    • 隐藏内部服务器IP
      提高内部服务器安全性
    • 配置简单
      固定格式的配置文件
    • 功能丰富
      支持四层和七层,支持动态下线主机
    • 性能较强
      并发数万甚至数十万

    常见有哪些负载均衡

    • 软件负载:
      • 四层:
        LVS(Linux Virtual Server)
        HAProxy(High Availability Proxy)
        Nginx()
        ……
      • 七层:
        HAProxy
        Nginx
        ……
    • 硬件负载:
      F5
      Netscaler
      ……

    典型应用场景

    • 应用场景:
      • 四层: Redis、 Mysql、 RabbitMQ、 Memcache等
      • 七层: Nginx、 Tomcat、 Apache、 PHP 、图片、动静分离、 API等

    HAProxy介绍

    • HAProxy: 是法国开发者Willy Tarreau开发的一个开源软件,是一款具备高并发、高性能的
      TCP和HTTP负载均衡器, 支持基于cookie的持久性, 自动故障切换,支持正则表达式及
      web状态统计。
    • LB Cluster:
      四层: lvs, nginx(stream模式且nginx1.9.0或更新版本), haproxy(mode tcp)
      七层: http: nginx(http), haproxy(mode http), httpd...
    • 官网:
      http://www.haproxy.org
      https://www.haproxy.com
    • 文档: https://cbonte.github.io/haproxy-dconv/

    HAProxy功能

    • HAProxy是TCP / HTTP反向代理服务器,尤其适合于高可用性高并发环境
      • 可以针对HTTP请求添加cookie,进行路由后端服务器
      • 可平衡负载至后端服务器,并支持持久连接
      • 支持基于cookie进行调度
      • 支持所有主服务器故障切换至备用服务器
      • 支持专用端口实现监控服务
      • 支持不影响现有连接情况下停止接受新连接请求
      • 可以在双向添加,修改或删除HTTP报文首部
      • 支持基于pattern实现连接请求的访问控制
      • 通过特定的URI为授权用户提供详细的状态信息
    • 历史版本更新功能: 1.4 1.5 1.6 1.7 1.8 1.9 2.0-dev
      • 1.8:多线程, HTTP/2缓存……
      • 1.7:服务器动态配置,多类型证书……
      • 1.6: DNS解析支持, HTTP连接多路复用……
      • 1.5:开始支持SSL, IPV6, keepalived……

    HAProxy 应用

    image.png

    HAProxy安装

    • Centos通过yum方式安装:
      yum install 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组成

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

    • 配置段:
      • global:全局配置段
      进程及安全配置相关的参数
      性能调整相关参数
      Debug参数
      • proxies:代理配置段
      defaults:为frontend, backend, listen提供默认配置
      frontend:前端,相当于nginx中的server {}
      backend:后端,相当于nginx中的upstream {}
      listen:同时拥有前端和后端配置

    Haproxy 配置-global

    • global配置参数:

    • https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#3
      • chroot #锁定运行目录
      • deamon #以守护进程运行
      • #stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin #socket文件
      • user, group, uid, gid #运行haproxy的用户身份
      • nbproc #开启的haproxy进程数,与CPU保持一致
      • nbthread #指定每个haproxy进程开启的线程数,默认为每个进程一个线程
      • cpu-map 1 0 #绑定haproxy 进程至指定CPU
      • maxconn #每个haproxy进程的最大并发连接数
      • maxsslconn #SSL每个haproxy进程ssl最大连接数
      • maxconnrate #每个进程每秒最大连接数
      • spread-checks #后端server状态check随机提前或延迟百分比时间,建议2-5(20%-50%)之间
      • pidfile #指定pid文件路径
      • log 127.0.0.1 local3 info #定义全局的syslog服务器;最多可以定义两个

    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

    • defaults 配置参数:
      • option redispatch #当server Id对应的服务器挂掉后,强制定向到其他健康的服务器
      • option abortonclose #当服务器负载很高的时候,自动结束掉当前队列处理比较久的链接
      • option http-keep-alive 60#开启会话保持
      • option forwardfor #开启IP透传
      • mode http #默认工作类型
      • timeout connect 120s #转发客户端请求到后端server的最长连接时间(TCP之前)
      • timeout server 600s #转发客户端请求到后端服务端的超时超时时长(TCP之后)
      • timeout client 600s #与客户端的最长空闲时间
      • timeout http-keep-alive 120s #session 会话保持超时时间,范围内会转发到相同的后端服务器
      • #timeout check 5s #对后端服务器的检测超时时间

    Proxies配置- frontend配置参数

    • bind:指定HAProxy的监听地址,可以是IPV4或IPV6,可以同时监听多个IP或端口,可同时用于listen字段中
      • bind [<address>]:<port_range> [, ...] [param*]
      • mode http/tcp #指定负载协议类型
      • use_backend backend_name #调用的后端服务器组名称
      示例:

      frontend WEB_PORT
       bind :80,:8080
       bind 192.168.7.102:10080,192.168.7.102:10043
       use_backend backend_name
      

    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 静态调度算法

    • balance: 指明对后端服务器的调度算法,配置在listen或backend
    • 静态算法:按照事先定义好的规则轮询公平调度,不关心后端服务器的当前负载、链接数和相应速度等,且无法实时修改权重,只能重启后生效。
      • static-rr:基于权重的轮询调度,不支持权重的运行时调整及后端服务器慢启动,其后端主机数量没有限制
      • first:根据服务器在列表中的位置,自上而下进行调度,但是其只会当第一台服务器的连接数达到上限,新请求才会分配给下一台服务,因此会忽略服务器的权重设置。

    HAProxy 动态调度算法

    • 动态算法:基于后端服务器 状态进行调度适当调整,比如优先调度至当前负载较低的服务器,且权重可以在haproxy运行时动态调整无需重启。
      • roundrobin(默认):基于权重的轮询动态调度算法,支持权重的运行时调整,不等于lvs 的rr,支持慢启动即新加的服务器会逐渐增加转发数,每个后端backend中最多支持4095个server,此为默认调度算法, server 权重设置 weight
      • leastconn: 加权的最少连接的动态,支持权重的运行时调整和慢启动,即当前后端服务器连接最少的优先调度,比较适合长连接的场景使用,比如MySQL等场景。

    HAProxy 调度算法-source

    • source:源地址hash,基于用户源地址hash并将请求转发到后端服务器,默认为静态即取模方式,但是可以通过hash-type支持的选项更改,后续同一个源地址请求将被转发至同一个后端web服务器,比较适用于session保持/缓存业务等场景。
      • consistent:一致性哈希,该hash是动态的,支持在线调整权重,支持慢启动,优点在于当服务器的总权重发生变化时,对调度结果影响是局部的,不会引起大的变动。

      listen web_prot_http_nodes
        bind 192.168.7.101:80
        mode http
        balance source
        hash-type consistent
        log global
        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
      

      • map-based:取模法,基于服务器权重的hash数组取模,该hash是静态的即不支持在线调整权重,不支持慢启动,其对后端服务器调度均衡,缺点是当服务器的总权重发生变化时,即有服务器上线或下线,都会因权重发生变化而导致调度结果整体改变, hash(o) mod n 。

    HAProxy 调度算法-uri

    • uri:基于对用户请求的uri做hash并将请求转发到后端指定服务器

      • map-based:取模法

      • consistent:一致性哈希
        http://example.org/absolute/URI/with/absolute/path/to/resource.txt #URI/URL
        ftp://example.org/resource.txt #URI/URL
        • /relative/URI/with/absolute/path/to/resource.txt #URI

      • uri: uniform resource identifier,统一资源标识符,是一个用于标识某一互联网资源名称的字符串

        uri调度算法示例:

        listen web_prot_http_nodes
          bind 192.168.7.101:80
          mode http #不支持tcp,会切换到tcp的roundrobin负载模式
          balance uri
          hash-type consistent
          log global
          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
          
        [root@s2 ~]# curl http://192.168.7.101/index.html
        <h1>192.168.7.101</h1>
        [root@s2 ~]# curl http://192.168.7.101/index.html
        <h1>192.168.7.101</h1>
        [root@s2 ~]# curl http://192.168.7.101/test.html
        <h1>192.168.7.101-test</h1>
        [root@s2 ~]# curl http://192.168.7.101/test.html
        <h1>192.168.7.101-test</h1>  
        

    HAProxy 调度算法-url_param

    • url_param:
      对用户请求的url中的<params>部分中的参数name作hash计算,并由服务器总权重相除以后派发至某挑出的服务器;通常用于追踪用户,以确保来自同一个用户的请求始终发往同一个Backend Server
      假设url = http://www.magedu.com/foo/bar/index.php?k1=v1&k2=v2
      则:
      host = "www.magedu.com"
      url_param = "k1=v1&k2=v2"

      示例:

      listen web_prot_http_nodes
        bind 192.168.7.101:80
        mode http #不支持tcp,会切换到tcp的roundrobin负载模式
        balance url_param name #基于参数name做hash
        hash-type consistent
        log global
        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
      

    HAProxy 调度算法-hdr

    • hdr(<name>):针对用户每个http头部(header)请求中的指定信息做hash, 此处由<name>指定的http首部将会被取出并做hash计算, 然后由服务器总权重相除以后派发至某挑出的服务器, 假如无有效的值,则会被轮询调度

      hdr( Cookie、 User-Agent、 host )
      
      listen web_prot_http_nodes
        bind 192.168.7.101:80
        mode http
        balance hdr(User-Agent)
        hash-type consistent
        log global
        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  
      

    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 <value>:为当前server指定cookie值,实现基于cookie的会话黏性
      cookie <name> [ rewrite | insert | prefix ] [ indirect ] [ nocache ] [ postonly ] [preserve ] [ httponly ] [ secure ] [ domain <domain> ]* [ maxidle <idle> ] [maxlife <life> ]
      <name>:cookie名称,用于实现持久连接
      rewrite:重写
      insert:插入
      prefix:前缀
      nocache:当client和hapoxy之间有缓存时,不缓存cookie

    • 基于cookie实现的session 保持

      listen web_prot_http_nodes
       bind 192.168.7.102:80
       mode http
       cookie SERVER-COOKIE insert indirect nocache
       server 192.168.7.101 192.168.7.101:8080 cookie web1 check inter 3000 fall 3 rise 5
       server 192.168.7.102 192.168.7.102:8080 cookie web2 check inter 3000 fall 3 rise 5
      

    小笔记: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:拒绝回复量

    修改报文首部

    • 在请求报文尾部添加指定首部
      reqadd <string> [{if | unless} <cond>] #支持条件判断

    • 在响应报文尾部添加指定首部
      rspadd <string> [{if | unless} <cond>]
      示例: rspadd X-Via:\ HAPorxy

    • 从请求报文中删除匹配正则表达式的首部
      reqdel <search> [{if | unless} <cond>]
      reqidel <search> [{if | unless} <cond>] 不分大小写

    • 从响应报文中删除匹配正则表达式的首部
      rspdel <search> [{if | unless} <cond>]
      rspidel <search> [{if | unless} <cond>]
      示例: rspidel server.* #从相应报文删除server信息
      rspidel X-Powered-By:.* #从响应报文删除X-Powered-By信息

      小笔记:

      #响应报文删除版本信息
      vim /etc/haproxy/haproxy.cfg
      listen  webs
       mode http
       rspidel server.*         #删除server版本信息
       rspidel X-Powered-By:.*  #删除php版本信息
       bind 192.168.37.7:80
       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 
       
      curl -I 192.168.37.7 
      

    HAProxy 日志配置

    • 在default配置项定义:
      log 127.0.0.1 local{1-7} info #基于syslog记录日志到指定设备,级别有(err、warning、 info、 debug)

    • 配置rsyslog:

      $ModLoad imudp
      $UDPServerRun 514
      local3.* /var/log/haproxy.log
      

      配置HAProxy:

      listen web_port
        bind 127.0.0.1:80
        mode http
        log global
        option tcplog
        server web1 127.0.0.1:8080 check inter 3000 fall 2 rise 5
      

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

    自定义记录日志

    • 将特定信息记录在日志中
      capture cookie <name> len <length> #捕获请求和响应报文中的 cookie并记录日志
      capture request header <name> len <length> #捕获请求报文中指定的首部内容和长度并记录日志
      capture response header <name> len <length> #捕获响应报文中指定的内容和长度首部并记录日志
      示例:
      capture request header Host len 256
      capture request header User-Agent len 512

    压缩功能

    • 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服务器状态监测

    • 三种状态监测方式:
      • 基于四层的传输端口做状态监测
      server 172.18.200.103 172.18.200.103:80 check inter 3s fall 3 rise 5 weight 1
      • 基于指定URI 做状态监测
      • 基于指定URI的request请求头部内容做状态监测

      option httpchk
      option httpchk <uri>
      option httpchk <method> <uri>
      option httpchk <method> <uri> <version>
      listen web_prot_http_nodes
      bind 192.168.7.102:80
      mode http
      log global
      option httpchk GET /wp-includes/js/jquery/jquery.js?ver=1.12.4 HTTP/1.0 #基于指定URL
      #option httpchk HEAD /wp-includes/js/jquery/jquery.js?ver=1.12.4 HTTP/1.0\r\nHost:\ 192.168.7.102 #通过request获取的头部信息进行匹配进行健康检测
      server 192.168.7.102 blogs.studylinux.net:80 check inter 3000 fall 3 rise 5
      server 192.168.7.101 192.168.7.101:8080 cookie web1 check inter 3000 fall 3 rise 5
      

    小笔记: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

    • ACL derivatives :
      • hdr([<name> [, <occ>]]):完全匹配字符串
      • hdr_beg([<name> [, <occ>]]):前缀匹配
      • hdr_dir([<name> [, <occ>]]):路径匹配
      • hdr_dom([<name> [, <occ>]]):域匹配
      • hdr_end([<name> [, <occ>]]):后缀匹配
      • hdr_len([<name> [, <occ>]]):长度匹配
      • hdr_reg([<name> [, <occ>]]):正则表达式匹配
      • hdr_sub([<name> [, <occ>]]):子串匹配

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

    • hdr <string>用于测试请求头部首部指定内容
      • hdr_dom(host) 请求的host名称,如 www.magedu.com
      • hdr_beg(host) 请求的host开头,如 www. img. video. download. ftp.
      • hdr_end(host) 请求的host结尾,如 .com .net .cn
      • path_beg 请求的URL开头,如/static、 /images、 /img、 /css
      • path_end 请求的URL中资源的结尾,如 .gif .png .css .js .jpg .jpeg

    flags

    • <flags>-条件标记
      -i 不区分大小写
      -m 使用指定的pattern匹配方法
      -n 不做DNS解析
      -u 禁止acl重名,否则多个同名ACL匹配或关系

    operator

    整数比较: 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进行匹配

    • <value>的类型:
      - Boolean #布尔值
      - integer or integer range #整数或整数范围,比如用于匹配端口范围
      - IP address / network #IP地址或IP范围, 192.168.0.1 ,192.168.0.1/24
      - string
      exact –精确比较
      substring—子串
      suffix-后缀比较
      prefix-前缀比较
      subdir-路径, /wp-includes/js/jquery/jquery.js
      domain-域名, www.magedu.com
      - regular expression #正则表达式
      - hex block #16进制

    Acl定义与调用

    • acl作为条件时的逻辑关系:
      - 与:隐式(默认)使用
      - 或:使用“or” 或 “||” 表示
      - 否定:使用“!“表示
      示例:
      if valid_src valid_port #与关系
      if invalid_src || invalid_port #或
      if ! invalid_src #非

      Acl 示例-域名匹配

      listen web_port
        bind 192.168.7.102:8800
        mode http
        log global
        acl test_host hdr_dom(host) www.magedu.com
        use_backend test_host if test_host
        default_backend default_web         #以上都没有匹配到的时候使用默认backend
      backend test_host
        mode http
        server web1 www.magedu.com check inter 2000 fall 3 rise 5
      backend default_web
        mode http
        server web1 192.168.7.101:8080 check inter 2000 fall 3 rise 5
      

      Acl-源地址子网匹配

      listen web_port
        bind 192.168.7.102:8800
        mode http
        log global
        acl ip_range_test src 172.18.200.102 192.168.0.0/24
        use_backend web2 if ip_range_test
        default_backend web1
      backend web1
        mode http
        server web1 192.168.7.101:8080 check inter 2000 fall 3 rise 5
      backend web2
        mode http
        server web1 192.168.7.102:8080 check inter 2000 fall 3 rise 5
      

      Acl示例-源地址访问控制

      listen web_port
        bind 192.168.7.102:8800
        mode http
        log global
        acl block_test src 192.168.7.103 192.168.7.104
        block if block_test
        default_backend web1
      backend web1
        mode http
        log global
        server web1 192.168.7.101:8080 check inter 2000 fall 3 rise 5
      

      Acl示例-匹配浏览器

      listen web_port
        bind 192.168.7.102:8800
        mode http
        log global
        acl block_test src 192.168.7.103 192.168.7.104
        acl redirect_test hdr(User-Agent) -m sub -i "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"
        block if block_test
        redirect prefix http://192.168.7.101:8080 if redirect_test
        default_backend web2
      backend web2
        mode http
        log global
        server web1 192.168.7.101:8080 check inter 2000 fall 3 rise 5
      

    小笔记: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 { ... }:定义当前主机的健康状态检测方法
    }
    

    应用层监测

    • HTTP_GET|SSL_GET:应用层检测

      HTTP_GET|SSL_GET {
        url {
            path <URL_PATH>:定义要监控的URL
            status_code <INT>:判断上述检测机制为健康状态的响应码
        }
        connect_timeout <INTEGER>:连接请求的超时时长
        nb_get_retry <INT>:重试次数
        delay_before_retry <INT>:重试之前的延迟时长
        connect_ip <IP ADDRESS>:向当前RS哪个IP地址发起健康状态检测请求
        connect_port <PORT>:向当前RS的哪个PORT发起健康状态检测请求
        bindto <IP ADDRESS>:发出健康状态检测请求时使用的源地址
        bind_port <PORT>:发出健康状态检测请求时使用的源端口
      }  
      

    TCP监测

    • 传输层检测 TCP_CHECK

      TCP_CHECK {
        connect_ip <IP ADDRESS>:向当前RS的哪个IP地址发起健康状态检测请求
        connect_port <PORT>:向当前RS的哪个PORT发起健康状态检测请求
        bindto <IP ADDRESS>:发出健康状态检测请求时使用的源地址
        bind_port <PORT>:发出健康状态检测请求时使用的源端口
        connect_timeout <INTEGER>:连接请求的超时时长
      }
      

    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
    

    相关文章

      网友评论

          本文标题:33-haproxy

          本文链接:https://www.haomeiwen.com/subject/tggjnhtx.html