Nginx Ingress路径路由访问应用内页面报404,主机路由运行正常
问题原因
- 核心问题是你的两个后端应用(vote、result)默认基于根路径
/生成内部跳转链接、静态资源引用路径,没有适配路径路由的前缀。
比如你访问http://voteapp.com/vote/打开投票首页后,页面内的跳转链接、资源路径会直接生成/submit、/static/style.css这类绝对路径,浏览器发起请求时会拼接为http://voteapp.com/submit,这个路径无法匹配你ingress中配置的/vote(/|$)(.*)、/result(/|$)(.*)规则,所以直接返回404。
而你切换到基于主机的路由后,两个应用都挂载在对应域名的根路径下,生成的根路径链接正好匹配ingress的默认全路径规则,所以功能完全正常。
验证方法
- 打开浏览器开发者工具(F12)切换到网络面板,点击页面内跳转链接,查看请求的完整URL,确认是否缺失
/vote//result前缀 - 手动请求带前缀的完整路径,比如
http://voteapp.com/vote/[跳转路径],如果可以正常返回,即可确认是链接前缀问题
解决方案
方案1:修改后端应用配置(最推荐)
给vote服务配置上下文路径为/vote,给result服务配置上下文路径为/result,让应用生成所有内部链接、资源路径时自动加上对应前缀,无需调整网关配置即可正常运行。
方案2:通过ingress注入替换规则(无需改应用)
在ingress的annotations中添加sub_filter规则,自动替换返回页面中的根路径链接,适配前缀规则:
apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: voting-app-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: /$2 kubernetes.io/ingress.class: nginx # 新增替换规则,针对两个服务的响应内容做路径替换 nginx.ingress.kubernetes.io/configuration-snippet: | location ~* ^/vote/ { sub_filter 'href="/' 'href="/vote/'; sub_filter 'src="/' 'src="/vote/'; sub_filter 'action="/' 'action="/vote/'; sub_filter_once off; } location ~* ^/result/ { sub_filter 'href="/' 'href="/result/'; sub_filter 'src="/' 'src="/result/'; sub_filter 'action="/' 'action="/result/'; sub_filter_once off; } spec: rules: - host: voteapp.com http: paths: - backend: serviceName: vote servicePort: vote-http path: /vote(/|$)(.*) - backend: serviceName: result servicePort: result-http path: /result(/|$)(.*)
注意:该方案无法覆盖JS代码内写死的绝对路径,部分场景可能存在漏替换的情况
内容的提问来源于stack exchange,提问作者Suraj Agarkar
相关产品推荐
相关产品推荐

