HAProxy 高级功能
介绍 HAProxy 高级配置及实用案例
HAProxy 四层负载
针对除HTTP以外的TCP协议应用服务访问的应用场景
MySQL
Redis
Memcached
RabbitMQ
问题: 后端服务器到底是与haproxy还是和客户端建立三次握手呢?
四层负载示例
注意:如果使用frontend和backend,一定在 frontend 和 backend 段中都指定mode tcp
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 leastconn server 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@centos6 ~]#mysql -utest -p123456 -e "show variables like 'hostname'"
+---------------+--------------------------+| Variable_name | Value |+---------------+--------------------------+| hostname | centos17.wangxiaochu.com |+---------------+--------------------------+[root@centos6 ~]#mysql -utest -p123456 -e "show variables like 'hostname'"+---------------+--------------------------+| Variable_name | Value |+---------------+--------------------------+| hostname | centos27.wangxiaochu.com |+---------------+--------------------------+[root@centos6 ~]#mysql -utest -p123456 -h10.0.0.7 -e 'select @@server_id'+-------------+| @@server_id |+-------------+|
17 |+-------------+[root@centos6 ~]#mysql -utest -p123456 -h10.0.0.7 -e 'select @@server_id'+-------------+| @@server_id |+-------------+|
27 |+-------------+
ACL示例-四层访问控制
frontend web_hostbind 10.0.0.7:80mode httpbalance roundrobinlog globaloption httplog###################### acl setting ############################### acl static_path path_beg -i /static /images /javascriptacl invalid_src src 192.168.1.0/24 10.0.0.8###################### acl hosts #################################use_backend static_path_host if HTTP_1.1 TRUE static_pathtcp-request connection reject if invalid_src #四层ACL控制 default_backend default_web
################### backend hosts ################################
backend php_server_hostmode httpserver web1 10.0.0.17 check inter 2000 fall 3 rise 5
backend static_path_hostmode httpserver web1 10.0.0.27 check inter 2000 fall 3 rise 5
backend default_webmode httpserver web1 10.0.0.37:80 check inter 2000 fall 3 rise 5
HAProxy Https 实现
haproxy支持https,基于性能考虑,证书是在后端服务器比如nginx上实现,即用户到haproxy利用tcp模式 再到后端服务器
范例: 基于tcp 模式实现
listen web_http bind 192.168.10.100:80redirect scheme https if !{ ssl_fc }mode httplog globalserver web1 10.0.0.8:80 checkserver web2 10.0.0.18:80 check
listen web_httpsbind 192.168.10.100:443mode tcplog globalserver web1 10.0.0.8:443 checkserver web2 10.0.0.18:443 check
Haproxy 可以实现 Https 的证书安全,即从用户到haproxy为https,从haproxy到后端服务器用http通信
#配置HAProxy支持https协议,支持ssl会话;bind *:443 ssl crt /PATH/TO/SOME_PEM_FILE
#指令 crt 后证书文件为PEM格式,需要同时包含证书和所有私钥 cat demo.key demo.crt > demo.pem
#把80端口的请求利用302重向定443bind *:80redirect scheme https if !{ ssl_fc }
#向后端传递用户请求的协议和端口(frontend或backend)http_request set-header X-Forwarded-Port %[dst_port]http_request add-header X-Forwared-Proto https if { ssl_fc }
证书制作
使用方法1
#方法1
[root@haproxy certs]#mkdir /etc/haproxy/certs/
[root@haproxy certs]#cd /etc/haproxy/certs/
[root@haproxy certs]#openssl genrsa -out haproxy.key 2048
[root@haproxy certs]#openssl req -new -x509 -key haproxy.key -out haproxy.crt -subj "/CN=www.web01.com" -days 355
[root@centos7 certs]#cat haproxy.key haproxy.crt > haproxy.pem
[root@centos7 certs]#openssl x509 -in haproxy.pem -noout -text #方法2
[root@centos7 ~]#mkdir /etc/haproxy/certs/
[oot@centos7 ~]#cd /etc/pki/tls/certs
[root@centos7 certs]#make /etc/haproxy/certs/haproxy.pem
umask 77 ; \PEM1=`/bin/mktemp /tmp/openssl.XXXXXX` ; \PEM2=`/bin/mktemp /tmp/openssl.XXXXXX` ; \/usr/bin/openssl req -utf8 -newkey rsa:2048 -keyout $PEM1 -nodes -x509 -days 365 -out $PEM2 ; \cat $PEM1 > /etc/haproxy/certs/haproxy.pem ; \echo ""#查看证书>> /etc/haproxy/certs/haproxy.pem ; \cat $PEM2 >> /etc/haproxy/certs/haproxy.pem ; \rm -f $PEM1 $PEM2Generating a 2048 bit RSA private key.+++..............................................+++writing new private key to '/tmp/openssl.x8hOA8'----
You are about to be asked to enter information that will be incorporatedinto 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 blankFor some fields there will be a default value,If you enter '.', the field will be left blank.----
Country Name (2 letter code) [XX]:CNState or Province Name (full name) []:beijingLocality Name (eg, city) [Default City]:beijingOrganization Name (eg, company) [Default Company Ltd]:wangOrganizational Unit Name (eg, section) []:itCommon Name (eg, your name or your server's hostname) []:www.wang.orgEmail Address []:[root@centos7 certs]#ll /etc/haproxy/certs/total 4-rw------- 1 root root 3027 Apr 4 10:35 haproxy.pem
Https 配置示例
[root@centos7 ~]#cat /etc/haproxy/conf.d/test.cfgfrontend 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 }
# 注意{ }内的空格http-request set-header X-forwarded-Port %[dst_port]http-request add-header X-forwarded-Proto https if { ssl_fc } mode httpbalance roundrobinlog globaloption httplog###################### acl setting ###############################acl mobile_domain hdr_dom(host) -i mobile.wang.org###################### acl hosts #################################default_backend pc_hosts
################### backend hosts #################################backend mobile_hostsmode httpserver web1 10.0.0.17:80 check inter 2000 fall 3 rise 5backend pc_hostsmode http#http-request set-header X-forwarded-Port %[dst_port] 也可加在此处#http-request add-header X-forwarded-Proto https if { ssl_fc } server web2 10.0.0.27:80 check inter 2000 fall 3 rise 5
修改后端服务器的日志格式
[root@centos27 ~]#vim /etc/httpd/conf/httpd.conf
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" \"%{XForwarded-Port}i\" \"%{X-Forwarded-Proto}i\"" combined
验证 Https
[root@master-db ~]#curl -IkL 172.16.1.211
HTTP/1.1 302 Found
content-length: 0
location: https://172.16.1.211/
cache-control: no-cacheHTTP/1.1 200 OK
server: nginx/1.22.1
date: Wed, 13 Nov 2024 15:21:30 GMT
content-type: text/html
content-length: 29
last-modified: Tue, 05 Nov 2024 14:33:04 GMT
etag: "672a2ca0-1d"
accept-ranges: bytes
set-cookie: WEBSRV=web01; path=/
cache-control: private