haproxy集群
1. HAProxy简介
- HAProxy是一个使用C语言编写的自由及开放源代码软件,其提供高可用性、负载均衡,以及基于TCP和HTTP的应用程序代理。
- HAProxy提供高可用性、负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费、快速并且可靠的一种解决方案。HAProxy特别适用于那些负载特大的web站点,这些站点通常又需要会话保持或七层处理。HAProxy运行在当前的硬件上,完全可以支持数以万计的并发连接。并且它的运行模式使得它可以很简单安全的整合进您当前的架构中, 同时可以保护你的web服务器不被暴露到网络上。
- HAProxy实现了一种事件驱动, 单一进程模型,此模型支持非常大的并发连接数。多进程或多线程模型受内存限制 、系统调度器限制以及无处不在的锁限制,很少能处理数千并发连接。事件驱动模型因为在有更好的资源和时间管理的用户空间(User-Space) 实现所有。
2. 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的状态
3. haproxy集群部署
环境说明
类型 | IP地址 | 需要安装的服务 | 系统版本 |
---|---|---|---|
Director | 192.168.200.145 | HAProxy | centos 8 |
RS1 | 192.168.200.144 | httpd | centos 8 |
RS2 | 192.168.200.151 | httpd | centos 8 |
3.1 关闭防火墙
//三台主机的防火墙都需要关闭
[root@haproxy ~]# systemctl stop firewalld
[root@haproxy ~]# systemctl disable --now firewalld
Removed /etc/systemd/system/multi-user.target.wants/firewalld.service.
Removed /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.
[root@haproxy ~]# vim /etc/selinux/config
[root@haproxy ~]# setenforce 0
[root@RS1 ~]# systemctl stop firewalld
[root@RS1 ~]# systemctl disable --now firewalld
Removed /etc/systemd/system/multi-user.target.wants/firewalld.service.
Removed /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.
[root@RS1 ~]# vim /etc/selinux/config
[root@RS1 ~]# setenforce 0
[root@RS2 ~]# systemctl stop firewalld
[root@RS2 ~]# systemctl disable --now firewalld
Removed /etc/systemd/system/multi-user.target.wants/firewalld.service.
Removed /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.
[root@RS2 ~]# vim /etc/selinux/config
[root@RS2 ~]# setenforce 0
3.2 安装haproxy
//安装haproxy所需依赖包
[root@haproxy ~]# yum -y install make gcc pcre-devel bzip2-devel openssl-devel systemd-devel
//创建haproxy用户和组
[root@haproxy ~]# useradd -r -M -s /sbin/nologin haproxy
//上传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
//进行编译安装haproxy
[root@haproxy ~]# cd haproxy-2.4.0
[root@haproxy haproxy-2.4.0]# make -j $(grep 'processor' /proc/cpuinfo |wc -l) \
> TARGET=linux-glibc \
> USE_OPENSSL=1 \
> USE_ZLIB=1 \
> USE_PCRE=1 \
> USE_SYSTEMD=1
[root@haproxy sbin]# make install prefix=/usr/local/haproxy
[root@haproxy haproxy-2.4.0]# which haproxy
/usr/local/sbin/haproxy
3.3 RS1和RS2配置
//RS1和RS2上安装httpd服务,并设置开机自启
[root@RS1 ~]# yum -y install httpd
[root@RS1 ~]# systemctl enable --now httpd
Created symlink/etc/systemd/system/multiuser.target.wants/httpd.service → /usr/lib/systemd/system/httpd.service.
[root@RS2 ~]# yum -y install httpd
[root@RS2 ~]# systemctl enable --now httpd
Created symlink/etc/systemd/system/multiuser.target.wants/httpd.service → /usr/lib/systemd/system/httpd.service.
//配置RS1和RS2的httpd服务
[root@RS1 ~]# echo "RS1" > /var/www/html/index.html
[root@RS2 ~]# echo "RS2" > /var/www/html/index.html
3.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
[root@haproxy ~]#
3.5 提供配置文件
//创建一个haproxy目录,用来存放haproxy配置文件
[root@haproxy ~]# mkdir /etc/haproxy
[root@haproxy ~]# cat > /etc/haproxy/haproxy.cfg <<EOF
[root@haproxy ~]#
log 127.0.0.1 local0 info #记录本机的info级别的日志存放到local0里
#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 //访问的时候要在域名或者IP地址后面加上这个才能访问到管理页面
bind 0.0.0.0:8189
stats enable
mode http
log global
stats uri /haproxy_stats
stats realm Haproxy\ Statistics
stats auth admin:admin //用于认证的用户和密码,这里我们设置用户和密码都为admin
#stats hide-version
stats admin if TRUE
stats refresh 30s
#---------------web设置-----------------------
listen webcluster
bind 0.0.0.0:80 //绑定的端口为80端口
mode http //模式为http,负载均衡协议是http协议
#option httpchk GET /index.html
log global
maxconn 3000
balance roundrobin
cookie SESSION_COOKIE insert indirect nocache
server web01 192.168.200.144:80 check inter 2000 fall 5
server web02 192.168.103.151:80 check inter 2000 fall 5
#server web01 192.168.80.102:80 cookie web01 check inter 2000 fall 5
EOF
3.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
[Install]
WantedBy=multi-user.target
EOF
//重新加载配置文件
[root@haproxy ~]# systemctl daemon-reload
//修改rsyslog服务文件,添加haproxy日志记录的位置,要和配置文件中的位置一致
[root@haproxy ~]# vim /etc/rsyslog.conf
# Save boot messages also to boot.log
local7.* /var/log/boot.log
local0.* /var/log/haproxy.log #添加这一行
[root@Director ~]# systemctl restart rsyslog
3.7 设置haproxy开机自启
[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 ~]# 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:8189 0.0.0.0:*
LISTEN 0 128 0.0.0.0:80 0.0.0.0:* 此80端口部署httpd服务端口
LISTEN 0 128 [::]:22 [::]:*
[root@haproxy ~]#
[root@haproxy ~]# ss -antlp
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=1000,fd=4))
LISTEN 0 128 0.0.0.0:8189 0.0.0.0:* users:(("haproxy",pid=105557,fd=8))
LISTEN 0 128 0.0.0.0:80 0.0.0.0:* users:(("haproxy",pid=105557,fd=9))
LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=1000,fd=6))
[root@haproxy ~]#
3.8 访问测试
[root@haproxy ~]# curl http://192.168.200.145
RS2
[root@haproxy ~]# curl http://192.168.200.145
RS1
[root@haproxy ~]# curl http://192.168.200.145
RS2
[root@haproxy ~]# curl http://192.168.200.145
RS1
[root@haproxy ~]# curl http://192.168.200.145
RS2
[root@haproxy ~]# curl http://192.168.200.145
RS1
4 haproxy web界面测试
5. haproxy web界面访问
6. haproxy负载均衡https
6.1 在RS1上配置证书
//在haproxy上安装openssl服务
[root@haproxy ~]# yum -y install openssl
//在RS1上安装mod_ssl 服务
[root@RS1 ~]# yum -y install mod_ssl
//创建密钥存放目录
[root@RS1 ~]# mkdir /etc/httpd/ssl
[root@RS1 ~]# cd /etc/httpd/ssl/
// 创建CA自签名证书,生成私钥
[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]:WhHan
Organization Name (eg, company) [Default Company Ltd]:abc
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]#
[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 = WhHan, O = abc, CN = *.jj.com
Getting Private key
[root@RS1 ssl]# ls
test.crt test.csr test.key
[root@RS1 ssl]#
//编译配置文件
[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 ssl]# systemctl restart httpd
[root@RS1 ssl]# 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 *:*
[root@RS1 ssl]#
6.2 在RS2上生成证书
/安装模块
[root@RS2 ~]# yum -y install openssl
[root@RS2 ~]# yum -y install mod_ssl
// 从RS1上传输密钥和证书到RS2
[root@RS1 ssl]# scp /etc/httpd/ssl/* root@192.168.200.151:/etc/httpd/ssl/
The authenticity of host '192.168.200.151 (192.168.200.151)' can't be established.
ECDSA key fingerprint is SHA256:4VPYR1bpyvu6BYTzkAkAZWVS/UttttbRezAdzsbF9N0.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.200.151' (ECDSA) to the list of known hosts.
root@192.168.200.151's password:
test.crt 100% 1147 1.0MB/s 00:00
test.csr 100% 968 1.2MB/s 00:00
test.key 100% 1679 2.5MB/s 00:00
[root@RS1 ssl]#
[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 *:80 *:*
LISTEN 0 128 [::]:22 [::]:*
LISTEN 0 128 *:443 *:*
7. 配置haproxy
[root@haproxy ~]# 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
8. 测试
[root@haproxy ~]# curl -k https://192.168.200.145
RS2
[root@haproxy ~]# curl -k https://192.168.200.145
RS1
[root@haproxy ~]# curl -k https://192.168.200.145
RS2
[root@haproxy ~]# curl -k https://192.168.200.145
RS1
[root@haproxy ~]#