最近在维护一套 Rancher 环境时,遇到了一个棘手的问题:用户无法在 Rancher UI 中查看容器日志,页面一直加载失败,浏览器控制台报错 WebSocket connection failed。经过一番排查,最终定位到问题出在两层 Nginx 反向代理的 WebSocket 支持配置上。本文将详细记录这个问题的排查过程、根本原因以及解决方案,希望能帮助遇到类似问题的同行。

一、问题现象

在 Rancher 管理界面中,点击某个 Pod 的“查看日志”按钮后,页面长时间显示“加载中”,随后提示连接失败。打开浏览器开发者工具(F12),在 Network 标签中看到 WebSocket 请求状态为失败,具体错误信息类似:

text

WebSocket connection to 'wss://test.klg.cofco.com/v3/subscribe?sockId=2' failed:

二、环境架构

我们的网络拓扑如下:

  • 域名 xxxx.com 解析到一台公网服务器 194(有公网 IP)。

  • 194 服务器 上运行 Nginx,配置了 SSL 证书,对外提供 HTTPS 服务。

  • 194 服务器 将请求反向代理到内网服务器 170(无公网 IP)。

  • 170 服务器 上同样运行 Nginx,再将请求转发到 Rancher 的 NodePort 端口 https://xxx:31043

即:客户端 → 194(SSL) → 170(内网代理) → Rancher NodePort

三、排查过程

1. 初步判断 WebSocket 握手失败

浏览器报错明确指向 WebSocket 连接失败,而 Rancher 的日志查看和终端功能均依赖 WebSocket 长连接。因此,问题很可能出在 WebSocket 握手环节。

2. 检查后端 Rancher 是否正常

在 170 服务器上直接使用 curl 测试 Rancher NodePort 是否支持 WebSocket:

bash

curl -k https://xxxx:31043/v3/subscribe? -H "Upgrade: websocket" -H "Connection: Upgrade" -v

返回 101 Switching Protocols,说明 Rancher 后端本身是正常的。

3. 检查 170 服务器 Nginx 配置

查看 170 的 Nginx 配置,发现已正确添加 WebSocket 所需头部:

nginx

proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

并且设置了较长的超时时间和关闭缓冲,看起来没有问题。

4. 检查 194 服务器 Nginx 配置

最终在 194 的 Nginx 配置中发现了问题所在。关键配置片段如下:

nginx

location / {
    proxy_http_version 1.1;
    proxy_set_header Connection "Keep-Alive";   # ❌ 固定为 Keep-Alive
    # 缺少 proxy_set_header Upgrade $http_upgrade;
    ...
}
  • 缺少 Upgrade 头传递:WebSocket 握手需要客户端发送 Upgrade: websocket,Nginx 必须通过 proxy_set_header Upgrade $http_upgrade; 将此头部转发给后端。

  • Connection 头被硬编码为 Keep-Alive:即使客户端发送 Connection: Upgrade,Nginx 转发时也会强制改为 Keep-Alive,导致后端无法识别这是一个 WebSocket 升级请求。

因此,当客户端发起 WebSocket 连接时,194 服务器根本没有将升级请求传递给 170 服务器,握手自然失败。

四、解决方案

修改 194 服务器 Nginx 配置

在 location / 中添加 WebSocket 支持,并移除冲突的 Connection 设置:

nginx

location / {
    proxy_http_version 1.1;
    # 传递 WebSocket 握手头部
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";

    # 删除或注释掉原来的 proxy_set_header Connection "Keep-Alive";
    # proxy_set_header Connection "Keep-Alive";

    # 其他原有配置保留(根据需要可调整超时等)
    proxy_next_upstream http_502 http_504 error timeout invalid_header;
    proxy_redirect off;
    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_connect_timeout 600;
    proxy_read_timeout 600;
    proxy_send_timeout 600;
    client_max_body_size 300m;
    proxy_pass http://xxx;   # upstream 指向 170 服务器

    # 可选:关闭缓冲,提升日志实时性
    proxy_buffering off;
}

重载 Nginx

在两台服务器上分别执行:

bash

sudo nginx -t && sudo nginx -s reload

验证

再次访问 Rancher 并尝试查看日志,打开浏览器开发者工具,查看 WebSocket 请求状态码应为 101 Switching Protocols,日志页面正常显示。

五、其他注意事项

即使 WebSocket 代理配置正确,以下因素也可能导致日志无法显示,建议一并检查:

  1. 服务器时钟同步
    Rancher 的 WebSocket 认证依赖 JWT,若 Rancher Server 与集群节点时间差超过 5 分钟,会导致连接被拒绝。确保所有相关服务器(包括代理服务器和 Rancher 节点)已配置 NTP 同步。

  2. 容器日志驱动
    确保容器运行时使用 json-file 日志驱动(Kubernetes 默认要求),否则 kubectl logs 可能无法读取。

  3. 节点 Kubelet 健康状态
    在集群节点上执行 kubectl logs <pod-name> 测试,若无法获取日志,需检查 Kubelet 服务是否正常。

  4. 防火墙/安全组
    确保代理服务器之间的端口(如 194→170 的 80 端口,170→Rancher NodePort 的端口)已放行。

六、总结

本次 Rancher 无法查看日志的问题,根本原因是 第一层 Nginx 代理未正确支持 WebSocket 协议,导致握手失败。在多级代理架构中,每一层都必须正确传递 Upgrade 和 Connection 头部,并确保超时设置足够长,以维持长连接。

希望通过本文的分享,能帮助大家在遇到类似 Rancher UI 功能异常时,快速定位到代理层配置问题,避免在错误的方向上花费过多时间。


彩蛋
如果使用 K3s 部署 Rancher,也可以尝试直接使用 Traefik Ingress 替代手动配置 Nginx,但生产环境仍需根据实际情况选择。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐