多层路由¶
通过路由器层级关系支持高级路由场景。
概览¶
多层路由允许在路由器之间建立层级关系, 使父路由器在子路由器做出最终路由决策前,通过中间件处理请求。
此功能允许父级中间件修改请求(添加请求头、执行身份认证等),进而影响子路由器如何判断规则并将流量路由到服务。
多层路由特别适合逐步丰富请求信息:每一层都为请求添加上下文,使路由决策越来越具体:
- 基于身份认证的路由:父路由器对请求进行身份认证,并将用户上下文(角色、权限)添加为请求头,子路由器根据这些请求头路由
- 分阶段应用中间件:在父级(针对指定域名/路径)应用通用中间件(限流、CORS),在子级应用特定中间件
提供者支持
以下提供者支持多层路由:
- 文件提供者(YAML、TOML、JSON)
- KV 存储(Consul、etcd、Redis、ZooKeeper)
- Kubernetes CRD(IngressRoute)
其他提供者(Docker、Kubernetes Ingress、Gateway API 等)不支持多层路由。
工作原理¶
Request → EntryPoint → Parent Router → Middleware → Child Router A → Service A
↓ → Child Router B → Service B
Modify Request
(e.g., add headers)
- 请求到达入口点
- 父路由器匹配其规则(例如
Host(`example.com`)) - 父级中间件执行,可能修改请求
- 一个子路由器匹配其规则(可以使用修改后的请求属性)
- 请求转发到匹配的子路由器所引用的服务
构建路由器层级¶
根路由器¶
- 没有
parentRefs(位于层级顶端) - 可以配置
tls、observability和entryPoints - 可以是父路由器(有子级),也可以是独立路由器(有服务)
- 可以应用模型(非根路由器不能使用模型)
中间路由器¶
- 通过
parentRefs引用父路由器 - 拥有一个或多个子路由器
- 不得定义
service - 不得配置
entryPoints、tls或observability
叶路由器¶
- 通过
parentRefs引用父路由器 - 必须定义
service - 不得配置
entryPoints、tls或observability
配置示例¶
基于身份认证的路由
## Dynamic configuration
http:
routers:
# Parent router with authentication
api-parent:
rule: "PathPrefix(`/api`)"
middlewares:
- auth-middleware
entryPoints:
- websecure
tls: {}
# Note: No service defined - this is a parent router
# Child router for admin users
api-admin:
rule: "HeaderRegexp(`X-User-Role`, `admin`)"
service: admin-service
parentRefs:
- api-parent
# Child router for regular users
api-user:
rule: "HeaderRegexp(`X-User-Role`, `user`)"
service: user-service
parentRefs:
- api-parent
middlewares:
auth-middleware:
forwardAuth:
address: "http://auth-service:8080/auth"
authResponseHeaders:
- X-User-Role
- X-User-Name
services:
admin-service:
loadBalancer:
servers:
- url: "http://admin-backend:8080"
user-service:
loadBalancer:
servers:
- url: "http://user-backend:8080"## Dynamic configuration
[http.routers]
# Parent router with authentication
[http.routers.api-parent]
rule = "PathPrefix(`/api`)"
middlewares = ["auth-middleware"]
entryPoints = ["websecure"]
[http.routers.api-parent.tls]
# Note: No service defined - this is a parent router
# Child router for admin users
[http.routers.api-admin]
rule = "HeaderRegexp(`X-User-Role`, `admin`)"
service = "admin-service"
parentRefs = ["api-parent"]
# Child router for regular users
[http.routers.api-user]
rule = "HeaderRegexp(`X-User-Role`, `user`)"
service = "user-service"
parentRefs = ["api-parent"]
[http.middlewares]
[http.middlewares.auth-middleware.forwardAuth]
address = "http://auth-service:8080/auth"
authResponseHeaders = ["X-User-Role", "X-User-Name"]
[http.services]
[http.services.admin-service.loadBalancer]
[[http.services.admin-service.loadBalancer.servers]]
url = "http://admin-backend:8080"
[http.services.user-service.loadBalancer]
[[http.services.user-service.loadBalancer.servers]]
url = "http://user-backend:8080"| Key | Value |
|------------------------------------------------------------------------|---------------------------------|
| `traefik/http/routers/api-parent/rule` | `PathPrefix(\`/api\`)` |
| `traefik/http/routers/api-parent/middlewares/0` | `auth-middleware` |
| `traefik/http/routers/api-parent/entrypoints/0` | `websecure` |
| `traefik/http/routers/api-parent/tls` | `true` |
| `traefik/http/routers/api-admin/rule` | `HeaderRegexp(\`X-User-Role\`, \`admin\`)` |
| `traefik/http/routers/api-admin/service` | `admin-service` |
| `traefik/http/routers/api-admin/parentrefs/0` | `api-parent` |
| `traefik/http/routers/api-user/rule` | `HeaderRegexp(\`X-User-Role\`, \`user\`)` |
| `traefik/http/routers/api-user/service` | `user-service` |
| `traefik/http/routers/api-user/parentrefs/0` | `api-parent` |
| `traefik/http/middlewares/auth-middleware/forwardauth/address` | `http://auth-service:8080/auth` |
| `traefik/http/middlewares/auth-middleware/forwardauth/authresponseheaders/0` | `X-User-Role` |
| `traefik/http/middlewares/auth-middleware/forwardauth/authresponseheaders/1` | `X-User-Name` |
| `traefik/http/services/admin-service/loadbalancer/servers/0/url` | `http://admin-backend:8080` |
| `traefik/http/services/user-service/loadbalancer/servers/0/url` | `http://user-backend:8080` |工作原理:
- 发往
/api/endpoint的请求匹配api-parent路由器 auth-middleware(ForwardAuth)验证请求并添加X-User-Role请求头- 子路由器对修改后的请求进行判断
- 如果为
X-User-Role: admin,则匹配api-admin路由器,并转发到admin-service - 如果为
X-User-Role: user,则匹配api-user路由器,并转发到user-service
在生产环境使用 Traefik OSS?
如果你在工作中使用 Traefik,可以考虑为 Traefik OSS 增加企业级 API 网关能力或商业支持。
为 Traefik OSS 增加 API 网关能力快捷且平滑,无需推倒重来,现有配置也会完整保留。请通过这个简短视频了解实际效果。