Hetzner Cloud Kubernetes集群Neo4j Bolt连接故障排查求助
问题概述
在Hetzner Cloud上部署了与Azure AKS配置一致的K8s集群,部署Neo4j后出现以下问题:
- 可通过Ingress路径访问Neo4j浏览器,但无法通过
bolt+s://server.mydomain.com:7687连接Neo4j服务器,握手失败 - 浏览器调试日志显示Bolt加密/未加密握手均失败,Chrome控制台报错:
Mixed Content: The page at 'https://server.mydomain.com/neo4j/browser/' was loaded over HTTPS, but requested an insecure resource 'http://server.mydomain.com:7687/'. This request has been blocked; the content must be served over HTTPS.
WebSocket connection to 'wss://server.mydomain.com:7687/' failed:
更新信息:
- 移除
load-balancer.hetzner.cloud/hostname注解后,Node.js后端Pod可正常连接Neo4j,但浏览器仍报混合内容及WebSocket错误 - 不加该注解会导致Let's Encrypt证书签发卡住,添加后证书可正常生成
核心配置差异(Ingress-Nginx Helm配置)
nginx: controller: watchIngressWithoutClass: true kind: DaemonSet config: use-forwarded-headers: "true" compute-full-forwarded-for: "true" use-proxy-protocol: "true" service: annotations: load-balancer.hetzner.cloud/name: server-lb load-balancer.hetzner.cloud/use-private-ip: "true" load-balancer.hetzner.cloud/disable-private-ingress: "true" load-balancer.hetzner.cloud/location: fsn1 load-balancer.hetzner.cloud/type: lb11 load-balancer.hetzner.cloud/uses-proxyprotocol: "true" load-balancer.hetzner.cloud/http-redirect-https: "true" load-balancer.hetzner.cloud/hostname: server.mydomain.com # nginx.ingress.kubernetes.io/websocket-services: neo4j extraArgs: default-ssl-certificate: "default/tls-secret" # nodeSelector: # server-type: server tcp: 7687: "default/neo4j:7687" 7474: "default/neo4j:7474"
排查与修复步骤
1. 解决混合内容错误
Chrome报错显示浏览器从HTTPS页面发起了HTTP请求到7687端口,这是因为Neo4j浏览器默认生成的Bolt连接地址使用了HTTP协议。需要调整Neo4j配置,让其告知浏览器使用HTTPS对应的WebSocket(WSS):
- 在Neo4j Helm values中设置:
这样Neo4j浏览器会生成neo4j: config: dbms.connector.bolt.advertised_address: "server.mydomain.com:7687" dbms.connector.bolt.tls_level: "REQUIRED" dbms.connector.http.advertised_address: "https://server.mydomain.com/neo4j" dbms.connector.https.advertised_address: "https://server.mydomain.com/neo4j"wss://server.mydomain.com:7687的连接地址,避免混合内容问题。
2. 确保TCP端口7687的SSL终止
当前Nginx Ingress的TCP转发是明文的,而浏览器用WSS连接需要SSL加密,可选择以下两种方案:
方案A:让Hetzner LB终止7687端口的SSL
- 在Hetzner Cloud控制台找到对应负载均衡器,添加TCP端口7687转发规则:
- 外部端口:7687,内部端口:7687
- 启用SSL终止,选择已有的Let's Encrypt证书(或关联域名自动生成)
- 启用Proxy Protocol(与Nginx配置匹配)
- 保持现有Nginx Ingress的TCP配置不变即可。
方案B:让Nginx Ingress终止7687端口的SSL
- 修改Nginx Ingress的TCP配置,为7687端口指定SSL相关参数:
依赖已配置的nginx: tcp: 7687: "default/neo4j:7687" controller: config: ssl-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-protocols: "TLSv1.2 TLSv1.3"default-ssl-certificate处理TCP端口的SSL终止。
3. 协调Hetzner LB hostname注解与证书签发
移除load-balancer.hetzner.cloud/hostname注解导致证书签发卡住,是因为Let's Encrypt需要域名解析到LB公网IP。可采取以下方式解决:
- 保留
load-balancer.hetzner.cloud/hostname注解,确保LB自动关联域名解析,同时按步骤2配置7687端口的SSL终止 - 若LB的hostname注解导致TCP端口DNS解析异常,可手动在域名服务商处添加A记录,将
server.mydomain.com指向LB公网IP,再移除load-balancer.hetzner.cloud/hostname注解,既保证证书正常签发,又避免LB自动配置的潜在冲突。
4. 验证Proxy Protocol配置
确保Nginx Ingress和Hetzner LB的Proxy Protocol配置完全一致:
- Nginx已配置
use-proxy-protocol: "true" - Hetzner LB已添加注解
load-balancer.hetzner.cloud/uses-proxyprotocol: "true" - 所有转发端口(80、443、7687、7474)都在LB上启用了Proxy Protocol
内容的提问来源于stack exchange,提问作者Vincenzo

