基于HAproxy搭建负载均衡
基于HAproxy搭建负载均衡器
HAproxy的优势
相比于nginx,处理能力更好,但是扩展性上没有nginx好
LVS处于四层上,处理能力最好,稳定强,成本低,不支持正则,处理上不太好
Haproxy 安装部署
- yum/dnf安装
yum install haproxy -y
配置文件在/etc/haproxy/haproxy.cfg
-
编译安装
- 下载源码包
wget -c https://repo.huaweicloud.com/haproxy/2.4/src/haproxy-2.4.8.tar.gz
- 下载源码编译工具
yum install -y gcc gcc-c++ make
- 下载Haproxy依赖包lua并编译安装
wget http://www.lua.org/ftp/lua-5.4.7.tar.gz tar zxf lua-5.4.7.tar.gz -C /usr/local/src/ cd /usr/local/src/lua-5.4.7 make linux test
- 查看lua版本信息
cp /usr/local/src/lua-5.4.7/src/lua /usr/bin/lua lua -v
- 解压haproxy源码包
tar xf haproxy-2.4.8.tar.gz -C /usr/local/src/ cd /usr/local/src/haproxy-2.4.8
- 安装编译时需要的依赖包
yum install openssl-devel pcre-devel systemd-devel -y
openssl-devel 是用来支持ssl的
pcre-devel 正则表达式库
- 编译安装Haproxy
make ARCH=x86_64 TARGET=linux-glibc USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 USE_SYSTEMD=1 USE_LUA=1 LUA_INC=/usr/local/src/lua-5.4.7/src/ LUA_LIB=/usr/local/src/lua-5.4.7/src/ make install PREFIX=/usr/local/haproxy
- 做二进制执行文件做软连接
ln -sv /usr/local/haproxy/sbin/haproxy /usr/sbin/haproxy
- 查看haproxy版本信息
haproxy -v
- 为haproxy服务配置启动脚本
vim /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 /usr/local/haproxy/haproxy.pid ExecReload=/bin/kill -USR2 $MAINPID [Install] WantedBy=multi-user.target
- 创建haproxy服务的配置文件
配置文件例子位置:/usr/local/src/haproxy-2.4.8/examples/
mkdir /etc/haproxy
vim /etc/haproxy/haproxy.cfg
global ##全局配置
maxconn 10000
stats socket /var/run/haproxy.stat mode 600 level admin
log 127.0.0.1 local2 info
user haproxy ##指定用户
group haproxy ##指定组
chroot /usr/local/haproxy ##服务工作目录
daemon ##开启保护进程
defaults ##默认配置
mode http
option httplog
log global
timeout client 1m
timeout server 1m
timeout connect 10s
timeout http-keep-alive 2m
timeout queue 15s
timeout tunnel 4h # for websocket
default-server inter 1000 weight 3
listen app1 ##此部分是前端部分和后端部分的结合
bind :80 ##监听的端口
log global
server web1 172.25.10.120:80 check ##后端的真实服务器地址
server web2 172.25.10.130:80 check ##后端的真实服务器地址
listen stats #配置监听页面
mode http
bind :9999 ##使用9999端口
stats enable
log global
stats uri /haproxy-status
stats auth haadmin:123456 ##指定登录监听页面的用户是haadmin,密码是123456
- 创建用户和组
useradd -r -s /sbin/nologin -d /usr/local/haproxy/ haproxy
- 启动haproxy服务
systemctl start haproxy.service
- 测试
整一个测试页面
for ((i=1; i<=8; i++))
do
curl http://192.168.202.69
echo "第 $i 次请求完成"
done
一个for循环 来看看返回的结果IP是否做了负载转发
HAproxy 配置文件
配置文件其实就包括两大部分
global:全局配置段, 进程及安全配置相关的参数 性能调整相关参数,日志等
defaults: 用来实现负载均衡的配置,包括frontend
, backend
, listen
frontend
:前端,相当于nginx配置中的server{}
backend
:后端,相当于nginx配置中的upstream{}
listen
:同时拥有前端和后端配置,配置简单
配置方法
- 前后端方法
前端frontend
front webcluster
bind 0.0.0.0:80
mod http
use_backend webcluster-host#使用哪一个后端
后端
backend webcluster-host
balance roundrobin#算法
server web1 172.25.254.10:80
server web1 172.25.254.20:80
- listen合并配置的方法
listen webcluster bind 0.0.0.0:80#bind监听的端口,*表示所有
mode http
balance roundrobin
server web1 172.25.254.10:80 check inter 2 fall 3 rise 5 weight 2
server web2 172.25.254.20:80 check inter 2 fall 3 rise 5 weight 1
全局配置及日志分类
- 多线程设定
nbthread 2#启用多线程
启动多线程情况启动多进程会报错,所以只能执行一个
pstree -p | grep haproxy#查看进程
cat /proc/进程号/status | grep thread
Haproxy的状态页面控制
通过web界面,显示当前HAproxy的运行状态
listen stats
mode http
bind *:7777
stats enable#启用状态页面
stats uri /status
stats auth 123:123456 #账号密码
基于cookie的会话保持
解决调度死板问题,一台主机两个不同的浏览器同时访问一个IP显示的是同样的内容
cookie保存在服务器
insert:插入新的cookie,默认不插入cookie
nocache:当客户端与服务器之间有缓存器(cdn),不允许中间缓存器缓存cookie,因为这会导致很多同一个cdn的请求都发送到同一台后端服务器
indirect:如果客户端已经有cookie,则不在发送cookie
当被调度到ip=172.25.254.10的服务器上时,会发送cookie=zee1,那么下次再来的时候,浏览器的cookie被缓存,再来的时候验证cookie=zee1,那么就还让它走10
HAproxy + keepalived 实现高可用
实际环境中,单台负载均衡可能会因为流量太大而down掉,因此通过keepalived来实现容错高可用
这个对与学网工的好理解,keepalived本身就是基于vrrp协议(虚拟路由冗余协议)里面的,通过VIP(虚拟IP)来实现容错,还有健康检查机制,主备切换通过优先级来判断。
Keepalived高可用服务的故障切换转移是通过VRRP机制来实现的。在Keepalived服务正常运行时,Master节点会不断向Backup节点发送(多播方式)心跳信息,用以通知Master节点的存活状态。当Master节点发生故障时,就无法发送心跳信息,Backup节点也就无法检测到来自Master的心跳信息,于是调用自身的接管程序,接管Master的资源和服务。当Master恢复时,Backup又会释放Master故障时自身接管的资源和服务,恢复到原来的备用角色。无论Master如何切换,对外都应该提供相同的服务IP地址,该IP也称作虚拟地址VIP。客户端并不需要因Master的改变而修改自己的配置,对他们来说这种切换是透明的。
核心功能
- HAPROXY
- 负载均衡会话保持,可以根据hash或者cookies实现会话保持
- 监控检测,支持TCP、HTPP两种后端服务器监控检测
- 统计监控,设置访问端口实现服务监控,也可带有页面用户认证
- ssl卸载,可以解析https报文并将请求解密为HTTP向后端服务器传输
- 其他功能,可以在http请求或者响应报文,添加、修改、删除首部信息,HTTP请求重写或者重定向;根据访问控制路由或阻断请求
安装
安装HAPROXY
和keepalived
yum -y install haproxy
yum -y install keepalived
也可参考上述的安装部署
keepalived配置
keepalived生成的配置文件位置:/etc/keepalived/keepalived.conf
配置文件主要由:1.全局段 2.VRRP实例段 3.脚本段组成
- 全局段定义(global_defs)
全局段定义允许用户设置全局相关信息,例如通知信息、关键参数配置等,该段配置在Master节点和Backup节点应当一致
global_defs {
notification_email {
sysadmin@example.com #接受者的邮箱 需要搭建SMTP服务器才可以实现
}
notification_email_from noreply@example.com
smtp_server 127.0.0.1
smtp_connect_timeout 60
vrrp_mcast_group4 224.0.0.18
}
notification_email定义报警邮件地址,当服务切换时发送报警邮件。
notification_email_from定义发件人信息,
smtp_server和smtp_connect_timeout分别定义了SMTP服务器及相应的连接超时时间,
vrrp_mcast_group4为VRRP IPv4多播地址,默认为224.0.0.18,如果同一局域网内有多组Keepalived时需要指定不同多播地址。如果想要实现发送邮件需要搭建smtp服务器
- VRRP实例段定义(vrrp_instance)
这部分主要用来定义具体服务的实例配置,包括Keepalived主备状态、接口、优先级、认证方式和VIP信息等,每个VRRP实例可以认为是Keepalived服务的一个实例或作为一个业务服务,在一组Keepalived服务配置中,VRRP实例可以有多个。
注意,存在于Master节点中的VRRP实例配置在Backup节点中也要有一致的配置(除了节点角色、优先级不同),这样才能实现故障切换转移。
vrrp_instance R1{
state MASTER
interface eth0
virtual_router_id 50
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass passwd
}
virtual_ipaddress {
10.230.137.100
}
track_script {
chk_haproxy
}
nopreempt
preempt_delay 2
}
vrrp_instance配置段定义了一个VRRP实例并设定实例名称;
state设定初始VRRP实例角色,配置先要为该实例所在的Keepalived服务器设定其角色,在Master服务器上设置为“MASTER”,在Backup服务器上则设置为“BACKUP”;
priority优先级设定,范围1-254,数字越大,表示实例优先级越高,在同一个VRRP实例里,Master节点优先级要高于Backup节点;
virtual_router_id虚拟路由ID标识,范围0-255,Master和Backup节点配置中相同VRRP实例的虚拟路由ID标识必须一致,否则将出现脑裂问题;
advert_int用来同步通知间隔,Master节点和Backup节点之间通信检查的时间间隔,单位是秒。
角色相关信息设定完毕后就要开始配置VIP并绑定至指定的网络接口上,在virtual_ipaddress中配置VIP,可以配置多个VIP,VIP将绑定至interface参数配置的网络接口上。
authentication认证配置段作用于同一个VRRP实例的MASTER和BACKUP之前的通信,具体的配置内容有auth_type认证类型,auth_pass认证密码,认证类型有PASS(Simple Passwd)和AH(IPSEC),官方推荐PASS,验证密码为明文方式,最多8位。同一个VRRP实例的MASTER和BACKUP使用相同的密码才能正常通信。
当添加nopreemp关键字时表示设置高可用模式为非抢占模式,如果去掉此关键字则为默认的抢占模式。抢占模式是指当高优先级节点恢复后会抢占低优先级节点成为MASTER,非抢占模式允许低优先级节点继续担任MASTER,preempt_delay用来设置抢占延迟,单位秒,范围0~1000,发现低优先级MASTER后多少秒开始抢占。
track_script配置段是用于调用指定脚本,脚本相关配置请参考下一节。
- 脚本段定义
默认情况下,Keepalived仅仅在节点宕机或Keepalived进程停掉的时候才会启动切换机制。但在实际工作中,有业务服务停止而Keepalived服务还存在的情况,这就会导致用户访问的VIP无法找到对应的服务,这时可以利用Keepalived触发预制的监测脚本,实现VIP漂移来继续提供服务。
vrrp_script chk_haproxy {
script "killall -0 haproxy"
interval 2
weight -2
fall 3
rise 1
}
vrrp_script配置段定义一段脚本配置并设定脚本段名称。
script用双引号设置引用的shell语句或者shell脚本,通过该语句或脚本执行结果来判断是否触发指定动作,成功的结果不会触发动作,执行失败会触发动作。
interval设置监控间隔时间,单位为秒,
weight设置当监控脚本执行结果为失败时触发priority值调整,正数为增加优先级,负数为降低优先级,范围-255~255,
fall设置认定结果为失败时的执行失败次数,
rise设置判定结果为成功时的执行成功次数。
- 完全配置
- master:
global_defs {
notification_email {
1786602444@qq.com
}
notification_email_from 1786602444@qq.com
smtp_server 127.0.0.1
smtp_connect_timeout 60
vrrp_mcast_group4 224.0.0.18
}
vrrp_instance R1{
state MASTER
interface ens33
virtual_router_id 50
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass passwd
}
virtual_ipaddress {
192.168.1.100
}
track_script {
chk_haproxy
}
nopreempt
preempt_delay 2
}
vrrp_script chk_haproxy {
script "killall -0 haproxy"
interval 2
weight -2
fall 3
rise 1
}
- backup:
global_defs {
notification_email {
1786602444@qq.com
}
notification_email_from 1786602444@qq.com
smtp_server 127.0.0.1
smtp_connect_timeout 60
vrrp_mcast_group4 224.0.0.18
}
vrrp_instance R1{
state BACKUP
interface ens33
virtual_router_id 50
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass passwd
}
virtual_ipaddress {
192.168.1.100
}
track_script {
chk_haproxy
}
nopreempt
preempt_delay 2
}
vrrp_script chk_haproxy {
script "killall -0 haproxy"
interval 2
weight -2
fall 3
rise 1
- 启动
systemctl start keepalived
## 开机自启
systemctl enable keepalived
haproxy配置
- 全局段定义(global)
全局参数配置,将配置与所有HAproxy服务器上
global
log /dev/log local0 info
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
log设置全局日志配置,语法为
log <address> <facility> <msglevel>
,上例中指定使用本机上的syslog服务中的local0日志设备,记录日志等级为info的日志。
chroot设置HAProxy工作目录,
pidfile设置HAProxy的pid文件位置,
maxconn设置每个HAProxy进程可用的最大连接数,
user及group设置HAProxy进程所属的用户及用户组,
daemon关键字表示以守护进程方式运行haproxy。
- 默认段定义(defaults)
默认段的作用是为后续前端代理及后端代理设置默认值
defaults
mode http
log global
option httplog
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
mode表示HAProxy的工作模式,设置tcp时为4层模式,设置http时为7层模式。log设置日志输出方式,配置为global表示将采用全局段log的配置。
option httplog关键字表示记录HTTP详细日志,包括HTTP请求、session状态、连接数等。
option http-server-close关键字表示每次请求完毕后主动关闭HTTP通道。
option forwardfor关键字表示应用程序想记录发起请求的客户端的IP地址,需要在HAProxy上配置此选项,这样HAProxy会把客户端的IP信息发送给服务器,在HTTP请求中添加"X-Forwarded-For"字段启用 X-Forwarded-For,在requests头部插入客户端IP发送给后端的server,使后端server获取到客户端的真实IP。
option redispatch关键字表示当使用了cookie时,HAProxy将会将其请求的后端服务器信息插入到cookie中,以保证会话的持久性,如果后端的服务器服务不可用,但客户端的cookie是不会刷新的,设置此参数会将客户的请求强制定向到另外一个后端服务器上,以保证服务的正常。
retries定义连接后端服务器的失败重连次数,连接失败次数超过此值后将会将对应后端服务器标记为不可用。
timeout为前缀的关键字指定了一些关于请求、连接、响应的最大超时时间,单位默认为毫秒,也可以加入后缀s(秒),m(分钟),h(小时),d(天)来指定。http-request设置HTTP请求超时时长,queue设置一个请求在队列里的超时时间,connect设置最大与服务端建立连接的时长,client设置客户端最大非活动时长,server设置服务端最大非活动时长,http-keep-alive设置最大等待新请求的空闲时长,check设置检测超时时长。
- 前端代理定义(frontend)
前端代理配置定义一个服务监听,用于接受用户请求,并将请求转发给后端处理,可以定义多个前端代理
frontend main
mode http
bind :80
default_backend nginx
frontend前端代理配置段定义一组前端服务并启动服务监听,同时设置代理名称。
mode设置工作模式,如果此参数未被设定则引用默认配置段配置的模式。
bind设置监听地址及端口,地址为空或者表示绑定至所有服务器的网络接口。
default_backend指定默认后端代理进行流量转发。
- 后端代理定义(backend)
用于接受前端代理请求,并根据设置的负载均衡策略将流量转发至后端并对后端进行健康检查,一个前端可以执行多个后端,同时一个后端可以被多个调用
backend nginx
mode http
balance roundrobin
server web1 host1:80 check inter 3s rise 1 fall 2
server web2 host2:80 check
backend后端代理配置段定义一组后端服务器,同时设置代理名称。mode设置工作模式如果此参数未被设定则引用默认配置段的模式。balance设置后端负载均衡转发策略。
server配置了相应的后端服务集群地址,是真实的服务器,一个backend对应一个或者多个实体服务器。配置依次为节点名称、节点IP和端口、启用四层健康检查,在上述示例中web1服务器还设定了检查的相关参数表示每3秒(inter)检查一次,执行两次(fall)失败认为故障,执行一次(rise)成功即为服务可用。
- listen 段定义状态监控页面
listen stats
mode http
bind *:7777
stats enable#启用状态页面
stats uri /status
stats auth 123:123456 #账号密码
- 启动
systemctl start haproxy
- 开机自启
systemctl enable haproxy
会话保持
HAProxy可以分为四层会话保持和七层会话保持,四层会话是基于源地址会话保持,根据请求的源地址来判断关联会话的依据,是指HAProxy在负载均衡时根据访问请求的源地址作为判断关联会话的依据,对于同一IP地址的所有访问请求在作负载均衡时均会被保持到后端的同一台服务器上。七层会话保持是基于cookie的会话保持,当客户端HTTP请求进入HAProxy时,根据负载均衡策略选择后端的一台服务器,后端服务器将HTTP响应返回HAProxy,此时HAproxy会插入该服务器的cookie并将插入cookie的HTTP响应返回至客户端,当该客户端再次发出请求时,带有上次插入cookie的HTTP请求进入HAProxy,HAProxy解析出cookie中服务器信息并将请求发送至相同的后端服务器。
四层会话保持其实只需要调工作模式,和负载策略
backend nginx
mode tcp
balance source
server web1 10.230.150.68:80 check cookie web1
server web3 10.230.150.70:80 check cookie web3
七层会话保持需要设置cookie并确保工作模式为http,
backend nginx
mode http
balance roundrobin
cookie WEBSRV insert indirect nocache
server web1 10.230.150.68:80 check cookie web1
server web3 10.230.150.70:80 check cookie web3
以上配置文件中的cookie设置了以WEBSRV为名称的cookie,然后在server配置中分别定义了不同的cookie值,通过浏览器访问HAProxy前端代理地址可以看到该cookie,利用该cookie实现会话保持,如图2所示。
SSL卸载
利用HAProxy可以实现SSL卸载功能,从而使客户端到HAProxy的访问采用SSL封装后的HTTPS,而HAProxy至后端服务器之间的通信则采用HTTP,从而消除服务器端的SSL加密运算开销。
实现SSL卸载需要再配置文件全局定义段加入SSL参数调整,以及在前端代理段加入SSL配置,
global
maxconn 20000
log 127.0.0.1 local0 info
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
user haproxy
group haproxy
daemon
tune.ssl.default-dh-param 2048
stats socket /var/lib/haproxy/stats
frontend main
bind :80
bind :443 ssl crt /etc/ssl/certs/web.pem
redirect scheme https if !{ ssl_fc }
default_backend nginx
全局段配置中增加了SSL参数tune.ssl.default-dh-param,设置值为2048,表示使用2048bit加密,和SSL秘钥加密位数保持一致。
前端代理配置bind加入443端口、SSL支持并绑定指定证书,证书文件内容为网站的证书和私钥通过命令(cat web.crt web.key | tee web.pem)拼接合成。配置段中还加入了HTTP到HTTPS的自动跳转功能(redirect scheme https if !{ ssl_fc }),在浏览器中输入域名或者IP地址,无需指定协议类型,如果导入根证书后的浏览器显示的状态是安全的则表示配置成功。
流量路由
HAproxy可以为数据库、邮件、页面等服务提供四层负载均衡机制,也可以从HTTP请求报文中提取指定数据并通过特定的访问控制列表(ACL)提供基于七层的流量转发机制
-
基于URL路径转发,HAproxy可以根据请求的URL路径做路由,通过配置不同的路径将不同的URL路径分发至不同的后端服务器,在下面的例子中,我们在两个页面服务器上分别配置了两个测试页面,test1.html、test2.html,页面内容简单标识了所在的服务器的信息,并利用转发机制实现基于URL的路径分发,涉及配置如下
-
frontend main bind :80 bind :443 ssl crt /etc/ssl/certs/web.pem redirect scheme https if !{ ssl_fc } acl is_test1 path_beg /test1 acl is_test2 path_beg /test2 use_backend test1 if is_test1 use_backend test2 if is_test2 default_backend nginx backend nginx balance roundrobin server web1 10.230.150.68:80 check backend test1 balance roundrobin server web2 10.230.150.69:80 check backend test2 balance roundrobin server web3 10.230.150.70:80 check
前端代理配置段中加入acl配置,设置的路由规则为匹配路径的前缀(path_beg)test1及test2,并配置use_backend参数将指定acl作用于指定后端服务器,is_test1规则匹配后路由至test1,is_test2规则匹配后路由至test2。
定义两组后端代理配置,分别配置test1及test2后端代理,指向相应的页面服务器。通过访问不同的路径HAProxy可以正确路由转发到指定后端页面服务器,没有命中acl的请求将转发至默认后端服务器,如下图所示。
acl is_test2 path_beg /test2
use_backend test1 if is_test1
use_backend test2 if is_test2
default_backend nginx
backend nginx
balance roundrobin
server web1 10.230.150.68:80 check
backend test1
balance roundrobin
server web2 10.230.150.69:80 check
backend test2
balance roundrobin
server web3 10.230.150.70:80 check