RH358优化Web服务器流量–使用HAProxy终止HTTPS流量和并进行负载均衡
本章节介绍如何使用HAProxy进行负载均衡设置来进行流控。
RH358专栏地址:https://blog.csdn.net/qq_41765918/category_11532281.html
文章目录
1. HAProxy描述
可以从繁忙的web服务器中卸载HTTPS解密和加密过程。TLS处理是CPU密集型的。通过将该操作委托给不同的系统,可以从web服务器释放一些资源,然后web服务器就有更多的处理能力来管理其工作负载。
另一种减少web服务器负载的方法是部署相同的web服务器群,然后在它们之间分发(或负载平衡)传入的web请求。
HAProxy是一个负载均衡器,可以将其配置为一个HTTPS终止程序,以从后端web服务器卸载TLS处理。将HAProxy部署在这些web服务器的前面。而不是直接访问web服务器,web客户端联系HAProxy。代表这些客户端,HAProxy从后端web服务器检索并返回所请求的对象。
终止HTTPS连接
下面的模式说明了如何使用HAProxy作为web服务器前的HTTPS终止程序。
-
web 客户端使用 HTTPS 从 HAProxy 请求 web 文档。对于客户端,HAProxy 就像 web 服务器
-
HAProxy 使用其 TLS 证书和私钥来解密 HTTPS 流量
-
HAProxy 以纯文本形式将请求转发到后端 web 服务
-
后端 web 服务将其回复发送到 HAProxy
-
HAProxy 使用其 TLS 证书和私钥来加密回复,发回到 web 客户端
某些 web 应用会动态构建 HTML 文档,以回复来自客户端的请求。这些文档可能包含引用网站其他部分的 HTML 链接。在构建这些链接时,web 应用必须使用 https:// 架构,即使该请求通过 HTTP 来自 HAProxy。HAProxy 可将 X-Forwarded-Proto HTTP 标头插入到请求中,值设为 https,以指示 web应用在其链接中使用正确的 scheme
其他 web 应用使用传入请求的来源 IP 地址来识别其客户端。但由于 HAProxy 在 web 服务前面,应用会看到来自HAProxy 系统的请求,而不是来自单个客户端。为解决此问题,HAProxy 在其转发到后端 web 服务器的所有请求中插入了 X-Forwarded-For HTTP 标头。HAProxy 将该标头的值设置为客户端的 IP 地址。
负载均衡请求
下面的模式说明了HAProxy如何作为负载均衡器工作。
Web客户端通过HAProxy访问Web服务器。然后HAProxy在后端web服务器之间分发请求。通过这种方式,HAProxy将负载分散到web服务器群之间。HAProxy还可以监视后端服务器并停止向无响应的服务器发送请求。
维护会话
当与web应用程序交互时,应用程序通常使用某种HTTP会话抽象来维护用户状态,通常使用HTTP cookie。因为HAProxy可以将您的请求定向到任何web服务器,所以会话信息必须是全局可用的,而不仅仅是在到达的第一个服务器上。
一些web应用程序将会话信息保存在一个中央存储中,例如数据库或内存中的共享存储(如Redis或memcached)。对于这些应用程序,HAProxy不需要任何特定的配置。
有些应用程序不能正确地处理web场中的多个自身实例。对于这些应用程序,可以在HAProxy中选择一个负载均衡算法来始终将客户端引导到相同的后端web服务器。
选择负载均衡算法
HAProxy支持多种负载均衡算法来在后端web服务器之间分发请求。
roundrobin
该算法依次向每个web服务器发送请求。
当web交付静态内容时,或者当web应用程序运行在后端服务器上,将用户会话保存在全局存储中时,将使用它。
source
该算法使用客户端的IP地址来选择后端服务器。使用这种算法,HAProxy总是将客户端请求转发到同一台服务器。当运行在后端服务器上的web应用程序不能全局管理会话时,可以使用此算法。
HAProxy 支持用于不同用例的其他算法。有关完整的列表,可参阅 /usr/share/doc/haproxy/configuration.txt
2. 部署和配置 HAProxy
安装haproxy包。
[root@host ~]# yum install haproxy
启动haproxy systemd服务。
[root@host ~]# systemctl enable --now haproxy
HAProxy使用/etc/haproxy/haproxy.cfg配置文件实现。该配置文件参数分组:
global:global部分定义了与haproxy进程相关的参数,比如用于守护进程的Linux用户帐户。通常不需要改变这个部分的任何内容。
defaults:defaults节为其他节的参数设置默认值。可以在下面的部分中重写这些参数
frontend name:frontend部分配置HAProxy的面向客户端。在本节中,将指定监听传入请求的网络端口。这也是将HAProxy配置为HTTPS终止程序的地方。
backend name:backend部分列出了所有后端web服务器。在本节中,您将指定用于检查后端服务器健康状况的负载均衡算法和机制。
listen name:listen部分允许以更紧凑的方式定义前端和后端配置。当设置很简单时,可以使用单个侦听部分,而不是前端和后端部分。
下面的例子展示了frontend和backend部分的声明。
frontend my-clients
bind *:80
# HAProxy在端口80上的所有接口上侦听传入请求。
default_backend my-web-farm
# HAProxy将请求分发到后端my-web-farm部分的web服务器上。
backend my-web-farm
balance roundrobin
# 负载均衡算法为roundrobin。
server web1 192.168.0.101:80 check inter 1s
server web2 192.168.0.102:80 check inter 1s
server web3 192.168.0.103:80 check inter 1s
# HAProxy将请求分发到三个后端web服务器上。此外,HAProxy每秒检查这些服务器的健康状况,这样它就不会向停机的web服务器发送请求。
如果愿意,可以使用listen 来配置更精简版本。
listen my-clients-and-web-farm
bind *:80
balance roundrobin
server web1 192.168.0.101:80 check inter 1s
server web2 192.168.0.102:80 check inter 1s
server web3 192.168.0.103:80 check inter 1s
配置HAProxy为HTTPS终结程序
在将HAProxy配置为HTTPS终止程序之前,请先获取服务器的TLS证书和私钥。HAProxy希望将证书和密钥放在一个文件中,因此可能必须创建该文件。因为该文件包含私钥,请将其存储在一个安全的目录中:
[root@host ~]# mkdir /etc/pki/haproxy/
[root@host ~]# chmod 700 /etc/pki/haproxy/
[root@host ~]# cat www.example.com.crt www.example.com.key > /etc/pki/haproxy/haproxy.pem
在 /etc/haproxy/haproxy.cfg配置文件中,在front一节中定义了HTTPS终止程序的配置。
frontend my-clients
bind *:443 ssl crt /etc/pki/haproxy/haproxy.pem
# HAProxy 在 443 端口监听传入的 HTTPS 请求。该端口上的流量使用 TLS。证书和私钥位于/etc/pki/haproxy/haproxy.pem
bind *:80
# HAProxy还在80端口上侦听不使用TLS加密的HTTP请求。
redirect scheme https if !{
ssl_fc }
# 如果一个未使用TLS加密的请求到达,HAProxy会响应一个302 HTTP重定向来指示客户端使用HTTPS代替。
option forwardfor
# 在将 X-Forwarded-For HTTP 标头转发到后端 web 服务器时,HAProxy 会将其插入到请求中,以便为它们提供客户端的IP 地址。默认的配置文件定义在 defaults 部分下定义option forwardfor 指令。因此,可在 frontend 部分中省略它
http-request add-header X-Forwarded-Proto https
# 当将请求转发到后端web服务器时,HAProxy会将X-Forwarded-Proto HTTP头插入到请求中,这样后端web服务器就知道初始连接使用的是HTTPS
default_backend my-web-farm
为HAProxy准备SELinux
SELinux允许HAProxy绑定并连接到http_cache_port_t和http_port_t端口类型。可以使用semanage port -l命令列出相关联的端口号。
root@host ~]# semanage port -l | \
grep -w -e http_cache_port_t -e http_port_t | grep tcp
http_cache_port_t tcp 8080, 8118, 8123, 10001-10010
http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000
要让HAProxy监听或连接到任何其他端口,可将haproxy_connect_any SELinux布尔值设置为on
[root@host ~]# setsebool -P haproxy_connect_any on
3. 在Varnish前面配置HAProxy
因为Varnish不能作为HTTPS终止程序工作,所以将HAProxy和Varnish一起使用是典型的配置。在这种设置中,HAProxy终止HTTPS连接,然后将流量以纯文本的形式转发给Varnish。Varnish将请求转发到后端web服务器,缓存响应,然后将它们发送回HAProxy以交付给web客户端。
下图显示了HAProxy终止HTTPS连接,然后对Varnish服务器进行负载均衡请求。
因为HAProxy和Varnish都将X-Forwarded-For HTTP报头插入到请求中,而且Varnish将HAProxy视为一个web客户端,所以正确配置报头是很复杂的。为了简化设置,HAProxy开发人员创建了HTTP PROXY协议。
HAProxy使用HTTP PROXY协议与Varnish进行通信。该协议传输来自web客户端的原始请求,以及特定的代理数据,如客户端的IP地址。有了这些信息,Varnish自动将正确的X-Forwarded-For HTTP头插入到后端web服务器的请求中。
配置代理协议的HAProxy
在backend部分,设置send-proxy-v2选项以使用Varnish激活HTTP PROXY协议。
backend my-varnish
server varnish 192.168.0.42:6081 send-proxy-v2 check inter 1s
因为HTTP代理协议管理X-Forwarded-For HTTP报头,所以要确保在defaults和backend部分下,从配置中移除option forwardfor指令。
为代理协议配置Varnish
对于Varnish,在varnishd命令的-a选项的末尾添加PROXY关键字。为此,通过创建一个drop-in目录重新配置varnish systemd服务
[root@host ~]# mkdir /etc/systemd/system/varnish.service.d/
[root@host ~]# vim /etc/systemd/system/varnish.service.d/httpport.conf
[Service]
ExecStart=
ExecStart=/usr/sbin/varnishd -a :6081,PROXY -f /etc/varnish/default.vcl -s malloc,256m
[root@host ~]# systemctl daemon-reload
[root@host ~]# systemctl restart varnish
4. 监控和管理HAProxy
HAProxy提供了一个HTML统计报表页面。在该页面中,可以检查和监视安装的行为。
默认配置禁用统计报表页面。要激活它,请在frontend部分中添加以下指令。
frontend stat-page
bind *:8080
# 可以创建一个专门的frontend部分,并在一个特定的端口上监听统计报告页面。也可以使用现有的frontend部分。
stats enable
# stats enable指令激活统计报表页面。
stats uri /haproxystats
# 默认情况下,使用/haproxy?stats的URL路径。可以使用stats uri指令更改该默认路径。在本例中,使用http://www.example.com:8080/haproxystats URL访问该页面。
stats auth operator1:redhat123
# 因为统计数据报告页面提供了关于您的配置的信息,所以使用stats auth指令使用登录名和密码来保护它。
stats admin if TRUE
# 默认情况下,统计报表页面是只读的。通过激活管理模式,您还可以直接从web界面禁用和启用后端web服务器。
HAProxy还创建/var/lib/haproxy/stats UNIX套接字。监视和报告工具,如Performance Co-Pilot (PCP),使用该套接字来检索HAProxy守护进程的状态并收集统计信息。在管理模式下,管理工具(如Ansible)可以禁用和启用后端web服务器。
/etc/haproxy/haproxy.cfg 配置文件在 global 部分下定义UNIX socket。若要激活 admin 模式,将 level admin 选项添加到 stats socket 指令中。
global
...output omitted...
# turn on stats unix socket
stats socket /var/lib/haproxy/stats level admin
...output omitted...
参考文档:/usr/share/doc/haproxy/configuration.txt
5. 课本练习
[student@workstation ~]$ lab optimizeweb-haproxy start
-
该命令在serverc和serverd上安装Apache HTTP Server,并部署测试web页面。该命令还生成一个SSL证书及其关联的私钥servera.lab.example.com。
-
在本练习中,将HAProxy部署在servera上,在serverc和serverd上运行的两个web服务器之间分配web流量。还可以将HAProxy配置为HTTPS终止程序。
下图显示客户端系统使用HTTPS通过HAProxy访问web内容。然后HAProxy使用HTTP从后端web服务器访问内容。
1. 安装haproxy包。
[root@servera ~]# yum -y install haproxy
2. 配置HAProxy HTTPS终止程序。
[root@servera ~]# mkdir /etc/pki/haproxy
[root@servera ~]# chmod 700 /etc/pki/haproxy
[root@servera ~]# cd optimizeweb-haproxy
[root@servera optimizeweb-haproxy]# ls
servera.lab.example.com.crt servera.lab.example.com.key
[root@servera optimizeweb-haproxy]# cat servera.lab.example.com.crt \
servera.lab.example.com.key > /etc/pki/haproxy/haproxy.pem
3. 在HAProxy配置文件中,添加一个frontend部分接受HTTPS(端口443)连接。
使用/etc/pki/haproxy/haproxy.pem作为HTTPS终止的SSL证书文件。声明两个后端web服务器。
-
编辑/etc/haproxy/haproxy.cfg配置文件。只保留global部分和defaults部分。删除所有现有的frontend和backend部分。
-
在文件的末尾,添加一个名为http-proxy的前端部分。在该部分中,侦听端口443,并使用/etc/pki/haproxy/haproxy.pem SSL文件。将HTTP X-Forwarded-proto头添加到所有传入请求中,让后端web服务器知道客户端使用HTTPS。将http-proxy前端部分与教室-web-farm后端部分相关联。
-
在名为classroom-web-farm的backend部分中声明两个后端web服务器。使用rounddrobin负载均衡算法,每秒钟检查一次后端web服务器的健康状况。
[root@servera ~]# vim /etc/haproxy/haproxy.cfg
frontend http-proxy
bind *:443 ssl crt /etc/pki/haproxy/haproxy.pem
http-request add-header X-Forwarded-Proto https
default_backend classroom-web-farm
backend classroom-web-farm
balance roundrobin
server serverc.lab.example.com 172.25.250.12:80 check inter 1s
server serverd.lab.example.com 172.25.250.13:80 check inter 1s
4. 开启并启动haproxy服务并打开防火墙端口。
[root@servera optimizeweb-haproxy]# systemctl enable --now haproxy
Created symlink /etc/systemd/system/multi-user.target.wants/haproxy.service → /usr/lib/systemd/system/haproxy.service.
[root@servera optimizeweb-haproxy]# systemctl status haproxy
● haproxy.service - HAProxy Load Balancer
Loaded: loaded (/usr/lib/systemd/system/haproxy.service; enabled; vendor preset: disabled)
Active: active (running) since Wed 2021-06-30 17:24:29 CST; 5s ago
Process: 2098 ExecStartPre=/usr/sbin/haproxy -f $CONFIG -c -q (code=exited, status=0/SUCCESS)
Main PID: 2100 (haproxy)
Tasks: 2 (limit: 11251)
Memory: 7.1M
CGroup: /system.slice/haproxy.service
├─2100 /usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid
└─2101 /usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid
[root@servera optimizeweb-haproxy]# firewall-cmd --permanent --add-service=https
success
[root@servera optimizeweb-haproxy]# firewall-cmd --reload
success
5. 验证配置与测试。
[student@workstation ~]$ curl --cacert cacert.pem https://servera.lab.example.com/
This is serverc
[student@workstation ~]$ curl --cacert cacert.pem https://servera.lab.example.com/
This is serverd
[student@workstation ~]$ curl --cacert cacert.pem https://servera.lab.example.com/
This is serverc
[student@workstation ~]$ curl --cacert cacert.pem https://servera.lab.example.com/
This is serverd
6. 配置HAProxy将来自客户端的HTTP(80)流量重定向为使用HTTPS(443)。
[root@servera optimizeweb-haproxy]# firewall-cmd --permanent --add-service=http
success
[root@servera optimizeweb-haproxy]# firewall-cmd --reload
success
[student@workstation ~]$ curl http://servera.lab.example.com/
curl: (7) Failed to connect to servera.lab.example.com port 80: Connection refused
[root@servera ~]# vim /etc/haproxy/haproxy.cfg
frontend http-proxy
bind *:443 ssl crt /etc/pki/haproxy/haproxy.pem
bind *:80
redirect scheme https if !{
ssl_fc }
http-request add-header X-Forwarded-Proto https
default_backend classroom-web-farm
[root@servera ]# systemctl restart haproxy
[student@workstation ~]$ curl -I http://servera.lab.example.com/
HTTP/1.1 302 Found
Cache-Control: no-cache
Content-length: 0
Location: https://servera.lab.example.com/
7. 激活统计报告页面监控HAProxy部署的状态。
因为该页面会显示HAProxy配置中的敏感信息,所以请使用operator1用户名和redhat123密码保护它
![7](F:/7.jpg)[root@servera ~]# vim /etc/haproxy/haproxy.cfg
frontend http-proxy
bind *:443 ssl crt /etc/pki/haproxy/haproxy.pem
bind *:80
redirect scheme https if !{
ssl_fc }
http-request add-header X-Forwarded-Proto https
default_backend classroom-web-farm
stats enable
stats auth operator1:redhat123
[root@servera ]# systemctl restart haproxy
浏览器访问:
https://servera.lab.example.com/haproxy?stats
完成实验
[student@workstation ~]$ lab optimizeweb-haproxy finish
总结
- 介绍HAProxy。
- 介绍如何部署和设置HAProxy。
- 演示如何在Varnish在配置HAProxy进行流控。
- 若喜欢金鱼哥的文章,顺手点个赞。也可点个关注,因为后续会不断上干货。