nginx反向代理+haproxy路由至OpenShift CRC应用故障排查
公网访问CRC应用配置方案
问题根因
所有报错均为七层转发配置不匹配导致,CRC集群、HAProxy本身运行无异常:
- 初始Nginx配置未手动指定Host头,由于你使用变量定义后端地址,Nginx不会自动传递正确的内部域名Host给后端,而你的HAProxy是四层TCP转发模式,工作在传输层不会修改任何HTTP层内容,CRC内置的路由组件收到Host头不匹配的请求时,会默认返回302跳转到内部域名
hello.apps-crc.testing,直接导致浏览器地址被替换。 - 添加
proxy_set_header Host $host;后,传给集群的Host头是公网域名ocp4apps.mydomain.org,但集群内仅配置了内部测试域名的路由规则,无法匹配到对应应用,因此返回应用不存在错误。 - 后续配置Ingress后出现404,是两个问题叠加:一是你配置的路径规则为
/hello,但基础Flask应用默认监听根路径/,请求携带/hello前缀无法匹配应用路由;二是未配置响应内容替换,集群返回的跳转、静态资源链接仍使用内部域名,公网无法正常加载。
方案一:Nginx层全转发配置(无需修改集群资源,最快生效)
不需要调整CRC内的任何路由、Ingress配置,直接在Nginx层完成头传递、域名替换、路径裁剪即可,替换/hello对应的location块为以下内容:
location /hello { set $hello_host hello.apps-crc.testing; # 传递正确的内部域名Host头,确保CRC路由能匹配到测试应用 proxy_set_header Host $hello_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; # 替换后端返回的3xx跳转地址,避免跳转到内部域名 proxy_redirect ~^https?://hello\.apps-crc\.testing(.*)$ https://ocp4apps.mydomain.org$1; # 替换响应正文里的内部域名为公网域名,避免静态资源、接口请求走内部地址 sub_filter 'hello.apps-crc.testing' 'ocp4apps.mydomain.org'; sub_filter_once off; sub_filter_types text/html text/css application/json application/javascript text/plain; # 注意:proxy_pass末尾加斜杠会自动裁剪location匹配的/hello前缀 # 例:公网请求/hello 传给后端的路径是/,正好匹配Flask根路由 # 如果你的Flask应用本身配置了/hello前缀,删掉末尾的斜杠即可 proxy_pass http://$hello_host/; }
配置完成后执行nginx -t验证语法无报错,执行systemctl reload nginx重载配置即可生效。
方案二:集群侧配置公网路由(适合长期使用)
如果不想在Nginx层做内容替换,可以直接在CRC集群内配置公网域名的路由规则,步骤如下:
- 删除之前创建的错误Ingress资源,重新创建正确的Ingress规则:
kind: Ingress apiVersion: networking.k8s.io/v1 metadata: name: overall-project-ingress namespace: overall-project-name spec: # 如需HTTPS可提前将公网域名证书存入对应Secret,测试环境可省略TLS配置 tls: - hosts: - ocp4apps.mydomain.org secretName: ocp4apps-tls rules: - host: ocp4apps.mydomain.org http: paths: - path: / pathType: Prefix backend: service: name: hello-service port: number: 8080
- 修改Nginx的location配置,直接透传公网域名Host头即可,无需额外内容替换:
location /hello { set $crc_haproxy 192.168.2.11; # 直接填HAProxy的监听IP,无需走内部DNS proxy_set_header Host ocp4apps.mydomain.org; 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; # 路径裁剪规则和方案一一致,根据应用实际监听路径决定是否加末尾斜杠 proxy_pass http://$crc_haproxy/; }
同样验证配置语法后重载Nginx即可。
额外说明
- 如果需要透传HTTPS到集群,将
proxy_pass的协议改为https,添加proxy_ssl_server_name on;配置,测试环境可添加proxy_ssl_verify off;跳过内部自签名证书验证。 - 如果配置后仍出现异常跳转,打开浏览器开发者工具查看网络请求的
Location响应头,确认跳转返回的层级后对应调整替换规则即可。
内容的提问来源于stack exchange,提问作者Herr R aus B
相关产品推荐
相关产品推荐

