Kubernetes中Nginx Ingress单应用跳转正常另一应用返回404问题排查
问题根因
你遇到的问题核心来自两个方面:
- 重写规则的位置逻辑错误
你将匹配^(/apps/bar)$(不带尾斜杠)的重写规则,写在了绑定路径/apps/bar/(.*)的location块的configuration-snippet中。该location的匹配规则要求路径必须包含/加后续内容,不带尾斜杠的/apps/bar请求永远无法进入这个location块,所以规则本身放在这里就不可能生效。 - 同Host下多Ingress资源的注解注入限制
Nginx Ingress控制器处理同一Host下多个独立Ingress资源的nginx.ingress.kubernetes.io/configuration-snippet注解时,默认只会将第一个创建的Ingress的snippet内容注入到server级的全局location ~* "^/"块中,后续创建的Ingress的snippet只会注入到自身对应的路径location块,不会写入全局块。
你先部署了foo.yaml,后部署bar.yaml,所以只有foo的重写规则被写入了全局location,能正常匹配到不带尾斜杠的/apps/foo请求,bar的规则没有进入全局块,自然无法触发跳转。
配置方案优化建议
有三种常用的修复方式,任选其一即可:
- 方案1:合并Ingress资源
将foo和bar的路径规则合并到同一个Ingress资源中,把两个重写规则都写在同一个configuration-snippet注解下,这样两个规则都会被注入到全局location块:
apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: common-ingress annotations: kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/proxy-read-timeout: "1800" nginx.ingress.kubernetes.io/proxy-send-timeout: "1800" nginx.ingress.kubernetes.io/rewrite-target: /$1 nginx.ingress.kubernetes.io/configuration-snippet: | rewrite ^(/apps/foo)$ $1/ redirect; rewrite ^(/apps/bar)$ $1/ redirect; spec: rules: - host: myhost http: paths: - path: /apps/foo/(.*) backend: serviceName: foo-service servicePort: 8080 - path: /apps/bar/(.*) backend: serviceName: foo-service servicePort: 8080
- 方案2:新增精确路径匹配规则
不需要自定义重写规则,给每个服务新增一条精确匹配不带尾斜杠路径的规则,配合现有rewrite-target注解自动实现跳转:
# 以bar为例,foo同理修改 paths: - path: /apps/bar pathType: Exact backend: serviceName: foo-service servicePort: 8080 - path: /apps/bar/(.*) backend: serviceName: foo-service servicePort: 8080
- 方案3:使用官方补全斜杠注解
直接添加nginx.ingress.kubernetes.io/append-slash: "true"注解,Nginx Ingress会自动为匹配到的路径补全尾斜杠,不需要手动写rewrite规则。
内容的提问来源于stack exchange,提问作者Stefano Borini
相关产品推荐
相关产品推荐

