Traefik
Lumie 클러스터는 K3s 내장 Traefik을 Ingress Controller로 사용합니다. Kong 게이트웨이를 대체하였으며, 외부에서 유입되는 모든 애플리케이션 트래픽(lumie-edu.com)을 처리합니다.
역할 분리
| 컴포넌트 | 도메인 | 노드 | DNS 진입 |
|---|---|---|---|
| Traefik | lumie-edu.com, dev.lumie-edu.com, dev.lumie-infra.com | 워커 노드 전체 | Cloudflare Proxy → NLB 168.107.42.253 |
| Teleport | lumie-infra.com, *.lumie-infra.com | 마스터 노드 (hostNetwork) | OCI 0213 NLB 158.180.89.154 직접 |
마스터 노드의 443 포트는 Teleport가 단독 점유합니다. 따라서 Traefik svclb DaemonSet은 마스터 노드에 배포되지 않도록 노드 레이블 svccontroller.k3s.cattle.io/enablelb를 제거하거나 node.kubernetes.io/exclude-from-external-load-balancers 레이블을 마스터에 설정합니다.
트래픽 흐름
K3s 설정 (masters.yml)
provision/ansible/group_vars/masters.yml에서 K3s 서버 인수를 정의합니다. Traefik과 svclb는 K3s 기본값인 활성화 상태를 유지합니다 — --disable traefik 옵션을 사용하지 않습니다:
# provision/ansible/group_vars/masters.yml
k3s_server_args:
- "--write-kubeconfig-mode 644"
- "--tls-san {{ ansible_host }}" # 공용 IP
- "--tls-san {{ private_ip }}" # 프라이빗 IP
- "--cluster-cidr {{ k3s_cluster_cidr }}"
- "--service-cidr {{ k3s_service_cidr }}"
--disable traefik 항목이 없으므로 K3s가 Traefik을 자동으로 설치하고 관리합니다.
HelmChartConfig (K3s 커스터마이즈)
K3s는 HelmChartConfig 리소스로 내장 Traefik Helm 차트 값을 오버라이드합니다. platform/traefik-config/helmchartconfig.yaml에 정의되어 있습니다:
apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
name: traefik
namespace: kube-system
spec:
valuesContent: |-
ports:
web:
transport:
respondingTimeouts:
readTimeout: 1200s
writeTimeout: 1200s
idleTimeout: 600s
websecure:
transport:
respondingTimeouts:
readTimeout: 1200s
writeTimeout: 1200s
idleTimeout: 600s
타임아웃을 1200초(20분)로 설정한 이유는 Zot 레지스트리에 대용량 이미지(~1.2GB Chromium 레이어 포함 report-svc)를 업로드할 때 기본 타임아웃으로 인해 HTTP 499가 발생했기 때문입니다. 이 값은 전체 Ingress에 전역 적용됩니다.
HTTP → HTTPS 리다이렉트는 K3s Traefik이 기본적으로 처리하며, 별도 설정이 필요 없습니다.
HTTP → HTTPS 리다이렉트
ports.web.redirectTo 설정으로 포트 80으로 유입된 모든 요청을 443으로 영구 리다이렉트(301)합니다. 별도의 IngressRoute나 미들웨어 없이 엔트리포인트 수준에서 처리됩니다.
StripPrefix 미들웨어
lumie-backend는 /api/<module> 경로로 외부에 노출되지만, 내부 Spring Boot 서블릿은 /<module> 경로로 요청을 처리합니다. strip-prefix.yaml에 정의된 Traefik Middleware 리소스로 경로 접두사를 제거합니다.
# applications/lumie/backend/lumie-backend/manifests/strip-prefix.yaml
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: strip-api-prefix
namespace: lumie-backend
spec:
stripPrefix:
prefixes:
- /api/tenant
- /api/auth
- /api/academy
- /api/admin
- /api/exam
- /api/content
- /api/attendance
- /api/billing
- /api/file
- /api/ai
이 미들웨어는 lumie-backend 네임스페이스에 정의되며, kustomization.yaml의 resources에 직접 포함됩니다:
# applications/lumie/backend/lumie-backend/kustomization.yaml
helmCharts:
- name: common
releaseName: lumie-backend
namespace: lumie-backend
valuesFile: common-values.yaml
resources:
- manifests/strip-prefix.yaml
Ingress에서 어노테이션으로 참조합니다:
annotations:
traefik.ingress.kubernetes.io/router.middlewares: lumie-backend-strip-api-prefix@kubernetescrd
미들웨어 참조 형식: <namespace>-<middleware-name>@kubernetescrd
lumie-backend Ingress 구성
lumie-backend는 두 개의 Ingress로 구성됩니다. /api/auth 경로는 JWT 없이 별도 Ingress로 처리합니다:
# common-values.yaml — 주 Ingress (StripPrefix 미들웨어 적용)
common:
ingress:
enabled: true
className: traefik
annotations:
traefik.ingress.kubernetes.io/router.middlewares: lumie-backend-strip-api-prefix@kubernetescrd
cert-manager.io/cluster-issuer: letsencrypt-prod
hosts:
- host: lumie-edu.com
paths:
- path: /api/tenant
pathType: Prefix
- path: /api/academy
pathType: Prefix
- path: /api/admin
pathType: Prefix
- path: /api/exam
pathType: Prefix
- path: /api/content
pathType: Prefix
- path: /api/attendance
pathType: Prefix
- path: /api/billing
pathType: Prefix
- path: /api/file
pathType: Prefix
- path: /api/ai
pathType: Prefix
tls:
- hosts:
- lumie-edu.com
secretName: lumie-backend-tls
# auth 경로: StripPrefix만 적용, TLS 없음
additionalIngresses:
- name: lumie-backend-auth
className: traefik
servicePort: 8080
annotations:
traefik.ingress.kubernetes.io/router.middlewares: lumie-backend-strip-api-prefix@kubernetescrd
hosts:
- host: lumie-edu.com
paths:
- path: /api/auth
pathType: Prefix
공통 Helm 차트 기본값
charts/common/values.yaml의 Ingress 기본 className은 traefik으로 설정되어 있습니다:
# charts/common/values.yaml
common:
ingress:
enabled: true
className: traefik # 모든 서비스의 기본 Ingress Class
annotations: {}
...
TLS 인증서 (cert-manager)
모든 인증서는 cert-manager + Let's Encrypt로 자동 발급/갱신됩니다.
# Ingress TLS 설정 예시
spec:
ingressClassName: traefik
tls:
- hosts:
- lumie-edu.com
secretName: lumie-frontend-tls
rules:
- host: lumie-edu.com
...
Ingress에 cert-manager.io/cluster-issuer: letsencrypt-prod 어노테이션을 추가하면 cert-manager가 자동으로 Certificate 리소스를 생성하고 시크릿에 TLS 키/인증서를 저장합니다.
JWT/CORS 처리 위치
Kong 시절에는 플러그인에서 처리하던 JWT 검증과 CORS 정책이 이제 Spring Boot 애플리케이션 레벨로 이동되었습니다:
| 기능 | 이전 (Kong) | 현재 |
|---|---|---|
| JWT 검증 | KongClusterPlugin: lumie-jwt | Spring Security 필터 체인 |
| CORS | KongClusterPlugin: lumie-cors | Spring WebMvcConfigurer |
| JWT 시크릿 | Kong Consumer + Vault | lumie-backend-jwt-secrets Secret |
| 클레임 헤더 주입 | Kong post-function | Spring Security Context |
운영 명령어
# Traefik 파드 상태 확인 (kube-system)
kubectl get pods -n kube-system -l app.kubernetes.io/name=traefik
# Traefik 버전 확인
kubectl get helmchart traefik -n kube-system
# HelmChartConfig 확인
kubectl get helmchartconfig -n kube-system
# Ingress 전체 목록
kubectl get ingress -A
# StripPrefix 미들웨어 확인
kubectl get middleware -A
# IngressRoute 확인 (Traefik CRD 기반)
kubectl get ingressroute -A
# Traefik 로그 확인
kubectl logs -n kube-system -l app.kubernetes.io/name=traefik --tail=100
# svclb DaemonSet 확인 (워커 노드에만 배포되어야 함)
kubectl get pods -n kube-system -l app=svclb-traefik -o wide
문제 해결
StripPrefix 미들웨어 미적용
# 미들웨어가 lumie-backend 네임스페이스에 존재하는지 확인
kubectl get middleware -n lumie-backend
# Ingress 어노테이션 확인 (네임스페이스 접두사 포함 여부)
kubectl describe ingress -n lumie-backend lumie-backend
# 어노테이션: lumie-backend-strip-api-prefix@kubernetescrd 형식이어야 함
마스터 노드에 svclb Pod가 배포되는 경우
# 마스터 노드 레이블 확인
kubectl get node k3s-master --show-labels | grep enablelb
# enablelb 레이블 제거
kubectl label node k3s-master svccontroller.k3s.cattle.io/enablelb-
443 포트 충돌 (Teleport와 Traefik)
마스터 노드에서 443 포트는 Teleport가 점유합니다. svclb DaemonSet이 마스터에 배포되면 포트 충돌이 발생합니다. 위의 레이블 제거 절차로 해결합니다.
관련 문서
- cert-manager — TLS 인증서 자동화
- Teleport — 인프라 접근 (lumie-infra.com)
- 클러스터 개요 — 노드 및 Ingress 구조
- Kong (레거시) — 이전 API 게이트웨이 참조