Kubernetes에서 Traefik으로 서비스 노출하기 - 고급편
출처: Kubernetes에서 Traefik으로 서비스 노출하기 - 고급편 (Exposing Services with Traefik on Kubernetes - Advanced)
본문
Kubernetes에서 Traefik으로 서비스 노출하기 - 고급편
이 가이드는 기본 가이드의 개념과 셋업을 바탕으로 이어져요. 진행하기 전에 기본 가이드를 끝냈고 Kubernetes에서 Traefik 셋업이 동작하는 상태인지 확인하세요.
이 고급 가이드에서는 Traefik 배포를 다음으로 강화하는 법을 배우게 됩니다:
-
보안 헤더와 접근 제어를 위한 미들웨어
-
자동 인증서 관리를 위한 Let's Encrypt (IngressRoute)
-
자동 인증서 관리를 위한 cert-manager (Gateway API)
-
상태 유지 애플리케이션을 위한 스티키 세션
-
복잡한 인증 시나리오를 포함한 계층적 라우팅을 위한 다중 레이어 라우팅 (IngressRoute 전용)
-
서비스 레벨에서 미들웨어를 적용하기 위한 서비스 미들웨어
사전 준비물
-
기본 가이드를 완료했을 것
-
Traefik Proxy가 설치된 Kubernetes 클러스터
-
클러스터와 상호작용하도록 구성된 kubectl
-
기본 가이드의 동작하는 Traefik 셋업
미들웨어 추가하기
미들웨어를 쓰면 요청이나 응답이 Traefik을 지나는 동안 수정할 수 있어요. 두 가지 유용한 미들웨어를 추가해 볼게요: 보안을 위한 Headers와 접근 제어를 위한 IP allowlist입니다.
미들웨어 만들기
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: secure-headers
namespace: default
spec:
headers:
frameDeny: true
sslRedirect: true
browserXssFilter: true
contentTypeNosniff: true
stsIncludeSubdomains: true
stsPreload: true
stsSeconds: 31536000
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: ip-allowlist
namespace: default
spec:
ipAllowList:
sourceRange:
- 127.0.0.1/32
- 10.0.0.0/8 # Typical cluster network range
- 192.168.0.0/16 # Common local network range
이걸 middlewares.yaml로 저장하고 적용하세요:
kubectl apply -f middlewares.yaml
Gateway API로 미들웨어 적용하기
Gateway API에서는 ExtensionRef 필터 타입으로 미들웨어를 적용할 수 있어요. 이것은 HTTPRoute 사양에 직접 통합되므로 Gateway API에서 Traefik 미들웨어를 쓰는 선호되고 표준적인 방식입니다.
이제 HTTPRoute를 갱신해서 ExtensionRef 필터로 이 미들웨어들을 참조하세요:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: whoami
namespace: default
spec:
parentRefs:
- name: traefik-gateway
sectionName: websecure
hostnames:
- "whoami.docker.localhost"
rules:
- matches:
- path:
type: PathPrefix
value: /api
filters:
- type: ExtensionRef
extensionRef: # Headers Middleware Definition
group: traefik.io
kind: Middleware
name: secure-headers
- type: ExtensionRef
extensionRef: # IP AllowList Middleware Definition
group: traefik.io
kind: Middleware
name: ip-allowlist
backendRefs:
- name: whoami-api
port: 80
- matches:
- path:
type: PathPrefix
value: /
filters:
- type: ExtensionRef
extensionRef: # Headers Middleware Definition
group: traefik.io
kind: Middleware
name: secure-headers
- type: ExtensionRef
extensionRef: # IP AllowList Middleware Definition
group: traefik.io
kind: Middleware
name: ip-allowlist
backendRefs:
- name: whoami
port: 80
whoami-route.yaml 파일을 갱신하고 적용하세요:
kubectl apply -f whoami-route.yaml
이 방식은 주석(annotation)이 아니라 Gateway API의 네이티브 필터 메커니즘을 사용해요. ExtensionRef 필터 타입을 쓰면 HTTPRoute 사양 안에서 Traefik 미들웨어를 직접 참조할 수 있는데, 이것이 Gateway API 설계 원칙과 더 일치합니다.
IngressRoute로 미들웨어 적용하기
미들웨어를 포함하도록 기존 IngressRoute를 갱신하세요:
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: whoami
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`whoami.docker.localhost`) && Path(`/api`)
kind: Rule
middlewares: # Middleware Definition
- name: secure-headers
- name: ip-allowlist
services:
- name: whoami-api
port: 80
- match: Host(`whoami.docker.localhost`)
kind: Rule
middlewares: # Middleware Definition
- name: secure-headers
- name: ip-allowlist
services:
- name: whoami
port: 80
tls:
certResolver: le
whoami-ingressroute.yaml 파일을 갱신하고 적용하세요:
kubectl apply -f whoami-ingressroute.yaml
미들웨어 효과 확인하기
보안 헤더가 적용되고 있는지 확인하세요:
curl -k -I -H "Host: whoami.docker.localhost" https://localhost/
응답에서 다음과 같은 보안 헤더가 보일 거예요:
HTTP/2 200
x-content-type-options: nosniff
x-frame-options: DENY
x-xss-protection: 1; mode=block
strict-transport-security: max-age=31536000; includeSubDomains; preload
content-type: text/plain; charset=utf-8
content-length: 403
IP allowlist를 테스트하려면 미들웨어의 sourceRange를 수정해 여러분의 IP를 제외하고 접근이 차단되는지 확인하면 됩니다.
Let's Encrypt로 인증서 생성하기
정보
Traefik의 내장 Let's Encrypt 통합은 IngressRoute에서 동작하지만 Gateway API 리스너용 인증서를 자동으로 발급하지는 않아요. Gateway API에는 cert-manager나 다른 인증서 컨트롤러를 사용해야 합니다.
IngressRoute를 Let's Encrypt와 함께 사용하기
Traefik values.yaml에 인증서 리졸버를 구성하세요:
additionalArguments:
- "[email protected]" #replace with your email
- "--certificatesresolvers.le.acme.storage=/data/acme.json"
- "--certificatesresolvers.le.acme.httpchallenge.entrypoint=web"
공개 DNS 필요
Let's Encrypt는 도메인 소유권을 검증하기 위해 공개적으로 접근 가능한 도메인이 필요할 수 있어요. whoami.docker.localhost 같은 로컬 도메인으로 테스트할 때는 인증서가 자체 서명으로 유지됩니다. 프로덕션에서는 Traefik 인스턴스를 가리키는 공개 DNS 레코드가 있는 실제 도메인으로 바꾸세요.
이 구성으로 Traefik 설치를 갱신하세요:
helm upgrade traefik traefik/traefik -n traefik --reuse-values -f values.yaml
Let's Encrypt 인증서로 IngressRoute를 갱신하세요:
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: whoami
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`whoami.docker.localhost`) && Path(`/api`)
kind: Rule
middlewares:
- name: secure-headers
- name: ip-allowlist
services:
- name: whoami-api
port: 80
- match: Host(`whoami.docker.localhost`)
kind: Rule
middlewares:
- name: secure-headers
- name: ip-allowlist
services:
- name: whoami
port: 80
tls:
certResolver: le
적용하세요:
kubectl apply -f whoami-ingressroute.yaml
Gateway API를 cert-manager와 함께 사용하기
Gateway API에는 cert-manager를 설치하세요:
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.10.0/cert-manager.yaml
Issuer와 Certificate를 만드세요:
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: letsencrypt
spec:
acme:
email: [email protected] # replace with your email
server: https://acme-v02-staging.api.letsencrypt.org/directory # Replace with the production server in production
privateKeySecretRef:
name: letsencrypt-account-key
solvers:
- http01:
gatewayHTTPRoute:
parentRefs:
- name: traefik
namespace: default
kind: Gateway
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: whoami
namespace: default
spec:
secretName: whoami-tls-le # Name of secret where the generated certificate will be stored.
dnsNames:
- "whoami.docker.localhost" # Replace a real domain
issuerRef:
name: letsencrypt
kind: Issuer
공개 DNS 필요
Let's Encrypt는 소유권을 검증하기 위해 공개적으로 접근 가능한 도메인이 필요해요. whoami.docker.localhost 같은 로컬 도메인을 쓰면 cert-manager가 챌린지를 시도하지만 실패하고, 인증서는 자체 서명으로 유지됩니다. 프로덕션에서는 클러스터의 인그레스 지점을 가리키는 공개 DNS 레코드가 있는 도메인으로 바꾸세요.
YAML 파일을 저장하고 적용하세요:
kubectl apply -f letsencrypt-issuer-andwhoami-certificate.yaml
이제 생성된 인증서를 쓰도록 Gateway를 갱신하세요:
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: traefik-gateway
namespace: default
spec:
gatewayClassName: traefik
listeners:
- name: web
port: 80
protocol: HTTP
allowedRoutes:
namespaces:
from: All
- name: websecure
port: 443
protocol: HTTPS
allowedRoutes:
namespaces:
from: All
tls:
certificateRefs:
- name: whoami-tls-le # References the secret created by cert-manager
갱신된 Gateway를 적용하세요:
kubectl apply -f gateway.yaml
기존 HTTPRoute는 이제 보안된 게이트웨이 리스너에 연결할 때 이 인증서를 사용할 거예요.
Let's Encrypt 인증서 확인하기
인증서가 발급되면 확인할 수 있어요:
# Check certificate status
kubectl get certificate -n default
# Verify the certificate chain
curl -v https://whoami.docker.localhost/ 2>&1 | grep -i "server certificate"
인증서가 Let's Encrypt가 발급한 것임을 볼 수 있을 거예요.
스티키 세션 구성하기
스티키 세션은 사용자의 요청이 항상 같은 백엔드 서버로 가도록 보장해요. 세션 상태를 유지하는 애플리케이션에 필수적이죠. whoami 서비스를 위해 스티키 세션을 구현해 볼게요.
먼저, 디플로이먼트 확장하기
스티키 세션을 시연하려면 먼저 디플로이먼트를 3개 레플리카로 확장하세요:
kubectl scale deployment whoami --replicas=3
Gateway API를 TraefikService와 함께 사용하기
먼저 스티키 세션용 TraefikService를 만드세요:
apiVersion: traefik.io/v1alpha1
kind: TraefikService
metadata:
name: whoami-sticky
namespace: default
spec:
weighted:
services:
- name: whoami
port: 80
weight: 1
sticky:
cookie:
name: sticky_cookie
secure: true
httpOnly: true
이걸 whoami-sticky-service.yaml로 저장하고 적용하세요:
kubectl apply -f whoami-sticky-service.yaml
이제 TraefikService를 참조하는 주석과 함께 HTTPRoute를 갱신하세요:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: whoami
namespace: default
spec:
parentRefs:
- name: traefik-gateway
sectionName: websecure
hostnames:
- "whoami.docker.localhost"
rules:
- matches:
- path:
type: PathPrefix
value: /api
filters:
- type: ExtensionRef
extensionRef: # Headers Middleware Definition
group: traefik.io
kind: Middleware
name: secure-headers
- type: ExtensionRef
extensionRef: # IP AllowList Middleware Definition
group: traefik.io
kind: Middleware
name: ip-allowlist
backendRefs:
- name: whoami-api
port: 80
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- group: traefik.io # <── tell Gateway this is a TraefikService
kind: TraefikService
name: whoami-sticky
filters:
- type: ExtensionRef
extensionRef: # Headers Middleware Definition
group: traefik.io
kind: Middleware
name: secure-headers
- type: ExtensionRef
extensionRef: # IP AllowList Middleware Definition
group: traefik.io
kind: Middleware
name: ip-allowlist
backendRefs:
- name: whoami
port: 80
whoami-route.yaml 파일을 갱신하고 적용하세요:
kubectl apply -f whoami-route.yaml
IngressRoute를 TraefikService와 함께 사용하기
먼저 스티키 세션용 TraefikService를 만드세요:
apiVersion: traefik.io/v1alpha1
kind: TraefikService
metadata:
name: whoami-sticky
namespace: default
spec:
weighted:
services:
- name: whoami
port: 80
sticky:
cookie:
name: sticky_cookie
secure: true
httpOnly: true
이걸 whoami-sticky-service.yaml로 저장하고 적용하세요:
kubectl apply -f whoami-sticky-service.yaml
이제 이 TraefikService를 쓰도록 IngressRoute를 갱신하세요:
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: whoami
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`whoami.docker.localhost`) && Path(`/api`)
kind: Rule
middlewares: # Middleware Definition
- name: secure-headers
- name: ip-allowlist
services:
- name: whoami-api
port: 80
- match: Host(`whoami.docker.localhost`)
kind: Rule
middlewares: # Middleware Definition
- name: secure-headers
- name: ip-allowlist
services:
- name: whoami-sticky # Changed from whoami to whoami-sticky
kind: TraefikService # Added kind: TraefikService
tls:
certResolver: le
whoami-ingressroute.yaml 파일을 갱신하고 적용하세요:
kubectl apply -f whoami-ingressroute.yaml
스티키 세션 테스트하기
여러 요청을 보내 모두 같은 백엔드 파드로 가는지 관찰하면 스티키 세션을 테스트할 수 있어요:
# First request - save cookies to a file
curl -k -c cookies.txt -H "Host: whoami.docker.localhost" https://localhost/
# Subsequent requests - use the cookies
curl -k -b cookies.txt -H "Host: whoami.docker.localhost" https://localhost/
curl -k -b cookies.txt -H "Host: whoami.docker.localhost" https://localhost/
각 응답의 Hostname 필드에 주목하세요. 쿠키 파일을 쓰면 모든 요청에서 똑같이 유지되어야 해요. 이게 스티키 세션이 동작한다는 증거입니다.
비교를 위해 쿠키 없이 요청을 보내 보세요:
# Requests without cookies should be load-balanced across different pods
curl -k -H "Host: whoami.docker.localhost" https://localhost/
curl -k -H "Host: whoami.docker.localhost" https://localhost/
이 응답들에서는 서로 다른 Hostname 값이 보일 거예요. 각 요청이 다른 파드로 로드 밸런싱되기 때문이죠.
브라우저 테스트
브라우저에서 테스트할 때는 쿠키를 유지하기 위해 같은 브라우저 세션을 써야 해요. 쿠키는 보안을 위해 httpOnly와 secure 플래그로 설정되므로 HTTPS 연결에서만 보내지고 JavaScript로 접근할 수 없어요.
더 고급 구성 옵션은 참조 문서를 확인하세요.
다중 레이어 라우팅 설정하기
다중 레이어 라우팅은 라우터 간 계층 관계를 가능하게 해요. 부모 라우터가 자식 라우터가 최종 라우팅 결정을 내리기 전에 미들웨어를 통해 요청을 처리할 수 있죠. 인증 기반 라우팅이나 단계별 미들웨어 적용에 특히 유용합니다.
IngressRoute 지원
다중 레이어 라우팅은 Kubernetes IngressRoute(CRD)에서 spec.parentRefs 필드로 네이티브 지원돼요. 이 기능은 표준 Kubernetes Ingress나 Gateway API 리소스를 쓸 때는 사용할 수 없습니다.
인증 기반 라우팅 예시
부모 IngressRoute가 요청을 인증하고, 자식 IngressRoute가 사용자 역할에 따라 트래픽을 지시하는 다중 레이어 라우팅 셋업을 만들어 볼게요.
부모 라우터 요구 사항
다중 레이어 라우팅에서 부모 라우터는 서비스를 정의하면 안 돼요. 자식 라우터가 자신의 매칭 규칙에 따라 서비스 선택을 처리할 거예요. 모든 자식 IngressRoute가 parentRefs로 부모를 올바르게 참조하는지 확인하세요.
먼저, 백엔드 서비스를 배포하세요:
# whoami-backends.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: admin-backend
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: admin-backend
template:
metadata:
labels:
app: admin-backend
spec:
containers:
- name: whoami
image: traefik/whoami
env:
- name: WHOAMI_NAME
value: "Admin Backend"
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: admin-backend
namespace: default
spec:
selector:
app: admin-backend
ports:
- port: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: user-backend
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: user-backend
template:
metadata:
labels:
app: user-backend
spec:
containers:
- name: whoami
image: traefik/whoami
env:
- name: WHOAMI_NAME
value: "User Backend"
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: user-backend
namespace: default
spec:
selector:
app: user-backend
ports:
- port: 80
백엔드 서비스를 적용하세요:
kubectl apply -f whoami-backends.yaml
이제 다중 레이어 라우팅용 미들웨어와 IngressRoute를 만드세요:
# mlr-ingressroute.yaml
apiVersion: v1
kind: Secret
metadata:
name: auth-secret
namespace: default
type: Opaque
stringData:
users: |
admin:$apr1$DmXR3Add$wfdbGw6RWIhFb0ffXMM4d0
user:$apr1$GJtcIY1o$mSLdsWYeXpPHVsxGDqadI.
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: auth-middleware
namespace: default
spec:
basicAuth:
secret: auth-secret
headerField: X-Auth-User
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: api-parent
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`api.docker.localhost`) && PathPrefix(`/api`)
kind: Rule
middlewares:
- name: auth-middleware
# Note: No services and no TLS config - this is a parent IngressRoute
---
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-Auth-User`, `admin`)
kind: Rule
services:
- name: admin-backend
port: 80
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: api-user
namespace: default
spec:
parentRefs:
- name: api-parent
namespace: default # Optional, defaults to same namespace
routes:
- match: HeadersRegexp(`X-Auth-User`, `user`)
kind: Rule
services:
- name: user-backend
port: 80
비밀번호 해시 생성
위의 비밀번호 해시는 htpasswd로 생성된 거예요. 자신만의 사용자 자격 증명을 만들려면:
# Using htpasswd (Apache utils)
htpasswd -nb admin yourpassword
다중 레이어 라우팅 구성을 적용하세요:
kubectl apply -f mlr-ingressroute.yaml
다중 레이어 라우팅 테스트하기
라우팅 동작을 테스트해 볼게요:
# Request goes through parent router → auth middleware → admin child router
curl -k -u admin:test -H "Host: api.docker.localhost" https://localhost/api
admin으로 인증하면 admin-backend 서비스의 응답이 보일 거예요. user:test 자격 증명으로 시도하면 user-backend 서비스에 도달하게 됩니다.
동작 방식
-
요청이 api.docker.localhost/api에 도달해요
-
부모 IngressRoute(api-parent)가 호스트와 경로를 기준으로 매칭해요
-
BasicAuth 미들웨어가 사용자를 인증하고 사용자 이름으로 X-Auth-User 헤더를 설정해요
-
자식 IngressRoute(api-admin 또는 api-user)가 헤더 값을 기준으로 매칭해요
-
요청이 적절한 Kubernetes 서비스로 전달돼요
크로스 네임스페이스 부모 참조
namespace 필드를 지정해서 다른 네임스페이스의 부모 IngressRoute를 참조할 수 있어요:
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: api-child
namespace: app-namespace
spec:
parentRefs:
- name: api-parent
namespace: shared-namespace # Parent in different namespace
routes:
- match: Path(`/child`)
kind: Rule
services:
- name: child-service
port: 80
크로스 네임스페이스 요구 사항
크로스 네임스페이스 부모 참조를 쓰려면 Traefik Helm values에서 allowCrossNamespace 옵션을 활성화해야 해요:
providers:
kubernetesCRD:
allowCrossNamespace: true
여러 부모 참조
자식 IngressRoute는 여러 부모 IngressRoute를 참조할 수 있어요:
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: api-child
namespace: default
spec:
parentRefs:
- name: parent-one
- name: parent-two
routes:
- match: Path(`/api`)
kind: Rule
services:
- name: child-service
port: 80
다중 레이어 라우팅에 대한 자세한 내용은 다중 레이어 라우팅 문서를 확인하세요.
서비스 미들웨어
서비스 미들웨어를 쓰면 개별 라우터가 아니라 서비스에 미들웨어를 적용할 수 있어요. 즉 어떤 라우터가 요청을 전달했든, 서비스가 처리하는 모든 요청에 미들웨어가 적용된다는 뜻이에요.
같은 미들웨어(예: 헤더, 속도 제한, 인증)를 서비스에 도달하는 모든 트래픽에 적용하고 싶은데 매 라우터에 구성하고 싶지 않을 때 유용합니다.
서비스 미들웨어를 언제 쓰나요?
다음과 같은 경우에 서비스 미들웨어를 쓰세요:
-
여러 라우터가 같은 서비스로 트래픽을 전달하는데 모두 같은 미들웨어를 적용해야 할 때
-
트래픽이 어떤 경로로 오든 서비스에 항상 미들웨어가 적용되도록 보장하고 싶을 때
-
관리하기 쉽도록 미들웨어 구성을 서비스 레벨에서 중앙 집중화할 때
서비스 레벨 vs 라우터 레벨 미들웨어
-
라우터 레벨 미들웨어: 트래픽이 그 특정 라우터의 규칙과 매칭될 때만 적용돼요
-
서비스 레벨 미들웨어: 어떤 라우터가 전달했든 서비스에 도달하는 모든 트래픽에 적용돼요
둘 다 구성되면 라우터 미들웨어가 먼저 실행되고, 이어서 서비스 미들웨어가 실행돼요.
IngressRoute를 서비스 미들웨어와 함께 사용하기
IngressRoute에서는 라우트 내의 서비스 참조에 직접 미들웨어를 붙일 수 있어요:
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: service-headers
namespace: default
spec:
headers:
customRequestHeaders:
X-Service-Middleware: "applied"
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: whoami
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`whoami.docker.localhost`)
kind: Rule
services:
- name: whoami
port: 80
middlewares:
- name: service-headers
tls: {}
이걸 service-middleware-ingressroute.yaml로 저장하고 적용하세요:
kubectl apply -f service-middleware-ingressroute.yaml
Gateway API를 백엔드 필터와 함께 사용하기
Gateway API는 backendRefs[].filters 필드를 통해 개별 백엔드에 직접 필터를 적용하는 걸 지원해요. 이로써 백엔드 레벨에서 요청 수정이 가능해집니다.
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: service-headers
namespace: default
spec:
headers:
customRequestHeaders:
X-Service-Middleware: "applied"
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: whoami
namespace: default
spec:
parentRefs:
- name: traefik-gateway
sectionName: websecure
hostnames:
- "whoami.docker.localhost"
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: whoami
port: 80
filters:
- type: ExtensionRef
extensionRef:
group: traefik.io
kind: Middleware
name: service-headers
Gateway API는 더 간단한 헤더 수정을 위해 네이티브 RequestHeaderModifier 필터 타입도 지원해요:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: whoami
namespace: default
spec:
parentRefs:
- name: traefik-gateway
sectionName: websecure
hostnames:
- "whoami.docker.localhost"
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: whoami
port: 80
filters:
- type: RequestHeaderModifier
requestHeaderModifier:
add:
- name: X-Backend-Header
value: "gateway-api-filter"
저장하고 적용하세요:
kubectl apply -f service-middleware-gateway.yaml
Kubernetes Ingress를 서비스 주석과 함께 사용하기
표준 Kubernetes Ingress에서는 주석으로 서비스에 미들웨어를 적용할 수 있어요:
apiVersion: v1
kind: Service
metadata:
name: whoami
namespace: default
annotations:
traefik.ingress.kubernetes.io/service.middlewares: default-service-headers@kubernetescrd
spec:
selector:
app: whoami
ports:
- port: 80
주석 값은 -@kubernetescrd 형식을 따릅니다.
서비스 미들웨어 테스트하기
서비스 미들웨어가 동작하는지 확인해 볼게요:
curl -k -H "Host: whoami.docker.localhost" https://localhost/
whoami 응답에서 서비스 미들웨어가 추가한 커스텀 헤더를 볼 수 있어요:
X-Service-Middleware: applied
서비스 미들웨어에 대한 자세한 내용은 참조 문서를 확인하세요.
결론
이 고급 가이드에서 다음을 배웠어요:
-
보안 헤더와 IP allow listing 같은 미들웨어로 보안 추가하기
-
Let's Encrypt(IngressRoute)와 cert-manager(Gateway API)로 인증서 관리 자동화하기
-
상태 유지 애플리케이션을 위한 스티키 세션 구현하기
-
인증 기반 라우팅을 위한 다중 레이어 라우팅 셋업하기 (IngressRoute 전용)
-
중앙 집중식 미들웨어 관리를 위해 서비스 레벨에서 미들웨어 적용하기
이런 고급 기능들 덕분에 Kubernetes에서 프로덕션 준비가 된 Traefik 배포를 만들 수 있어요. 각각은 여러분의 특정 요구에 맞게 더 커스터마이즈할 수 있습니다.
다음 단계
이제 Kubernetes에서 Traefik의 기본과 고급 기능을 모두 익혔으니, 다음을 탐구해 보고 싶을 거예요:
-
쿼리 매개변수 매칭, 헤더 기반 라우팅 등 고급 라우팅 옵션
-
인증, 속도 제한, 요청 수정을 위한 추가 미들웨어
-
Traefik 배포를 모니터링하고 디버깅하기 위한 관측성 기능
-
TCP 서비스 노출을 위한 TCP 서비스
-
UDP 서비스 노출을 위한 UDP 서비스
-
Kubernetes 통합에 대한 자세한 내용을 담은 Kubernetes 프로바이더 문서
-
Gateway API 통합에 대한 자세한 내용을 담은 Gateway API 프로바이더 문서