
在Kubernetes集群中,Ingress Nginx Controller提供了强大的URL重写功能,能够帮助优化应用的路由结构,提升用户体验和系统可维护性。本文将介绍常见的URL重写场景及其实现方法。
1、简化URL路径:将长路径缩短,提高访问便利性;
2、增加路径前缀:为多个模块添加统一的路径标识;
3、设置应用根路径:将子路径设为应用的根路径;
4、流量隔离: 在多团队、多版本共存时,通过前缀隔离流量;
5、服务迁移到k8s:将遗留系统逐步迁移到 Kubernetes,需要保留老接口的同时暴露新接口;
当应用内部路径较长时,可以通过重写规则简化外部访问路径。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: shorten-path
annotations:
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/rewrite-target: /api/v1/$1
spec:
ingressClassName: nginx
rules:
- host: app.example.com
http:
paths:
- path: /user/(.*)
pathType: Prefix
backend:
service:
name: user-service
port:
number: 8080此配置将把外部访问的 /user/profile 重写为内部路径 /api/v1/profile 。
当需要通过统一前缀访问不同服务模块时:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: add-prefix
annotations:
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
ingressClassName: nginx
rules:
- host: portal.example.com
http:
paths:
- path: /admin(/|$)(.*)
pathType: Prefix
backend:
service:
name: admin-service
port:
number: 8080此配置将把 /admin/dashboard 重写为内部路径 /dashboard ,同时保留了外部访问的前缀。
当需要将子路径设置为应用的根路径时:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: root-path
annotations:
nginx.ingress.kubernetes.io/app-root: /home
spec:
ingressClassName: nginx
rules:
- host: www.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80此配置会将根路径 / 重定向到 /home 路径,实现应用主页的简化访问。
典型诉求 | 推荐注解 | 关键词 |
|---|---|---|
把 /v1/user/123 变成 /user/123 | rewrite-target | 路径缩短 |
把 /api/user 变成 /user | rewrite-target | 去掉前缀 |
把 / 重定向到 /home | app-root | 根路径跳转 |
把 /user 和 /order 分别转发到不同命名空间 | configuration-snippet | 跨命名空间转发 |
把 /v1 与 /v2 灰度到不同版本 | canary-* 系列注解 | 金丝雀发布 |
操作 | 命令 | 说明 |
|---|---|---|
查看重写结果 | curl -vH "Host: app.example.com" http://<ingress-ip>/mobile/profile | 观察 Location 与 X-Accel-Redirect |
验证正则 | kubectl exec -n ingress-nginx <nginx-pod> -- nginx -t | 检查语法 |
实时日志 | kubectl logs -n ingress-nginx -f <nginx-pod> | 快速定位 404/500 |
强制重载 | kubectl rollout restart deployment ingress-nginx-controller -n ingress-nginx | 立即生效 |
应用场景示例:
背景:移动端 App 已经上线,URL 不能变;但后端重构后,内部路径层级加深。通过 Ingress 将外部短路径“映射”到内部长路径,客户端无感知。
# shorten-url.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: shorten-path
annotations:
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/rewrite-target: /api/v2/internal/$1
spec:
ingressClassName: nginx
rules:
- host: app.example.com
http:
paths:
- path: /mobile/(.*)
pathType: Prefix
backend:
service:
name: mobile-api
port:
number: 80外部请求 | 内部转发 | 备注 |
|---|---|---|
GET /mobile/profile | GET /api/v2/internal/profile | 正则 $1 捕获 profile |
背景:公司有统一网关域名 corp.example.com,但不同业务团队(admin、store、pay)需要独立部署。
# prefix-gateway.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: corp-gateway
annotations:
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
ingressClassName: nginx
rules:
- host: corp.example.com
http:
paths:
- path: /admin(/|$)(.*)
pathType: Prefix
backend:
service:
name: admin-svc
port:
number: 80
- path: /store(/|$)(.*)
pathType: Prefix
backend:
service:
name: store-svc
port:
number: 80外部请求 | 内部转发 | 团队 |
|---|---|---|
POST /admin/login | POST /login | Admin |
GET /store/items/123 | GET /items/123 | Store |
背景:前端 React/Angular 项目打包后需要把 / 重定向到 /home;同时保留 /static 等静态资源路径。
# root-redirect.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: spa-root
annotations:
nginx.ingress.kubernetes.io/app-root: /home
nginx.ingress.kubernetes.io/configuration-snippet: |
# 静态资源不走
rewrite
location ~* ^/(static|assets|favicon) {
rewrite ^ $request_uri break;
}
spec:
ingressClassName: nginx
rules:
- host: www.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-spa
port:
number: 80外部请求 | 浏览器行为 | 说明 |
|---|---|---|
GET / | 301 → /home | 对 SEO 友好 |
GET /static/app.js | 直接 200 | 静态资源无重写 |
背景:团队 A 的服务 user-svc 部署在 ns-a,团队 B 的服务 order-svc 部署在 ns-b,需要统一暴露在网关域名下。
# cross-ns.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: cross-ns-gateway
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
ingressClassName: nginx
rules:
- host: api.example.com
http:
paths:
- path: /user(/|$)(.*)
pathType: Prefix
backend:
service:
name: user-svc.ns-a.svc.cluster.local # FQDN
port:
number: 80
- path: /order(/|$)(.*)
pathType: Prefix
backend:
service:
name: order-svc.ns-b.svc.cluster.local
port:
number: 80背景:新版本 /v2 灰度 10% 流量,老版本 /v1 保留 90%。
# canary-v2.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-canary
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "10"
nginx.ingress.kubernetes.io/rewrite-target: /v2/$1
spec:
ingressClassName: nginx
rules:
- host: api.example.com
http:
paths:
- path: /(.*)
pathType: Prefix
backend:
service:
name: api-v2
port:
number: 80
---# 老版本保持原样
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata: name: api-stable
spec:
ingressClassName: nginx
rules: - host: api.example.com
http:
paths:
- path: /(.*)
pathType: Prefix
backend:
service:
name: api-v1
port:
number: 801、使用正则表达式时,确保开启 nginx.ingress.kubernetes.io/use-regex: “true” 注解。
2、路径捕获组从$1开始,对应正则表达式中的第一个括号。
3、测试时可以使用 curl -v 命令查看完整的请求和响应过程。
4、修改Ingress配置后,通常需要等待几秒钟让变更生效。
5、正则顺序敏感:把更精确的路径放到前面,否则会被通配符覆盖。
6、避免双斜杠:使用 /1 而非 /1/ 防止出现 //。
7、非幂等操作慎用 301:浏览器会缓存 301,调试时先用 302。
8、灰度场景请用 canary-* 注解,不要手动改权重,避免误伤全量流量。
9、跨域场景 配合 nginx.ingress.kubernetes.io/cors-allow-origin: "*" 使用。
通过合理使用Ingress Nginx的URL重写功能,可以显著提升Kubernetes应用的访问友好性和维护便利性。
“无他,惟手熟尔”!有需要的用起来!
如果你觉得这篇文章有用,欢迎点赞、转发、收藏、留言、推荐❤!