K8s Ingress重定向返回404 Not Found问题解决问询
K8s多Namespace下Nginx Ingress静态资源404问题解决
问题场景
在K8s的dev、uat1、uat2、prod四个Namespace部署包含Nginx前端的5个微服务应用栈,使用Nginx Ingress做路由时出现以下问题:
- 访问Ingress路径能路由到前端Pod,但前端返回大量静态资源404(如
http://x.x.x.x/js/chunk-xxx.js) - 手动在URL中添加对应环境前缀(如
/dev/)后,静态资源请求返回200,确认请求被重定向到了无命名空间前缀的URL
当前Ingress配置示例
dev环境
kubectl describe ing Name: ingress-dev Labels: <none> Namespace: dev Address: x.x.x.x Ingress Class: <none> Default backend: <default> Rules: Host Path Backends ---- ---- -------- * /frontend-dev nginx-npm:8080 (x.x.x.x:8080) Annotations: kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/rewrite-target: /$2
uat1环境
kubectl describe ing -n uat1 Name: ingress-uat1 Labels: <none> Namespace: uat Address: x.x.x.x Ingress Class: <none> Default backend: <default> Rules: Host Path Backends ---- ---- -------- * /frontend-uat nginx-npm:8080 (x.x.x.x:8080) Annotations: kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/rewrite-target: /$2
prod环境
kubectl describe ing -n prod Name: ingress-prod Labels: <none> Namespace: prod Address: x.x.x.x Ingress Class: <none> Default backend: <default> Rules: Host Path Backends ---- ---- -------- * /frontend-prod nginx-npm:8080 (x.x.x.x:8080) Annotations: kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/rewrite-target: /$2
问题原因
- Ingress路径规则与rewrite注解不匹配:当前路径仅配置了
/frontend-dev,未捕获后续子路径,且rewrite-target: /$2中的$2无对应分组捕获,导致Ingress无法正确路由静态资源请求。 - 前端资源路径为绝对路径:前端编译时未指定环境前缀,生成的静态资源路径为根路径(如
/js/xxx.js),浏览器直接请求Ingress根路径,而该路径未配置路由到对应Namespace的前端服务。
解决方案
方案1:修正Ingress配置
调整每个环境的Ingress路径规则,增加分组捕获以匹配所有子请求,修正rewrite逻辑:
dev环境Ingress配置(YAML格式)
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-dev namespace: dev annotations: kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/rewrite-target: /$2 spec: rules: - http: paths: - path: /frontend-dev(/|$)(.*) pathType: Prefix backend: service: name: nginx-npm port: number: 8080
uat1环境Ingress配置
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-uat1 namespace: uat1 annotations: kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/rewrite-target: /$2 spec: rules: - http: paths: - path: /frontend-uat(/|$)(.*) pathType: Prefix backend: service: name: nginx-npm port: number: 8080
prod环境Ingress配置
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-prod namespace: prod annotations: kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/rewrite-target: /$2 spec: rules: - http: paths: - path: /frontend-prod(/|$)(.*) pathType: Prefix backend: service: name: nginx-npm port: number: 8080
方案2:调整前端应用baseURL
在前端构建时,为不同环境指定对应前缀的publicPath(Vue/React等主流框架均支持该配置):
- dev环境:
publicPath: "/frontend-dev/" - uat1环境:
publicPath: "/frontend-uat/" - prod环境:
publicPath: "/frontend-prod/"
配置后前端生成的所有静态资源路径会自动带上环境前缀,浏览器请求时会直接访问http://x.x.x.x/frontend-dev/js/xxx.js,无需手动添加前缀。
验证步骤
- 应用修正后的Ingress配置:
kubectl apply -f ingress-dev.yaml - 若调整了
publicPath,重新构建并部署前端应用 - 访问对应环境的Ingress路径(如
http://x.x.x.x/frontend-dev),检查静态资源请求URL是否包含前缀,且返回200状态码。
内容的提问来源于stack exchange,提问作者sanjeeth
相关产品推荐
相关产品推荐

