Skip to content
Published on

쿠버네티스 네트워킹의 종말과 부활: 2026년 3월 이전에 반드시 알아야 할 5가지 변화

Authors
  • Name
    Twitter

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가지 핵심 관점에서 분석합니다:

  1. 시한폭탄의 카운트다운 -- Ingress NGINX의 공식 은퇴와 그 여파
  2. 어노테이션의 늪에서 탈출 -- 구조적 결함과 Gateway API의 해법
  3. 역할의 분리 -- 인프라 관리자와 개발자의 평화로운 공존
  4. 벤더 종속성 탈피 -- 이식성(Portability)의 실현
  5. 성능의 도약 -- HTTP/3와 QUIC의 본격 도입
  ┌─────────────────────────────────────────────────────────────────┐
2026년 쿠버네티스 네트워킹 전환 로드맵         │
  ├──────────┬──────────┬──────────┬──────────┬──────────┬──────────┤
2025.032025.112026.032026.062026.112027+  │          │          │          │          │          │          │
Ingress  │ 은퇴     │ ■ EOL ■  │ GatewayAKS/GKEIngressNightmare│ 공식     │ 보안패치 │ API v1.5 │ 연장지원 │ APICVE 발생 │ 발표     │ 완전종료  (예상)   │ 종료     │ 잔존    │
  │          │          │          │          │          │ 가능성↓ │
GW APIGW 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 IDCVSS설명
CVE-2025-245148.8auth-url 어노테이션을 통한 설정 주입
CVE-2025-10978.8auth-tls-match-cn 어노테이션을 통한 설정 주입
CVE-2025-10988.8mirror-target/mirror-host 어노테이션을 통한 설정 주입
CVE-2025-245134.8auth-url 파일 경로 검증 부재
CVE-2025-19749.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-snippetnginx.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-snippetserver 블록에 그대로 삽입되기 때문입니다.

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 ProviderGatewayClass데이터 플레인 구현체 등록, 파라미터 정의ClusterRole: gatewayclass-admin
Cluster OperatorGateway, ReferenceGrant리스너 설정, TLS 인증서 관리, 네임스페이스 접근 제어Role: gateway-admin (infra-ns)
Application DeveloperHTTPRoute, 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 TCPHead-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)개선 효과
전송 계층TCPUDP + QUIC커널 의존성 감소
연결 수립TCP 3-way handshake + TLS handshake (2~3 RTT)QUIC 0-RTT / 1-RTT최대 67% 지연 감소
HOL BlockingTCP 수준에서 발생스트림 수준으로 격리병렬 처리 효율 향상
연결 마이그레이션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 기본 사용
LibreSSL3.6.0+ 지원OpenBSD 프로젝트
QuicTLSOpenSSL + QUIC 패치OpenSSL 포크, QUIC API 추가
OpenSSL미지원 (3.x 기준)향후 지원 예정

NGINX Gateway Fabric은 기본적으로 BoringSSL을 사용하여 빌드되므로, 별도의 SSL 라이브러리 교체 없이 HTTP/3를 사용할 수 있습니다.

2) 방화벽 및 네트워크 설정

  ┌─────────────────────────────────────────────────────────┐
HTTP/3 네트워크 요구사항                     │
  │                                                         │
  │  인바운드 규칙에 UDP 443 추가 필수:  │                                                         │
기존 (HTTP/2):  │  ┌──────────────────────────────────────┐               │
  │  │ TCP 80HTTP                     │               │
  │  │ TCP 443HTTPS (TLS over TCP)     │               │
  │  └──────────────────────────────────────┘               │
  │                                                         │
HTTP/3 추가 후:  │  ┌──────────────────────────────────────┐               │
  │  │ TCP 80HTTP                     │               │
  │  │ TCP 443HTTPS (TLS over TCP)     │               │
  │  │ UDP 443QUIC (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-targetRequestRedirect, URLRewrite 필터높음
Policy 대체 가능proxy-read-timeout, proxy-body-sizePolicy Attachment중간
기능별 대체canary, canary-weightbackendRefs.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 APIGateway API비고
호스트 기반 라우팅spec.rules[].hostspec.hostnames동등
경로 기반 라우팅spec.rules[].http.pathsspec.rules[].matches[].pathGateway API가 더 유연
TLS 종단spec.tlsGateway.listeners[].tls역할 분리 (Gateway에서 관리)
HTTPS 리다이렉트어노테이션 (벤더 종속)RequestRedirect 필터 (표준)Gateway API 우위
URL 재작성어노테이션 (벤더 종속)URLRewrite 필터 (표준)Gateway API 우위
카나리 배포어노테이션 (벤더 종속)backendRefs.weight (표준)Gateway API 우위
헤더 매칭미지원 (어노테이션 한정)spec.rules[].matches[].headersGateway 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 우위
교차 네임스페이스미지원ReferenceGrantGateway 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가지 핵심 변화와 대응 방향

#변화핵심 메시지즉시 행동
1Ingress NGINX EOL2026년 3월 이후 보안 패치 없음마이그레이션 계획 수립 착수
2어노테이션 탈출구조적 결함이 보안 취약점으로 직결snippets 사용 즉시 제거
3역할 분리GatewayClass/Gateway/Route 3계층 모델RBAC 정책 재설계
4벤더 이식성Conformance Test 기반 표준화멀티 클라우드 전략 재검토
5HTTP/3 & QUICUDP 기반 차세대 프로토콜방화벽 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. 참고 자료

공식 문서 및 발표

NGINX Gateway Fabric

보안 및 CVE

마이그레이션 가이드

클라우드 벤더

HTTP/3 및 QUIC