企业级反向代理 HAProxy
社区版网站:http://www.haproxy.org/ github:https://github.com/haproxy #选偶数版本,长期支持版本,不要选dev开发版 点版本下载的是源码,需要编译安装
haproxy ubuntu自带了,如果要装最新的包,就在社区版网站左侧点debian包,选择对应版本,会出现命令
根据命令执行,第一步不用,第二部实际上是添加仓库
#红帽系列没有提供包安装,那就采用源码编译安装吧#注意需要lua支持,centos7的lua版本太低,需要先编译lua,在编译安装haproxy
#范例:Ubuntu #安装依赖包(这里以为依赖顺便把lua装上了) [root@ubuntu2204 ~]#apt update && apt -y install gcc make libssl-dev libpcre3 libpcre3-dev zlib1g-dev libreadline-dev libsystemd-dev liblua5.4-dev #下载 [root@ubuntu2204 ~]#wget http://www.haproxy.org/download/2.8/src/haproxy-2.8.0.tar.gz [root@ubuntu2204 ~]#tar xf haproxy-2.8.0.tar.gz;cd haproxy-2.8.0/ #编译安装 (-j表示多进程并行编译) [root@ubuntu2204 haproxy-2.8.0]#make -j 2 ARCH=x86_64 TARGET=linux-glibc USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 USE_SYSTEMD=1 USE_PROMEX=1 USE_LUA=1 [root@ubuntu2204 haproxy-2.8.0]#make install PREFIX=/apps/haproxy
#准备配置文件 [root@centos7 ~]# mkdir /etc/haproxy#方式1:复制源码中的范例配置文件做为初始配置文件 (必须cfg结尾) [root@haproxy haproxy-2.8.3]#cp examples/quick-test.cfg /etc/haproxy/haproxy.cfg
#设置用户和目录权限 [root@centos7 ~]# useradd -m -r -s /sbin/nologin -d /var/lib/haproxy haproxy
#创建service文件 [root@centos7 ~]#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 /var/lib/haproxy/haproxy.pid ExecReload=/bin/kill -USR2 $MAINPID LimitNOFILE=100000 #HAProxy能打开的文件个数 [Install] WantedBy=multi-user.target[root@centos7 ~]#systemctl daemon-reload [root@centos7 ~]#systemctl status haproxy.service #开机启动 [root@centos7 ~]#systemctl enable --now haproxy.service
启用状态页
#修改配置文件(下面追加) [root@centos7 ~]#vim /etc/haproxy/haproxy.cfg #启用状态页功能 listen statsmode httpbind 0.0.0.0:9999 #状态页端口 stats enablelog globalstats uri /haproxy-status #状态页地址stats auth admin:123456 #状态页用户密码 [root@centos7 ~]#systemctl reload haproxy.service#浏览器上查看状态页 10.0.0.200:9999/haproxy-status
Haproxy 官方镜像 https://hub.docker.com/_/haproxy/范例: 基于 Docker 安装 Haproxy #cat haproxy.cfg global maxconn 100000 stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin uid 99 gid 99 daemon pidfile /var/lib/haproxy/haproxy.pid log 127.0.0.1 local3 infodefaults option http-keep-alive option forwardfor maxconn 100000 mode http timeout connect 300000ms timeout client 300000ms timeout server 300000mslisten statsmode httpbind 0.0.0.0:9999stats enablelog globalstats uri /haproxy-statusstats auth admin:123456#新版 docker run -d --name my-running-haproxy -v /root/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro -p 9999:9999 --sysctl net.ipv4.ip_unprivileged_port_start=0 haproxy:2.8.2-alpine3.18 #旧版 docker run -d --name my-running-haproxy -v /root/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro -p 9999:9999 --sysctl net.ipv4.ip_unprivileged_port_start=0 haproxy:2.6.0-alpine3.16#ip_unprivileged_port_start是优化,正常特权端口是1024以内端口,这里设0表示所有端口都非特权端口,都能使用
HAProxy 的配置文件haproxy.cfg由两大部分组成,分别是global和proxies部分 global:全局配置段proxies:代理配置段
chroot /apps/haproxy #锁定运行目录(安全,只能访问这个目录下,被黑客控制也只能在这个目录下) deamon #以守护进程运行 stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin #socket文件,并可以通过此文件管理,新版不再支持多进程 stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin process 1 #socket文件,并可以通过此文件管理,旧版指定进程 user, group, uid, gid #运行haproxy对应worker进程的用户身份 #nbproc n #开启的haproxy worker 进程数,默认进程数是一个, nbproc从HAProxy 2.5开始不再支持 nbthread 1 #默认值auto,和多进程 nbproc配置互斥(版本有关,CentOS8的haproxy1.8无此问题),指定每个haproxy进程开启的线程数,默认为每个进程一个线程#如果同时启用nbproc和nbthread 会出现以下日志的错误,无法启动服务,此项不指定,默认为auto,即也可以实现自动生成和CPU核数相同的线程数 Apr 7 14:46:23 haproxy haproxy: [ALERT] 097/144623 (1454) : config : cannot enable multiple processes if multiple threads are configured. Please use either nbproc or nbthread but not both.#注意:下面方式不支持线程绑定 #cpu-map 1 0 #绑定haproxy worker 进程至指定CPU,将第1个worker进程绑定至0号CPU #cpu-map 2 1 #绑定haproxy worker 进程至指定CPU,将第2个worker进程绑定至1号CPU cpu-map auto:1/1-8 0-7 #haproxy2.4中启用nbthreads,在global配置中添加此选项,可以进行自动的线程和CPU的绑定,nbproc选项2.5版本中将会删除,每个进程中1-8个线程分别绑定0-7号CPU,注意:新版用此项进行线程绑定 maxconn n #每个haproxy进程的最大并发连接数 maxsslconn n #每个haproxy进程ssl最大连接数,用于haproxy 配置了证书的场景下 maxconnrate n #每个进程每秒创建的最大连接数量 #haproxy可以主动检查,nginx只能被动检查(访问了再检查)。下面参数可以让检查请求前后时间错开 spread-checks n #后端server状态check随机提前或延迟百分比时间,建议2-5(20%-50%)之间,默认值0 pidfile #指定pid文件路径 log 127.0.0.1 local2 info #定义全局的syslog服务器;日志服务器需要开启UDP协议,最多可以定义两个
#语法检查 /usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -c -q#修改haproxy对应worker进程的用户身份(缩进没关系) [root@ubuntu ~]#vim /etc/haproxy/haproxy.cfg globaluser haproxygroup haproxy[root@ubuntu ~]#systemctl reload haproxy.service #查看是否生效 [root@ubuntu ~]#ps auxf|grep haproxy
HAProxy 支持利用rsyslog服务记录日志到指定日志文件中
HAProxy配置
#在global配置项定义: log 127.0.0.1:514 local{0-7} info #基于syslog记录日志到指定设备,级别包括:err、warning、info、debug 通过514端口接受日志 local自定义日志,用0-7中的某一个 #例: log 127.0.0.1:514 local6 infolisten web_portbind 127.0.0.1:80mode httplog global #开启当前web_port的日志功能,默认不记录日志server web1 127.0.0.1:8080 check inter 3000 fall 2 rise 5# systemctl reload haproxy.service
Rsyslog配置
vim /etc/rsyslog.conf $ModLoad imudp $UDPServerRun 514 #监听514 ...... local6.info /var/log/haproxy.log #日志写入位置(这个配置也可以写在只配置文件中) ......# systemctl restart rsyslog
defaults [<name>] #默认配置项,针对以下的frontend、backend和listen生效,可以多个name也可以没有name listen <name> #将frontend和backend合并在一起配置,相对于frontend和backend配置更简洁,生产常用 frontend <name> #前端servername,类似于Nginx的一个虚拟主机 server和LVS服务集群。 backend <name> #后端服务器组,等于nginx的upstream和LVS中的RS服务器
[root@ubuntu ~]#vim /etc/rsyslog.conf global... listen webservers #起个名字bind 192.168.10.200:80 #本机监听地址server web1 10.0.0.201:80server web2 10.0.0.202:80[root@ubuntu ~]#systemctl reload haproxy.service#注意这时候,如果一个后端挂了,haproxy不会去监测,依然会把请求打上去#追加健康检查 [root@ubuntu ~]#vim /etc/rsyslog.conf listen webserversbind 192.168.10.200:80 #本机监听地址server web1 10.0.0.201:80 check #自动定期检查后端,默认2s(L4只查端口开没开,不严谨)#每1s检查后端,5次失败就异常,3次成功才算恢复正常,权重3,最大连接数10000server web2 10.0.0.202:80 check inter 1000 fall 1 rise 3 weight 3 maxconn 10000server localhost 127.0.0.1:80 redir http://www.baidu.com #重定向到百度 [root@ubuntu ~]#systemctl reload haproxy.service
server配置
#针对一个server配置 check #对指定real进行健康状态检查,如果不加此设置,默认不开启检查,只有check后面没有其它配置也可以启用检查功能#默认对相应的后端服务器IP和端口,利用TCP连接进行周期性健康性检查,注意必须指定端口才能实现健康性检查addr <IP> #可指定的健康状态监测IP,可以是专门的数据网段,减少业务网络的流量port <num> #指定的健康状态监测端口inter <num> #健康状态检查间隔时间,默认2000 msfall <num> #后端服务器从线上转为线下的检查的连续失效次数,默认为3rise <num> #后端服务器从下线恢复上线的检查的连续有效次数,默认为2 weight <weight> #默认为1,最大值为256,0(状态为蓝色)表示不参与负载均衡,但仍接受持久连接 backup #将后端服务器标记为备份状态,只在所有非备份主机down机时提供服务,类似Sorry Server disabled #将后端服务器标记为不可用状态,即维护状态,除了持久模式,将不再接受连接,状态为深黄色,支持优雅平滑下线,继续处理旧请求,不接受新请求 maxconn <maxconn> #指定每个后端server的最大并发连接数,放在,放在server 指令后面 redir http://www.baidu.com #将请求临时(302)重定向至其它URL,只适用于http模式,放在server 指令后面
redirect 配置
#注意:此指令和redir功能相似,但不属于server指令后面,是独立存放在listen,frontend,backend语句块 redirect prefix http://www.baidu.com/ #将请求临时(302)重定向至其它URL,只适用于http模式
#把listen拆成前端frontend,后端backen [root@ubuntu ~]#vim /etc/rsyslog.conf frontend web-http-80bind 192.168.10.200:80 #本机监听地址use_backend httpservers1 #调度到指定后端 backend httpservers1 #后端有两台server web1 10.0.0.201:80 checkserver web2 10.0.0.202:80 checkbackend httpservers2 #可以写多组后端server web2 10.0.0.202:80 check [root@ubuntu ~]#systemctl reload haproxy.service
#存放业务配置 [root@ubuntu ~]#mkdir /etc/haproxy/conf.d [root@ubuntu ~]#vim /etc/haproxy/conf.d/www.magedu.org.cfg#修改service文件 [root@centos7 ~]#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 -f /etc/haproxy/conf.d -c -q #追加配置文件目录 ExecStart=/usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -f /etc/haproxy/conf.d -p /var/lib/haproxy/haproxy.pid ExecReload=/bin/kill -USR2 $MAINPID LimitNOFILE=100000[Install] WantedBy=multi-user.target[root@centos7 ~]#systemctl daemon-reload [root@centos7 ~]#systemctl restart haproxy.service
HAProxy动态: 可以动态修改后端服务器的权重,平滑修改
动态修改用Socat工具控制 (通过socket连接)
#提前配置socket文件路径 [root@ubuntu2204 ~]#vim /etc/haproxy/haproxy.cfg globalstats socket /var/lib/haproxy/haproxy.sock mode 600 level admin [root@ubuntu2204 ~]#systemctl reload haproxy.service#安装socat [root@ubuntu1804 ~]#apt update && apt -y install socat [root@centos ~]#yum -y install socat#查看当前socket支持的指令 [root@centos7 ~]#echo "help" | socat stdio /var/lib/haproxy/haproxy.sock [root@centos7 ~]#echo "show version" | socat stdio /var/lib/haproxy/haproxy.sock #显示当前执行的任务 [root@centos7 ~]#echo "show tasks" | socat stdio /var/lib/haproxy/haproxy.sock #查看后端 [root@centos7 ~]#echo "show backend" | socat stdio /var/lib/haproxy/haproxy.sock #显示信息 [root@centos7 ~]#echo "show info" | socat stdio /var/lib/haproxy/haproxy.sock #查看server状态 ..."show servers state" #获取权重(服务器分组名/服务名) ..."get weight webservers/web1" #修改权重 ..."set weight webservers/web1 6" #禁用服务 ..."disable server webservers/web1" #恢复服务 ..."enable server webservers/web1"
6.1 基于 Cookie 的会话保持
6.2 HAProxy 状态页
6.3 IP透传
四层透传没意义,后面nginx无法解析
6.4 报文修改
6.5 自定义日志格式
6.6 压缩功能
6.7 后端服务器健康性监测
6.8 ACL (比nginx和lvs强大的地方)
frontend httpserverbind 192.168.10.100:80acl acl_static path_beg -i /statichttp-request deny if HTTP_1.0 #拒绝http1.0use_backend pc_hosts if acl_staticdefault_backend mobile_hostsbackend pc_hostsserver web01 10.0.0.201:80backend mobile_hostsserver web02 10.0.0.202:80
defaults #option forwardfor #no option http-use-htx 支持html文件,此设置和版本有关,2.1不支持 #...... #加下面行 errorfile 500 /usr/local/haproxy/html/500.http errorfile 502 /usr/local/haproxy/html/502.http errorfile 503 /usr/local/haproxy/html/503.http#范例: [root@centos7 ~]#vim /etc/haproxy/haproxy.cfg defaults ... errorfile 503 /apps/haproxy/html/503.http listen .......[root@centos7 ~]#vim /apps/haproxy/html/503.http HTTP/1.1 503 Service Unavailable Content-Type:text/html;charset=utf-8<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>报错页面</title> </head> <body> <center><h1>网站维护中......请稍候再试</h1></center> <center><h2>联系电话:400-123-4567</h2></center> <center><h3>503 Service Unavailable</h3></center> </body>[root@centos7 ~]#systemctl restart haproxy #将后端服务器down,可以观察到以下页面
listen redis-portbind 10.0.0.7:6379mode tcpbalance leastconnserver server1 10.0.0.17:6379 checkserver server2 10.0.0.27:6379 check backup
范例:对 MySQL 服务实现四层负载
[root@centos7 ~]#vim /etc/haproxy/haproxy.cfg listen wang_mysqlbind 10.0.0.7:3306mode tcpbalance leastconnserver mysql1 10.0.0.17:3306 check server mysql2 10.0.0.27:3306 check #如果不写端口号,可以转发,但无法check状态#或者使用frontend和backend实现 frontend mysqlbind :3306mode tcp #必须指定tcp模式 default_backend mysqlsrvs backend mysqlsrvsmode tcp #必须指定tcp模式 balance leastconnserver mysql1 10.0.0.17:3306server mysql2 10.0.0.27:3306[root@centos7 ~]#systemctl restart haproxy#在后端服务器安装和配置mariadb服务 [root@centos7 ~]#yum -y install mariadb-server [root@centos7 ~]#mysql -e "grant all on *.* to test@'10.0.0.%' identified by '123456'" [root@centos7 ~]#vim /etc/my.cnf [mysqld] server-id=17 #在另一台主机为27 [root@centos7 ~]#systemctl start mariadb
[root@centos7 ~]#cat /etc/haproxy/conf.d/test.cfg frontend wang_http_portbind 10.0.0.7:80 ###################### https setting ############################## bind 10.0.0.7:443 ssl crt /etc/haproxy/certs/haproxy.pemredirect scheme https if !{ ssl_fc } # 注意{ }内的空格 default_backend pc_hosts backend mobile_hostsserver web1 10.0.0.17:80backend pc_hostsserver web2 10.0.0.27:80