멀티 레이어 라우팅
멀티 레이어 라우팅 (Multi-Layer Routing)
본문
Multi-Layer Routing
고급 라우팅 시나리오를 위한 계층적 라우터 관계를 제공해요.
Overview (개요)
멀티 레이어 라우팅을 이용하면 라우터 사이에 계층적 관계를 만들 수 있어요. 부모 라우터가 미들웨어로 요청을 처리한 뒤, 자식 라우터가 최종 라우팅 결정을 내리는 구조예요.
이 기능 덕분에 부모 레벨의 미들웨어가 요청을 수정(헤더 추가, 인증 수행 등)할 수 있고, 그 수정 내용이 자식 라우터가 규칙을 평가하고 서비스로 트래픽을 보내는 방식에 영향을 줘요.
멀티 레이어 라우팅은 특히 점진적 요청 강화(progressive request enrichment)에 유용해요. 각 레이어가 요청에 맥락을 더하면서 점점 더 구체적인 라우팅 결정을 내릴 수 있게 해 주죠:
-
인증 기반 라우팅: 부모 라우터가 요청을 인증하고 사용자 맥락(역할, 권한)을 헤더로 추가하면, 자식 라우터가 이 헤더를 기준으로 라우팅해요.
-
단계적 미들웨어 적용: 공통 미들웨어(레이트 리밋, CORS)는 부모 레벨(특정 도메인/경로)에 적용하고, 특정 미들웨어는 자식 레벨에 적용해요.
Provider 지원
멀티 레이어 라우팅은 다음 provider에서 지원돼요:
-
File provider (YAML, TOML, JSON)
-
KV 스토어 (Consul, etcd, Redis, ZooKeeper)
-
Kubernetes CRD (IngressRoute)
다른 provider(Docker, Kubernetes Ingress, Gateway API 등)에서는 멀티 레이어 라우팅을 사용할 수 없어요.
How It Works (동작 원리)
Request → EntryPoint → Parent Router → Middleware → Child Router A → Service A
↓ → Child Router B → Service B
Modify Request
(e.g., add headers)
-
요청이 엔트리포인트에 도착해요.
-
부모 라우터가 자신의 규칙(예:
Host(example.com))에 따라 매칭돼요. -
부모 미들웨어가 실행되며 요청을 수정할 수 있어요.
-
하나의 자식 라우터가 자신의 규칙(수정된 요청 속성을 사용할 수 있어요)에 따라 매칭돼요.
-
요청은 매칭된 자식 라우터의 서비스로 전달돼요.
Building a Router Hierarchy (라우터 계층 만들기)
Root Routers (루트 라우터)
-
parentRefs가 없어요(계층의 최상위). -
tls,observability,entryPoints구성을 가질 수 있어요. -
부모 라우터(자식이 있는 경우)이거나 독립 라우터(service가 있는 경우)일 수 있어요.
-
모델(model)을 적용할 수 있어요(비-루트 라우터는 모델을 가질 수 없어요).
Intermediate Routers (중간 라우터)
-
parentRefs로 부모 라우터(들)를 참조해요. -
하나 이상의 자식 라우터를 가져요.
-
service를 정의하면 안 돼요.
-
entryPoints,tls,observability구성을 가지면 안 돼요.
Leaf Routers (리프 라우터)
-
parentRefs로 부모 라우터(들)를 참조해요. -
service를 반드시 정의해야 해요.
-
entryPoints,tls,observability구성을 가지면 안 돼요.
Configuration Example (설정 예시)
인증 기반 라우팅
File (YAML)
## 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"
File (TOML)
## 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"
KV (Consul/etcd/Redis/ZK)
| 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을 사용하고 있다면, 엔터프라이즈급 API 게이트웨이 기능이나 Traefik OSS에 대한 상용 지원을 고려해 보세요.
-
API 게이트웨이 데모 영상 보기
-
24/7/365 OSS 지원 요청하기
Traefik OSS에 API 게이트웨이 기능을 추가하는 것은 빠르고 자연스러워요. 기존 구성을 갈아엎거나 교체할 필요 없이 모든 설정이 그대로 유지돼요. 이 짧은 영상에서 직접 확인해 보세요.