Ingress를 배우고 나면 자연스럽게 이런 고민이 생깁니다.
- 웹 서비스와 비디오 서비스가 같은 도메인/Ingress를 공유해야 할 때,
서로 다른 팀(또는 서로 다른 조직) 이면 누가 Ingress 리소스를 관리해야 하지? - 컨트롤러별로 annotation이 달라서(nginx/traefik/…) 설정이 산으로 가는데,
Kubernetes가 “이 설정이 맞는지” 검증도 못 한다면 운영은 어떻게 안정적으로 하지? - HTTP 말고 TCP/UDP/gRPC, 트래픽 분할(카나리), 헤더 조작, 리다이렉트/리라이트 같은 걸
“표준 리소스 스펙”으로 표현할 수는 없나?
이런 문제를 정면으로 해결하려고 나온 것이 Gateway API입니다.
1) Ingress의 구조적 한계
1.1 멀티 테넌시(팀/조직 분리) 어려움
Ingress는 결국 “하나의 Ingress 리소스”에 룰이 몰리기 쉽습니다.
my-online-store.com/→ web 팀my-online-store.com/watch→ video 팀
이렇게 되면 Ingress 한 개를 여러 팀이 공동 수정해야 해서 충돌/조율 비용이 커집니다.
1.2 확장 기능이 “annotation”으로 흩어짐
Ingress 기본 스펙은 주로 HTTP host/path 매칭 정도고, 그 이상의 기능은 컨트롤러별 annotation으로 우회합니다.
- nginx는 nginx annotation
- traefik은 traefik annotation
- 같은 요구사항이라도 문법/동작이 달라지고,
- Kubernetes는 annotation 내용을 “그냥 문자열”로 취급해서 검증/일관성/이식성이 약합니다.
2) Gateway API는 무엇인가?
Gateway API는 Kubernetes 공식(SIG) 프로젝트로, L4/L7 트래픽 라우팅을 표준 리소스로 다룹니다.
- “차세대 Ingress”에 가까운 포지션
- Ingress/Load Balancing/Service Mesh API를 더 표준화되고 확장 가능하게 만들려는 목적
핵심 철학은 이겁니다.
인프라 제공자(플랫폼) / 클러스터 운영자 / 앱 개발자의 역할을 리소스로 분리해서
멀티 테넌시와 거버넌스를 동시에 만족시키자
3) 멀티 테넌시를 위한 3계층 리소스 모델
Gateway API는 3개의 핵심 오브젝트로 역할을 분리합니다.
3.1 GatewayClass (인프라 제공자/플랫폼 팀)
“어떤 구현체(컨트롤러)를 쓸 것인가”를 정의합니다.
- 예: NGINX Gateway Controller, Istio, Envoy Gateway 등
controllerName이 컨트롤러가 기대하는 값과 일치해야 함
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: nginx
spec:
controllerName: nginx.org/gateway-controller
3.2 Gateway (클러스터 운영자/SRE)
GatewayClass의 “인스턴스”입니다.
어떤 포트/프로토콜로 들어오는 트래픽을 받을지(listener)를 정의합니다.
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: nginx-gateway
namespace: default
spec:
gatewayClassName: nginx
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: All
listeners: 포트/프로토콜/라우트 부착 정책(allowedRoutes)을 명시적으로 표현allowedRoutes: “어떤 네임스페이스의 Route가 이 Gateway에 붙을 수 있는가”를 제어 → 멀티 테넌시 핵심
3.3 Route(앱 개발자)
Ingress의 “규칙”에 해당하는 부분을 앱 팀이 분리해서 관리합니다.
- HTTPRoute, TCPRoute, UDPRoute, TLSRoute, GRPCRoute 등(컨트롤러 지원 범위에 따라)
parentRefs로 어느 Gateway에 붙는지 지정
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: basic-route
namespace: default
spec:
parentRefs:
- name: nginx-gateway
rules:
- matches:
- path:
type: PathPrefix
value: /app
backendRefs:
- name: my-app
port: 80
이 구조 덕분에 “Gateway(인프라 진입점)”는 운영자가 통제하고,
“서비스별 라우팅 규칙(Route)”은 각 팀이 자기 네임스페이스에서 독립적으로 관리할 수 있습니다.
4) 컨트롤러 설치가 먼저다 (Ingress와 동일)
Ingress와 마찬가지로 Gateway API도 컨트롤러가 반드시 필요합니다.
(리소스만 만든다고 트래픽이 처리되지 않습니다.)
예시로 NGINX Gateway Fabric(NGF)을 설치하는 흐름(강의/가이드 텍스트 기반)은 다음과 같습니다.
kubectl kustomize "https://github.com/nginx/nginx-gateway-fabric/config/crd/gateway-api/standard?ref=v1.6.2" | kubectl apply -f -
kubectl kustomize "https://github.com/nginx/nginx-gateway-fabric/config/crd/gateway-api/experimental?ref=v1.6.2" | kubectl apply -f -
helm install ngf oci://ghcr.io/nginx/charts/nginx-gateway-fabric \
--create-namespace -n nginx-gateway
- Gateway API는 CRD 기반이므로(HTTPRoute 등) CRD 설치가 선행됩니다.
- “standard / experimental” 리소스는 지원 레벨이 다를 수 있습니다.
5) Ingress에서 annotation으로 하던 것들을 “스펙으로” 한다
Gateway API의 강점은 구조화된 스펙입니다.
Ingress에서 흔히 보던 “컨트롤러별 annotation 트릭”을 표준 필드로 끌어올립니다.
5.1 HTTP → HTTPS 리다이렉트 (Ingress에서는 nginx annotation이 필요했던 케이스)
Gateway API는 Route의 filter로 명확히 표현합니다.
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: https-redirect
namespace: default
spec:
parentRefs:
- name: nginx-gateway
rules:
- filters:
- type: RequestRedirect
requestRedirect:
scheme: https
5.2 Path Rewrite (Ingress의 rewrite-target 대체)
Ingress에서는 nginx.ingress.kubernetes.io/rewrite-target 같은 annotation을 썼다면,
Gateway API는 URLRewrite로 “의미를 스펙에 박아” 넣습니다.
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: rewrite-path
namespace: default
spec:
parentRefs:
- name: nginx-gateway
rules:
- matches:
- path:
type: PathPrefix
value: /old
filters:
- type: URLRewrite
urlRewrite:
path:
replacePrefixMatch: /new
backendRefs:
- name: my-app
port: 80
5.3 헤더 조작 (Request/Response)
Ingress에서는 복잡한 annotation으로 컨트롤러별 문법을 외워야 했던 영역입니다.
Gateway API는 filter로 통일합니다.
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: header-mod
namespace: default
spec:
parentRefs:
- name: nginx-gateway
rules:
- filters:
- type: RequestHeaderModifier
requestHeaderModifier:
add:
- name: x-env
value: staging
backendRefs:
- name: my-app
port: 80
6) 트래픽 분할(카나리)과 미러링: “표준 필드”로 한 눈에 보이게
6.1 트래픽 분할(80/20)
Ingress에서는 컨트롤러별 “카나리 annotation”을 알아야 했고, 설정만 봐서는 전체 스토리가 안 보이는 경우가 많았습니다.
Gateway API는 backendRefs.weight로 명시합니다.
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: traffic-split
namespace: default
spec:
parentRefs:
- name: nginx-gateway
rules:
- backendRefs:
- name: v1-service
port: 80
weight: 80
- name: v2-service
port: 80
weight: 20
6.2 요청 미러링
운영 트래픽을 복제해서 새 버전/분석 시스템에 보내는 형태도 filter로 표현합니다.
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: request-mirror
namespace: default
spec:
parentRefs:
- name: nginx-gateway
rules:
- filters:
- type: RequestMirror
requestMirror:
backendRef:
name: mirror-service
port: 80
backendRefs:
- name: my-app
port: 80
7) TLS(HTTPS)도 “Gateway의 listener”에서 선언적으로
Ingress에서도 TLS는 가능하지만, “HTTPS 강제 리다이렉트” 같은 것들은 annotation으로 흩어지곤 했습니다.
Gateway API는 listener에 TLS termination을 명확히 모델링합니다.
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: nginx-gateway-tls
namespace: default
spec:
gatewayClassName: nginx
listeners:
- name: https
protocol: HTTPS
port: 443
tls:
mode: Terminate
certificateRefs:
- kind: Secret
name: tls-secret
allowedRoutes:
namespaces:
from: All
tls.mode: Terminate→ 게이트웨이에서 TLS 종료(복호화) 후 백엔드로 전달certificateRefs→ 어떤 Secret의 인증서를 쓸지 명시
8) HTTP만? 아니다: TCP/UDP 같은 L4도 표준으로
Ingress가 “대부분 HTTP 중심”이었다면, Gateway API는 L4도 정식 리소스(또는 listener + route 조합)로 확장할 수 있게 설계되었습니다.
예: TCP(3306) 리스너
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: tcp-gateway
namespace: default
spec:
gatewayClassName: nginx
listeners:
- name: tcp
protocol: TCP
port: 3306
allowedRoutes:
namespaces:
from: All
UDP(53) 리스너
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: udp-gateway
namespace: default
spec:
gatewayClassName: nginx
listeners:
- name: udp
protocol: UDP
port: 53
allowedRoutes:
namespaces:
from: All
실제로 TCPRoute/UDPRoute 등의 세부 동작은 “컨트롤러 구현/지원 상태”에 따라 달라질 수 있으니, 사용하는 컨트롤러의 지원 범위를 확인하는 습관이 필요합니다.
9) gRPC 라우팅(개념)
가이드 텍스트에서는 HTTPRoute로 gRPC 메서드 매칭 예시를 보여주지만, 실제 지원/필드 모델은 컨트롤러 및 Gateway API 버전에 따라 차이가 날 수 있습니다. 핵심은:
- gRPC도 “표준 라우팅 모델” 안에서 다룰 수 있게 확장되고 있고
- Ingress 대비 “표현력/일관성”이 커지는 방향이라는 점입니다.
10) 네임스페이스/권한 관점에서 Gateway API가 특히 유리한 이유
Ingress에서 가장 아픈 지점이 “한 Ingress를 여러 팀이 만지는 문제”였는데, Gateway API는 설계 자체가 이를 분리합니다.
- 플랫폼/인프라 팀:
GatewayClass - 클러스터 운영팀:
Gateway(+ listener, allowedRoutes로 경계 설정) - 앱 팀:
HTTPRoute(자기 네임스페이스에서 규칙 관리)
그리고 멀티테넌시 통제를 강화하는 핵심 레버가:
allowedRoutes(어떤 namespace의 route가 붙을 수 있는가)
입니다.
11) 운영에서 바로 확인하는 커맨드
# Gateway API CRD들이 설치되어 있는지
kubectl get crd | grep gateway.networking.k8s.io
# GatewayClass / Gateway / HTTPRoute 상태 확인
kubectl get gatewayclass
kubectl get gateway -A
kubectl get httproute -A
# 라우트가 게이트웨이에 "붙었는지"는 status/conditions가 힌트가 됨
kubectl describe gateway <name> -n <ns>
kubectl describe httproute <name> -n <ns>
12) 정리
Gateway API는 “Ingress의 다음 버전”이라는 표현보다, 다음 문제를 해결하는 새로운 표준 라우팅 API로 이해하는 게 정확합니다.
- 멀티테넌시: 한 리소스를 여러 팀이 공유해 충돌하는 문제를 리소스 모델로 분리
- 컨트롤러 종속 annotation 지옥 → 구조화된 스펙/필드로 표준화
- HTTP뿐 아니라 TCP/UDP/TLS/gRPC 등 L4/L7를 한 체계로 확장 가능
- 트래픽 분할, 미러링, 헤더 조작 같은 고급 기능을 “읽기 쉬운 YAML”로 표현
다음 단계로는 실습에서 보통 이 순서로 접근하면 좋습니다.
- 컨트롤러 설치(예: NGINX Gateway Fabric)
- GatewayClass 확인(controllerName 매칭)
- Gateway 생성(listener/allowedRoutes 설계)
- 각 팀 네임스페이스에서 HTTPRoute 생성(parentRefs로 부착)
- 리다이렉트/리라이트/트래픽 분할/헤더 수정 같은 필터 적용
'CKA' 카테고리의 다른 글
| Design Kubernetes (0) | 2026.01.06 |
|---|---|
| Network - 정리(2) (0) | 2026.01.05 |
| Network - Ingress (1) | 2026.01.05 |
| Network - Service Networking (0) | 2026.01.05 |
| Network - IPAM(IP Address Management) (0) | 2026.01.05 |