通过haproxy本地端口随机负载指定范围端口,每30分钟刷新动态端口,通过Haproxy sock直接在内存中动态地修改后端服务器的配置,实现不中断现有连接的平滑端口转发切换。
apt-get instal -y socat
apt-get install -y --no-install-recommends software-properties-common
add-apt-repository ppa:vbernat/haproxy-2.6
apt-get install haproxy=2.6.\*
本地端口34441 随机负载 远程服务器 40000-50000端口
vim /etc/haproxy/haproxy.cfg
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin
stats timeout 30s
user haproxy
group haproxy
daemon
# Default SSL material locations
ca-base /etc/ssl/certs
crt-base /etc/ssl/private
# See: https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.3&config=intermediate
ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
errorfile 400 /etc/haproxy/errors/400.http
errorfile 403 /etc/haproxy/errors/403.http
errorfile 408 /etc/haproxy/errors/408.http
errorfile 500 /etc/haproxy/errors/500.http
errorfile 502 /etc/haproxy/errors/502.http
errorfile 503 /etc/haproxy/errors/503.http
errorfile 504 /etc/haproxy/errors/504.http
listen stats
bind *:8100
mode http
stats enable
stats uri /stats
stats refresh 10s
stats hide-version
http-request use-service prometheus-exporter if { path /metrics }
frontend kr1_frontend
mode tcp
bind *:34441
default_backend kr1_dynamic_backend
backend kr1_dynamic_backend
mode tcp
balance roundrobin
server kr11 kr1.sundayhk.com:40001 check
server kr12 kr1.sundayhk.com:40002 check
server kr13 kr1.sundayhk.com:40003 check
frontend kr2_frontend
mode tcp
bind *:34442
default_backend kr2_dynamic_backend
backend kr2_dynamic_backend
mode tcp
balance roundrobin
server kr21 kr2.sundayhk.com:40001 check
server kr22 kr2.sundayhk.com:40002 check
server kr23 kr2.sundayhk.com:40003 check
vim /data/shell/haproxy_dynamic_port.sh
#!/bin/bash
# HAProxy Runtime API socket path
SOCKET="/run/haproxy/admin.sock"
# Check if HAProxy socket exists
if [ ! -S "$SOCKET" ]; then
echo "Error: HAProxy socket not found at $SOCKET. Make sure HAProxy is running and the socket path is correct."
exit 1
fi
# Define the server configurations in an array
declare -a configs=(
"kr1_dynamic_backend kr1 kr1.sundayhk.com 40000 50000"
"kr2_dynamic_backend kr2 kr2.sundayhk.com 40000 50000"
# 可继续添加
)
# Loop through each configuration to update the backend servers
for config in "${configs[@]}"; do
read -r BACKEND_NAME SERVER_PREFIX TARGET_HOST START_PORT END_PORT <<< "$config"
# Resolve the hostname to an IP address once per backend
TARGET_IP=$(dig +short "$TARGET_HOST" | grep -E '^[0-9.]+$' | head -n 1)
if [ -z "$TARGET_IP" ]; then
echo "Warning: Could not resolve hostname '$TARGET_HOST'. Skipping this backend."
continue
fi
echo "---"
echo "Updating backend '$BACKEND_NAME' at $(date)"
echo "Resolved host '$TARGET_HOST' to IP '$TARGET_IP'"
echo "---"
# Loop through each server (e.g., kr11, kr12, kr13) to update its port
for i in {1..3}; do
SERVER_NAME="${SERVER_PREFIX}${i}"
# --- KEY CHANGE: Generate a new random port for each server ---
RANDOM_PORT=$((RANDOM % (END_PORT - START_PORT + 1) + START_PORT))
echo "Updating server '$SERVER_NAME' to $TARGET_IP:$RANDOM_PORT"
# Disable the old server configuration
echo "disable server $BACKEND_NAME/$SERVER_NAME" | sudo socat - UNIX-CONNECT:$SOCKET
# Set the new server address and port
echo "set server $BACKEND_NAME/$SERVER_NAME addr $TARGET_IP port $RANDOM_PORT" | sudo socat - UNIX-CONNECT:$SOCKET
# Enable the updated server
echo "enable server $BACKEND_NAME/$SERVER_NAME" | sudo socat - UNIX-CONNECT:$SOCKET
done
echo "Successfully updated all servers for backend '$BACKEND_NAME'."
done
echo "All HAProxy backends have been updated."
crontab -e
0,30 * * * * /data/shell/haproxy_dynamic_port.sh >> /var/log/haproxy_dynamic_port.log 2>&1
该脚本不会修改
/etc/haproxy/haproxy.cfg
文件。该配置文件只有手动编辑,并重新加载或重启服务才会发生改变。
该脚本每 30 分钟执行一次,它只在运行时才会改变 HAProxy 后端转发的目标端口。当服务器重启或 HAProxy 服务重启时,它会再次读取 /etc/haproxy/haproxy.cfg
文件,并恢复到haproxy.cfg
文件中定义的初始配置。等到下次定时任务才会执行改变动态端口。
root@gw630:/var/log# echo "show servers state" | sudo socat - UNIX-CONNECT:/run/haproxy/admin.sock
1
# be_id be_name srv_id srv_name srv_addr srv_op_state srv_admin_state srv_uweight srv_iweight srv_time_since_last_change srv_check_status srv_check_result srv_check_health srv_check_state srv_agent_state bk_f_forced_id srv_f_forced_id srv_fqdn srv_port srvrecord srv_use_ssl srv_check_port srv_check_addr srv_agent_addr srv_agent_port
4 kr1_dynamic_backend 1 kr11 119.152.53.17 2 0 1 1 201 6 0 4 7 0 0 0 kr1.sundayhk.com 47498 - 0 0 - - 0
4 kr1_dynamic_backend 2 kr12 119.152.53.17 2 0 1 1 201 6 0 4 7 0 0 0 kr1.sundayhk.com 42370 - 0 0 - - 0
4 kr1_dynamic_backend 3 kr13 119.152.53.17 2 0 1 1 201 6 3 4 6 0 0 0 kr1.sundayhk.com 44408 - 0 0 - - 0
6 kr2_dynamic_backend 1 kr21 153.63.23.38 2 0 1 1 200 6 3 4 6 0 0 0 kr2.sundayhk.com 47379 - 0 0 - - 0
6 kr2_dynamic_backend 2 kr22 153.63.23.38 2 0 1 1 200 6 3 4 6 0 0 0 kr2.sundayhk.com 49693 - 0 0 - - 0
6 kr2_dynamic_backend 3 kr23 153.63.23.38 2 0 1 1 200 6 3 4 6 0 0 0 kr2.sundayhk.com 49866 - 0 0 - - 0