Traefik Kubernetes Ingress NGINX 문서
Traefik Kubernetes Ingress NGINX 문서 (Traefik Kubernetes Ingress NGINX Documentation)
본문
Traefik & NGINX 어노테이션이 있는 Ingress
이 프로바이더는 Ingress 사양을 지원하여 클러스터 서비스에 대한 액세스를 관리하는 Kubernetes Ingress 컨트롤러예요. 또한 Ingress에서 ingress-nginx 어노테이션을 다수 지원하여, 팀이 최소한의 구성 변경으로 NGINX Ingress Controller에서 Traefik으로 마이그레이션할 수 있게 해줘요.
NGINX Ingress Controller 은퇴 (Retirement)
Kubernetes NGINX Ingress Controller 프로젝트는 2026년 3월에 은퇴를 발표했으며 더 이상 업데이트나 보안 패치를 받지 않을 거예요. Traefik은 NGINX 어노테이션을 지원함으로써 마이그레이션 경로를 제공하여, 모든 Ingress 구성을 다시 작성하지 않고도 워크로드를 전환할 수 있게 해줍니다.
→ 단계별 지침은 NGINX에서 Traefik으로 마이그레이션 가이드를 참고하세요.
NGINX Ingress Controller 은퇴에 대한 자세한 내용은 공식 Kubernetes 블로그 공지도 참고하세요.
요구 사항 (Requirements)
Helm 차트 없이 Traefik을 설치하는 경우, Traefik Kubernetes Ingress NGINX 프로바이더에 대한 RBAC를 추가/업데이트해야 해요.
네임스페이스 셀렉터용 추가 RBAC
watchNamespaceSelector 옵션을 사용할 때 Traefik은 네임스페이스를 나열(list)하고 감시(watch)할 권한이 필요해요. 이 권한은 아래 RBAC 구성에 포함되어 있어요.
# Install RBAC for Traefik Ingress NGINX provider:
kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v3.7/docs/content/reference/dynamic-configuration/kubernetes-ingress-nginx-rbac.yml
Ingress 발견 (Ingress Discovery)
이 프로바이더는 기본적으로 클러스터의 모든 Ingress를 발견하는데, 표준 Kubernetes Ingress 프로바이더도 함께 사용한다면 중복 라우터가 생길 수 있어요.
모범 사례 (Best Practices)
- IngressClass를 사용해 이 프로바이더가 처리할 Ingress를 지정
- watchNamespace를 구성해 발견을 단일 네임스페이스로 제한
- watchNamespaceSelector를 사용해 네임스페이스 라벨 기반으로 Ingress를 대상 지정
IngressClass 선택 로직 (IngressClass Selection Logic)
기본적으로 프로바이더는 spec.controller가 controllerClass(기본값: k8s.io/ingress-nginx)와 일치하는 모든 IngressClass를 선택하고, 그중 하나라도 참조하는 모든 Ingress를 집게 됩니다. ingressClassByName: true로 설정하면 두 번째 포함 경로가 추가되어, 이름이 ingressClass와 일치하는 IngressClass도 spec.controller가 controllerClass와 일치하지 않더라도 집게 됩니다. 컨트롤러 기반 선택을 좁히지는 않으며 두 경로가 독립적으로 적용됩니다.
구성 예시 (Configuration Example)
아래에서 설명하는 것처럼 Kubernetes Ingress NGINX 프로바이더를 활성화할 수 있어요.
File (YAML)
providers:
kubernetesIngressNGINX:
# Namespace discovery
watchNamespace: "default"
# OR use namespace selector (mutually exclusive with watchNamespace)
# watchNamespaceSelector: "environment=production"
# IngressClass configuration
ingressClass: "nginx"
controllerClass: "k8s.io/ingress-nginx"
watchIngressWithoutClass: false
ingressClassByName: false
globalAuthURL: "http://foo.com/auth"
proxyConnectTimeout: 60
proxyReadTimeout: 60
proxySendTimeout: 60
proxyRequestBuffering: false
clientBodyBufferSize: "16384" # 16k
proxyBuffering: false
proxyBodySize: "1048576" # 1m
proxyBufferSize: "8192" # 8k
proxyBuffersNumber: 4
upstreamKeepaliveTimeout: 60
customHTTPErrors:
- "404"
- "503"
allowCrossNamespaceResources: true
allowSnippetAnnotations: false
globalAllowedResponseHeaders:
- "X-Custom-Header1"
- "X-Custom-Header2"
ipAllowListStrategy:
depth: 2
strictValidatePathType: false
File (TOML)
[providers.kubernetesIngressNGINX]
# Namespace discovery
watchNamespace = "default"
# OR use namespace selector (mutually exclusive with watchNamespace)
# watchNamespaceSelector = "environment=production"
# IngressClass configuration
ingressClass = "nginx"
controllerClass = "k8s.io/ingress-nginx"
watchIngressWithoutClass = false
ingressClassByName = false
globalAuthURL = "http://foo.com/auth"
proxyConnectTimeout = 60
proxyReadTimeout = 60
proxySendTimeout = 60
proxyRequestBuffering = false
clientBodyBufferSize = "16384" # 16k
proxyBuffering = false
proxyBodySize = "1048576" # 1m
proxyBufferSize = "8192" # 8k
proxyBuffersNumber = 4
upstreamKeepaliveTimeout = 60
customHTTPErrors = ["404", "503"]
allowCrossNamespaceResources = true
allowSnippetAnnotations = false
globalAllowedResponseHeaders = ["X-Custom-Header1", "X-Custom-Header2"]
strictValidatePathType = false
[providers.kubernetesIngressNGINX.ipAllowListStrategy]
depth = 2
CLI
--providers.kubernetesingressnginx=true
--providers.kubernetesingressnginx.watchnamespace=default
--providers.kubernetesingressnginx.ingressclass=nginx
--providers.kubernetesingressnginx.controllerclass=k8s.io/ingress-nginx
--providers.kubernetesingressnginx.watchingresswithoutclass=false
--providers.kubernetesingressnginx.ingressclassbyname=false
--providers.kubernetesingressnginx.globalauthurl=http://foo.com/auth
--providers.kubernetesingressnginx.proxyconnecttimeout=60
--providers.kubernetesingressnginx.proxyreadtimeout=60
--providers.kubernetesingressnginx.proxysendtimeout=60
--providers.kubernetesingressnginx.proxyrequestbuffering=false
--providers.kubernetesingressnginx.clientbodybuffersize=16384 # 16k
--providers.kubernetesingressnginx.proxybuffering=false
--providers.kubernetesingressnginx.proxybodysize=1048576 # 1m
--providers.kubernetesingressnginx.proxybuffersize=8192 # 8k
--providers.kubernetesingressnginx.proxybuffersnumber=4
--providers.kubernetesingressnginx.upstreamkeepalimetimeout=60
--providers.kubernetesingressnginx.customhttperrors=404,503
--providers.kubernetesingressnginx.allowCrossNamespaceResources=true
--providers.kubernetesingressnginx.allowsnippetannotations=false
--providers.kubernetesingressnginx.globalAllowedResponseHeaders=X-Custom-Header1,X-Custom-Header2
--providers.kubernetesingressnginx.ipallowliststrategy.depth=2
--providers.kubernetesingressnginx.strictvalidatepathtype=false
Helm Chart Values
providers:
kubernetesIngressNginx:
# -- Enable Kubernetes Ingress NGINX provider
enabled: true
# Namespace discovery
# -- Namespace the controller watches for updates to Kubernetes objects
# When using rbac.namespaced, it will watch helm release namespace and namespaces listed in this array
namespaces:
- default
# OR use namespace selector (mutually exclusive with namespaces)
# namespaceSelector: "environment=production"
# IngressClass configuration
# -- Name of the ingress class this controller satisfies
ingressClass: "nginx"
# -- Ingress Class Controller value this controller satisfies
controllerClass: "k8s.io/ingress-nginx"
# -- Define if Ingress Controller should also watch for Ingresses without an IngressClass or the annotation specified
watchIngressWithoutClass: false
# -- Define if Ingress Controller should watch for Ingress Class by Name together with Controller Class
ingressClassByName: false
이 프로바이더는 들어오는 Ingress 이벤트를 감시하고 NGINX 어노테이션을 Traefik의 동적 구성으로 자동 변환하여, 트래픽을 클러스터 서비스로 라우팅하기 위한 해당 라우터, 서비스, 미들웨어 및 기타 구성 요소를 만듭니다.
구성 옵션 (Configuration Options)
| Field | Description | Default | Required |
| providers.providers ThrottleDuration | 구성 리로드 이후, 새로운 구성 갱신 이벤트를 반영하기까지 기다리는 최소 시간. 이 시간 안에 여러 이벤트가 발생하면 가장 최근 이벤트 하나만 반영되고 나머지는 모두 버려져요. 이 옵션은 프로바이더별로 설정할 수 없지만, 스로틀링 알고리즘은 각 프로바이더에 독립적으로 적용됩니다. | 2s | No |
| providers. kubernetesIngressNGINX. endpoint | 서버 엔드포인트 URL. 자세한 정보는 여기. | "" | No |
| providers. kubernetesIngressNGINX. token | Kubernetes 클라이언트 구성에 사용되는 Bearer 토큰. | "" | No |
| providers. kubernetesIngressNGINX. certAuthFilePath | 인증 기관 파일의 경로. Kubernetes 클라이언트 구성에 사용됨. | "" | No |
| providers. kubernetesIngressNGINX. throttleDuration | 새 구성을 생성하기 전에 두 Kubernetes 이벤트 사이에 대기하는 최소 시간. 초당 여러 번 갱신되는 Kubernetes 클러스터가 Traefik 구성을 계속 바꾸는 것을 방지해요. 비워 두면 모든 이벤트가 포착됩니다. | 0s | No |
| providers. kubernetesIngressNGINX. globalAuthURL | 모든 location에 대해 인증을 제공하는 서비스의 URL. 인그레스별 auth-url 어노테이션이 이 옵션보다 우선해요. | "" | No |
| providers. kubernetesIngressNGINX. watchNamespace | 컨트롤러가 Kubernetes 객체 갱신을 감시하는 네임스페이스. 이 매개변수를 비워 두면 모든 네임스페이스가 감시됩니다. | "" | No |
| providers. kubernetesIngressNGINX. watchNamespaceSelector | 셀렉터로, 컨트롤러가 Kubernetes 객체 갱신을 감시하는 네임스페이스를 선택해요. | "" | No |
| providers. kubernetesIngressNGINX. ingressClass | 이 컨트롤러가 처리하는 IngressClass의 이름. ingressClassByName이 true일 때 이 이름의 IngressClass는 spec.controller 값과 무관하게 발견에 포함됩니다. | "nginx" | No |
| providers. kubernetesIngressNGINX. controllerClass | 이 컨트롤러가 충족하는 Ingress Class Controller 값. | "k8s.io/ingress-nginx" | No |
| providers. kubernetesIngressNGINX. watchIngressWithoutClass | Ingress Controller가 IngressClass나 지정된 어노테이션이 없는 Ingress도 감시할지 여부를 정의해요. | false | No |
| providers. kubernetesIngressNGINX. ingressClassByName | true일 때, 이름이 ingressClass와 일치하는 모든 IngressClass는 그 spec.controller가 controllerClass와 일치하지 않더라도 발견에 포함됩니다. 이는 컨트롤러 기반 선택과 함께 평가되며 대체가 아닙니다. | false | No |
| providers. kubernetesIngressNGINX. publishService | Ingress 컨트롤러 앞에 있는 서비스. namespace/name 형태를 취해요. | "" | No |
| providers. kubernetesIngressNGINX. publishStatusAddress | 이 컨트롤러가 충족하는 Ingress 객체의 로드 밸런서 상태로 설정할 커스터마이즈된 주소(또는 쉼표로 구분된 여러 주소). | "" | No |
| providers. kubernetesIngressNGINX. defaultBackendService | 알려진 서버 이름과 일치하지 않는 HTTP 요청(catch-all)을 제공하는 데 사용되는 서비스. 'namespace/name' 형태를 취해요. | "" | No |
| providers. kubernetesIngressNGINX. disableSvcExternalName | ExternalName 유형의 Services 지원을 비활성화해요. | false | No |
| providers. kubernetesIngressNGINX. proxyConnectTimeout | 서버에 대한 연결이 수립될 때까지 기다리는 시간. 값은 단위가 없는 초 단위예요. 인그레스별 타임아웃이 구성되지 않았을 때 전역 연결 타임아웃으로 사용됩니다. 인그레스별 타임아웃은 nginx.ingress.kubernetes.io/proxy-connect-timeout 어노테이션으로 구성할 수 있어요. | 60 | No |
| providers. kubernetesIngressNGINX. proxyReadTimeout | 두 연속 읽기 작업 사이의 시간. 값은 단위가 없는 초 단위예요. 인그레스별 타임아웃이 구성되지 않았을 때 전역 읽기 타임아웃으로 사용됩니다. 인그레스별 타임아웃은 nginx.ingress.kubernetes.io/proxy-read-timeout 어노테이션으로 구성할 수 있어요. | 60 | No |
| providers. kubernetesIngressNGINX. proxySendTimeout | 두 연속 쓰기 작업 사이의 시간. 값은 단위가 없는 초 단위예요. 인그레스별 타임아웃이 구성되지 않았을 때 전역 전송 타임아웃으로 사용됩니다. 인그레스별 타임아웃은 nginx.ingress.kubernetes.io/proxy-send-timeout 어노테이션으로 구성할 수 있어요. | 60 | No |
| providers. kubernetesIngressNGINX. proxyrequestbuffering | 모든 인그레스에 대해 기본적으로 요청 버퍼링이 활성화되는지 여부를 정의해요. | false | No |
| providers. kubernetesIngressNGINX. clientBodyBufferSize | 클라이언트 요청 본문을 읽기 위한 기본 버퍼 크기(바이트). | 16384 | No |
| providers. kubernetesIngressNGINX. proxybuffering | 모든 인그레스에 대해 기본적으로 응답 버퍼링이 활성화되는지 여부를 정의해요. | false | No |
| providers. kubernetesIngressNGINX. proxyBodySize | 클라이언트 요청 본문의 기본 최대 크기(바이트). | 1048576 | No |
| providers. kubernetesIngressNGINX. proxyBufferSize | 응답 본문을 읽기 위한 기본 버퍼 크기(바이트). | 8192 | No |
| providers. kubernetesIngressNGINX. proxyBuffersNumber | 응답을 읽기 위한 기본 버퍼 수. | 4 | No |
| providers. kubernetesIngressNGINX. proxyNextUpstream | 요청을 재시도해야 하는 경우를 정의해요. 허용되는 값은 공백으로 구분된 error, timeout, http_XXX(예: http_502), non_idempotent, off(재시도 비활성화) 목록이에요. 인그레스별 값이 구성되지 않았을 때 전역 proxy-next-upstream 구성으로 사용됩니다. 인그레스별 구성은 nginx.ingress.kubernetes.io/proxy-next-upstream 어노테이션으로 설정할 수 있어요. | "error timeout" | No |
| providers. kubernetesIngressNGINX. proxyNextUpstreamTries | 백엔드 서버가 응답하지 않을 때 가능한 재시도 횟수를 제한해요. 0은 무제한 재시도를 의미하며, 사용 가능한 서버 수로 제한됩니다. 인그레스별 값이 구성되지 않았을 때 전역 재시도 횟수 구성으로 사용됩니다. 인그레스별 재시도 제한은 nginx.ingress.kubernetes.io/proxy-next-upstream-tries 어노테이션으로 설정할 수 있어요. | 3 | No |
| providers. kubernetesIngressNGINX. proxyNextUpstreamTimeout | 백엔드 서버가 응답하지 않을 때 요청을 재시도하는 총 경과 시간을 제한해요. 타임아웃 값은 단위가 없는 초 단위예요. 0은 타임아웃 없음을 의미해요. 인그레스별 값이 구성되지 않았을 때 전역 재시도 타임아웃으로 사용됩니다. 인그레스별 재시도 타임아웃은 nginx.ingress.kubernetes.io/proxy-next-upstream-timeout 어노테이션으로 설정할 수 있어요. | 0 | No |
| providers. kubernetesIngressNGINX. upstreamKeepaliveTimeout | 업스트림 서버에 대한 keep-alive 연결의 유휴 타임아웃을 정의해요. 값은 단위가 없는 초 단위예요. | 60 | No |
| providers. kubernetesIngressNGINX. customHTTPErrors | 어떤 상태가 기본 백엔드를 호출해 오류 페이지를 반환하게 되는지 정의해요. | [] | No |
| providers. kubernetesIngressNGINX. allowCrossNamespaceResources | Ingress가 다른 네임스페이스의 리소스(예: ConfigMaps, Secrets)를 참조할 수 있게 해요. | false | No |
| providers. kubernetesIngressNGINX. globalAllowedResponseHeaders | 커스텀 헤더 어노테이션 안에 허용되는 응답 헤더 목록. 커스텀 헤더 어노테이션이 효과를 발휘하려면 이를 구성해야 해요. | [] | No |
| providers. kubernetesIngressNGINX. ipAllowListStrategy | allowlist-source-range 및 whitelist-source-range 어노테이션의 클라이언트 IP를 결정하기 위한 IP 전략을 정의해요. 설정하면 전략이 모든 생성된 IPAllowList 미들웨어에 적용됩니다. | - | No |
| providers. kubernetesIngressNGINX. ipAllowListStrategy. depth | X-Forwarded-For 헤더에서 클라이언트 IP를 추출할 때 건너뛸 신뢰하는 프록시 홉 수. 0은 깊이 기반 추출을 비활성화해요. | 0 | No |
| providers. kubernetesIngressNGINX. ipAllowListStrategy. excludedIPs | 클라이언트 IP를 찾기 위해 X-Forwarded-For 헤더를 스캔할 때 제외할 IP 목록. | [] | No |
| providers. kubernetesIngressNGINX. ipAllowListStrategy. ipv6Subnet | 허용 목록을 확인할 때 IPv6 주소를 그룹화하는 데 사용되는 IPv6 서브넷 크기. 0은 서브넷 그룹화를 비활성화해요. | 0 | No |
| providers. kubernetesIngressNGINX. httpentrypoint | HTTP 요청에 사용할 엔트리포인트를 정의해요. | "" | No |
| providers. kubernetesIngressNGINX. httpsentrypoint | HTTPS 요청에 사용할 엔트리포인트를 정의해요. | "" | No |
| providers. kubernetesIngressNGINX. strictValidatePathType | 경로에 정규식 문자가 포함되고 pathType이 Prefix 또는 Exact일 때 인그레스 전체를 거부할지 여부를 정의해요. | true | No |
endpoint
Kubernetes 서버 엔드포인트 URL이에요.
Kubernetes에 배포될 때 Traefik은 KUBERNETES_SERVICE_HOST와 KUBERNETES_SERVICE_PORT 또는 KUBECONFIG 환경 변수를 읽어 엔드포인트를 구성해요.
액세스 토큰은 /var/run/secrets/kubernetes.io/serviceaccount/token에서, SSL CA 인증서는 /var/run/secrets/kubernetes.io/serviceaccount/ca.crt에서 조회됩니다. 둘 다 Kubernetes 안에 배포될 때 자동으로 마운트돼요.
클러스터 안에서 환경 변수 값을 오버라이드하려면 엔드포인트를 지정할 수 있어요.
환경 변수를 찾지 못하면 Traefik은 external-cluster 클라이언트로 Kubernetes API 서버에 연결하려고 해요. 이 경우 엔드포인트가 필요합니다. 특히 관련 kubeconfig가 부여한 인증과 권한을 사용해 Kubernetes 클러스터에 연결하기 위해 kubectl proxy가 사용하는 URL로 설정할 수 있어요.
File (YAML)
providers:
kubernetesIngressNGINX:
endpoint: "http://localhost:8080"
# ...
File (TOML)
[providers.kubernetesIngressNGINX]
endpoint = "http://localhost:8080"
# ...
CLI
--providers.kubernetesingressnginx.endpoint=http://localhost:8080
라우팅 구성 (Routing Configuration)
라우팅(routing) 문서의 전용 섹션을 참고하세요.
프로덕션에서 Traefik OSS를 사용하고 계신가요?
직장에서 Traefik을 사용하고 있다면 기업용 API 게이트웨이 기능이나 Traefik OSS에 대한 상용 지원을 고려해 보세요.
- API 게이트웨이 데모 영상 보기
- 24/7/365 OSS 지원 요청하기
Traefik OSS에 API 게이트웨이 기능을 추가하는 일은 빠르고 매끄러워요. 교체(rip and replace)가 필요 없고 모든 구성이 그대로 유지됩니다. 이 짧은 영상에서 실제 동작을 확인해 보세요.