- Published on
쿠버네티스 네트워킹의 종말과 부활: 2026년 3월 이전에 반드시 알아야 할 5가지 변화
- Authors
- Name
- 1. 서론: 당신의 클러스터가 위험에 처해 있습니다
- 2. [Takeaway 1] 시한폭탄의 카운트다운: Ingress NGINX의 공식 은퇴
- 3. [Takeaway 2] 어노테이션(Annotation)의 늪에서 탈출하기
- 4. [Takeaway 3] 역할의 분리: 인프라 관리자와 개발자의 평화로운 공존
- 5. [Takeaway 4] 벤더 종속성을 깨는 이식성(Portability)의 실현
- 6. [Takeaway 5] 성능의 도약: HTTP/3와 QUIC의 본격 도입
- 7. 실전 마이그레이션 가이드
- 8. 종합 마이그레이션 체크리스트
- 9. 결론: 이제 행동해야 할 때입니다
- 10. 참고 자료
1. 서론: 당신의 클러스터가 위험에 처해 있습니다
2026년 3월, 쿠버네티스 생태계에서 가장 광범위하게 사용되어 온 인프라 구성 요소 중 하나가 공식적으로 생명을 다합니다. Ingress NGINX Controller(kubernetes/ingress-nginx)의 EOL(End of Life)입니다.
이것은 단순한 버전 업그레이드나 마이너 변경이 아닙니다. 인터넷에 연결된 쿠버네티스 클러스터의 약 **41~50%**가 Ingress NGINX를 사용하고 있으며, RKE2, IBM Cloud, Alibaba ACK 등 주요 플랫폼에서 기본 인그레스 컨트롤러로 탑재되어 있습니다. 이 컨트롤러가 더 이상 보안 패치, 버그 수정, 그리고 어떠한 릴리스도 받지 못하게 된다는 것은 곧 수십만 개의 프로덕션 클러스터가 보호받지 못하는 상태로 방치된다는 것을 의미합니다.
"In March 2026, Kubernetes will retire Ingress NGINX, a piece of critical infrastructure for about half of cloud native environments... Half of you will be affected. You have two months left to prepare... We cannot overstate the severity of this situation or the importance of beginning migration..."
-- Kat Cosgrove, CNCF Ambassador & DevRel Engineer
이 글에서는 이 전환의 본질을 5가지 핵심 관점에서 분석합니다:
- 시한폭탄의 카운트다운 -- Ingress NGINX의 공식 은퇴와 그 여파
- 어노테이션의 늪에서 탈출 -- 구조적 결함과 Gateway API의 해법
- 역할의 분리 -- 인프라 관리자와 개발자의 평화로운 공존
- 벤더 종속성 탈피 -- 이식성(Portability)의 실현
- 성능의 도약 -- HTTP/3와 QUIC의 본격 도입
┌─────────────────────────────────────────────────────────────────┐
│ 2026년 쿠버네티스 네트워킹 전환 로드맵 │
├──────────┬──────────┬──────────┬──────────┬──────────┬──────────┤
│ 2025.03 │ 2025.11 │ 2026.03 │ 2026.06 │ 2026.11 │ 2027+ │
│ │ │ │ │ │ │
│ Ingress │ 은퇴 │ ■ EOL ■ │ Gateway │ AKS/GKE │ Ingress │
│ Nightmare│ 공식 │ 보안패치 │ API v1.5 │ 연장지원 │ API │
│ CVE 발생 │ 발표 │ 완전종료 │ (예상) │ 종료 │ 잔존 │
│ │ │ │ │ │ 가능성↓ │
│ GW API │ GW API │ │ │ │ │
│ v1.2 │ v1.4 GA │ │ │ │ │
└──────────┴──────────┴──────────┴──────────┴──────────┴──────────┘
▲ ▲ ▲
│ │ │
CVE-2025-1974 커뮤니티 지원 클라우드 벤더
CVSS 9.8 완전 종료 연장 지원 종료
2. [Takeaway 1] 시한폭탄의 카운트다운: Ingress NGINX의 공식 은퇴
2.1 무엇이 은퇴하는가: 정확한 범위 정의
혼동을 방지하기 위해 명확히 해야 할 것이 있습니다. 은퇴하는 것은 kubernetes/ingress-nginx 컨트롤러 프로젝트입니다. GA(General Availability) 상태인 Ingress API 자체(networking.k8s.io/v1)는 쿠버네티스에서 여전히 지원됩니다. 그러나 Ingress API를 실제로 동작시키는 가장 대중적인 구현체가 사라지는 것이므로, 실질적 영향은 막대합니다.
┌─────────────────────────────────────────────────────────┐
│ 은퇴 범위 명확화 │
│ │
│ ✗ 은퇴 대상: kubernetes/ingress-nginx 컨트롤러 │
│ (커뮤니티 유지보수 프로젝트) │
│ │
│ ✓ 유지 대상: Ingress API (networking.k8s.io/v1) │
│ F5 NGINX Ingress Controller (상용) │
│ 기타 서드파티 Ingress 구현체 │
│ │
│ ★ 새 표준: Gateway API (gateway.networking.k8s.io) │
└─────────────────────────────────────────────────────────┘
2.2 왜 지금인가: 구조적 문제의 누적
Ingress NGINX 프로젝트의 은퇴는 갑작스러운 결정이 아닙니다. 수년간 누적된 구조적 문제들이 임계점에 도달한 결과입니다:
1) 유지보수 인력의 고갈
프로젝트는 오랜 기간 동안 단 한두 명의 자원봉사자에 의존해 왔습니다. 인터넷에 연결된 클러스터의 절반에 영향을 미치는 핵심 인프라가 개인의 여가 시간에 의존한다는 것은 지속 가능한 모델이 아닙니다.
"For a long time, we've considered big companies or end user companies that rely on open source not contributing back to be a moral issue. But now, I think it's very easy to make the argument that not contributing back to open source is, in fact, a security issue. You have to start considering open source contributions as part of your security plan."
-- Kat Cosgrove
2) 감당할 수 없는 기술 부채
한때 유연성으로 평가받았던 기능들, 특히 snippets 어노테이션을 통한 임의의 NGINX 설정 주입 기능이 이제는 감당할 수 없는 보안 취약점으로 인식됩니다. 이 문제는 뒤에서 더 자세히 다루겠습니다.
3) IngressNightmare: CVE-2025-1974의 충격
2025년 3월에 발견된 CVE-2025-1974(CVSS 9.8)은 Ingress NGINX의 구조적 취약성을 극적으로 드러냈습니다.
2.3 IngressNightmare: 역대 최악의 쿠버네티스 취약점
CVE-2025-1974는 단독 취약점이 아니라, 5개의 연쇄 취약점(CVE-2025-1097, CVE-2025-1098, CVE-2025-24513, CVE-2025-24514, CVE-2025-1974)으로 구성된 공격 체인입니다.
| CVE ID | CVSS | 설명 |
|---|---|---|
| CVE-2025-24514 | 8.8 | auth-url 어노테이션을 통한 설정 주입 |
| CVE-2025-1097 | 8.8 | auth-tls-match-cn 어노테이션을 통한 설정 주입 |
| CVE-2025-1098 | 8.8 | mirror-target/mirror-host 어노테이션을 통한 설정 주입 |
| CVE-2025-24513 | 4.8 | auth-url 파일 경로 검증 부재 |
| CVE-2025-1974 | 9.8 | 인증 없는 원격 코드 실행(Unauthenticated RCE) |
공격 시나리오:
공격자 (Pod 네트워크 접근 가능)
│
▼
┌──────────────────────────┐
│ Admission Webhook │ ← 인증 없이 접근 가능
│ (8443 포트) │
└──────────┬───────────────┘
│ 악의적 Ingress 객체 전송
▼
┌──────────────────────────┐
│ NGINX 설정 주입 │ ← 임의의 NGINX directive 삽입
│ (CVE-2025-1097/1098/ │
│ 24514 활용) │
└──────────┬───────────────┘
│ 조작된 설정으로 RCE 달성
▼
┌──────────────────────────┐
│ 컨트롤러 Pod 장악 │ ← CVE-2025-1974
│ (CVSS 9.8) │
└──────────┬───────────────┘
│ ServiceAccount 토큰 탈취
▼
┌──────────────────────────┐
│ 전체 클러스터 시크릿 │ ← 모든 네임스페이스의
│ 접근 및 클러스터 탈취 │ Secret 열람 가능
└──────────────────────────┘
Wiz Research에 따르면, 클라우드 환경의 약 43%가 이 취약점에 노출되어 있었으며, Fortune 500 기업을 포함한 6,500개 이상의 클러스터가 취약한 Admission Controller를 퍼블릭 인터넷에 노출하고 있었습니다.
이 사건의 핵심 교훈은 명확합니다: 어노테이션 기반 설정 주입이라는 아키텍처 자체가 근본적인 보안 위협이라는 것입니다.
2.4 EOL 타임라인과 플랫폼별 영향
| 시점 | 이벤트 | 영향 |
|---|---|---|
| 2025년 3월 | IngressNightmare(CVE-2025-1974) 발표 | 긴급 패치 배포 (v1.12.1, v1.11.5) |
| 2025년 11월 | Ingress NGINX 공식 은퇴 발표 | 커뮤니티 마이그레이션 권고 시작 |
| 2026년 3월 | 커뮤니티 지원 완전 종료 | 보안 패치, 버그 수정, 릴리스 일체 중단 |
| 2026년 11월 | AKS Application Routing 연장 지원 종료 | Azure 관리형 환경도 지원 종료 |
| 2026년 11월 이후 | 모든 공식/연장 지원 종료 | 완전한 자체 책임 운영 |
"Best-effort maintenance will continue until March 2026. Afterward, there will be no further releases, no bugfixes, and no updates to resolve any security vulnerabilities that may be discovered."
-- Tabitha Sable, Kubernetes Security Response Committee
클라우드 벤더별 대응 현황:
| 클라우드 벤더 | 대응 전략 | 연장 지원 | 권장 대안 |
|---|---|---|---|
| Azure (AKS) | Application Routing Add-on 내 ingress-nginx 지원 | 2026년 11월까지 (보안 패치만) | Gateway API + NGINX Gateway Fabric |
| GCP (GKE) | GKE Gateway Controller 제공 | 벤더 자체 구현으로 전환 권고 | GKE Gateway Controller |
| AWS (EKS) | AWS Load Balancer Controller | 자체 구현으로 이미 분리 | AWS Gateway API Controller |
| 자체 호스팅 | 직접 마이그레이션 필요 | 없음 (2026년 3월 종료) | NGINX Gateway Fabric, Envoy Gateway 등 |
자체 호스팅 환경에서 운영 중인 조직에게 상황은 가장 긴급합니다. 2026년 3월 이후 발견되는 모든 보안 취약점에 대해 어떠한 공식 패치도 제공되지 않습니다.
3. [Takeaway 2] 어노테이션(Annotation)의 늪에서 탈출하기
3.1 어노테이션 기반 설정의 구조적 결함
Ingress API의 가장 근본적인 한계는 표현력의 부족입니다. Ingress 리소스의 spec은 호스트 기반 라우팅과 경로 기반 라우팅이라는 가장 기초적인 기능만을 지원합니다. 그 결과, 실무에서 필요한 거의 모든 고급 기능은 **어노테이션(annotation)**이라는 비구조적 메커니즘에 의존하게 되었습니다.
어노테이션의 근본적인 문제점을 분석하면 다음과 같습니다:
1) 타입 안전성의 부재
어노테이션은 단순한 key: value 문자열 쌍입니다. 스키마 검증이 없으므로 오타, 잘못된 값 형식, 잘못된 키 이름이 배포 시점까지 발견되지 않습니다.
# 이 오타를 발견할 수 있겠습니까?
metadata:
annotations:
# 오타: "rewrite-target" → "rewrite-traget"
nginx.ingress.kubernetes.io/rewrite-traget: /$2
# 타입 오류: 숫자여야 하지만 문자열 전달
nginx.ingress.kubernetes.io/proxy-read-timeout: 'sixhundred'
# 잘못된 prefix: "nginx.ingress.kubernetes.io" → "nginx.kubernetes.io"
nginx.kubernetes.io/ssl-redirect: 'true'
위 세 가지 모두 kubectl apply 시 아무런 오류 없이 적용됩니다. 문제는 런타임에 예상치 못한 동작으로만 나타나며, 이를 디버깅하는 데 수 시간이 소요될 수 있습니다.
2) 벤더 종속성의 강화
각 Ingress Controller는 자체적인 어노테이션 네임스페이스를 사용합니다:
# ingress-nginx 전용
nginx.ingress.kubernetes.io/canary: 'true'
nginx.ingress.kubernetes.io/canary-weight: '20'
# Traefik 전용
traefik.ingress.kubernetes.io/router.middlewares: default-rate-limit@kubernetescrd
# HAProxy 전용
haproxy.org/rate-limit-requests: '100'
# AWS ALB 전용
alb.ingress.kubernetes.io/target-type: ip
동일한 기능(카나리 배포, 속도 제한 등)을 구현하면서도 완전히 다른 어노테이션 문법을 사용합니다. 한 컨트롤러에서 다른 컨트롤러로 마이그레이션할 때, 모든 어노테이션을 수작업으로 변환해야 합니다.
3) 감사(Audit) 및 거버넌스의 불가능
어노테이션은 Ingress 리소스의 메타데이터에 평탄하게 나열됩니다. 수십 개의 어노테이션이 붙은 Ingress 객체에서 보안에 민감한 설정을 식별하는 것은 사실상 불가능합니다. RBAC으로 특정 어노테이션만 제한하는 것도 불가능합니다 -- 어노테이션을 쓸 수 있으면 모든 어노테이션을 쓸 수 있습니다.
3.2 snippets 어노테이션: 설계된 취약점
어노테이션 문제의 극단적 사례가 바로 nginx.ingress.kubernetes.io/configuration-snippet과 nginx.ingress.kubernetes.io/server-snippet입니다. 이 어노테이션들은 임의의 NGINX 설정 디렉티브를 직접 주입할 수 있게 합니다.
# 위험: 임의의 NGINX 설정 주입 가능
metadata:
annotations:
nginx.ingress.kubernetes.io/configuration-snippet: |
# 정상적 사용 의도: 커스텀 헤더 추가
more_set_headers "X-Custom-Header: value";
# 악의적 활용: 서버 정보 탈취
# proxy_pass http://internal-service.kube-system.svc.cluster.local;
# 악의적 활용: 인증 우회
# satisfy any;
# allow all;
이 기능은 CVE-2023-5043 등 여러 보안 취약점의 직접적인 원인이었습니다. Ingress 객체를 생성할 수 있는 권한만 있으면, 사실상 NGINX 프로세스의 전체 설정을 조작할 수 있었습니다. 이는 configuration-snippet 어노테이션이 NGINX 설정 파일의 location 블록에, server-snippet이 server 블록에 그대로 삽입되기 때문입니다.
3.3 Gateway API의 어노테이션 없는 모델(Annotation-less Model)
Gateway API는 이 문제를 구조화된 API 타입으로 해결합니다. 어노테이션에 의존하는 대신, 타입이 지정된(Typed) CRD 필드를 통해 설정을 표현합니다.
비교 예시: HTTPS 리다이렉트와 경로 재작성
기존 Ingress + 어노테이션 방식:
# Ingress 방식: 어노테이션에 의존
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: 'true'
nginx.ingress.kubernetes.io/rewrite-target: /$2
nginx.ingress.kubernetes.io/proxy-read-timeout: '600'
nginx.ingress.kubernetes.io/proxy-send-timeout: '600'
nginx.ingress.kubernetes.io/proxy-body-size: '100m'
nginx.ingress.kubernetes.io/cors-allow-origin: 'https://example.com'
nginx.ingress.kubernetes.io/cors-allow-methods: 'GET, POST, PUT'
nginx.ingress.kubernetes.io/cors-allow-headers: 'Content-Type, Authorization'
nginx.ingress.kubernetes.io/enable-cors: 'true'
nginx.ingress.kubernetes.io/limit-rps: '100'
nginx.ingress.kubernetes.io/canary: 'true'
nginx.ingress.kubernetes.io/canary-weight: '20'
spec:
ingressClassName: nginx
tls:
- hosts:
- app.example.com
secretName: app-tls
rules:
- host: app.example.com
http:
paths:
- path: /api(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: api-service
port:
number: 80
Gateway API 방식:
# Gateway API 방식: 구조화된 스펙
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: my-app
spec:
parentRefs:
- name: production-gateway
hostnames:
- app.example.com
rules:
# 규칙 1: HTTPS 리다이렉트 (어노테이션 없이 스펙으로 표현)
- filters:
- type: RequestRedirect
requestRedirect:
scheme: https
statusCode: 301
matches:
- headers:
- name: X-Forwarded-Proto
value: http
# 규칙 2: API 라우팅
- matches:
- path:
type: PathPrefix
value: /api
filters:
- type: URLRewrite
urlRewrite:
path:
type: ReplacePrefixMatch
replacePrefixMatch: /
backendRefs:
- name: api-service
port: 80
weight: 80
- name: api-service-canary
port: 80
weight: 20
핵심 차이점 분석:
| 측면 | Ingress + 어노테이션 | Gateway API |
|---|---|---|
| 타입 안전성 | 없음 (문자열 key-value) | 있음 (CRD 스키마 검증) |
| IDE 지원 | 없음 | 자동완성, 실시간 검증 |
| 배포 시 검증 | 없음 (런타임 오류) | Admission Webhook 검증 |
| 카나리 배포 | 어노테이션 (벤더 종속) | backendRefs.weight (표준) |
| HTTPS 리다이렉트 | 어노테이션 (벤더 종속) | RequestRedirect 필터 (표준) |
| 경로 재작성 | 어노테이션 + 정규식 | URLRewrite 필터 (표준) |
| RBAC 제어 | 어노테이션 단위 제어 불가 | 리소스 단위 RBAC 가능 |
| 감사 추적 | 어렵다 | CRD 수준에서 가능 |
3.4 Policy Attachment: 어노테이션의 진정한 대안
Gateway API의 Policy Attachment 모델은 어노테이션이 담당하던 횡단 관심사(cross-cutting concerns)를 독립적인 리소스로 분리합니다.
# 타임아웃 정책: 별도의 리소스로 관리
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: BackendLBPolicy
metadata:
name: api-timeout-policy
spec:
targetRefs:
- group: ''
kind: Service
name: api-service
sessionPersistence:
sessionName: my-session
type: Cookie
---
# TLS 정책: 백엔드 TLS 설정을 별도 리소스로 분리
apiVersion: gateway.networking.k8s.io/v1alpha3
kind: BackendTLSPolicy
metadata:
name: api-backend-tls
spec:
targetRefs:
- group: ''
kind: Service
name: api-service
validation:
caCertificateRefs:
- name: backend-ca-cert
group: ''
kind: ConfigMap
hostname: api-internal.example.com
이 모델의 장점은 명확합니다:
- 관심사의 분리: 라우팅 규칙(HTTPRoute)과 운영 정책(Policy)이 독립적으로 관리됩니다
- 재사용성: 하나의 정책을 여러 서비스에 부착(attach)할 수 있습니다
- RBAC 적용: 정책 리소스에 대해 별도의 RBAC 규칙을 적용할 수 있습니다
- 감사 용이성: 어떤 정책이 어떤 대상에 적용되어 있는지 명확하게 추적할 수 있습니다
4. [Takeaway 3] 역할의 분리: 인프라 관리자와 개발자의 평화로운 공존
4.1 Ingress의 거버넌스 문제
기존 Ingress API의 근본적인 설계 한계 중 하나는 역할 분리의 부재입니다. 단일 Ingress 리소스 안에 인프라 설정(TLS 인증서, 리스너 포트)과 애플리케이션 라우팅 규칙(경로 매칭, 백엔드 서비스)이 혼재합니다.
# Ingress: 인프라와 애플리케이션 설정이 혼재
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app
# 누가 이 어노테이션을 관리하는가? 인프라팀? 개발팀?
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: 'true' # 인프라 관심사
nginx.ingress.kubernetes.io/proxy-body-size: '50m' # 인프라 관심사
nginx.ingress.kubernetes.io/rewrite-target: /$1 # 애플리케이션 관심사
nginx.ingress.kubernetes.io/canary-weight: '10' # 애플리케이션 관심사
spec:
ingressClassName: nginx # 인프라 관심사
tls:
- hosts:
- app.example.com
secretName: production-tls-cert # 인프라 관심사 (시크릿 관리)
rules:
- host: app.example.com # 혼합 관심사
http:
paths:
- path: /api/(.*) # 애플리케이션 관심사
pathType: ImplementationSpecific
backend:
service:
name: api-service # 애플리케이션 관심사
port:
number: 80
이 구조에서는 개발자가 자신의 라우팅 규칙을 변경하기 위해 인프라 설정이 포함된 동일한 리소스를 수정해야 합니다. 반대로, 인프라 관리자가 TLS 인증서를 교체하려면 애플리케이션 라우팅 규칙이 포함된 리소스에 접근해야 합니다.
4.2 Gateway API의 역할 기반 리소스 계층
Gateway API는 이 문제를 3계층 리소스 모델로 해결합니다:
┌─────────────────────────────────────────────────────────────┐
│ Layer 1: GatewayClass │
│ ───────────────────── │
│ 담당: Infrastructure Provider (클라우드 벤더, 플랫폼 팀) │
│ 역할: 데이터 플레인 구현체 정의 │
│ 예시: "nginx", "envoy", "gke-l7-global" │
│ RBAC: cluster-admin 수준 │
├─────────────────────────────────────────────────────────────┤
│ Layer 2: Gateway │
│ ───────────────── │
│ 담당: Cluster Operator (플랫폼/인프라 엔지니어) │
│ 역할: 리스너, TLS, IP 주소, 포트, 허용 네임스페이스 설정 │
│ 예시: 443 포트 HTTPS 리스너, 와일드카드 인증서 │
│ RBAC: namespace-admin 수준 (인프라 네임스페이스) │
├─────────────────────────────────────────────────────────────┤
│ Layer 3: HTTPRoute / GRPCRoute / TCPRoute │
│ ─────────────────────────────────────────── │
│ 담당: Application Developer (서비스 개발자) │
│ 역할: 라우팅 규칙, 백엔드 서비스 매핑, 트래픽 가중치 │
│ 예시: /api → api-service, 카나리 20% │
│ RBAC: namespace-editor 수준 (애플리케이션 네임스페이스) │
└─────────────────────────────────────────────────────────────┘
역할별 책임 매트릭스:
| 역할 | 리소스 | 책임 범위 | RBAC 예시 |
|---|---|---|---|
| Infrastructure Provider | GatewayClass | 데이터 플레인 구현체 등록, 파라미터 정의 | ClusterRole: gatewayclass-admin |
| Cluster Operator | Gateway, ReferenceGrant | 리스너 설정, TLS 인증서 관리, 네임스페이스 접근 제어 | Role: gateway-admin (infra-ns) |
| Application Developer | HTTPRoute, GRPCRoute | 라우팅 규칙 정의, 백엔드 서비스 매핑, 트래픽 분배 | Role: route-editor (app-ns) |
4.3 실전 RBAC 구성 예시
1단계: Infrastructure Provider -- GatewayClass 정의
# 인프라 제공자가 정의하는 GatewayClass
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: nginx-gateway-fabric
spec:
controllerName: gateway.nginx.org/nginx-gateway-controller
parametersRef:
group: gateway.nginx.org
kind: NginxProxy
name: production-proxy-config
2단계: Cluster Operator -- Gateway 설정
# 클러스터 운영자가 관리하는 Gateway
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: production-gateway
namespace: gateway-infra # 인프라 전용 네임스페이스
spec:
gatewayClassName: nginx-gateway-fabric
listeners:
- name: https
protocol: HTTPS
port: 443
tls:
mode: Terminate
certificateRefs:
- name: wildcard-tls-cert
kind: Secret
allowedRoutes:
namespaces:
from: Selector
selector:
matchLabels:
gateway-access: 'true' # 허용된 네임스페이스만
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: Same
---
# 교차 네임스페이스 참조 허용
apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata:
name: allow-gateway-to-app-secrets
namespace: app-team-a
spec:
from:
- group: gateway.networking.k8s.io
kind: Gateway
namespace: gateway-infra
to:
- group: ''
kind: Service
3단계: Application Developer -- HTTPRoute 정의
# 개발자가 자신의 네임스페이스에서 관리하는 HTTPRoute
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: api-routes
namespace: app-team-a # 애플리케이션 네임스페이스
spec:
parentRefs:
- name: production-gateway
namespace: gateway-infra # 인프라 네임스페이스의 Gateway 참조
sectionName: https
hostnames:
- api.example.com
rules:
- matches:
- path:
type: PathPrefix
value: /v1
backendRefs:
- name: api-v1
port: 8080
weight: 80
- name: api-v2
port: 8080
weight: 20 # 카나리 배포: 20% 트래픽을 v2로
RBAC 정책 예시:
# 개발자용 Role: HTTPRoute만 생성/수정 가능
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: route-editor
namespace: app-team-a
rules:
- apiGroups: ['gateway.networking.k8s.io']
resources: ['httproutes', 'grpcroutes']
verbs: ['get', 'list', 'watch', 'create', 'update', 'patch', 'delete']
- apiGroups: ['gateway.networking.k8s.io']
resources: ['gateways']
verbs: ['get', 'list'] # Gateway는 조회만 가능
---
# 인프라 운영자용 Role: Gateway 관리 가능, Route 생성 불가
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: gateway-admin
namespace: gateway-infra
rules:
- apiGroups: ['gateway.networking.k8s.io']
resources: ['gateways', 'referencegrants']
verbs: ['get', 'list', 'watch', 'create', 'update', 'patch', 'delete']
- apiGroups: ['']
resources: ['secrets']
verbs: ['get', 'list', 'watch', 'create', 'update']
이 구조가 제공하는 실질적 가치는 다음과 같습니다:
- 개발자 자율성: 개발자는 인프라팀의 승인 없이도 자신의 네임스페이스에서 라우팅 규칙을 자유롭게 변경할 수 있습니다
- 인프라 안전성: 개발자가 TLS 인증서, 리스너 포트, 허용 네임스페이스 등 인프라 설정을 실수로 변경할 위험이 원천적으로 차단됩니다
- 교차 네임스페이스 보안:
ReferenceGrant를 통해 다른 네임스페이스의 리소스 참조를 명시적으로 허용해야 하므로, 무단 접근이 방지됩니다 - 셀프서비스 거버넌스: 플랫폼 팀은
allowedRoutes를 통해 어떤 네임스페이스가 Gateway를 사용할 수 있는지 제어하고, 개발팀은 그 범위 안에서 자유롭게 운영합니다
5. [Takeaway 4] 벤더 종속성을 깨는 이식성(Portability)의 실현
5.1 이식성 문제의 본질
Ingress API가 벤더 이식성을 제공하지 못하는 이유는 단순합니다: 표준 스펙이 너무 빈약하기 때문입니다. Ingress API의 spec은 호스트 매칭, 경로 매칭, TLS 종단이라는 최소한의 기능만 정의합니다. 실무에서 필요한 모든 고급 기능(카나리 배포, 속도 제한, 헤더 조작, 타임아웃, 재시도 등)은 어노테이션을 통해 각 벤더가 독자적으로 구현합니다.
결과적으로, Ingress 리소스를 작성하는 순간 특정 컨트롤러에 종속됩니다. 이는 "Write once, run anywhere"라는 쿠버네티스의 이상과 정면으로 충돌합니다.
┌─────────────────────────────────────────────────────────────┐
│ Ingress API의 이식성 한계 │
│ │
│ Ingress spec (표준) 어노테이션 (비표준) │
│ ┌───────────────────┐ ┌──────────────────────────────┐ │
│ │ host: app.com │ │ nginx.ingress.k8s.io/... │ │
│ │ path: /api │ │ traefik.ingress.k8s.io/... │ │
│ │ tls: cert │ │ alb.ingress.k8s.io/... │ │
│ │ │ │ haproxy.org/... │ │
│ │ (이식 가능) │ │ (이식 불가 - 벤더 종속) │ │
│ └───────────────────┘ └──────────────────────────────┘ │
│ 20% 80% │
│ 실제 설정의 20%만이 나머지 80%는 벤더 고유 │
│ 이식 가능 어노테이션에 의존 │
└─────────────────────────────────────────────────────────────┘
5.2 Gateway API의 이식성 전략
Gateway API는 기능을 **3가지 지원 수준(Support Level)**으로 계층화하여 이식성과 확장성을 동시에 확보합니다:
| 지원 수준 | 설명 | 이식성 | 적합성 테스트 |
|---|---|---|---|
| Core | 모든 구현체가 반드시 지원해야 하는 핵심 기능 | 완전 이식 가능 | 필수 통과 |
| Extended | 이식 가능하지만 모든 구현체가 지원하지 않을 수 있는 기능 | 조건부 이식 가능 | 선택적 통과 |
| Implementation-specific | 벤더 고유의 확장 기능 | 이식 불가 | 대상 아님 |
Core 기능 (완전 이식 가능):
# 이 HTTPRoute는 어떤 Gateway API 구현체에서든 동일하게 동작합니다
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: portable-route
spec:
parentRefs:
- name: my-gateway
hostnames:
- app.example.com
rules:
- matches:
- path:
type: PathPrefix # Core: 경로 매칭
value: /api
- headers: # Core: 헤더 매칭
- name: X-Version
value: v2
filters:
- type: RequestHeaderModifier # Core: 헤더 조작
requestHeaderModifier:
add:
- name: X-Gateway
value: production
backendRefs:
- name: api-service
port: 8080
Extended 기능 (이식 가능하나 구현체 확인 필요):
# Extended 기능: 대부분의 구현체가 지원하지만 확인 필요
rules:
- filters:
- type: RequestRedirect # Extended: HTTP 리다이렉트
requestRedirect:
scheme: https
statusCode: 301
- type: URLRewrite # Extended: URL 재작성
urlRewrite:
path:
type: ReplacePrefixMatch
replacePrefixMatch: /v2
backendRefs:
- name: api-v1
port: 8080
weight: 90 # Extended: 트래픽 가중치 (카나리)
- name: api-v2
port: 8080
weight: 10
5.3 Conformance Test: 이식성의 보증 수표
Gateway API의 이식성은 단순한 약속이 아니라 **Conformance Test(적합성 테스트)**라는 구체적인 검증 메커니즘으로 뒷받침됩니다.
각 구현체는 Gateway API 프로젝트가 제공하는 표준화된 테스트 스위트를 통과해야 합니다. 이 테스트는 실제로 Gateway와 Route를 생성하고, 트래픽을 보내서, API 사양과 동일하게 동작하는지 검증합니다.
┌─────────────────────────────────────────────────────────────┐
│ Conformance Test 프로세스 │
│ │
│ 1. Gateway API 테스트 스위트 실행 │
│ └─> 표준 Gateway/HTTPRoute 리소스 배포 │
│ │
│ 2. 실제 트래픽 전송 및 동작 검증 │
│ └─> 경로 매칭, 헤더 필터링, 리다이렉트 등 │
│ │
│ 3. 결과 리포트 생성 │
│ └─> Core 100%, Extended features 목록 │
│ │
│ 4. 공식 인증 (Conformance Profile) │
│ └─> Gateway API 공식 구현체 목록 등재 │
└─────────────────────────────────────────────────────────────┘
주요 구현체별 Conformance 현황:
| 구현체 | Core 적합성 | Extended 기능 | 비고 |
|---|---|---|---|
| NGINX Gateway Fabric | 통과 | HTTP 라우팅, TLS, URL 재작성, 가중치 기반 분배 | NGINX 데이터 플레인 |
| Envoy Gateway | 통과 | 전체 Extended 기능 지원 | Envoy Proxy 데이터 플레인 |
| GKE Gateway Controller | 통과 | GCP 네이티브 통합 | Google Cloud 전용 |
| Istio | 통과 | 서비스 메쉬 통합 | Istio 데이터 플레인 |
| Contour | 통과 | Envoy 기반 | VMware 지원 |
| Traefik | 통과 | 미들웨어 통합 | v3+ 지원 |
5.4 실질적 이식성 시나리오: 멀티 클라우드 마이그레이션
Conformance Test가 보장하는 이식성은 멀티 클라우드 운영에서 실질적 가치를 발휘합니다:
┌──────────────────┐ ┌──────────────────┐
│ AWS EKS │ │ Azure AKS │
│ │ │ │
│ GatewayClass: │ │ GatewayClass: │
│ aws-gateway │ │ azure-gateway │
│ (구현체 변경) │ │ (구현체 변경) │
│ │ │ │
│ Gateway: ───────┼─────┼─ Gateway: ──────┐│
│ (최소 수정) │ │ (최소 수정) ││
│ │ │ ││
│ HTTPRoute: ─────┼─────┼─ HTTPRoute: ────┘│
│ (동일 재사용) │ │ (동일 재사용) │
└──────────────────┘ └──────────────────┘
│ │
└───────┬────────────────┘
│
동일한 HTTPRoute 매니페스트를
GatewayClass만 변경하여 재사용
기존 Ingress 방식에서는 AWS ALB Ingress Controller에서 GKE Ingress Controller로 이동할 때 모든 어노테이션을 다시 작성해야 했습니다. Gateway API에서는 GatewayClass만 변경하면 나머지 리소스(Gateway, HTTPRoute)는 Core/Extended 기능 범위 내에서 그대로 재사용할 수 있습니다.
6. [Takeaway 5] 성능의 도약: HTTP/3와 QUIC의 본격 도입
6.1 왜 HTTP/3인가: TCP의 구조적 한계
HTTP/2는 멀티플렉싱을 통해 동일 TCP 연결에서 여러 스트림을 동시에 처리할 수 있게 했습니다. 그러나 TCP 프로토콜 자체의 Head-of-Line(HOL) Blocking 문제를 해결하지 못했습니다.
HTTP/2 over TCP의 Head-of-Line Blocking 문제:
TCP 연결
┌─────────────────────────────────────────────────┐
│ Stream 1: [패킷1][패킷2][ 손실 ][패킷4] │
│ Stream 2: [패킷A][패킷B] ← 대기 [패킷D] │ ← 블로킹!
│ Stream 3: [패킷X][패킷Y] ← 대기 [패킷Z] │ ← 블로킹!
└─────────────────────────────────────────────────┘
패킷3 손실 시 → 모든 스트림이 대기
HTTP/3 over QUIC의 독립 스트림:
QUIC 연결
┌─────────────────────────────────────────────────┐
│ Stream 1: [패킷1][패킷2][ 손실 ][패킷4] │ ← 이 스트림만 영향
│ Stream 2: [패킷A][패킷B][패킷C] [패킷D] │ ← 정상 진행!
│ Stream 3: [패킷X][패킷Y][패킷Z] │ ← 정상 진행!
└─────────────────────────────────────────────────┘
패킷3 손실 시 → Stream 1만 영향
HTTP/3는 TCP 대신 QUIC(Quick UDP Internet Connections) 프로토콜을 사용합니다. QUIC은 UDP 위에 구축되며, 각 스트림이 독립적으로 전달됩니다. 하나의 스트림에서 패킷 손실이 발생해도 다른 스트림에 영향을 주지 않습니다.
6.2 HTTP/3의 핵심 성능 이점
| 특성 | HTTP/2 (TCP) | HTTP/3 (QUIC) | 개선 효과 |
|---|---|---|---|
| 전송 계층 | TCP | UDP + QUIC | 커널 의존성 감소 |
| 연결 수립 | TCP 3-way handshake + TLS handshake (2~3 RTT) | QUIC 0-RTT / 1-RTT | 최대 67% 지연 감소 |
| HOL Blocking | TCP 수준에서 발생 | 스트림 수준으로 격리 | 병렬 처리 효율 향상 |
| 연결 마이그레이션 | IP/포트 변경 시 재연결 필요 | Connection ID 기반 유지 | 모바일 환경 안정성 |
| 암호화 | TLS 선택적 | TLS 1.3 필수 (내장) | 기본 암호화 보장 |
| 패킷 손실 복구 | 전체 연결 영향 | 개별 스트림 독립 복구 | 손실 허용 네트워크 성능 향상 |
6.3 NGINX Gateway Fabric에서의 HTTP/3 지원
NGINX는 v1.25.0부터 QUIC과 HTTP/3를 공식 지원하며, NGINX Gateway Fabric을 통해 쿠버네티스 환경에서 HTTP/3를 활용할 수 있습니다.
HTTP/3 활성화를 위한 NginxProxy 설정:
apiVersion: gateway.nginx.org/v1alpha1
kind: NginxProxy
metadata:
name: http3-enabled-proxy
spec:
config:
http:
http3: true
http3MaxConcurrentStreams: 128
altSvcHeader: true # Alt-Svc 헤더 자동 추가
Gateway에서 HTTP/3 리스너 구성:
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: http3-gateway
namespace: gateway-infra
spec:
gatewayClassName: nginx-gateway-fabric
listeners:
# HTTPS (TCP) + HTTP/3 (UDP) 동시 리스닝
- name: https-tcp
protocol: HTTPS
port: 443
tls:
mode: Terminate
certificateRefs:
- name: wildcard-tls-cert
- name: https-udp
protocol: HTTPS # HTTP/3는 HTTPS 프로토콜로 선언
port: 443 # 동일 포트, UDP로 QUIC 처리
tls:
mode: Terminate
certificateRefs:
- name: wildcard-tls-cert
Service에서 UDP 포트 노출:
apiVersion: v1
kind: Service
metadata:
name: nginx-gateway-fabric
namespace: gateway-infra
spec:
type: LoadBalancer
ports:
- name: https-tcp
port: 443
targetPort: 443
protocol: TCP
- name: https-udp
port: 443
targetPort: 443
protocol: UDP # QUIC을 위한 UDP 포트 필수
6.4 HTTP/3 도입 시 주의사항
HTTP/3 도입 시 반드시 확인해야 할 기술적 요구사항과 주의사항이 있습니다:
1) SSL 라이브러리 요구사항
QUIC 프로토콜 지원을 위해서는 QUIC 호환 SSL 라이브러리가 필요합니다. 표준 OpenSSL은 QUIC API를 지원하지 않으므로(OpenSSL 3.x 기준), 다음 대안 중 하나를 사용해야 합니다:
| SSL 라이브러리 | QUIC 지원 | 비고 |
|---|---|---|
| BoringSSL | 네이티브 지원 | Google 개발, NGINX Gateway Fabric 기본 사용 |
| LibreSSL | 3.6.0+ 지원 | OpenBSD 프로젝트 |
| QuicTLS | OpenSSL + QUIC 패치 | OpenSSL 포크, QUIC API 추가 |
| OpenSSL | 미지원 (3.x 기준) | 향후 지원 예정 |
NGINX Gateway Fabric은 기본적으로 BoringSSL을 사용하여 빌드되므로, 별도의 SSL 라이브러리 교체 없이 HTTP/3를 사용할 수 있습니다.
2) 방화벽 및 네트워크 설정
┌─────────────────────────────────────────────────────────┐
│ HTTP/3 네트워크 요구사항 │
│ │
│ 인바운드 규칙에 UDP 443 추가 필수: │
│ │
│ 기존 (HTTP/2만): │
│ ┌──────────────────────────────────────┐ │
│ │ TCP 80 ← HTTP │ │
│ │ TCP 443 ← HTTPS (TLS over TCP) │ │
│ └──────────────────────────────────────┘ │
│ │
│ HTTP/3 추가 후: │
│ ┌──────────────────────────────────────┐ │
│ │ TCP 80 ← HTTP │ │
│ │ TCP 443 ← HTTPS (TLS over TCP) │ │
│ │ UDP 443 ← QUIC (HTTP/3 over UDP) │ ← 추가 필수 │
│ └──────────────────────────────────────┘ │
│ │
│ 주의: 많은 기업 방화벽과 클라우드 보안 그룹이 │
│ UDP 443을 기본적으로 차단합니다. │
└─────────────────────────────────────────────────────────┘
- 클라우드 보안 그룹: AWS Security Group, Azure NSG, GCP Firewall Rules에서 UDP 443 인바운드를 명시적으로 허용해야 합니다
- CDN/WAF 호환성: 일부 CDN이나 WAF가 QUIC 트래픽을 차단하거나 제대로 처리하지 못할 수 있습니다
- 로드밸런서 지원: 클라우드 로드밸런서가 UDP 트래픽을 올바르게 라우팅하는지 확인해야 합니다. AWS NLB, Azure Load Balancer, GCP Network Load Balancer는 UDP를 지원합니다
3) Alt-Svc 헤더를 통한 점진적 전환
HTTP/3 도입은 점진적으로 진행할 수 있습니다. 서버는 HTTP/2 응답에 Alt-Svc 헤더를 포함시켜 클라이언트에게 HTTP/3 사용 가능을 알립니다:
Alt-Svc: h3=":443"; ma=86400
클라이언트(브라우저)는 이 헤더를 받은 후 다음 요청부터 HTTP/3를 시도합니다. 실패 시 자동으로 HTTP/2로 폴백됩니다. 2025년 기준 Chrome 87+, Firefox 88+, Safari 14+ 등 전체 브라우저의 95% 이상이 HTTP/3를 지원합니다.
4) eBPF를 활용한 QUIC 연결 마이그레이션
Linux 5.7+ 커널에서는 eBPF를 활용한 QUIC 패킷 라우팅을 지원합니다. 이를 통해 QUIC의 Connection Migration 기능을 활용할 수 있어, 클라이언트의 네트워크가 변경되더라도(Wi-Fi에서 LTE로 전환 등) 연결이 유지됩니다.
# nginx.conf에서 eBPF 기반 QUIC 라우팅 활성화
quic_bpf on; # Linux 5.7+ 필수
7. 실전 마이그레이션 가이드
7.1 마이그레이션 전략 개요
Ingress NGINX에서 Gateway API로의 마이그레이션은 한 번에 완료하는 Big Bang 방식이 아니라, **단계적 전환(Progressive Migration)**이 권장됩니다.
┌──────────────────────────────────────────────────────────────┐
│ 단계적 마이그레이션 전략 │
│ │
│ Phase 1: 인벤토리 및 평가 (1~2주) │
│ ├─ 전체 Ingress 리소스 목록화 │
│ ├─ 사용 중인 어노테이션 분류 │
│ ├─ snippets 사용 여부 파악 (보안 위험 우선 제거) │
│ └─ 의존성 매핑 (cert-manager, external-dns 등) │
│ │
│ Phase 2: Gateway API 인프라 구축 (1~2주) │
│ ├─ Gateway API CRD 설치 │
│ ├─ NGINX Gateway Fabric 또는 대안 컨트롤러 배포 │
│ ├─ GatewayClass, Gateway 리소스 생성 │
│ └─ 비프로덕션 환경에서 검증 │
│ │
│ Phase 3: 점진적 라우팅 전환 (2~4주) │
│ ├─ ingress2gateway 도구로 초기 변환 │
│ ├─ 수동 검토 및 어노테이션 → 필터/정책 변환 │
│ ├─ 서비스별 순차 전환 (비핵심 → 핵심 서비스) │
│ └─ 병렬 운영(Ingress + Gateway API) 기간 │
│ │
│ Phase 4: 완전 전환 및 정리 (1~2주) │
│ ├─ 모든 트래픽이 Gateway API 경유 확인 │
│ ├─ Ingress 리소스 제거 │
│ ├─ ingress-nginx 컨트롤러 제거 │
│ └─ 모니터링 및 알림 재설정 │
└──────────────────────────────────────────────────────────────┘
7.2 Phase 1: 인벤토리 수집
전체 Ingress 리소스 조회:
# 모든 네임스페이스의 Ingress 리소스 목록
kubectl get ingress -A -o wide
# 사용 중인 어노테이션 전체 추출
kubectl get ingress -A -o json | \
jq -r '.items[].metadata.annotations // {} | keys[]' | \
sort | uniq -c | sort -rn
# snippets 어노테이션 사용 여부 긴급 확인 (보안 위험)
kubectl get ingress -A -o json | \
jq -r '.items[] | select(.metadata.annotations["nginx.ingress.kubernetes.io/configuration-snippet"] != null or .metadata.annotations["nginx.ingress.kubernetes.io/server-snippet"] != null) | .metadata.namespace + "/" + .metadata.name'
# IngressClass 확인
kubectl get ingressclass
어노테이션 분류 체크리스트:
| 분류 | 어노테이션 예시 | Gateway API 대체 | 긴급도 |
|---|---|---|---|
| 보안 위험 | configuration-snippet, server-snippet | 제거 또는 Custom Filter | 즉시 |
| 표준 대체 가능 | ssl-redirect, rewrite-target | RequestRedirect, URLRewrite 필터 | 높음 |
| Policy 대체 가능 | proxy-read-timeout, proxy-body-size | Policy Attachment | 중간 |
| 기능별 대체 | canary, canary-weight | backendRefs.weight | 중간 |
| 구현체 의존 | upstream-hash-by, affinity | 구현체별 CRD 확인 | 낮음 |
7.3 Phase 2: ingress2gateway 도구 활용
ingress2gateway는 Kubernetes SIG-Network에서 공식 제공하는 마이그레이션 도구입니다.
설치:
# Go 환경이 있는 경우
go install github.com/kubernetes-sigs/ingress2gateway@latest
# 또는 GitHub Releases에서 바이너리 다운로드
# https://github.com/kubernetes-sigs/ingress2gateway/releases
기본 사용법:
# 클러스터의 Ingress 리소스를 자동 변환
ingress2gateway print --all-namespaces
# 특정 네임스페이스만 변환
ingress2gateway print --namespace production
# 파일 기반 변환
ingress2gateway print --input-file ingress-resources.yaml
# ingress-nginx 프로바이더 지정 (어노테이션 변환 지원)
ingress2gateway print --providers ingress-nginx --all-namespaces
# 결과를 파일로 저장
ingress2gateway print --providers ingress-nginx --all-namespaces > gateway-resources.yaml
변환 예시:
입력 (Ingress):
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-app
namespace: production
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: 'true'
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
ingressClassName: nginx
tls:
- hosts:
- app.example.com
secretName: app-tls
rules:
- host: app.example.com
http:
paths:
- path: /api(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: api-service
port:
number: 80
출력 (Gateway API):
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: nginx
namespace: production
spec:
gatewayClassName: nginx
listeners:
- name: app-example-com-https
hostname: app.example.com
port: 443
protocol: HTTPS
tls:
certificateRefs:
- name: app-tls
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: example-app
namespace: production
spec:
parentRefs:
- name: nginx
hostnames:
- app.example.com
rules:
- matches:
- path:
type: PathPrefix
value: /api
filters:
- type: URLRewrite
urlRewrite:
path:
type: ReplacePrefixMatch
replacePrefixMatch: /
backendRefs:
- name: api-service
port: 80
중요 주의사항: ingress2gateway는 시작점일 뿐, 모든 어노테이션을 완벽하게 변환하지는 않습니다. 특히 구현체 고유 기능(snippets, 커스텀 Lua 스크립트 등)은 수동으로 재설계해야 합니다. 변환 결과를 반드시 검토하고, 비프로덕션 환경에서 충분히 테스트한 후 적용하세요.
7.4 Phase 3: NGINX Gateway Fabric 배포
Helm을 이용한 설치:
# Gateway API CRD 설치
kubectl kustomize \
"https://github.com/kubernetes-sigs/gateway-api/config/crd?ref=v1.2.1" \
| kubectl apply -f -
# NGINX Gateway Fabric 설치
helm install ngf oci://ghcr.io/nginx/charts/nginx-gateway-fabric \
--create-namespace \
--namespace nginx-gateway \
--set service.type=LoadBalancer
GatewayClass 확인:
# 설치 후 GatewayClass 확인
kubectl get gatewayclass
# NAME CONTROLLER ACCEPTED
# nginx gateway.nginx.org/nginx-gateway-controller True
Gateway 생성 및 검증:
# Gateway 리소스 적용
kubectl apply -f gateway.yaml
# Gateway 상태 확인
kubectl get gateway -n gateway-infra
# NAME CLASS ADDRESS PROGRAMMED AGE
# production-gateway nginx 203.0.113.10 True 5m
# HTTPRoute 적용
kubectl apply -f httproute.yaml
# HTTPRoute 상태 확인
kubectl get httproute -n app-team-a
# NAME HOSTNAMES AGE
# api-routes ["api.example.com"] 2m
# 실제 트래픽 테스트
curl -H "Host: api.example.com" https://203.0.113.10/v1/health
7.5 Ingress vs Gateway API 기능 비교 종합표
| 기능 | Ingress API | Gateway API | 비고 |
|---|---|---|---|
| 호스트 기반 라우팅 | spec.rules[].host | spec.hostnames | 동등 |
| 경로 기반 라우팅 | spec.rules[].http.paths | spec.rules[].matches[].path | Gateway API가 더 유연 |
| TLS 종단 | spec.tls | Gateway.listeners[].tls | 역할 분리 (Gateway에서 관리) |
| HTTPS 리다이렉트 | 어노테이션 (벤더 종속) | RequestRedirect 필터 (표준) | Gateway API 우위 |
| URL 재작성 | 어노테이션 (벤더 종속) | URLRewrite 필터 (표준) | Gateway API 우위 |
| 카나리 배포 | 어노테이션 (벤더 종속) | backendRefs.weight (표준) | Gateway API 우위 |
| 헤더 매칭 | 미지원 (어노테이션 한정) | spec.rules[].matches[].headers | Gateway API 우위 |
| 헤더 조작 | 어노테이션 (벤더 종속) | RequestHeaderModifier 필터 | Gateway API 우위 |
| 트래픽 미러링 | 어노테이션 (벤더 종속) | RequestMirror 필터 (Extended) | Gateway API 우위 |
| 타임아웃 | 어노테이션 (벤더 종속) | HTTPRoute timeouts (v1.2+) | Gateway API 우위 |
| 재시도 | 어노테이션 (벤더 종속) | HTTPRoute retry (v1.2+) | Gateway API 우위 |
| gRPC 라우팅 | 미지원 (어노테이션 한정) | GRPCRoute (GA) | Gateway API 우위 |
| TCP/UDP 라우팅 | 미지원 | TCPRoute, UDPRoute (Experimental) | Gateway API 우위 |
| 역할 기반 분리 | 미지원 | GatewayClass/Gateway/Route 분리 | Gateway API 우위 |
| 교차 네임스페이스 | 미지원 | ReferenceGrant | Gateway API 우위 |
| 벤더 이식성 | 낮음 (어노테이션 종속) | 높음 (Conformance Test) | Gateway API 우위 |
| 백엔드 TLS | 어노테이션 (벤더 종속) | BackendTLSPolicy (v1.4 GA) | Gateway API 우위 |
| WebSocket | 어노테이션 (벤더 종속) | 표준 지원 (v1.2+) | Gateway API 우위 |
8. 종합 마이그레이션 체크리스트
아래는 Ingress NGINX에서 Gateway API로의 전환을 위한 포괄적인 체크리스트입니다. 조직의 상황에 맞게 활용하시기 바랍니다.
8.1 평가 단계
- 전체 클러스터의 Ingress 리소스 수와 네임스페이스 매핑 완료
- 사용 중인 Ingress NGINX 어노테이션 전수 조사 완료
-
configuration-snippet/server-snippet사용 여부 확인 및 보안 위험 평가 - ingress-nginx 컨트롤러 버전 확인 (CVE-2025-1974 패치 적용 여부)
- cert-manager, external-dns 등 연동 시스템 의존성 파악
- 현재 트래픽 패턴 및 라우팅 규칙 문서화
8.2 계획 단계
- 대상 Gateway API 구현체 선정 (NGINX Gateway Fabric, Envoy Gateway 등)
- GatewayClass/Gateway/Route 역할 분리 정책 수립
- 네임스페이스 전략 설계 (인프라용, 애플리케이션용)
- RBAC 정책 설계 (인프라팀 vs 개발팀 권한 분리)
- 마이그레이션 순서 결정 (비핵심 서비스 우선)
- 롤백 계획 수립
- HTTP/3 도입 여부 결정
8.3 실행 단계
- Gateway API CRD 설치 (
gateway.networking.k8s.io) - Gateway API 구현체 컨트롤러 배포
- GatewayClass 리소스 생성 및 상태 확인 (
ACCEPTED: True) - Gateway 리소스 생성 및 IP 주소 할당 확인 (
PROGRAMMED: True) -
ingress2gateway도구로 초기 변환 실행 - 변환 결과 수동 검토 및 누락된 기능 보완
- 비프로덕션 환경에서 변환된 HTTPRoute 테스트
- DNS 가중치 기반으로 트래픽 점진적 전환
- 프로덕션 환경 전환 및 모니터링
8.4 검증 단계
- 모든 라우팅 경로의 정상 응답 확인
- TLS 인증서 종단 및 갱신 정상 동작 확인
- 카나리/가중치 기반 배포 동작 확인
- 헤더 기반 라우팅 동작 확인
- 에러 페이지 및 기본 백엔드 동작 확인
- 모니터링 및 알림 정상 동작 확인
- 부하 테스트 수행 및 성능 기준선 비교
8.5 정리 단계
- 기존 Ingress 리소스 제거
- ingress-nginx 컨트롤러 Deployment/DaemonSet 제거
- ingress-nginx 관련 ConfigMap, ServiceAccount, RBAC 리소스 정리
- ingress-nginx Service(LoadBalancer) 제거 및 IP 주소 회수
- Helm 릴리스 정리 (해당 시)
- CI/CD 파이프라인에서 Ingress 관련 매니페스트 제거 또는 Gateway API로 교체
- IaC(Terraform, Pulumi 등)에서 ingress-nginx 모듈 제거
- 팀 교육 및 운영 문서 업데이트
9. 결론: 이제 행동해야 할 때입니다
Ingress NGINX의 은퇴는 단순히 하나의 컨트롤러가 사라지는 사건이 아닙니다. 이것은 쿠버네티스 네트워킹 패러다임 전체의 전환점입니다.
요약: 5가지 핵심 변화와 대응 방향
| # | 변화 | 핵심 메시지 | 즉시 행동 |
|---|---|---|---|
| 1 | Ingress NGINX EOL | 2026년 3월 이후 보안 패치 없음 | 마이그레이션 계획 수립 착수 |
| 2 | 어노테이션 탈출 | 구조적 결함이 보안 취약점으로 직결 | snippets 사용 즉시 제거 |
| 3 | 역할 분리 | GatewayClass/Gateway/Route 3계층 모델 | RBAC 정책 재설계 |
| 4 | 벤더 이식성 | Conformance Test 기반 표준화 | 멀티 클라우드 전략 재검토 |
| 5 | HTTP/3 & QUIC | UDP 기반 차세대 프로토콜 | 방화벽 UDP 443 개방 검토 |
지금 바로 실행해야 할 3가지 행동:
1. 인벤토리 수집 (오늘)
# 지금 바로 실행하세요
kubectl get ingress -A -o json | \
jq -r '[.items[] | {
namespace: .metadata.namespace,
name: .metadata.name,
annotations: (.metadata.annotations // {} | keys | length),
has_snippets: ((.metadata.annotations // {}) |
has("nginx.ingress.kubernetes.io/configuration-snippet") or
has("nginx.ingress.kubernetes.io/server-snippet"))
}]'
2. ingress2gateway 도구 실행 (이번 주)
go install github.com/kubernetes-sigs/ingress2gateway@latest
ingress2gateway print --providers ingress-nginx -A > gateway-migration.yaml
3. NGINX Gateway Fabric 테스트 환경 구축 (이번 달)
# 비프로덕션 클러스터에서 테스트
kubectl kustomize \
"https://github.com/kubernetes-sigs/gateway-api/config/crd?ref=v1.2.1" \
| kubectl apply -f -
helm install ngf oci://ghcr.io/nginx/charts/nginx-gateway-fabric \
--create-namespace --namespace nginx-gateway
쿠버네티스 커뮤니티가 10년간 쌓아온 경험과 교훈이 Gateway API라는 새로운 표준에 녹아 있습니다. 어노테이션의 늪에서 벗어나 타입 안전한 API로, 단일 리소스의 혼재에서 역할 기반 분리로, 벤더 종속에서 이식성의 자유로 나아갈 때입니다.
2026년 3월이라는 데드라인은 위협이 아니라 기회입니다. 이 전환을 통해 더 안전하고, 더 유연하며, 더 표준화된 네트워킹 인프라를 구축할 수 있습니다. 지금 시작하세요.
10. 참고 자료
공식 문서 및 발표
- Ingress NGINX Retirement: What You Need to Know | Kubernetes Blog
- Gateway API v1.2: WebSockets, Timeouts, Retries, and More | Kubernetes Blog
- Gateway API v1.4: New Features | Kubernetes Blog
- Gateway API Official Documentation
- Gateway API Conformance
- Ingress-nginx CVE-2025-1974: What You Need to Know | Kubernetes Blog
NGINX Gateway Fabric
- F5 NGINX Gateway Fabric Documentation
- NGINX Gateway Fabric GitHub
- What's New in F5 NGINX Gateway Fabric 2.3.0
- Gateway Architecture | NGINX Documentation
- Gateway API Compatibility | NGINX Documentation
보안 및 CVE
- IngressNightmare: CVE-2025-1974 | Wiz Blog
- Detecting and Mitigating IngressNightmare | Sysdig
- IngressNightmare CVE-2025-1974 | FortiGuard Labs
마이그레이션 가이드
- Migrating from Ingress | Gateway API Documentation
- Migrating from Ingress-NGINX | Gateway API Documentation
- ingress2gateway GitHub
- Introducing ingress2gateway | Kubernetes Blog
클라우드 벤더
- AKS Application Routing Add-on Ingress-NGINX Update | AKS Engineering Blog
- The End of an Era: Transitioning Away from Ingress NGINX | Google Open Source Blog