ip_hash实现会话保持需确保nginx获取真实客户端ip并在upstream首行配置,不支持weight/backup;docker中须用自定义bridge网络、透传x-real-ip头,并避免$remote_addr为网关地址。

在 Docker 容器集群中使用 Nginx 的 ip_hash 实现会话保持,关键在于确保 Nginx 能正确获取客户端真实 IP,并在 upstream 块中启用哈希策略。宝塔面板 + Docker 环境下需特别注意容器网络模式和代理头传递。
ip_hash 作用与适用场景
ip_hash 是一种会话保持机制:对客户端 IP 做哈希运算,固定分配到某台后端服务器。适合有登录态、本地缓存或状态依赖的应用(如 PHP Session 未集中存储时)。但要注意——它不解决 IP 集群(如用户走 NAT 或代理)导致的哈希倾斜问题。
Docker 环境下的 ip_hash 配置要点
必须满足两个前提:Nginx 要拿到真实客户端 IP;后端容器能被稳定寻址。常见坑是默认使用 bridge 网络时,$remote_addr 变成 Docker 网关地址(如 172.18.0.1),导致所有请求哈希到同一台后端。
- 用自定义 bridge 网络并开启
enable_ipv6: false,避免 IPv6 干扰哈希结果 - 启动 Nginx 容器时加
--network=your_net,确保与后端容器同网段 - 在 Nginx 配置中显式设置
proxy_set_header X-Real-IP $remote_addr,但ip_hash本身只认$remote_addr,所以重点是让这个变量等于真实 IP - 若前端有云 WAF 或 CDN,需在宝塔或 Nginx 中配置
set_real_ip_from+real_ip_header X-Forwarded-For,否则$remote_addr仍是代理 IP
实际配置示例(宝塔 + Docker)
假设你已用宝塔创建 Nginx 容器,并挂载了自定义配置文件 /www/wwwroot/loadbalance.conf:
在 Linux 上通过 Docker 运行 OpenClaw,并使用 Tailscale 实现远程访问。⚠️ 涉及 sudo、Docker、Tailscale和凭证挂载——请先查阅安全章节...
upstream backend {
ip_hash; # 启用 IP 哈希,必须放在 server 列表上方
server backend-app1:80;
server backend-app2:80;
server backend-app3:80;
}
<p>server {
listen 80;
location / {
proxy_pass <a href="https://www.php.cn/link/65b5b8d1f89bf53a5713bc3afdd83e9e">https://www.php.cn/link/65b5b8d1f89bf53a5713bc3afdd83e9e</a>;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}</p>
⚠️ 注意:ip_hash 不支持 backup 或 weight 参数,加了会报错;若某台后端宕机,Nginx 会自动跳过,但哈希槽位不变,可能造成部分 IP 请求失败——建议搭配健康检查(max_fails=2 fail_timeout=30s)使用。
验证是否生效
从同一台客户端机器连续发起请求(比如用 curl 循环 5 次),观察后端 access.log 中的访问 IP 是否始终落在同一台容器上:
- 成功表现:5 次请求日志都来自同一个容器 IP(如 172.18.0.3)
- 失败常见原因:
$remote_addr显示为 172.18.0.1(Docker 网关)、配置未重载、用了 HTTPS 但没透传头信息、浏览器开了多个标签页触发不同连接复用
不复杂但容易忽略。










