文章目录
1 HAProxy简介
HAProxy:是法国人Willy Tarreau 开发的一个开源软件,是一 款应对客户端10000 以上的同时连接的高性能的TCP和HTTP 负载均衡器。
其功能是用来提供基于cookie的持久性,基于内容的交换,过载保护的高级流量管制,自动故障切换,以正则表达式为基础的标题控制运行时间,基于Web 的报表,高级日志记录以帮助排除故障的应用或网络及其他功能。
haproxy是高可用代理软件,是一种免费,快速且可靠的解决方案,可为基于TCP和HTTP的应用程序提供高可用性,借助HAProxy可以快速并且可靠的提供基于TCP和HTTP应用的代理解决方案
2 HAProxy支持两种主要的代理模式
2.1 TCP
TCP 即4层 (大多用于邮件服务器、内部协议通信服务器等),在4层模式下,HAProxy仅在客户端和服务器之间转发双向流量。它主要是通过分析IP层及TCP/UDP层的流量实现的基于IP加端口的负载均衡。仅建立一次TCP连接。
2.2 HTTP
HTTP 即7层模式,HAProxy会分析协议,并且能通过允许、拒绝、交换、增加、修改或删除请求 (request)或者回应(response)里指定内容来控制协议,七层负载均衡器可以根据报文内容,再配合负载均衡算法来选择后端服务器,因此也称为“内容交换器”。
负载均衡器与客户端及后端的服务器会分别建立一次TCP连接,七层负载均衡对负载均衡设备的要求更高,而七层负载均 衡的处理能力也必然低于四层模式的负载均衡。
3 HAProxy优缺点
3.1 优点
- 免费开源,稳定性也是非常好。单haproxy也跑得不错,稳定性可以与硬件级的F5相媲美
- 最高可以同时维护40000~50000个并发连接,单位时间内处理的最大请求数为20000个,最大数据处理能力可达10Gbps
- haproxy支持连接拒绝
- haproxy支持全透明代理(已具备硬件防火墙的典型特点)
- 自带强大的监控服务器状态的页面,实际环境中我们结合Nagios进行邮件或短信报警
- HAProxy支持虚拟主机,通过frontend指令来实现,这样实现web负载均衡更加灵活
- 能够补充Nginx的一些缺点比如Session的保持,Cookie的引导等工作
- 支持url检测后端的服务器出现的问题
3.2 缺点
- 重载配置的功能需要重启进程,虽然也是 soft restart,但没有 Nginx 的 reaload 更为平滑和友好
- 多进程模式支持不够好
- 不支持 HTTP cache 功能,现在不少开源的 lb 项目,都或多或少具备 HTTP cache 功能
4 HAProxy核心功能
- 负载均衡:L4和L7两种模式,支持RR/静态RR/LC/IP Hash/URI Hash/URL_PARAM Hash/HTTP_HEADER Hash等丰富的负载均衡算法
- 健康检查:支持TCP和HTTP两种健康检查模式
- 会话保持:对于未实现会话共享的应用集群,可通过Insert Cookie/Rewrite Cookie/Prefix Cookie,以及上述的多种Hash方式实现会话保持
- SSL:HAProxy可以解析HTTPS协议,并能够将请求解密为HTTP后向后端传输
- HTTP请求重写与重定向
- 监控与统计:HAProxy提供了基于Web的统计信息页面,展现健康状态和流量数据。基于此功能,使用者可以开发监控程序来监控HAProxy的状态
- HAProxy 是TCP / HTTP 反向代理服务器,尤其适合于高可用性环境
- 可以针对HTTP 请求添加cookie,进行路由后端服务器
- 支持基于cookie 进行调度
- 支持所有主服务器故障切换至备用服务器
- 支持专用端口实现监控服务
- 支持不影响现有连接情况下停止接受新连接请求
- 可以在双向添加,修改或删除HTTP 报文首部
- 支持响应报文压缩
- 支持基于pattern 实现连接请求的访问控制
- 通过特定的URI 为授权用户提供详细的状态信息
- 支持动态程序的反向代理
- 支持基于数据库的反向代理
5 HAProxy的关键特性
- 高性能
通常情况下,HAProxy自身只占用15%的处理时间,剩余的85%都是在系统内核层完成的 - 高稳定性
一旦成功启动,除非操作系统或硬件故障,否则就不会崩溃
6 haproxy负载均衡http
6.1 实验环境
haproxy | 192.168.25.146 |
---|---|
RS1 | 192.168.25.147 |
RS2 | 192.168.25.148 |
6.2 在RS上部署http网站服务
// 关闭防火墙
[root@RS1 ~]# systemctl stop --now firewalld
[root@RS1 ~]# vi /etc/selinux/config
SELINUX=disabled
[root@RS1 ~]# setenforce 0
[root@RS1 ~]# reboot
[root@RS1 ~]# getenforce
Disabled
[root@RS2 ~]# systemctl stop --now firewalld
[root@RS2 ~]# vi /etc/selinux/config
SELINUX=disabled
[root@RS2 ~]# setenforce 0
[root@RS1 ~]# reboot
[root@RS2 ~]# getenforce
Disabled
//安装http服务
[root@RS1 ~]# yum -y install httpd
[root@RS2 ~]# yum -y install httpd
// 启动httpd服务
[root@RS1 ~]# systemctl enable --now httpd
Created symlink /etc/systemd/system/multi-user.target.wants/httpd.service → /usr/lib/systemd/system/httpd.service.
[root@RS2 ~]# systemctl enable --now httpd
Created symlink /etc/systemd/system/multi-user.target.wants/httpd.service → /usr/lib/systemd/system/httpd.service.
//修改不同的web访问页面
[root@RS1 ~]# echo web147 > /var/www/html/index.html
[root@RS1 ~]# echo web147 > /var/www/html/index.html
6.3 haproxy安装
// 安装依赖包
[root@haproxy ~]# yum -y install make gcc pcre-devel bzip2-devel openssl-devel systemd-devel
// 创建用户账户
[root@haproxy ~]# useradd -r -M -s /sbin/nologin haproxy
//下载haproxy安装包并解压,这里我是本地下载上传的
https://github.com/haproxy/haproxy/archive/refs/tags/v2.4.0.tar.gz //haproxy下载链接
[root@haproxy ~]# ls
anaconda-ks.cfg haproxy-2.4.0.tar.gz
[root@haproxy ~]# tar xf haproxy-2.4.0.tar.gz
[root@haproxy ~]# ls
anaconda-ks.cfg haproxy-2.4.0 haproxy-2.4.0.tar.gz
// 编译安装
[root@haproxy ~]# cd haproxy-2.4.0
[root@haproxy haproxy-2.4.0]#
[root@haproxy haproxy-2.4.0]# make clean // 清理编译失败的缓存
[root@haproxy haproxy-2.4.0]# make -j $(nproc) TARGET=linux-glibc \
> USE_OPENSSL=1 USE_PCRE=1 USE_SYSTEMD=1
[root@haproxy haproxy-2.4.0]# make install prefix=/usr/local/haproxy // 指定安装路径
[root@haproxy local]# which haproxy
/usr/local/sbin/haproxy
6.4 配置各个负载的内核参数
[root@haproxy ~]# echo 'net.ipv4.ip_nonlocal_bind = 1' >> /etc/sysctl.conf
[root@haproxy ~]# echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf
[root@haproxy ~]# sysctl -p
net.ipv4.ip_nonlocal_bind = 1 //非本地绑定功能打开
net.ipv4.ip_forward = 1 // ip_forward打开
6.5 提供配置文件
[root@haproxy ~]# mkdir /etc/haproxy
cat > /etc/haproxy/haproxy.cfg <<EOF
#--------------全局配置----------------
global
log 127.0.0.1 local0 info
#log loghost local0 info
maxconn 20480
#chroot /usr/local/haproxy
pidfile /var/run/haproxy.pid
#maxconn 4000
user haproxy
group haproxy
daemon
#---------------------------------------------------------------------
#common defaults that all the 'listen' and 'backend' sections will
#use if not designated in their block
#---------------------------------------------------------------------
defaults
mode http
log global
option dontlognull
option httpclose
option httplog
#option forwardfor
option redispatch
balance roundrobin
timeout connect 10s
timeout client 10s
timeout server 10s
timeout check 10s
maxconn 60000
retries 3
#--------------统计页面配置------------------
listen admin_stats
bind 0.0.0.0:8189
stats enable
mode http
log global
stats uri /haproxy_stats
stats realm Haproxy\ Statistics
stats auth admin:admin
#stats hide-version
stats admin if TRUE
stats refresh 30s
#---------------web设置-----------------------
listen webcluster
bind 0.0.0.0:80
mode http
#option httpchk GET /index.html
log global
maxconn 3000
balance roundrobin
cookie SESSION_COOKIE insert indirect nocache //可以删除
server web01 192.168.25.147:80 check inter 2000 fall 5
server web02 192.168.25.148:80 check inter 2000 fall 5
#server web01 192.168.80.102:80 cookie web01 check inter 2000 fall 5 // 如果不用也可以删除
EOF
6.6 haproxy.service文件编写
cat > /usr/lib/systemd/system/haproxy.service <<EOF
[Unit]
Description=HAProxy Load Balancer
After=syslog.target network.target
[Service]
ExecStartPre=/usr/local/sbin/haproxy -f /etc/haproxy/haproxy.cfg -c -q
ExecStart=/usr/local/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /var/run/haproxy.pid
ExecReload=/bin/kill -USR2 $MAINPID
[Install]
WantedBy=multi-user.target
EOF
[root@haproxy ~]# systemctl daemon-reload //重新加载
// 启动服务
[root@haproxy ~]# systemctl enable --now haproxy
Created symlink /etc/systemd/system/multi-user.target.wants/haproxy.service → /usr/lib/systemd/system/haproxy.service.
[root@haproxy ~]# systemctl status haproxy
● haproxy.service - HAProxy Load Balancer
Loaded: loaded (/usr/lib/systemd/system/haproxy.service; enabled; vendor p>
Active: active (running) since Fri 2021-10-15 04:28:31 EDT; 8s ago
Process: 21322 ExecStartPre=/usr/local/sbin/haproxy -f /etc/haproxy/haproxy>
Main PID: 21325 (haproxy)
Tasks: 5 (limit: 49290)
Memory: 8.6M
CGroup: /system.slice/haproxy.service
├─21325 /usr/local/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p>
└─21327 /usr/local/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p>
10月 15 04:28:30 haproxy systemd[1]: Starting HAProxy Load Balancer...
10月 15 04:28:31 haproxy systemd[1]: Started HAProxy Load Balancer.
10月 15 04:28:31 haproxy haproxy[21325]: [NOTICE] (21325) : New worker #1 (>
// 查看端口
[root@haproxy ~]# ss -antl
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:8189 0.0.0.0:*
LISTEN 0 128 0.0.0.0:80 0.0.0.0:*
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 [::]:22 [::]:*
6.7 测试
6.8 启用日志服务
[root@haproxy ~]# vim /etc/rsyslog.conf
# Save boot messages also to boot.log
local0.* /var/log/haproxy.log
local7.* /var/log/boot.log
[root@haproxy ~]# systemctl restart rsyslog // 重启服务
6.9 haproxy的web界面
7 haproxy负载均衡https
7.1 生成网页步骤略可查看上面步骤
7.2 配置HTTPD
7.2.1 在RS1上配置证书
// 安装openssl软件和模块
[root@DR ~]# yum -y install openssl
[root@RS1 ~]# yum -y install mod_ssl
//创建密钥存放目录
[root@RS1 ~]# mkdir /etc/httpd/ssl
// 创建CA自签名证书,生成私钥
[root@RS1 ~]# cd /etc/httpd/ssl
[root@RS1 ssl]# openssl genrsa -out test.key 2048
Generating RSA private key, 2048 bit long modulus (2 primes)
.................................+++++
.....................................................................................................................................................................+++++
e is 65537 (0x010001)
[root@RS1 ssl]# ls
test.key
//生成证书
[root@RS1 ssl]# openssl req -new -key test.key -out test.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:HuBei
Locality Name (eg, city) [Default City]:WuHan
Organization Name (eg, company) [Default Company Ltd]:runtime
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:*.jj.com
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
[root@RS1 ssl]# ls
test.csr test.key
[root@RS1 ssl]# openssl x509 -req -days 365 -in test.csr -signkey test.key -out test.crt
Signature ok
subject=C = CN, ST = HuBei, L = WuHan, O = runtime, CN = *.jj.com
Getting Private key
[root@RS1 ssl]# ls
test.crt test.csr test.key
//编译配置文件
[root@RS1 ~]# vim /etc/httpd/conf.d/ssl.conf
DocumentRoot "/var/www/html" //取消注释
ServerName www.example.com:443 //取消注释
SSLCertificateFile /etc/httpd/ssl/test.crt //修改证书存放位置
SSLCertificateKeyFile /etc/httpd/ssl/test.key //修改密钥存放位置
//重启服务
[root@RS1 ~]# systemctl restart httpd
[root@RS1 ~]# ss -antl
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 *:80 *:*
LISTEN 0 128 [::]:22 [::]:*
LISTEN 0 128 *:443 *:*
7.2.2 在RS2上配置证书
//安装模块
[root@RS2 ~]# yum -y install openssl
[root@RS2 ~]# yum -y install mod_ssl
// 从RS1上传输密钥和证书
[root@RS2 ~]# mkdir /etc/httpd/ssl
[root@RS1 ~]# scp /etc/httpd/ssl/* [email protected]:/etc/httpd/ssl/
The authenticity of host '192.168.25.148 (192.168.25.148)' can't be established.
ECDSA key fingerprint is SHA256:1RKF1dDMiNk1NgpQCf2BP231oK3MOjFXoSDgRJ2FeS4.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.25.148' (ECDSA) to the list of known hosts.
[email protected]'s password:
test.crt 100% 1159 528.1KB/s 00:00
test.csr 100% 976 2.1MB/s 00:00
test.key 100% 1675 2.8MB/s 00:00
[root@RS2 ~]# cd /etc/httpd/ssl
[root@RS2 ssl]# ls
test.crt test.csr test.key
//修改配置文件
[root@RS2 ~]# vim /etc/httpd/conf.d/ssl.conf
DocumentRoot "/var/www/html"
ServerName www.example.com:443
SSLCertificateFile /etc/httpd/ssl/test.crt
SSLCertificateKeyFile /etc/httpd/ssl/test.key
// 重启服务
[root@RS2 ~]# systemctl restart httpd
[root@RS2 ~]# ss -antl
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 [::]:22 [::]:*
LISTEN 0 128 *:443 *:*
LISTEN 0 128 *:80 *:*
7.2.3 配置haproxy
[root@DR ~]# vim /etc/haproxy/haproxy.cfg
#---------------------------------------------------------------------
defaults
mode tcp #这里修改为tcp
log global
option dontlognull
option httpclose
option httplog
#---------------web设置-----------------------
listen webcluster
bind 0.0.0.0:443 #这里要修改为443端口
mode tcp #这里修改为tcp
#option httpchk GET /index.html
log global
maxconn 3000
balance roundrobin
server web01 192.168.25.147:443 check inter 2000 fall 5 #端口修改为443
server web02 192.168.25.148:443 check inter 2000 fall 5 #端口修改为443
// 重启服务
[root@DR ~]# systemctl restart haproxy
[root@DR ~]# ss -antl
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 0.0.0.0:443 0.0.0.0:*
LISTEN 0 128 0.0.0.0:8189 0.0.0.0:*
LISTEN 0 128 [::]:22 [::]:*
7.3 测试
[root@DR ~]# curl -k https://192.168.25.146
web148
[root@DR ~]# curl -k https://192.168.25.146
web147
[root@DR ~]# curl -k https://192.168.25.146
web148
[root@DR ~]# curl -k https://192.168.25.146
web147