본문 바로가기
WIKI 기술 지식 베이스

멀티 레이어 라우팅

원문 보기 위키 갱신

멀티 레이어 라우팅 (Multi-Layer Routing)

출처: 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 게이트웨이 기능을 추가하는 것은 빠르고 자연스러워요. 기존 구성을 갈아엎거나 교체할 필요 없이 모든 설정이 그대로 유지돼요. 이 짧은 영상에서 직접 확인해 보세요.

더 알아보기 (Learn more)