Kubernetes Nginx Ingress如何重写Pod返回的URL前缀?
解决Ingress路径重写后响应URL跳转404的简便方案
嘿,这个问题我之前部署应用时也碰到过,其实不用复杂的配置,只要优化下Ingress的注解和路径规则,就能自动让Pod返回的URL带上/app前缀,完美解决404问题。
优化后的完整Ingress配置
kind: Ingress metadata: annotations: kubernetes.io/ingress.class: nginx # 开启正则匹配,合并/app和/app/的重复规则 nginx.ingress.kubernetes.io/use-regex: "true" nginx.ingress.kubernetes.io/rewrite-target: /$2 # 核心:自动重写响应里的根路径URL为带/app前缀的版本 nginx.ingress.kubernetes.io/sub-filter: 'href="/' 'href="/app/' nginx.ingress.kubernetes.io/sub-filter: 'src="/' 'src="/app/' # 如果应用返回带完整域名的绝对URL,加上这条规则 nginx.ingress.kubernetes.io/sub-filter: 'https://www.example.com/' 'https://www.example.com/app/' labels: app: example name: example namespace: default spec: rules: - host: www.example.com http: paths: - backend: serviceName: app servicePort: 80 # 正则匹配所有/app开头的路径,包括/app、/app/、/app/xxx path: /app(/|$)(.*) tls: - hosts: - www.example.com secretName: example-tls
关键细节解释
- 合并重复路径规则:你之前写了
/app和/app/两个路径,其实用/app(/|$)(.*)的正则就能一次匹配所有情况,配合use-regex: "true"开启正则支持,rewrite-target: /$2会把/app/xxx里的xxx部分传递给Pod的根路径,完全满足你原来的路由需求。 - 自动重写响应URL:通过
sub-filter注解,Nginx会自动扫描响应内容,把所有href="/、src="/这类根路径开头的链接替换成/app/开头的,这样Pod返回的/content就会变成/app/content,浏览器自然会请求正确的路径。如果你的应用会返回带完整域名的绝对URL(比如https://www.example.com/content),就加上最后一条sub_filter规则替换域名后的前缀。 - 比其他方案更简便:不用修改应用代码配置base_url,也不用手动维护一堆Ingress路径规则,只需要几个注解就能全局搞定响应URL的重写。
额外加分项:如果应用支持请求头
如果你的应用能够读取X-Forwarded-Prefix这个请求头,并且会根据这个头自动生成带前缀的URL,那可以完全不用sub_filter,只需要在Ingress注解里加一行:
nginx.ingress.kubernetes.io/proxy-set-header: "X-Forwarded-Prefix /app"
这样应用收到请求时就知道自己的访问前缀是/app,生成的所有URL都会自动带上这个前缀,从根源解决问题,这是最理想的方案,但前提是你的应用支持这个请求头。
内容的提问来源于stack exchange,提问作者Andrey Okhotnikov
相关产品推荐
相关产品推荐

