Kubernetes IngressRoute
본문
IngressRoute
IngressRoute는 Traefik HTTP 라우터의 CRD 구현이에요.
IngressRoute 객체를 만들기 전에 Definitions와 RBAC 같은 Traefik Kubernetes CRD를 Kubernetes 클러스터에 적용해야 해요.
이렇게 하면 IngressRoute kind와 기타 Traefik 전용 리소스가 등록돼요.
Configuration Example (설정 예시)
IngressRoute는 아래와 같이 선언할 수 있어요:
IngressRoute
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: test-name
namespace: apps
spec:
ingressClassName: traefik-lb
entryPoints:
- web
parentRefs:
- name: parent-gateway
namespace: default # Optional - defaults to same namespace
routes:
- kind: Rule
# Rule on the Host
match: Host(`test.example.com`)
# Attach a middleware
middlewares:
- name: middleware1
namespace: apps
# Enable Router observability
observability:
accessLogs: true
metrics: true
tracing: true
# Set a priority
priority: 10
services:
# Target a Kubernetes Support
- kind: Service
name: foo
namespace: apps
# Customize the connection between Traefik and the backend
passHostHeader: true
port: 80
responseForwarding:
flushInterval: 1ms
scheme: https
sticky:
cookie:
httpOnly: true
name: cookie
secure: true
strategy: wrr
weight: 10
tls:
# Generate a TLS certificate using a certificate resolver
certResolver: foo
domains:
- main: example.net
sans:
- a.example.net
- b.example.net
# Customize the TLS options
options:
name: opt
namespace: apps
# Add a TLS certificate from a Kubernetes Secret
secretName: supersecret
Configuration Options (설정 옵션)
| Field | Description | Default | Required |
| ingressClassName | 사용할 IngressClass 클러스터 리소스를 정의해요. 더 이상 사용되지 않는 kubernetes.io/ingress.class 어노테이션을 대체해요. spec 필드가 어노테이션보다 우선해요. | | No |
| entryPoints | 엔트리포인트 이름 목록이에요. 지정하지 않으면 HTTP 라우터는 기본 엔트리포인트 목록의 모든 엔트리포인트에서 요청을 받아들여요. | | No |
| parentRefs | 멀티 레이어 라우팅을 위한 부모 IngressRoute 리소스 참조 목록이에요. 지정하면 이 IngressRoute의 라우터들은 참조된 부모 IngressRoute 라우터들의 자식이 돼요. 자세한 내용은 Multi-Layer Routing 섹션을 참고해 주세요. | | No |
| parentRefs[n].name | 참조된 부모 IngressRoute 리소스의 이름이에요. | | Yes |
| parentRefs[n].namespace | 참조된 부모 IngressRoute 리소스의 네임스페이스예요. 지정하지 않으면 자식 IngressRoute와 같은 네임스페이스로 기본 설정돼요. 교차 네임스페이스 참조는 allowCrossNamespace provider 옵션이 활성화되어야 해요. | | No |
| routes | 라우트 목록이에요. | | Yes |
| routes[n].kind | 라우터 매칭 종류로, 아직 Rule만 허용돼요. | "Rule" | No |
| routes[n].match | 기본 라우터에 해당하는 규칙을 정의해요. | | Yes |
| routes[n].priority | 라우트 매칭을 위해 같은 길이의 규칙을 구분하는 우선순위를 정의해요. 설정하지 않으면 우선순위는 규칙의 길이와 정확히 같아서, 가장 긴 길이가 가장 높은 우선순위를 가져요. 우선순위 값 0은 무시되고 기본 규칙 길이 정렬이 사용돼요. 음수 값도 지원돼요. | 0 | No |
| routes[n].middlewares | IngressRoute에 연결할 미들웨어 목록이에요. 자세한 내용은 여기를 참고해 주세요. | "" | No |
| routes[n]. middlewares[m]. name | 미들웨어 이름이에요. @ 문자는 허용되지 않아요. 자세한 내용은 여기를 참고해 주세요. | | Yes |
| routes[n]. middlewares[m]. namespace | 미들웨어 네임스페이스예요. 미들웨어가 IngressRoute와 같은 네임스페이스에 있으면 비워둘 수 있어요. 자세한 내용은 여기를 참고해 주세요. | | No |
| routes[n]. observability. accessLogs | 라우트가 액세스 로그를 생성할지 정의해요. 자세한 내용은 여기를 참고해 주세요. | false | No |
| routes[n]. observability. metrics | 라우트가 메트릭을 생성할지 정의해요. 자세한 내용은 여기를 참고해 주세요. | false | No |
| routes[n]. observability. tracing | 라우트가 트레이스를 생성할지 정의해요. 자세한 내용은 여기를 참고해 주세요. | false | No |
| routes[n]. observability. traceVerbosity | 이 라우트의 트레이싱 상세 수준을 정의해요. 유효한 값은 minimal과 detailed예요. 자세한 내용은 여기를 참고해 주세요. | minimal | No |
| tls | TLS 구성이에요. 빈 값({})일 수 있어요: 이 경우 자체 서명 인증서가 생성되거나(기본 인증서가 정의되어 있으면) 기본 인증서가 사용돼요. | | No |
| routes[n]. services | TraefikService와 Kubernetes service의 모든 조합 목록이에요. 옵션의 전체 목록은 Service 문서에 있어요. | | No |
| tls.secretName | 인증서를 저장하는 데 사용되는 시크릿 이름(IngressRoute와 같은 네임스페이스)이에요. | "" | No |
| tls. options.name | 사용할 TLSOption의 이름이에요. 자세한 내용은 여기를 참고해 주세요. | "" | No |
| tls. options.namespace | 사용할 TLSOption의 네임스페이스예요. | "" | No |
| tls.certResolver | 자동 TLS 인증서를 생성하는 데 사용할 Certificate Resolver의 이름이에요. | "" | No |
| tls.domains | 생성된 인증서로 제공할 도메인 목록이에요(하나의 tls.domain = 하나의 인증서). 자세한 내용은 전용 섹션을 참고해 주세요. | | No |
| tls. domains[n].main | 주요 도메인 이름이에요. | "" | Yes |
| tls. domains[n].sans | 대체 도메인(SAN) 목록이에요. | | No |
Middleware (미들웨어)
-
각 HTTP 라우터에 미들웨어 목록을 연결할 수 있어요.
-
미들웨어는 규칙이 매칭될 때만, 그리고 요청을 서비스로 전달하기 전에 적용돼요.
-
미들웨어는 라우터에서 선언된 순서와 같은 순서로 적용돼요.
-
Kubernetes에서 middleware 옵션을 사용하면 이름과 네임스페이스로 미들웨어를 연결할 수 있어요(Middleware가 IngressRoute와 같은 네임스페이스에 있으면 네임스페이스를 생략할 수 있어요).
몇 개의 미들웨어가 연결된 IngressRoute
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: my-app
namespace: apps
spec:
entryPoints:
- websecure
routes:
- match: Host(`example.com`)
kind: Rule
middlewares:
# same namespace as the IngressRoute
- name: middleware01
# default namespace
- name: middleware02
namespace: apps
# Other namespace
- name: middleware03
namespace: other-ns
services:
- name: whoami
port: 80
routes.services.kind
name 필드는 서로 다른 타입의 객체를 참조할 수 있으므로, 모호함을 피하려면 kind 필드를 사용해요. kind 필드는 다음 값을 허용해요:
-
Service (기본값): Kubernetes Service를 참조해요.
-
TraefikService: TraefikService 객체를 참조해요.
TLS Options (TLS 옵션)
options 필드는 TLS 파라미터를 세밀하게 제어할 수 있게 해 줘요. TLSOption을 참조하며, Host 규칙이 정의된 경우에만 적용돼요.
Server Name Association (서버 이름 연결)
TLS 옵션 참조는 항상 규칙의 Host 부분에 있는 호스트 이름에 매핑되며, 라우터나 라우터 규칙에는 매핑되지 않아요. 규칙에는 Host 부분이 여러 개 있을 수도 있어요. 이 경우 TLS 옵션 참조는 그만큼의 호스트 이름에 매핑돼요.
TLS 옵션은 위에서 언급한 매핑과 TLS 핸드셰이크 중에 제공된 서버 이름을 기반으로 선택되며, 이 모든 과정은 실제 라우팅이 일어나기 전에 완료돼요.
도메인 프론팅의 경우, Host Header와 연결된 TLS 옵션과 SNI가 다르면 Traefik은 상태 코드 421로 응답해요.
Conflicting TLS Options (TLS 옵션 충돌)
TLS 옵션 참조는 호스트 이름에 매핑되므로, 구성이(Host 규칙의) 같은 호스트 이름이 두 TLS 옵션 참조와 매칭되는 상황을 만들면 아래 예시처럼 충돌이 발생해요.
충돌 감지는 네임스페이스에 국한되지 않아요: 어떤 네임스페이스에 정의된 IngressRoute든, 심지어 다른 provider에서 온 라우터든, 같은 엔트리포인트에서 같은 호스트 이름을 제공하는 순간 이 라우터와 충돌해요.
Example (예시)
IngressRoute01
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: IngressRoute01
namespace: apps
spec:
entryPoints:
- foo
routes:
- match: Host(`example.net`)
kind: Rule
tls:
options: foo
...
IngressRoute02
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: IngressRoute02
namespace: apps
spec:
entryPoints:
- foo
routes:
- match: Host(`example.net`)
kind: Rule
tls:
options: bar
...
이런 경우 두 매핑은 모두 폐기되고, 이 라우터들의 호스트 이름(예시의 example.net)은 대신 기본 TLS 옵션과 연결돼요.
기본 TLS 옵션
default TLS 옵션은 충돌 해결의 폴백이므로, 교체할 수 있는 옵션보다 덜 안전해서는 안 돼요.
자세한 내용은 Conflicting TLS Options를 참고해 주세요.
Multi-Layer Routing with IngressRoutes (IngressRoute를 이용한 멀티 레이어 라우팅)
멀티 레이어 라우팅은 IngressRoute 사이에 계층적 관계를 만들 수 있게 해 줘요. 부모 IngressRoute가 자식 IngressRoute가 라우팅 결정을 내리기 전에 미들웨어를 적용할 수 있어요.
이는 특히 인증 기반 라우팅에 유용해요. 부모 IngressRoute가 요청을 인증하고 맥락(예: 사용자 역할을 헤더로)을 추가하면, 자식 IngressRoute가 그 맥락을 기반으로 라우팅해요.
자식 IngressRoute가 여러 라우트를 가진 부모 IngressRoute를 참조하면, 모든 부모 라우터가 모든 자식 라우터의 부모가 돼요.
포괄적인 멀티 레이어 라우팅 문서
멀티 레이어 라우팅 개념, 검증 규칙, 사용 사례에 대한 자세한 내용은 전용 Multi-Layer Routing 페이지를 참고해 주세요.
Configuration Requirements (구성 요건)
Root IngressRoutes (루트 IngressRoute)
-
parentRefs가 없어요(계층의 최상위). -
entryPoints,tls,observability구성을 가질 수 있어요. -
부모 IngressRoute(자식이 있는 경우)이거나 독립 IngressRoute(service가 있는 경우)일 수 있어요.
Intermediate IngressRoutes (중간 IngressRoute)
-
parentRefs로 부모 IngressRoute(들)를 참조해요. -
하나 이상의 자식 IngressRoute를 가져요.
-
service를 정의하면 안 돼요.
-
entryPoints,tls,observability구성을 가지면 안 돼요.
Leaf IngressRoutes (리프 IngressRoute)
-
parentRefs로 부모 IngressRoute(들)를 참조해요. -
service를 반드시 정의해야 해요.
-
entryPoints,tls,observability구성을 가지면 안 돼요.
교차 네임스페이스 참조
교차 네임스페이스 부모 참조는 allowCrossNamespace provider 옵션이 활성화되어야 해요. 비활성화되면 자식 IngressRoute 생성을 건너뛰고 오류가 기록돼요.
Example: Authentication-Based Routing (예시: 인증 기반 라우팅)
ForwardAuth가 있는 부모 IngressRoute와 자식 IngressRoute
Parent IngressRoute
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: api-parent
namespace: default
spec:
entryPoints:
- websecure
tls:
certResolver: letsencrypt
routes:
# Parent route with authentication - no services
- match: Host(`api.example.com`) && PathPrefix(`/api`)
kind: Rule
middlewares:
- name: auth-middleware
namespace: default
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: auth-middleware
namespace: default
spec:
forwardAuth:
address: "http://auth-service.default.svc.cluster.local:8080/auth"
authResponseHeaders:
- X-User-Role
- X-User-Name
Child IngressRoutes (자식 IngressRoute)
# Child IngressRoute for admin users
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: api-admin
namespace: default
spec:
parentRefs:
- name: api-parent
namespace: default # Optional - defaults to same namespace
routes:
- match: HeadersRegexp(`X-User-Role`, `admin`)
kind: Rule
services:
- name: admin-service
port: 80
---
# Child IngressRoute for regular users
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: api-user
namespace: default
spec:
parentRefs:
- name: api-parent
routes:
- match: HeadersRegexp(`X-User-Role`, `user`)
kind: Rule
services:
- name: user-service
port: 80
Services
apiVersion: v1
kind: Service
metadata:
name: auth-service
namespace: default
spec:
ports:
- port: 8080
selector:
app: auth-service
---
apiVersion: v1
kind: Service
metadata:
name: admin-service
namespace: default
spec:
ports:
- port: 80
selector:
app: admin-backend
---
apiVersion: v1
kind: Service
metadata:
name: user-service
namespace: default
spec:
ports:
- port: 80
selector:
app: user-backend
동작 원리:
-
https://api.example.com/api/endpoint로 가는 요청이 부모 라우터에 매칭돼요. -
auth-middleware(ForwardAuth)가auth-service로 요청을 검증해요. -
auth-service가X-User-Role헤더(예:admin또는user)와 함께 200 OK를 반환해요. -
자식 라우터들이 수정된 요청(
X-User-Role헤더 포함)에 대해 규칙을 평가해요. -
역할에 따라 요청이
admin-service나user-service로 라우팅돼요.