K8s Nginx Ingress实现无尾斜杠路径强制重定向至带尾斜杠
解决Nginx Ingress无尾斜杠路径的重定向问题
问题背景
现有正常工作的Ingress配置如下:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: kubernetes.io/ingress.provider: nginx nginx.ingress.kubernetes.io/rewrite-target: /$1 nginx.ingress.kubernetes.io/backend-protocol: HTTPS kubernetes.io/ingress.class: "nginx" name: kube-blahblah namespace: kubernetes-blahblah spec: rules: - http: paths: - path: /blahblah/(.*) pathType: Prefix backend: service: name: some-service port: number: 443
访问带尾斜杠的http://somehost:someport/blahblah/时,应用及内部资源加载一切正常;但访问无尾斜杠的http://somehost:someport/blahblah时会触发404错误。
尝试添加独立Ingress匹配/blahblah(Exact类型):
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: kubernetes.io/ingress.provider: nginx nginx.ingress.kubernetes.io/rewrite-target: / nginx.ingress.kubernetes.io/backend-protocol: HTTPS kubernetes.io/ingress.class: "nginx" name: kube-just-blahblah namespace: kubernetes-blahblah spec: rules: - http: paths: - path: /blahblah pathType: Exact backend: service: name: some-service port: number: 443
虽然能映射到资源,但客户端加载内部资源时出现异常——原本应请求http://somehost:someport/blahblah/file1.html的资源,会被错误地请求为http://somehost:someport/file1,根源是原请求没有尾斜杠,导致相对路径计算错误。
使用configuration-snippet注解可以实现重定向:
nginx.ingress.kubernetes.io/configuration-snippet: | rewrite ^(/blahblah)$ $1/ permanent;
但该注解因安全风险不被推荐,希望找到无需连接后端服务、直接让客户端重定向到/blahblah/的简洁方案。
推荐解决方案
利用Nginx Ingress官方支持的永久重定向注解,创建一个单独的Ingress规则,直接在Ingress层面完成重定向,无需转发请求到后端服务:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: kubernetes.io/ingress.class: "nginx" # 配置永久重定向到带尾斜杠的路径 nginx.ingress.kubernetes.io/permanent-redirect: /blahblah/ name: kube-blahblah-redirect namespace: kubernetes-blahblah spec: rules: - http: paths: - path: /blahblah pathType: Exact backend: # 使用集群默认的空后端,仅满足Ingress规则的必填字段要求 service: name: default-http-backend port: number: 80
方案说明
- 重定向逻辑:
permanent-redirect注解会让Ingress直接返回301永久重定向响应,客户端收到后自动请求/blahblah/,后续资源的相对路径会基于带尾斜杠的根路径生成,彻底解决资源请求路径错误的问题。 - 后端配置:这里使用的
default-http-backend是Nginx Ingress安装时默认创建的服务,由于重定向是在Ingress层面直接处理,实际不会转发请求到该后端,只是为了满足Ingress规则对backend字段的必填要求。
如果集群中没有default-http-backend,也可以临时创建一个简单的空服务(无需实际运行Pod),或者使用任意已存在的服务端口(同样不会实际转发请求)。
内容的提问来源于stack exchange,提问作者eftshift0
相关产品推荐
相关产品推荐

