使用HAproxy实现负载均衡
原创
©著作权归作者所有:来自51CTO博客作者明明星空的原创作品,请联系作者获取转载授权,否则将追究法律责任
一、HAproxy介绍
1、HAproxy
通过频繁的HTTPS认证会消耗大量的CPU资源,这个时候将TLS验证方式放置在其他设备上进行处理将会提高性能,HAproxy可以终结HTTPS流量,并实现负载均衡的目的,让整个服务器每个位置受到的负载差不多,提高系统整体运行效率。
2、HAproxy架构图
客户端通过访问HAproxy的方式来获取后端数据,并且HAproxy提供了TLS验证功能,也一定程度缓解了后端服务器的压力,通过设置多个Back-end web server,可以提高并发数量,实现负载均衡的效果。
二、环境准备
1、实验拓扑
2、 设备说明
操作系统
| IP地址
| 说明
|
centos1
| 172.16.10.1/24
| HAproxy负载均衡器
|
centos2
| 172.16.10.2/24
| 后端服务器1(内网主机1)
|
centos3
| 172.16.10.3/24
| 后端服务器2(内网主机2)
|
centos4
| 172.16.10.4/24
| 后端服务器3(内网主机3)
|
3、写入hosts文件
[root@fronted ~]# echo 172.16.10.1 haproxy >> /etc/hosts
[root@fronted ~]# for i in {2..4}; do echo 172.16.10.$i backend_server$((i-1)) >> /etc/hosts ; done
4、ssh免密登录
[root@fronted ~]# ssh-keygen
[root@fronted ~]# for i in {1..4}; do ssh-copy-id root@172.16.10.$i; done
三、服务器配置
1、 下载软件包
例如:下载httpd软件
[root@fronted ~]# yum -y --downloadonly install httpd
2、复制文件
[root@fronted ~]# mkdir httpd
[root@fronted ~]# find /var/ -name "*.rpm" -exec cp -a {} /root/httpd/ \;
3、将文件发送至局域网主机
使用for循环一次性将文件发送至后端主机
[root@fronted ~]# for i in {1..4};do scp -r /root/httpd/ 172.16.10.$i:~/.;done
4、 进入局域网主机,安装软件
由于做了前面的操作,本次安装软件也同样使用循环
[root@fronted ~]# for i in {1..3}; do ssh backend_server$i rpm -vih /root/httpd/* --force --nodeps; done
5、编辑index.html文件
[root@fronted ~]# for i in {1..3}; do ssh backend_server$i "echo 'backend_server$i' > /var/www/html/index.html"; done
[root@fronted ~]# for i in {1..3}; do ssh backend_server$i 'cat /var/www/html/index.html'; done
backend_server1
backend_server2
backend_server3
6、设置firewalld和selinux
# 防火墙设置
[root@fronted ~]# for i in {1..3}; do ssh backend_server$i "firewall-cmd --add-service=http --permanent"; done
[root@fronted ~]# for i in {1..3}; do ssh backend_server$i "firewall-cmd --add-service=https --permanent"; done
[root@fronted ~]# for i in {1..3}; do ssh backend_server$i "firewall-cmd --reload"; done
7、启动HTTPD服务
[root@fronted ~]#for i in {1..3}; do ssh backend_server$i "systemctl enable httpd --now"; done
8、测试服务是否启动
[root@fronted ~]# curl backend_server1
backend_server1
[root@fronted ~]# curl backend_server2
backend_server2
[root@fronted ~]# curl backend_server3
backend_server3
9、服务器配置小结
本次使用shell发现3台backend_server的配置几乎一模一样,可以编辑一个shell脚本一键部署
#!/bin/bash
# 软件包的下载&&安装
echo "=========软件包的下载&&安装========="
yum -y --downloadonly install httpd
mkdir httpd
find /var/ -name "*.rpm" -exec cp -a {} /root/httpd/ \;
for i in {1..4};do scp -r /root/httpd/ 172.16.10.$i:~/.;done
echo "=========部署WEB服务器========="
# 循环部署WEB服务器
for i in {1..3};
do
ssh backend_server$i rpm -vih /root/httpd/* --force --nodeps;
ssh backend_server$i "echo 'backend_server$i' > /var/www/html/index.html";
ssh backend_server$i 'cat /var/www/html/index.html';
ssh backend_server$i "firewall-cmd --add-service=http --permanent";
ssh backend_server$i "firewall-cmd --add-service=https --permanent";
ssh backend_server$i "firewall-cmd --reload";
ssh backend_server$i "systemctl enable httpd --now";
done
echo "=========测试========="
# 测试
for i in {1..3};
do
curl backend_server$i;
done
四、 HAproxy配置
1、 安装软件
[root@fronted ~]# yum -y install haproxy
2、 开启HAproxy
[root@fronted ~]# systemctl enable haproxy --now
Created symlink /etc/systemd/system/multi-user.target.wants/haproxy.service → /usr/lib/systemd/system/haproxy.service.
3、创建证书
命令创建方式
[root@fronted ~]# openssl genrsa 2048 > /etc/pki/tls/private/mmx.rsa.key
[root@fronted ~]# openssl req -new -key server.rsa.key -out /etc/pki/tls/private/mmx.csr
[root@fronted ~]# openssl x509 -req -days 365 -in server.csr -signkey server.rsa.key -out /etc/pki/tls/private/mmx.crt
[root@fronted ~]# mkdir -p /etc/pki/tls/haproxy/
[root@fronted ~]# chmod 700 /etc/pki/tls/haproxy/
[root@fronted ~]# cat /etc/pki/tls/private/mmx.crt /etc/pki/tls/private/mmx.rsa.key > /etc/pki/tls/haproxy/haproxy.pem
使用ansible方式创建证书。之前准备好的,直接拿来用^ __ ^
---
- name: 创建密钥
hosts: XXX
vars:
rsa_path: "/etc/pki/tls/private/mmx.rsa.key"
csr_path: "/etc/pki/tls/private/mmx.csr"
crt_path: "/etc/pki/tls/private/mmx.crt"
haproxy_pem_path: "/etc/pki/haproxy/haproxy.pem"
tasks:
- name: 创建privite文件夹
ansible.builtin.file:
path: /etc/pki/tls/private/
state: directory
recurse: yes
- name: 创建haproxy文件夹
ansible.builtin.file:
path: /etc/pki/haproxy
state: directory
mode: '0700'
recurse: yes
- name: 安装openssl
yum:
name: openssl
state: present
- name: 安装python3-pyOpenSSL
yum:
name: python3-pyOpenSSL
state: present
- name: 创建RSA私钥(key)
community.crypto.openssl_privatekey:
path: "{{ rsa_path }}"
- name: 生成CSR文件
openssl_csr:
path: "{{ csr_path }}"
privatekey_path: "{{ rsa_path }}"
subject_alt_name: "DNS:demo.example.com,DNS:www.example.com"
common_name: demo.example.com
C: CN
ST: hubei
L: wuhan
O: mmx
backup: yes
- name: 生成CRT文件
community.crypto.x509_certificate:
path: "{{ crt_path }}"
privatekey_path: "{{ rsa_path }}"
csr_path: "{{ csr_path }}"
provider: selfsigned
- name: 证书和密钥放置一个文件中
shell: |
cat "{{ rsa_path }}" "{{ crt_path }}" > "{{ haproxy_pem_path }}"
- name: Create a directory if it does not exist
ansible.builtin.file:
path: "{{ haproxy_pem_path }}"
state: file
mode: '0700'
# openssl req -in mmx.csr -noout -text
# openssl req -in mmx.crt -noout -text
4、添加子配置文件
由于添加了HTTPS认证,需要将证书文件加入配置文件中
配置说明
| 说明
|
bind *:80
| 放行端口
|
bind *:443 ssl crt /etc/pki/haproxy/haproxy.pem
| 放行端口+ssl证书
|
balance roundrobin/source
| 轮询(依次访问)/基于IP地址
|
http-request add-header X-Forwarded-Proto https
| 转发到https流量
|
redirect scheme https if !{ ssl_fc }
| 如果到达的请求不使用TLS加密,haproxy会返回302 HTTP重定向,指示客户端使用HTTPS
|
option forwardfor
| 记录IP地址
|
default_backend XX
| 请求的后端
|
backend web_server
| 后端信息说明
|
server app1 172.16.10.2:80 check
| 后端设备描述、检查运行状态
|
[root@fronted /etc/haproxy]# cat > /etc/haproxy/conf.d/load_balance.cfg <<END
frontend load_balance
bind *:443 ssl crt /etc/pki/haproxy/haproxy.pem
bind *:80
redirect scheme https if !{ ssl_fc }
option forwardfor
http-request add-header X-Forwarded-Proto https
default_backend web_server
stats enable
backend web_server
balance roundrobin
server app1 172.16.10.2:80 check
server app2 172.16.10.3:80 check
server app3 172.16.10.4:80 check
END
5、设置selinux允许haproxy流量
[root@fronted ~]# setsebool -P haproxy_connect_any on
6、放行防火墙
[root@fronted /etc/haproxy]# firewall-cmd --add-service=http --permanent
[root@fronted /etc/haproxy]# firewall-cmd --add-service=https --permanent
[root@fronted /etc/haproxy]# firewall-cmd --reload
7、重启服务
[root@fronted ~]# systemctl restart haproxy.service
五、监控和管理HAproxy
HAProxy提供了一个HTML统计报表页面。从该页面,您可以检查和监视您的安装行为。如果激活管理模式,则可以暂时禁用后端服务器,使其不再接收流量。该特性对于维护非常有用目的。
1、新增一个stat-page
默认配置禁用统计报表命令,如果要激活他,在frontend中添加如下命令
admin模式:缺省情况下,统计报表页面为只读状态。通过激活管理模式,您也可以直接从web界面禁用和启用后端web服务器。
[root@fronted /etc/haproxy/conf.d]# cat > stat_page.cfg <<END
frontend stat-page
bind *:8080
stats enable
stats uri /haproxystats
stats auth mmx:mmx123
stats admin if TRUE
END
2、 重启HAproxy,浏览器进入配置界面
用户名:mmx 密码:mmx123
登录IP:ip地址:配置端口/监控目录
3、 admin模式
配置文件/etc/haproxy/haproxy.cfg在global部分下定义了UNIX套接字。要激活管理模式,将级别admin选项添加到stats socket指令中。
global
...
stats socket /var/lib/haproxystats level admin
...
六、HAproxy和Varnish结合使用
1、架构图
由于HAproxy和Varnish都将X-Forwarded-For HTTP报头插入到请求中,并且Varnish将HAProxy视为web客户端,因此正确配置报头是复杂的。为了简化这个设置,HAproxy开发人员创建了HTTP PROXY协议。
HAProxy使用HTTP PROXY协议与Varnish通信。该协议传输来自web客户端的原始请求,以及特定的代理数据,如客户端的P地址。有了这些信息,Varnish自动将正确的XForwarded-For HTTP报头插入到后端web服务器的请求中。
2、配置proxy协议的HAproxy
在backend下server字段加入send-proxy-v2字段即可不转发HTTP报头请求,转而由varnish进行转发,并且将配置文件option forwardfor字段移除。
[root@fronted /etc/haproxy]# cat > /etc/haproxy/conf.d/load_balance.cfg <<END
frontend load_balance
bind *:443 ssl crt /etc/pki/haproxy/haproxy.pem
bind *:80
redirect scheme https if !{ ssl_fc }
# 以下字段移除
# option forwardfor
http-request add-header X-Forwarded-Proto https
default_backend varnish_server
stats enable
backend varnish_server
balance roundrobin
# 新增send-proxy-v2参数
server varnish 172.16.20.1:80 send-proxy-v2 check inter 1s
server varnish 172.16.20.2:80 send-proxy-v2 check inter 1s
server varnish 172.16.20.3:80 send-proxy-v2 check inter 1s
END
3、配置proxy协议的Varnish
在service文件中降入RROXY字段
[root@fronted ~]# mkdir /etc/systemd/system/varnish.service.d
[root@fronted ~]# cat > /etc/systemd/system/varnish.service.d/httpport.conf <<END
[Service]
ExecStart=
ExecStart=/usr/sbin/varnishd -a :80,PROXY -f /etc/varnish/default.vcl -s malloc,256m
END
[root@fronted ~]# systemctl daemon-reload
[root@fronted ~]# systemctl restart varnish
七、测试
1、Linux终端测试
[root@fronted ~]# curl https://192.168.0.100
# 显示没有证书
curl: (60) SSL certificate problem: self signed certificate
More details here: https://curl.haxx.se/docs/sslcerts.html
curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.
# curl -k --cert 私钥路径 IP地址/域名进行查看
[root@fronted ~]# curl -k --cert /etc/pki/haproxy/haproxy.pem https://localhost
backend_server3
[root@fronted ~]# curl -k --cert /etc/pki/haproxy/haproxy.pem https://localhost
backend_server1
[root@fronted ~]# curl -k --cert /etc/pki/haproxy/haproxy.pem https://localhost
backend_server2
2、浏览器测试
由于接的是同一内网,使用本机浏览器进行测试