HAProxy的四層與七層的區別及透傳IP實戰案例【轉】
阿新 • • 發佈:2020-08-11
一.HAProxy在四層的工作原理
在四層負載裝置中,把client傳送的報文目標地址(原來是負載均衡裝置的IP地址),根據均衡裝置設定的選擇web伺服器的規則選擇對應的web伺服器IP地址,這樣client就可以直接跟此伺服器建立TCP連線併發送資料。
我們其實可以把haproxy在四層的工作流程分為兩個階段:
第一階段:
client傳送http請求報文到haproxy,haproxy由於工作在第四層,因此通過拆包可以檢視到TCP/IP包頭資訊,haproxy根據定義的規則將client請求的目標地址修改為後端的web伺服器的IP地址,與此同時還將源地址修改為haproxy的IP地址並轉發給後端的web伺服器。第二階段:
後端的web伺服器將響應的結果封裝成響應報文傳送給haproxy伺服器後,haproxy再將報文的源地址修改為haproxy的IP地址,目標地址修改為client的IP地址並轉發給client。
二.HAProxy在七層的工作原理
七層負載均衡伺服器起了一個代理伺服器的作用,伺服器建立一次TCP連線要三次握手,而client要訪問webserver要先與七層負載裝置進行三次握手後建立TCP連線,把要訪問的報文資訊傳送給七層負載均衡;然後七層負載均衡再根據設定的均衡規則選擇特定的webserver,然後通過三次握手與此臺webserver建立TCP連線,然後webserver把需要的資料傳送給七層負載均衡裝置,負載均衡裝置再把資料傳送給client;所以,七層負載均衡裝置起到了代理伺服器的作用。 我們其實可以把haproxy在七層的工作流程分為四個階段: 第一階段: client傳送http請求報文到haproxy,haproxy接收到client的http請求報文後,會檢視client的請求報文,根據http請求報文的資訊在結合haproxy自身定義的規則判斷出client要訪問後端的web伺服器; 第二階段: haproxy根據client的請求報文判斷要訪問的後端的web伺服器後,會代替客戶端的重新發起http請求報文到後端的web伺服器; 第三階段: 後端的web伺服器接收到haproxy的http請求報文後,如果訪問的資源存在且許可權允許的話會將haproxy請求的資源封裝成響應報文併發送給haproxy伺服器; 第四階段: haproxy接收到web伺服器的響應報文後,haproxy將後端web伺服器返回的結果封裝成響應報文併發送給client。
三.HAProxy的四層與七層的區別
如上圖所示,HAProxy的四層與七層的主要區別就在於是否重新發起了http請求,如果重新發來http請求則說明工作在第七層,若沒有重新發起http請求則說明haproxy工作在第四次。
這也就是為什麼HAProxy在反向代理MySQL,Redis,RDP等服務時需要特別指定mode為TCP模式的主要原因,因為工作在七層會重新發起http請求,而重新發起的http請求MySQL,Redis,RDP等服務壓根就不認識,因為這些服務都有著自己預設的協議。
四.七層(基於http)負載實現IP透傳案例
1>.nginx伺服器端配置
[[email protected] ~]# cat /yinzhengjie/softwares/nginx/conf/nginx.conf #編輯nginx的主配置檔案
worker_processes 4;
worker_cpu_affinity 00000001 00000010 00000100 00001000;
events {
worker_connections 100000;
use epoll;
accept_mutex on;
multi_accept on;
}
http {
include mime.types;
default_type text/html;
server_tokens off;
charset utf-8;
log_format my_access_json '{"@timestamp":"$time_iso8601",'
'"host":"$server_addr",'
'"clientip":"$remote_addr",'
'"size":$body_bytes_sent,'
'"responsetime":$request_time,'
'"upstreamtime":"$upstream_response_time",'
'"upstreamhost":"$upstream_addr",'
'"http_host":"$host",'
'"uri":"$uri",'
'"domain":"$host",'
'"xff":"$http_x_forwarded_for",'
'"referer":"$http_referer",'
'"tcp_xff":"$proxy_protocol_addr",'
'"http_user_agent":"$http_user_agent",'
'"status":"$status"}';
access_log logs/access_json.log my_access_json;
ssl_certificate /yinzhengjie/softwares/nginx/certs/www.yinzhengjie.org.cn.crt;
ssl_certificate_key /yinzhengjie/softwares/nginx/certs/www.yinzhengjie.org.cn.key;
ssl_session_cache shared:sslcache:20m;
ssl_session_timeout 10m;
include /yinzhengjie/softwares/nginx/conf.d/*.conf;
}
[[email protected] ~]#
[[email protected] ~]# nginx -t
nginx: the configuration file /yinzhengjie/softwares/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /yinzhengjie/softwares/nginx/conf/nginx.conf test is successful
[[email protected] ~]#
[[email protected] ~]#
[[email protected] ~]# cat /yinzhengjie/softwares/nginx/conf.d/node101_yinzhengjie_org.cn.conf #編輯nginx的子配置檔案
server {
listen 80;
listen 443 ssl;
server_name node101.yinzhengjie.org.cn;
access_log /yinzhengjie/softwares/nginx/logs/node101_yinzhengjie_org_cn_access.log my_access_json;
error_log /yinzhengjie/softwares/nginx/logs/node101_yinzhengjie_org_cn_error.log;
location / {
root /yinzhengjie/data/web/nginx;
index index.html;
}
location = /favicon.ico {
root /yinzhengjie/data/web/nginx/images/jd;
}
location ~ \.php$ {
#"$document_root"會呼叫root目錄,若不寫root指令對應的目錄路徑,則"$document_root"所對應的值為空.
#root /yinzhengjie/data/web/php;
#指定PHP伺服器地址
fastcgi_pass 172.30.1.106:9000;
fastcgi_index index.php;
#fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
#如果"SCRIPT_FILENAME"後面是絕對路徑則可以省略上面的"root /data/nginx/php;"
fastcgi_param SCRIPT_FILENAME /yinzhengjie/data/web/php$fastcgi_script_name;
#千萬別忘記新增改行,若不新增"include fastcgi_params;"儘管上面配置的都正確,nginx也無法將fastcgi程式的處理結果返回給瀏覽器,返回給瀏覽器的只能是一個零位元組的檔案。
include fastcgi_params;
}
}
[[email protected] ~]#
[[email protected] ~]# nginx -t
nginx: the configuration file /yinzhengjie/softwares/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /yinzhengjie/softwares/nginx/conf/nginx.conf test is successful
[[email protected] ~]#
[[email protected] ~]# ss -ntl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:22 *:*
LISTEN 0 128 :::22 :::*
[[email protected] ~]#
[[email protected] ~]# nginx #啟動nginx服務
[[email protected] ~]#
[[email protected] ~]# ss -ntl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:80 *:*
LISTEN 0 128 *:22 *:*
LISTEN 0 128 *:443 *:*
LISTEN 0 128 :::22 :::*
[[email protected] ~]#
2>.使用瀏覽器直接訪問nginx伺服器地址("http://node101.yinzhengjie.org.cn/")
[[email protected] ~]# >/yinzhengjie/softwares/nginx/logs/node101_yinzhengjie_org_cn_access.log #為了便於觀測,我將之前日誌清空。
[[email protected] ~]#
[[email protected] ~]# tail -10f /yinzhengjie/softwares/nginx/logs/node101_yinzhengjie_org_cn_access.log #觀察訪問日誌
{"@timestamp":"2020-01-03T21:50:46+08:00","host":"172.30.1.101","clientip":"172.30.1.254","size":0,"responsetime":0.000,"upstreamtime":"
-","upstreamhost":"-","http_host":"node101.yinzhengjie.org.cn","uri":"/index.html","domain":"node101.yinzhengjie.org.cn","xff":"-","refe
rer":"-","tcp_xff":"","http_user_agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.39
45.88 Safari/537.36","status":"304"}
{"@timestamp":"2020-01-03T21:50:46+08:00","host":"172.30.1.101","clientip":"172.30.1.254","size":25214,"responsetime":0.000,"upstreamtim
e":"-","upstreamhost":"-","http_host":"node101.yinzhengjie.org.cn","uri":"/favicon.ico","domain":"node101.yinzhengjie.org.cn","xff":"-",
"referer":"http://node101.yinzhengjie.org.cn/","tcp_xff":"","http_user_agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537
.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36","status":"200"}
3>.編輯haproxy伺服器的配置檔案
[[email protected] ~]# cat /etc/haproxy/haproxy.cfg #使用haproxy配置反向代理nginx
global
maxconn 100000
chroot /yinzhengjie/softwares/haproxy
#如果需要使用動態排程演算法需要將socket功能開啟
stats socket /yinzhengjie/softwares/haproxy/haproxy.sock mode 600 level admin
user haproxy
group haproxy
daemon
nbproc 2
cpu-map 1 0
cpu-map 2 1
nbthread 2
pidfile /yinzhengjie/softwares/haproxy/haproxy.pid
log 127.0.0.1 local5 info
defaults
option http-keep-alive
option forwardfor
option redispatch
option abortonclose
maxconn 100000
mode http
timeout connect 300000ms
timeout client 300000ms
timeout server 300000ms
listen stats
mode http
bind 0.0.0.0:9999
stats enable
log global
stats uri /haproxy-status
stats auth haadmin:q1w2e3r4ys
listen WEB_PORT_80
bind 172.30.1.102:80
mode http
server web01 172.30.1.101:80 check inter 3000 fall 3 rise 5
[[email protected] ~]#
[[email protected] ~]#
[[email protected] ~]# systemctl restart haproxy #別忘記重啟haproxy使配置生效。
[[email protected] ~]#
4>.使用瀏覽器直接訪問haproxy伺服器地址("http://node102.yinzhengjie.org.cn/")
[[email protected] ~]# >/yinzhengjie/softwares/nginx/logs/node101_yinzhengjie_org_cn_access.log
[[email protected] ~]#
[[email protected] ~]# tail -10f /yinzhengjie/softwares/nginx/logs/node101_yinzhengjie_org_cn_access.log
{"@timestamp":"2020-01-03T22:08:44+08:00","host":"172.30.1.101","clientip":"172.30.1.102","size":0,"responsetime":0.000,"upstreamtime":"-","upstream
host":"-","http_host":"node102.yinzhengjie.org.cn","uri":"/index.html","domain":"node102.yinzhengjie.org.cn","xff":"172.30.1.254","referer":"-","tcp
_xff":"","http_user_agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36","sta
tus":"304"}
五.四層負載實現IP透傳案例
1>.修改nginx的主配置檔案(標紅色的引數必須的配置)
[[email protected] ~]# cat /yinzhengjie/softwares/nginx/conf/nginx.conf
worker_processes 4;
worker_cpu_affinity 00000001 00000010 00000100 00001000;
events {
worker_connections 100000;
use epoll;
accept_mutex on;
multi_accept on;
}
http {
include mime.types;
default_type text/html;
server_tokens off;
charset utf-8;
log_format my_access_json '{"@timestamp":"$time_iso8601",'
'"host":"$server_addr",'
'"clientip":"$remote_addr",'
'"size":$body_bytes_sent,'
'"responsetime":$request_time,'
'"upstreamtime":"$upstream_response_time",'
'"upstreamhost":"$upstream_addr",'
'"http_host":"$host",'
'"uri":"$uri",'
'"domain":"$host",'
'"xff":"$http_x_forwarded_for",'
'"referer":"$http_referer",'
'"tcp_xff":"$proxy_protocol_addr",'
'"http_user_agent":"$http_user_agent",'
'"status":"$status"}';
access_log logs/access_json.log my_access_json;
ssl_certificate /yinzhengjie/softwares/nginx/certs/www.yinzhengjie.org.cn.crt;
ssl_certificate_key /yinzhengjie/softwares/nginx/certs/www.yinzhengjie.org.cn.key;
ssl_session_cache shared:sslcache:20m;
ssl_session_timeout 10m;
include /yinzhengjie/softwares/nginx/conf.d/*.conf;
}
[[email protected] ~]#
[[email protected] ~]#
[[email protected] ~]# nginx -t
nginx: the configuration file /yinzhengjie/softwares/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /yinzhengjie/softwares/nginx/conf/nginx.conf test is successful
[[email protected] ~]#
2>.修改nginx的子配置檔案(標紅色的引數必須的配置)
[[email protected] ~]# cat /yinzhengjie/softwares/nginx/conf.d/node101_yinzhengjie_org.cn.conf
server {
listen 80 proxy_protocol;
listen 443 ssl;
server_name node101.yinzhengjie.org.cn;
access_log /yinzhengjie/softwares/nginx/logs/node101_yinzhengjie_org_cn_access.log my_access_json;
error_log /yinzhengjie/softwares/nginx/logs/node101_yinzhengjie_org_cn_error.log;
location / {
root /yinzhengjie/data/web/nginx;
index index.html;
}
location = /favicon.ico {
root /yinzhengjie/data/web/nginx/images/jd;
}
}
[[email protected] ~]#
[[email protected] ~]# nginx -t
nginx: the configuration file /yinzhengjie/softwares/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /yinzhengjie/softwares/nginx/conf/nginx.conf test is successful
[[email protected] ~]#
3>.重新載入nginx的配置檔案
[[email protected] ~]# ps -ef | grep nginx | grep -v grep
root 2825 1 0 21:43 ? 00:00:00 nginx: master process nginx
nginx 2984 2825 0 22:24 ? 00:00:00 nginx: worker process
nginx 2985 2825 0 22:24 ? 00:00:00 nginx: worker process
nginx 2986 2825 0 22:24 ? 00:00:00 nginx: worker process
nginx 2987 2825 0 22:24 ? 00:00:00 nginx: worker process
[[email protected] ~]#
[[email protected] ~]# nginx -s reload
[[email protected] ~]#
[[email protected] ~]# ps -ef | grep nginx | grep -v grep
root 2825 1 0 21:43 ? 00:00:00 nginx: master process nginx
nginx 3025 2825 7 22:26 ? 00:00:00 nginx: worker process
nginx 3026 2825 7 22:26 ? 00:00:00 nginx: worker process
nginx 3027 2825 10 22:26 ? 00:00:00 nginx: worker process
nginx 3028 2825 11 22:26 ? 00:00:00 nginx: worker process
[[email protected] ~]#
[[email protected] ~]#
4>.編輯haproxy的配置檔案(標紅色的引數必須的配置)
[[email protected] ~]# cat /etc/haproxy/haproxy.cfg
global
maxconn 100000
chroot /yinzhengjie/softwares/haproxy
#如果需要使用動態排程演算法需要將socket功能開啟
stats socket /yinzhengjie/softwares/haproxy/haproxy.sock mode 600 level admin
user haproxy
group haproxy
daemon
nbproc 2
cpu-map 1 0
cpu-map 2 1
nbthread 2
pidfile /yinzhengjie/softwares/haproxy/haproxy.pid
log 127.0.0.1 local5 info
defaults
option http-keep-alive
option forwardfor
option redispatch
option abortonclose
maxconn 100000
mode http
timeout connect 300000ms
timeout client 300000ms
timeout server 300000ms
listen stats
mode http
bind 0.0.0.0:9999
stats enable
log global
stats uri /haproxy-status
stats auth haadmin:q1w2e3r4ys
listen WEB_PORT_80
bind 172.30.1.102:80
mode tcp
server web01 172.30.1.101:80 send-proxy check inter 3000 fall 3 rise 5
[[email protected] ~]#
[[email protected] ~]# systemctl restart haproxy #別忘記重啟haproxy使配置生效。
[[email protected] ~]#
5>.使用瀏覽器直接訪問haproxy伺服器地址("http://node102.yinzhengjie.org.cn/")
[[email protected] ~]#
[[email protected] ~]# >/yinzhengjie/softwares/nginx/logs/node101_yinzhengjie_org_cn_access.log
[[email protected] ~]#
[[email protected] ~]# tail -10f /yinzhengjie/softwares/nginx/logs/node101_yinzhengjie_org_cn_access.log
{"@timestamp":"2020-01-03T22:30:36+08:00","host":"172.30.1.101","clientip":"172.30.1.102","size":0,"responsetime":0.000,"upstreamtime":"-",
"upstreamhost":"-","http_host":"node102.yinzhengjie.org.cn","uri":"/index.html","domain":"node102.yinzhengjie.org.cn","xff":"-","referer":"
-","tcp_xff":"172.30.1.254","http_user_agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0
.3945.88 Safari/537.36","status":"304"}
轉自 尹正傑部落格
HAProxy的四層與七層的區別及透傳IP實戰案例 - 尹正傑 - 部落格園 https://www.cnblogs.com/yinzhengjie/p/12127959.html