K8s Gateway API란?
Kubernetes Gateway API는 기존 Ingress 리소스의 한계를 극복하기 위해 SIG-Network에서 설계한 차세대 트래픽 라우팅 표준이다. Ingress가 단일 리소스로 모든 것을 처리하려 했다면, Gateway API는 GatewayClass → Gateway → HTTPRoute라는 계층 구조로 역할을 분리한다. 인프라 운영자와 애플리케이션 개발자가 각자의 관심사에 집중할 수 있도록 설계된 것이 핵심이다.
2023년 10월 GA(v1.0)를 달성했고, 현재 대부분의 주요 컨트롤러(Envoy Gateway, Istio, Cilium, Traefik, NGINX Gateway Fabric)가 지원한다. 기존 Ingress를 대체할 표준으로 자리잡고 있어 새 프로젝트라면 Gateway API부터 시작하는 것이 권장된다.
Ingress vs Gateway API 비교
- 리소스 구조: Ingress는 단일 리소스. Gateway API는 GatewayClass, Gateway, HTTPRoute 3계층으로 분리
- 프로토콜: Ingress는 HTTP/HTTPS만. Gateway API는 TCP, UDP, gRPC, TLS 모두 지원
- 헤더 기반 라우팅: Ingress는 어노테이션 의존(컨트롤러마다 다름). Gateway API는 네이티브 지원
- 트래픽 분할: Ingress는 불가(별도 CRD 필요). Gateway API는 backendRefs weight로 내장
- 역할 분리: Ingress는 없음. Gateway API는 인프라팀(GatewayClass/Gateway) ↔ 개발팀(Route) 명확 분리
- 이식성: Ingress는 어노테이션이 컨트롤러 종속. Gateway API는 표준 스펙으로 컨트롤러 간 이식 가능
핵심 리소스 3계층 구조
1. GatewayClass — 인프라 레벨
클러스터 관리자가 정의하는 리소스로, 어떤 컨트롤러가 Gateway를 관리할지 지정한다. StorageClass와 유사한 개념이다.
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: envoy-gateway
spec:
controllerName: gateway.envoyproxy.io/gatewayclass-controller
2. Gateway — 플랫폼 레벨
실제 로드밸런서/프록시 인스턴스를 정의한다. 어떤 포트에서 어떤 프로토콜을 수신할지, TLS 인증서는 무엇을 쓸지 선언한다.
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: api-gateway
namespace: infra
spec:
gatewayClassName: envoy-gateway
listeners:
- name: https
protocol: HTTPS
port: 443
tls:
mode: Terminate
certificateRefs:
- kind: Secret
name: api-tls-cert
allowedRoutes:
namespaces:
from: Selector
selector:
matchLabels:
gateway-access: "true"
allowedRoutes로 어떤 네임스페이스의 Route가 이 Gateway에 붙을 수 있는지 제어한다. 이것이 역할 분리의 핵심이다.
3. HTTPRoute — 애플리케이션 레벨
개발팀이 자신의 네임스페이스에서 라우팅 규칙을 정의한다. Gateway를 참조(parentRefs)하기만 하면 된다.
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: user-service-route
namespace: app-team
spec:
parentRefs:
- name: api-gateway
namespace: infra
hostnames:
- "api.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /users
headers:
- name: X-API-Version
value: "v2"
backendRefs:
- name: user-service-v2
port: 8080
weight: 90
- name: user-service-v3
port: 8080
weight: 10
위 예시에서 헤더 매칭과 가중치 기반 트래픽 분할이 모두 네이티브로 동작한다. Ingress에서는 불가능하거나 어노테이션 해킹이 필요했던 기능이다.
실전 패턴: 카나리 배포
Gateway API의 가장 강력한 실전 활용은 카나리 배포다. backendRefs의 weight만 조절하면 된다.
# 카나리 시작: 5%만 새 버전으로
backendRefs:
- name: app-stable
port: 8080
weight: 95
- name: app-canary
port: 8080
weight: 5
# 점진 확대: 50%
backendRefs:
- name: app-stable
port: 8080
weight: 50
- name: app-canary
port: 8080
weight: 50
# 완전 전환: 100%
backendRefs:
- name: app-canary
port: 8080
weight: 100
Argo Rollouts나 Flagger 같은 도구와 연동하면 weight 조절을 자동화할 수 있다. HTTPRoute의 weight는 이미 표준 필드이므로 별도 CRD 없이 바로 동작한다.
HTTPRoute 고급 필터
HTTPRoute는 filters 필드로 요청/응답을 변환할 수 있다.
rules:
- matches:
- path:
type: PathPrefix
value: /legacy
filters:
- type: URLRewrite
urlRewrite:
path:
type: ReplacePrefixMatch
replacePrefixMatch: /api/v1
- type: RequestHeaderModifier
requestHeaderModifier:
add:
- name: X-Forwarded-By
value: gateway-api
remove:
- X-Debug-Header
backendRefs:
- name: api-service
port: 8080
지원되는 필터 종류: RequestHeaderModifier, ResponseHeaderModifier, URLRewrite, RequestRedirect, RequestMirror, ExtensionRef. 특히 RequestMirror는 프로덕션 트래픽을 복제해서 새 버전에 테스트하는 데 유용하다.
TLS 설정과 Cross-Namespace 참조
Gateway API에서 TLS는 Gateway 리소스의 listeners에서 설정한다. 중요한 점은 ReferenceGrant를 통한 크로스 네임스페이스 참조다.
# cert-manager가 관리하는 인증서 (cert namespace)
apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata:
name: allow-gateway-cert
namespace: cert
spec:
from:
- group: gateway.networking.k8s.io
kind: Gateway
namespace: infra
to:
- group: ""
kind: Secret
ReferenceGrant가 없으면 다른 네임스페이스의 Secret을 참조할 수 없다. 이 명시적 권한 부여 모델이 보안을 강화한다.
GRPCRoute와 TCPRoute
Gateway API는 HTTP 외에도 다양한 프로토콜 Route를 제공한다.
apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
name: grpc-user-route
spec:
parentRefs:
- name: api-gateway
rules:
- matches:
- method:
service: user.UserService
method: GetUser
backendRefs:
- name: user-grpc-service
port: 50051
gRPC 서비스의 service/method 레벨까지 라우팅이 가능하다. Ingress에서는 gRPC 라우팅에 별도 어노테이션과 설정이 필요했지만, Gateway API는 전용 리소스로 깔끔하게 처리한다.
마이그레이션 전략: Ingress → Gateway API
기존 Ingress에서 Gateway API로 전환할 때 권장되는 단계:
- 병행 운영: 기존 Ingress는 유지하면서 Gateway API를 추가 배포
- Route 변환: Ingress 규칙을 HTTPRoute로 변환.
ingress2gatewayCLI 도구 활용 가능 - DNS 전환: 트래픽을 점진적으로 새 Gateway로 이동 (DNS weight 또는 외부 LB 활용)
- Ingress 제거: 모든 트래픽이 Gateway API를 통과하면 기존 Ingress 삭제
# ingress2gateway 도구로 자동 변환
$ ingress2gateway print --input-file ingress.yaml
# 변환된 HTTPRoute + Gateway YAML 출력
운영 팁과 모니터링
- Gateway 상태 확인:
kubectl get gateway -A로 Accepted/Programmed 상태 확인 - Route 연결 상태:
kubectl get httproute -A -o wide로 parentRef 바인딩 확인 - 디버깅: Route의 status.parents[].conditions에서 Accepted=False이면 allowedRoutes 설정 확인
- 메트릭: Envoy Gateway 기준 Prometheus 메트릭 자동 노출. Grafana 대시보드 연동 권장
Gateway API는 Kubernetes 네트워킹의 미래다. Ingress의 어노테이션 지옥에서 벗어나 표준화된 선언적 트래픽 관리를 시작해보자. 더 자세한 K8s 운영 패턴은 K8s Ephemeral Container 디버깅 글과 K8s Kyverno 정책 엔진 심화 글도 참고하길 바란다.