设为首页 收藏本站
查看: 2158|回复: 1

[经验分享] Haproxy 使用攻略

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2019-1-1 09:35:43 | 显示全部楼层 |阅读模式
前言          HAProxy是法国人Willy Tarreau开发的一款可应对客户端10000以上的同时连接的高性能的TCP和
  HTTP负载均衡器。由于其丰富强大的功能在国内备受推崇,是目前主流的负载均衡器。本文介绍其功能特性并结合配置实例演示,如有错误敬请赐教。
  Haproxy主要工作位置:
  
  1. 支持http反向代理
  2. 支持动态程序的反向代理
  3. 支持基于数据库的反向代理
  

  Haproxy 程序组成:
  程序环境:
       安装:yum install haproxy -y
  主程序: /usr/sbin/haproxy
  配置文件: /etc/haproxy/haproxy.cfg
  主配置文件主要结构:1. global 全局配置段 2. proxies代理配置段
  索引
  1. global:全局配置段配置
  1.1 全局日志配置
  1.2 性能调整常见参数
  2.proxies:代理配置段结构
  3.实现简单proxy配置实验
  3.1 方法1
  3.2 方法2
  4.代理配置段常见配置参数
  4.1 Balance调度算法相关
  4.2 server:定义后端主机相关选项
  4.3 实现图形化配置页
  4.4 default默认配置中定义的内容
  4.5 forwardfor后端记录真实请求配置
  4.6 自定义错误页面
  4.7 自定义修改报文首部
  4.8 自定义连接超时相关配置
  5. ACL灵活转发详解
  5.1 acl语法
  5.2 匹配条件进阶
  5.3 acl作为条件时的逻辑关系
  5.4 系统预定义ACL(部分)
  5.5 配置block拒绝访问
  5.6 指定backend组
  5.7 http 7层访问控制
  5.8 tcp 4层连接控制
  5.9 配置HAProxy支持https协议
  6. 附实现动静分离实验示例
  

  

  1. global:全局配置段
  1.1 log:全局日志配置
  默认发往本机的日志服务器;
  (1) 系统默认:log         127.0.0.1 local2
  发往远端可添加:log          远端IP  local2
  (2) 修改本机日志配置文件:
  vim  /etc/rsyslog.conf
  $ModLoad imudp          #取消注释
  $UDPServerRun 514    #取消注释
  local2.*                                                /var/log/haproxy.log  #新增
  (3) 远端日志配置(配合前端log配置)
  vim  /etc/rsyslog.conf
  local2.*                                                /var/log/haproxy.log  #新增
  

  1.2 性能调整(依据生产环境适当调整):
  maxconn :设定每个haproxy进程所能接受的最大并发连接数
  maxconnrate :设置每个进程每秒种所能建立的最大连接数量
  maxse***ate :设置每个进程每秒种所能建立的最大会话数量
  maxsslconn : 每进程支持SSL的最大连接数量
  spread-checks  健康检测延迟时长比建议2-5之间
  2.proxies:代理配置段结构
      (1). defaults:为frontend, backend, listen提供默认配置
      (2). fronted:前端,指定接收客户端连接侦听套接字设置
      (3). backend:后端,指定将连接请求转发至后端服务器的相关设置
      (4). listen:同时拥有前端和后端,适用于一对一环境
  3.实现简单proxy配置:
  实验拓扑:

  3.1  方法一:
  配置 /etc/haproxy/haproxy.cfg :
  将frontend段、backend段注释,新建如下配置
  frontend http *:80                #均衡器端采用http 协议,监听80端口
          default_backend websrvs   #引用后端自定义服务器组名websrvs
  backend websrvs                   #设定默认后端,自定义名字为websrvs
          balance roundrobin        #轮询方式为加权轮询
          server web1 192.168.43.61:80 check    #设定后端服务器IP ,并引入健康检查
          server web2 192.168.43.63:80 check    #设定后端服务器IP ,并引入健康检查
  

  service haproxy start
  在浏览器访问http://172.18.43.62 刷新即可看到轮询效果

  3.2 方法2:
  上面两段配置也可以配置在一段实现相同功能,配置如下:
  listen http
          bind :80
          balance roundrobin
          server web1 192.168.43.61:80 check
          server web2 192.168.43.63:80 check
  配置参数 bind:指定一个或多个前端侦听地址和端口
  语法: bind []: [, ...] [param*]
  示例:
      listen http_proxy
      bind :80,:443
      bind 10.0.0.1:10080,10.0.0.1:10443
  4.代理配置段常见配置参数
  4.1Balance相关
  balance:后端服务器组内的服务器调度算法
  语法: balance  [  ]
  balance url_param  [check_post]
  调度算法:
  ① roundrobin:基于权重轮询,动态算法, 支持权重的运行时调整,支持慢启动;每个后端backend中最多支持4095个server
      server options: weight #
  ② static-rr:基于权重轮询,静态算法,不支持权重的运行时调整及慢启动;后端主机数量无上限
  ③ leastconn:加权最少连接,动态算法,最少连接的后端服务器优先分配接收新连接,相同连接时轮询,推荐在较长会话的场景使用,例如MySQL、 LDAP等,不适合http。
  ④ first:根据服务器在列表中的位置,自上而下进行调度;前面服务器的连接数达到上限,新请求才会分配给下一台服务器。
  ⑤ hdr():对于每个http请求,此处由指定的http首部将会被取出做hash计算; 并由服务器总权重相除以后派发至某挑出的服务器; 无有效值的会被轮询调度
  例:hdr(host)     hdr(Cookie)
  ⑤ rdp-cookie 远程桌面相关
  hash类算法:
  需配合参数:hash-type   
  method:
      map-based:除权取余法,哈希数据结构是静态数组
      consistent:一致性哈希,哈希数据结构是一棵树
  ⑥ source:源地址hash,新连接先按权重分配,后续连接按source分配请求
  ⑦ uri:对URI的左半部分或整个uri做hash计算,并除以服务器总权重取模,以后派发至某挑出的服务器,适用于后端缓存服务器
  ://:@:/;?#
  左半部分: /;
  整个uri: /;?#
  ⑧ url_param:对用户请求的uri听部分中的参数的值(通常为用户ID)作hash计算,并由服务器总权重相除以后派发至某挑出的服务器;通常用于追踪用户,以确保来自同一个用户的请求始终发往同一个Backend Server。
  

  4.2 server:定义后端主机相关选项
  语法:
  server  [:[port]] [param*]
  :服务器在haproxy上的自定义名称;出现在日志及警告信息
  :服务器地址,支持使用主机名
  [:[port]]:端口映射;省略时,表示同bind中绑定的端口
  [param*]:server后可加的参数
  weight :权重,默认为1
  maxconn :当前server的最大并发连接数
  backlog :当server的连接数达到上限后的后援队列长度
  backup:设定当前server为备用服务器
  check:对当前server做健康状态检测,只用于四层检测
  注意: httpchk, “smtpchk”, “mysql-check”, “pgsql-check” and “sslhello-chk” 用于定义应用层检测方法
  addr :检测时使用的IP地址(检测的不一定是vip)
  port :针对此端口进行检测
  inter :连续两次检测之间的时间间隔,默认单位为毫秒,默认为2000ms
  rise :连续多少次检测结果为“成功”才标记服务器为可用;默认为2
  fall :连续多少次检测结果为“失败”才标记服务器为不可用;默认为3
  disabled:标记为不可用
  redir :将发往此server的所有GET和HEAD类的请求重定向至指定的URL
  cookie :为当前server指定cookie值,实现基于cookie的会话黏性。
  基于cookie的session sticky的实现:
  frontend http
  bind 172.18.43.62:80               
          default_backend websrvs  
  backend websrvs                  
          balance roundrobin
  cookie SRV insert nocache
  #自定义会话添加cookie信息SRV,insert:插入 nocache:不缓存增加保密性     
          server web1 192.168.43.61:80 check   weight 2 cookie srv1 #自定义该server添加cookie信息为srv1
          server web2 192.168.43.63:80 check   maxconn 5000 cookie srv2 #自定义该server添加cookie信息为srv2
  server sorroyserver 192.168.43.62:80 backup
  4.3 实现图形化配置页面
  stats enable 添加这条参数后会在web页面启用统计页;参数可放置位置。

  我们在frontend段添加stats enable ,重启haproxy。浏览器访问172.18.43.62/haproxy?stats即可

  相关参数:
  ① stats refresh 设定自动刷新时间间隔
  若服务器出现故障,默认手动刷新才能才能看到状态的变化,可设置自动刷新
      例:添加stats refresh 2s
  ② stats uri  自定义stats page uri
  默认为/haproxy?stats 可自定义uri
      例:stats uri  /hastas
  重启后访问http://172.18.43.62/hastas即可
  ③ stats hide-version
  如上图所示界面会显示haproxy版本信息,若想隐藏版本加上此参数即可
  ④ stats auth : 认证时的账号和密码,可使用多次。如多个用户定义多行即可,例:
      stats auth ha1:centos1
      stats auth ha2:centos2
  ⑤ stats realm  认证时浏览器弹出对话框的提示信息
      例:stats realm "haproxy info"
  ⑥ stats admin { if | unless }  启用stats page中的管理功能
      例:stats  admin  if TRUE
  将stats分离出单独语句块,采用内网的6666端口提高访问安全性示例:
  listen admin
          bind 192.168.43.62:6666
          stats enable
          stats uri /status
          stats realm "haproxy info"
          stats auth ha1:centos
          stats hide-version
          stats refresh 5s
          stats admin if TRUE
  从内网访问界面:

  

  4.4 default中定义的内容
  可以在frontend、backend、listen中分别进行定义,如没有指定将默认default中设置,如:
  maxconn :为指定的frontend定义其最大并发连接数;默认为3000
  mode { tcp|http|health } 定义haproxy的工作模式(默认http)
  tcp:基于layer4实现代理;可代理mysql, pgsql, ssh,ssl等协议,https时使用此模式,默认模式
  http:仅当代理协议为http时使用,centos实际默认模式
  health:工作为健康状态检查的响应模式,当连接请求到达时回应“OK”后即断开连接,较少使用
  TCP模式的健康状态检测示例:
  

  listen ssh
           bind :22022
           balance leastconn
           mode tcp
           server sshsrv1 172.16.100.6:22 check
           server sshsrv2 172.16.100.7:22 check
  

  4.5 forwardfor配置
  语法 :option forwardfor [ except  ] [ header  ] [ if-none ]
  在由haproxy发往后端主机的请求报文中添加“X-ForwardedFor”首部,其值为前端客户端的地址;用于向后端主发送真实的客户端IP
      [ except  ]:请求报请来自此处指定的网络时不予添加此首部,如haproxy自身所在网络
      [ header  ]:使用自定义的首部名称,而非“XForwarded-For”
      [ if-none ] 如果没有首部才添加首部,如果有使用默认值
  默认defaults中有一条配置option forwardfor       except 127.0.0.0/8
  若想后端日志记录真实请求客户端IP,需更改后端两台服务器配置文件:
  vim /etc/httpd/conf/httpd.conf
  LogFormat "%{x-forwarded-for}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" haformat
  #添加日志格式
  CustomLog logs/access_log haformat #修改记录日志
  重载客户端httpd服务,浏览器刷新请求。在客户端观看日志即可看到真实请求服务器
  tail -f /var/log/httpd/access_log
  

  4.6 自定义错误页面
  ① errorfile   自定义错误页
          : HTTP status code.  支持200, 400, 403, 408, 500, 502, 503, 504.
          :错误页文件路径
      例:errorfile 400 /etc/haproxy/errorfiles/400badreq.http
  ② rrorloc         相当于errorloc302  ,利用302重定向至指URL
      例:errorloc 503 http://www.magedu.com/error_pages/503.html
  4.7修改报文首部
  ① reqadd  [{if | unless} ]    在请求报文尾部添加指定首部(用于web端区分从哪个调度器发来请求)
  例:在frontend中添加  reqadd  X-via:\  haproxy1
  后端修改httpd.conf中logformat添加%{X-via}i
  再次访问日志就会看到是通过哪个调度器调度到本机
  ② rspadd  [{if | unless} ]  在响应报文尾部添加指定首部 (用于haproxy之前的调度器查看用于排错)
  示例: rspadd X-Via:\ HAPorxy
  ③ reqdel  [{if | unless} ]
  reqidel  [{if | unless} ] (ignore case) 不分大小写
  从请求报文中删除匹配正则表达式的首部
  ④ rspdel  [{if | unless} ]
  rspidel  [{if | unless} ] (ignore case) 不分大小写
  从响应报文中删除匹配正则表达式的首部
  示例: rspidel Server.*  用于隐藏web服务器版本信息
  rspadd Server:\ Apache 15.1 结合上例可伪造server信息
  4.8 定义连接超时
  ① timeout client     客户端最长空闲连接超时时长 默认单位是毫秒
  ② timeout server    后端服务器最长空闲连接超时时长
  ③ timeout http-keep-alive     持久连接的持久时长
  ④ timeout http-request      一次完整的HTTP请求的最大等待时长
  ⑤ timeout connect      成功连接后端服务器的最大等待时长
  ⑥ timeout client-fin    客户端半连接的空闲时长
  ⑦ timeout server-fin      后端服务器半连接的空闲时长
  5. ACL灵活转发详解
  acl:访问控制列表(ACL)的使用提供了一个灵活的解决方案来执行内容交换,并且通常基于从请求中提取的内容、响应或任何环境状态进行决策,是haproxy的重要特色。
  5.1 语法
  acl   [flags] [operator] []...
  : ACL名称,可使用字母 数字 : . - _区分字符大小写
  : 比较的标准和条件
          dst 目标IP
          dst_port 目标PORT
          src 源IP
          src_port 源PORT
          示例: acl invalid_src src 172.16.100.200
  
          -i 不区分大小写
          -m 使用指定的pattern匹配方法
          -n 不做DNS解析
          -u 强制每个ACL必须唯一ID,否则多个同名ACL或关系
          --  强制flag结束. 当字符串和某个flag相似时使用
  [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进行匹配
  的类型:
      - boolean
      - integer or integer range
      - IP address / network
      - string (exact, substring, suffix, prefix, subdir,domain)
      - regular expression
      - hex block
  5.2 匹配条件进阶:
  (1)base : string
  返回第一个主机头和请求的路径部分的连接,该请求从第一个斜杠开始,并在问号之前结束,对虚拟主机有用
  ://:@:/;?#
      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
  (2)path : string
  提取请求的URL路径,该路径从第一个斜杠开始,并在问号之前结束(无主机部分)
  ://:@:/;?#
      path : exact string match
      path_beg : prefix match
      path_dir : subdir match
      path_dom : domain match
      path_end : suffix match
      path_len : length match
      path_reg : regex match
      path_sub : substring match
  例:acl adminpath path_beg  -i  /admin
  acl imagefile  path_end  .jpg  .png   .bmp
  (3)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
  (4)req.hdr([[,]]) : string
  提取在一个HTTP请求报文的首部
      hdr([[,]]) : exact string match
      hdr_beg([[,]]) : prefix match
      hdr_dir([[,]]) : subdir match
      hdr_dom([[,]]) : domain match
      hdr_end([[,]]) : suffix match
      hdr_len([[,]]) : length match
      hdr_reg([[,]]) : regex match
      hdr_sub([[,]]) : substring match
  (5)status : integer
  返回在响应报文中的状态码
  5.3 acl作为条件时的逻辑关系:
      - 与:隐式(默认)使用
      - 或:使用“or” 或 “||”表示
      - 否定:使用“!“ 表示
      同一个组名可定义多次
  示例: if invalid_src invalid_port 与关系
      if invalid_src || invalid_port 或
      if ! invalid_src 非
  5.4 预定义ACL(部分)
  

  ACL名称
  
  

  等价于
  
  

  说明
  
  TRUE
  always_true
  总是匹配
  FALSE
  always_false
  从不匹配
  HTTP_1.1
  req_ver 1.1
  匹配HTTP协议1.1
  HTTP
  req_proto_http
  匹配HTTP协议
  

  LOCALHOST
  
  

  src 127.0.0.1/8
  
  

  匹配从localhost来的连接
  
  

  METH_CONNECT
  
  

  method CONNECT
  
  

  匹配HTTP CONNECT方法
  
  

  5.5 配置block拒绝访问
  语法:block { if | unless }    阻止7层请求if/unless一个条件匹配
  例1:
  frontend http
  acl deny_src src 172.18.0.108
  #自定义源地址为172.18.0.108的acl组deny_src
  acl deny_port dst_port 80:100
  #自定义目标端口为80到100的acl组deny_port
  block if deny_src || deny_port
  #如果属于deny_src组或deny_port组则拒绝访问
  block unless deny_src #如果不属于acl组deny_src则拒绝访问
  例2(阻止curl访问):
  acl bad_curl hdr_sub(User-Agent) -i curl
  block if bad_curl
  5.6 指定backend组
  语法:use_backend  [{if | unless} ]
  当if/unless一个基于ACL的条件匹配时切换指定backend(可实现动静分离)
  例1:
  acl imagefile path_end .jpg .png .bmp
  acl appfile path_end .php
  use_backend websrvs1 if imagefile
  use_backend websrvs2 if appfile
  例2:

  例3:
  acl webhost hdr(host) web.运维网.com
  acl apphost hdr(host) app.运维网.com
  use_backend websrvs if webhost
  use_backend appsrvs if apphost
  5.7 http 7层访问控制
  语法:http-request { allow | deny |add-header  |set-header   } [ { if | unless } ]
  对7层请求的访问控制
  5.8 tcp4层连接控制
  语法:tcp-request connection {accept|reject} [{if | unless} ]
  根据第4层条件对传入连接执行操作
  例:
  listen ssh
  bind :22022
  balance leastconn
  acl invalid_src src 172.16.200.2
  tcp-request connection reject if invalid_src
  mode tcp
  server sshsrv1 172.16.100.6:22 check
  server sshsrv2 172.16.100.7:22 check backup
  5.9 配置HAProxy支持https协议:
  ① 支持ssl会话;
  bind *:443 ssl crt /PATH/TO/SOME_PEM_FILE
  crt 后证书文件为PEM格式,且同时包含证书和所有私钥
  为实验方便自签证书方法:
  在etc/pki/tls/certs/目录下执行make命令可获得同时包含证书和所有私钥的证书
  cd /etc/pki/tls/certs/
  make /etc/haproxy/haproxy.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 httpsif { ssl_fc }
  例:

  测试:

  向后端传递用户请求:

  修改后端httpd.conf中日志格式即可

  6. 附基于ACL的动静分离示例
  frontend web *:80
          acl url_static path_beg -i /static /images /javascript /stylesheets
          acl url_static path_end -i .jpg .gif .png .css .js .html .txt .htm
          use_backend staticsrvs if url_static
          default_backend appsrvs
  backend staticsrvs
          balance roundrobin
          server stcsrv1 172.16.100.6:80 check
  backend appsrvs
          balance roundrobin
          server app1 172.16.100.7:80 check
          server app1 172.16.100.7:8080 check
  listen stats
         bind :9091
         stats enable
         stats auth admin:admin
         stats admin if TRUE
  

  





运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-658150-1-1.html 上篇帖子: haproxy (3) 下篇帖子: haproxy专题学习
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表