Overview
Kubernetes는 기본적으로 Ingress 리소스를 통해 L7(HTTP/HTTPS) 트래픽을 처리하지만, 이 방식은 Layer 4(L4) 수준의 트래픽 제어나 멀티 프로토콜, 복잡한 인증 처리 등에서 한계를 가진다.
이를 해결하기 위해 등장한 Kubernetes Gateway API는 L4~L7까지 유연하게 다룰 수 있는 새로운 네트워크 모델이다.
Ingress를 단순히 확장한 것이 아닌, 현대 클라우드 네트워크를 위한 진화된 표준이며, 서비스 메시, API Gateway, 로드밸런서 등을 하나의 공통 구조로 통합 관리할 수 있게 해준다.

📅 관련 글
2022.08.08 - [Container Orchestration/Kubernetes] - Kubernetes Ingress란? (클러스터 외부 트래픽 관리)
2024.06.24 - [Container Orchestration/Kubernetes] - Ingress Nginx란?
주요 이정표
시점 | 내용 |
2019년 후반 | SIG-Network에서 Ingress의 한계를 해결하기 위한 새로운 API 디자인 논의 시작 |
2020년 4월 | Gateway API 최초 알파 릴리스 (v1alpha1) 발표 |
2021~2022 | 다양한 컨트롤러(Envoy, Istio, NGINX, GKE 등)에서 Gateway API 지원 시작 |
2023년 | 일부 리소스(Gateway, HTTPRoute)가 v1beta1 또는 v1 로 안정화 준비 |
2024년 이후 | 많은 클라우드/서비스메시 벤더들이 공식 지원 중, Ingress 대비 실전 배포 증가 |
Gateway API란?
Gateway API는 Kubernetes에서 네트워크 트래픽을 외부로부터 클러스터 내부의 서비스로 안전하고 유연하게 전달하기 위한 새로운 표준 API 리소스 집합이다.
전통적으로는 Ingress 리소스를 통해 HTTP/HTTPS 요청을 클러스터 내부 서비스로 라우팅했지만, Ingress는 기능 확장에 한계가 있었고, L4(Transport Layer) 수준의 트래픽이나 멀티 프로토콜, 고급 라우팅 제어를 지원하기 어려웠다.
이러한 배경에서 등장한 것이 바로 Gateway API 이다.
왜 나왔어?
기존 Ingress 리소스는 너무 단순하고 확장성 부족,
모든 컨트롤러가 annotation에 의존해서 혼란스럽고 표준화 어려움.
👉 그래서 Gateway API는 Ingress의 진화 버전이자, L4~L7 통합을 위한 차세대 표준으로 만들어졌다.
Gateway API의 목적
Gateway API는 단순히 Ingress를 대체하는 것이 아니라, 다음과 같은 목표를 가지고 설계되었다.
- L4~L7 트래픽을 모두 지원하는 유연한 아키텍처
- 멀티 테넌시 및 보안 분리 구조 지원
- 컨트롤러 벤더 독립적인 표준화된 API
- Cloud Provider, Service Mesh, API Gateway 등 다양한 환경에서 통합 가능
- 선언적 구성(Helm/Kustomize)에 적합한 구조
핵심 리소스 구조
리소스 | 설명 |
GatewayClass | 인프라 제공자가 정의하는 Gateway 구현 클래스 |
Gateway | 실제 L4/L7 트래픽을 수신하는 리소스 |
Route (HTTPRoute, TLSRoute, TCPRoute, GRPCRoute) | 서비스로 트래픽을 라우팅하는 규칙 |
ReferencePolicy, BackendPolicy | 고급 권한과 정책 제어 리소스 |
어떤 문제를 해결할 수 있을까?
- 단순 HTTP 트래픽 외에 TCP, TLS, gRPC 등 다양한 프로토콜을 하나의 Gateway에서 처리할 수 있음
- 서로 다른 팀/서비스 간에 Gateway 자원을 안전하게 공유 가능
- cert-manager, Service Mesh 등과 통합해 TLS 자동화 및 보안 구성 간소화
- 멀티 클러스터 환경에서 Gateway를 통합 API로 추상화하여 외부 진입점 관리
왜 L4/L7 혼합 시나리오가 필요한가?
현실의 서비스는 단일 프로토콜로만 동작하지 않는다. 예를 들어:
- HTTP API는 HTTPRoute로 처리
- gRPC 서버는 GRPCRoute로 라우팅
- 게임 서버는 TCP를 사용하므로 TCPRoute 필요
- TLS termination은 TLSRoute에서 처리
이러한 혼합된 요구를 단일 Gateway 리소스로 구성할 수 있는 것이 Gateway API의 강점이다.
Gateway API vs Ingress 비교표
항목 | Ingress | Gateway API |
API 안정성 | v1 (Stable) | v1 / v1alpha2 (일부 기능) |
지원 프로토콜 | HTTP/HTTPS (L7 전용) | HTTP, HTTPS, gRPC, TCP, TLS (L4~L7 혼합 지원) |
라우팅 리소스 | 단일 리소스 (Ingress) | 다중 리소스 (HTTPRoute, TCPRoute, TLSRoute, GRPCRoute) |
TLS 처리 방식 | Secret 참조 (단순 구성) | certificateRefs로 세분화, 다양한 모드 지원 (Terminate, Passthrough 등) |
역할 분리 | 없음 (Ingress 하나로 구성) | GatewayClass/Gateway/Route로 명확히 분리 |
멀티 테넌시 | 제한적 (네임스페이스 기반 공유 불명확) | AllowedRoutes로 네임스페이스/권한 범위 제어 |
커스텀 확장성 | 제한적 (annotation 기반) | 고도로 유연함 (CRD 기반 확장 및 표준화) |
컨트롤러 독립성 | 대부분 NGINX에 종속 (Ingress Controller) | 컨트롤러 선택 가능 (NGINX, Istio, Envoy, GKE, AWS 등) |
gRPC 지원 | 불완전 (Path 기반 라우팅만) | 완전한 GRPCRoute 지원 (서비스/메서드 기준) |
L4 지원 (TCP 등) | 미지원 | TCPRoute로 가능 |
Helm/Kustomize 호환성 | 제한적 구조 | 선언적 구조로 자동화에 용이 |
향후 확장성 | 개발 중단 예정 아님, 그러나 제한적 | Kubernetes 공식 차세대 네트워크 표준으로 확장 중 |
- Ingress는 단순하고 빠르게 설정할 수 있지만, 기능 확장성과 역할 분리가 부족하다.
- Gateway API는 더 복잡해 보일 수 있지만, 실제 운영 환경에서 요구되는 다양한 기능(L4~L7, TLS 자동화, 멀티 테넌시 등)을 체계적으로 지원한다.
- 특히
Service Mesh
,Multi-cluster
,TLS 관리
,gRPC
등 최신 트렌드와 어울리는 구조
Ingress NGINX Controller가 이미 설치되어 있어도 괜찮을까?
문제 없다.
- Gateway API는 Ingress Controller와 완전히 별개로 동작한다.
- 서로 다른 리소스 (Ingress vs HTTPRoute, Gateway)를 바라보며, 서로 다른 컨트롤러가 관리한다.
- 단, 포트 충돌만 조심하면 됩니다 (예: 두 컨트롤러가 모두 LoadBalancer 80/443 포트를 쓰려 할 때).
팁
- Ingress NGINX는 보통 ingress-nginx 네임스페이스에 설치되고 Ingress 리소스를 감지한다.
- NGINX Gateway Controller는 nginx-gateway 네임스페이스에 설치되며 Gateway, HTTPRoute 등을 감지한다.
결론
항목 | 가능 여부 | 설명 |
Helm으로 NGINX Gateway 설치 | ✅ 가능 | nginx-stable/kubernetes-gateway Chart 사용 |
Ingress NGINX Controller와 동시 운영 | ✅ 가능 | 리소스/컨트롤러가 분리되어 충돌 없음 |
포트 충돌 가능성 | ⚠️ 주의 | ❌ LoadBalancer IP가 다르면 충돌 없음 |
Gateway 리소스를 어디에 만들어야 할까?
리소스 | 위치 기준 | 설명 |
GatewayClass | 클러스터 전역 | 어떤 Gateway 컨트롤러를 사용할지 지정 |
Gateway | 애플리케이션(Service)이 존재하는 네임스페이스 | 실제로 트래픽을 수신하는 진입점 |
Route (HTTPRoute 등) | 애플리케이션 네임스페이스 | Gateway를 참조하여 라우팅 정의 |
이해 포인트
GatewayClass
는 전역 리소스니까 네임스페이스가 없다 (cluster-scoped
)Gateway
는 특정 네임스페이스에 생성되며, 해당 네임스페이스에 존재하는 Route만 기본적으로 받아들인다- 물론
allowedRoutes
설정으로 다른 네임스페이스도 허용할 수 있다.
- 물론
Route
(HTTPRoute
,TLSRoute
등)는 자신의 네임스페이스에서 Gateway를parentRefs
로 참조한다
default
네임스페이스에 있는 애플리케이션을 외부에서 노출하고 싶다면:
Gateway
→default
네임스페이스에 생성HTTPRoute
→default
네임스페이스에 생성Service
,Deployment
→ 역시default
에 존재
advanced: 네임스페이스 분리하고 싶다면?
예를 들어 Gateway는 ingress-system
네임스페이스에 있고, 애플리케이션은 app-namespace
에 있을 수도 있다.
이때는 Gateway
의 allowedRoutes
설정을 다음처럼 바꿔줘야 한다.
allowedRoutes:
namespaces:
from: All
또는 더 안전하게
allowedRoutes:
namespaces:
from: Selector
selector:
matchLabels:
route-allowed: "true"
그리고 app-namespace에 label 추가
kubectl label namespace app-namespace route-allowed=true
- 이렇게 하면 네임스페이스 간 정책 기반 라우팅 제어도 가능하다.
ReferenceGrant란?
ReferenceGrant는 다른 네임스페이스에 있는 리소스를 참조할 수 있도록 허용하는 보안 리소스이다.
Kubernetes Gateway API는 보안 원칙에 따라,
HTTPRoute, TCPRoute 등의 Route 리소스가 다른 네임스페이스의 Service를 참조하려면 명시적인 허가가 필요하다.
이때 필요한 것이 바로 ReferenceGrant이다.
언제 필요할까?
Gateway
는default
네임스페이스에 있고,- 실제 애플리케이션은
mario-ns, tetris-ns
등 다른 네임스페이스에 존재 HTTPRoute
에서 해당 서비스를 라우팅 대상으로 지정하고 싶은 경우
이 경우 서비스가 위치한 네임스페이스에서 ReferenceGrant
를 선언해야 한다.
왜 필요한가?
Ingress에서는 네임스페이스 간 참조를 자유롭게 했지만,
Gateway API는 보안에 더 민감하게 설계되어 있어,
명확한 허가 없이는 다른 네임스페이스의 리소스를 참조할 수 없다.
이는 멀티 테넌시 환경이나 팀 간 리소스 분리를 할 때 강력한 보안 이점을 제공한다.
예시
# mario-ns에 생성
apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata:
name: allow-mario-service
namespace: mario-ns
spec:
from:
- group: gateway.networking.k8s.io
kind: HTTPRoute
namespace: default
to:
- group: ""
kind: Service
- 이 예시는 default 네임스페이스에 있는
HTTPRoute
가 mario-ns
네임스페이스에 있는Service
를 참조할 수 있도록 허용한다.
참고 요약
항목 | 설명 |
리소스 타입 | ReferenceGrant |
배치 위치 | 서비스가 존재하는 네임스페이스 |
목적 | 네임스페이스 간 Route → Service 참조 허용 |
보안 효과 | L7 트래픽 제어에 RBAC 수준의 제한을 제공 |
ReferenceGrant는 Gateway API의 보안 모델에서 매우 중요한 핵심 개념으로,
서비스 간 경계를 명확히 하고, 네임스페이스 기반의 안전한 라우팅을 가능하게 한다.
실습 1: HTTPRoute + TLSRoute + GRPCRoute + TCPRoute
실습 환경: Kind 또는 Minikube + NGINX Gateway Controller
CRD 설치
kubectl kustomize https://github.com/nginx/nginx-gateway-fabric/config/crd/gateway-api/standard | kubectl apply -f -
NGINX Gateway Controller - Helm 설치 방법
# Installing the Chart from the OCI Registry
helm install ngf oci://ghcr.io/nginx/charts/nginx-gateway-fabric \
--namespace nginx-gateway \
--create-namespace \
--wait
# Installing the Chart from the OCI Registry NodePort
helm install ngf oci://ghcr.io/nginx/charts/nginx-gateway-fabric \
--namespace nginx-gateway \
--create-namespace \
--set service.type=NodePort
# Installing the Chart via Sources
## Pulling the Chart
helm pull oci://ghcr.io/nginx/charts/nginx-gateway-fabric --untar
cd nginx-gateway-fabric
## Installing the Chart
helm install ngf . --create-namespace -n nginx-gateway
- 위 명령어는 기본 설치이며, 필요 시 values.yaml 파일을 커스터마이징해서 사용할 수도 있다.
설명 요약
필드 | 설명 |
nginxGateway.gatewayClassName |
Gateway 리소스에서 사용하는 class 이름 (예: nginx) |
replicaCount |
기본적으로 1이지만, 가용성 확보를 위해 2로 설정 |
service.type |
LoadBalancer로 설정하여 외부 IP 할당 |
externalTrafficPolicy |
Local 설정 시 클라이언트의 실제 IP 유지 가능 |
metrics.enable |
Prometheus에서 수집할 수 있도록 메트릭 활성화 |
pullPolicy |
이미지 캐시 정책 (IfNotPresent이면 캐시 있음) |
GatewayClass, Gateway 설정
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: nginx-gateway
spec:
controllerName: nginx.org/gateway-controller
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: mixed-gateway
namespace: default
spec:
gatewayClassName: nginx-gateway
listeners:
- name: http
port: 80
protocol: HTTP
allowedRoutes:
namespaces:
from: Same
- name: tls
port: 443
protocol: HTTPS
tls:
mode: Terminate
certificateRefs:
- name: my-cert
kind: Secret
allowedRoutes:
namespaces:
from: Same
- name: grpc
port: 50051
protocol: HTTP
allowedRoutes:
namespaces:
from: Same
- name: tcp
port: 3306
protocol: TCP
allowedRoutes:
namespaces:
from: Same
from: Same
vs from: All
vs from: Selector
설정 값 | 의미 | 특징 |
Same | Gateway와 같은 네임스페이스의 Route만 허용 | 보안에 좋고, 단순함 |
All | 모든 네임스페이스의 Route 허용 | 유연하지만 보안적으로 넓은 권한 |
Selector | 특정 라벨을 가진 네임스페이스만 허용 | 유연 + 안전의 균형 |
Same 사용 시 (기본값)
allowedRoutes:
namespaces:
from: Same
Gateway
와 같은 네임스페이스에 존재하는HTTPRoute
만 사용 가능- 다른 네임스페이스의 서비스 라우팅 불가
- 운영 초기나 보안 민감 환경에서는 추천
All 사용 시
allowedRoutes:
namespaces:
from: All
- 모든 네임스페이스에 존재하는
HTTPRoute
,GRPCRoute
,TCPRoute
등을 수용 가능 - 여러 팀, 여러 앱이 각자 네임스페이스에
Route
를 정의하고도 공통Gateway
로 진입 가능 - 운영 유연성은 높지만, 신중한 관리 필요
Selector 사용 시
allowedRoutes:
namespaces:
from: Selector
selector:
matchLabels:
route-allowed: "true"
- 특정 라벨을 가진 네임스페이스의 Route만 허용
from: All
보다 더 안전하고 세밀한 권한 제어 가능- 팀/서비스 단위로 네임스페이스에 라벨을 부여해서 정교한 멀티테넌시 구성에 적합
kubectl label namespace mario-ns route-allowed=true
kubectl label namespace tetris-ns route-allowed=true
HTTPRoute 예시
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: web-http
spec:
parentRefs:
- name: mixed-gateway
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: web
port: 80
TLSRoute 예시
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TLSRoute
metadata:
name: tls-app
spec:
parentRefs:
- name: mixed-gateway
hostnames:
- "tls.example.com"
rules:
- backendRefs:
- name: secure-svc
port: 443
GRPCRoute 예시
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: GRPCRoute
metadata:
name: grpc-api
spec:
parentRefs:
- name: mixed-gateway
rules:
- matches:
- method:
service: my.grpc.Service
method: GetStatus
backendRefs:
- name: grpc-service
port: 50051
TCPRoute 예시
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TCPRoute
metadata:
name: tcp-db
spec:
parentRefs:
- name: mixed-gateway
rules:
- backendRefs:
- name: mysql-db
port: 3306
실습 2: Helm 템플릿으로 Gateway 리소스 자동화
다양한 환경(dev, staging, prod)에 따라 Gateway 리소스를 자동 생성하고 싶을 때 Helm은 큰 도움이 된다.
templates/gateway.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: {{ include "myapp.fullname" . }}-gateway
spec:
gatewayClassName: {{ .Values.gateway.className }}
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: Same
{{- if .Values.gateway.enableTLS }}
- name: https
protocol: HTTPS
port: 443
tls:
mode: Terminate
certificateRefs:
- name: {{ .Values.gateway.tlsSecret }}
allowedRoutes:
namespaces:
from: Same
{{- end }}
values.yaml
gateway:
className: nginx-gateway
enableTLS: true
tlsSecret: my-cert
설치
helm upgrade --install myapp ./mychart -f values.yaml
실습 3: Gateway API 기반의 클러스터 간 통신 (Multi-cluster Gateway)
멀티 클러스터 환경에서는 클러스터 A의 Gateway를 통해 클러스터 B의 서비스를 노출하거나 통신을 중계해야 하는 경우가 많다.
Gateway API는 이런 구조에서 다음과 같은 방법으로 사용된다.
시나리오 구성
- 클러스터 A: 외부 요청 수신용 Gateway
- 클러스터 B: 내부 서비스 제공
- 클러스터 간 연결: VPN, VPC Peering, 혹은 Istio/Linkerd 기반 서비스 메시
설정 예시
클러스터 A에서의 TCPRoute
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TCPRoute
metadata:
name: db-forward
spec:
parentRefs:
- name: mixed-gateway
rules:
- backendRefs:
- name: db-proxy
port: 3306
db-proxy
는 클러스터 B에 있는 DB에 연결하는 Proxy Pod이다. (예: socat
, cloud-sql-proxy
, custom TCP forwarder 등)
이런 방식으로 클러스터 A에서 들어온 외부 요청을 클러스터 B로 안전하게 전달할 수 있다.
실습 4: GRPCRoute와 Service Mesh 통합 전략
gRPC는 HTTP/2 기반 프로토콜이므로 기존 Ingress에서는 정교한 라우팅이 어려웠다. Gateway API는 GRPCRoute를 통해 서비스 메시와의 통합에 유리하다.
📎 시나리오
- Istio 또는 Linkerd 환경에서 Gateway API를 통합 엔트리 포인트로 사용
- 내부 통신은 메시를 통해 이루어지고, 외부 진입만 Gateway가 담당
예시: Istio + GRPCRoute
Istio 1.21 이상에서는 Gateway API를 지원한다.
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: GRPCRoute
metadata:
name: grpc-public
spec:
parentRefs:
- name: istio-ingressgateway
namespace: istio-system
rules:
- matches:
- method:
service: my.grpc.Service
backendRefs:
- name: internal-grpc
port: 50051
- 이렇게 하면 Gateway API → Istio Envoy → 내부 서비스 흐름이 만들어져, 외부 진입 포인트를 Gateway API로 통합할 수 있다.
실습 5: Gateway API + Cert-Manager로 TLS 자동화 구성
TLS 인증서를 수동으로 관리하는 것은 번거롭고 위험하다. Gateway API는 cert-manager와 함께 사용할 때 매우 강력한 TLS 자동화를 제공한다.
💡 구성 흐름
cert-manager
가 Let's Encrypt에서 인증서 자동 발급Secret
으로 저장- Gateway에서
certificateRefs
로 해당 Secret 참조
예시: 자동 TLS 구성
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: tls-cert
spec:
secretName: my-cert
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
dnsNames:
- example.mydomain.com
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: game-gateway
namespace: default
spec:
gatewayClassName: nginx-gateway
listeners:
- name: https
port: 443
protocol: HTTPS
hostname: example.domain.com
tls:
mode: Terminate
certificateRefs:
- name: my-cert # cert-manager 가 발급한 Secret
allowedRoutes:
namespaces:
from: Same
- 이렇게 구성하면 Gateway 리스너가 자동 발급된 인증서를 사용하게 되며,
cert-manager
는 자동 갱신까지 관리한다.
실습6: 구성 요약
- GatewayClass 이름:
nginx-gateway
- 도메인: 하나 (예:
game.example.com
)metal-lb-nginx-gateway.domain → A → 10.10.10.62
game.example.com → CNAME → metal-lb-nginx-gateway.domain
- Path 기반 분기:
/mario
→ mario 서비스/tetris
→ tetris 서비스
- Pod 2개: 각각 mario, tetris 앱
- 외부 접속 가능: LoadBalancer 타입
설치 순서 정리
# helm chart pull
helm pull oci://ghcr.io/nginx/charts/nginx-gateway-fabric --untar
cd nginx-gateway-fabric
# 1. CRD 설치
kubectl kustomize https://github.com/nginx/nginx-gateway-fabric/config/crd/gateway-api/standard | kubectl apply -f -
## experimental CRD (Option)
kubectl kustomize https://github.com/nginx/nginx-gateway-fabric/config/crd/gateway-api/experimental | kubectl apply -f -
# 2. Helm 차트 설치
helm install ngf . --create-namespace -n nginx-gateway -f mgmt.yaml
# 3. 리소스 배포
kubectl apply -f gateway.yaml
kubectl apply -f httproute.yaml
kubectl apply -f mario-refer.yaml
kubectl apply -f tetris-refer.yaml
kubectl apply -f mario-deployment.yaml
kubectl apply -f tetris-deployment.yaml
# 업그레이드
helm upgrade ngf . -n nginx-gateway -f mgmt.yaml
values.yaml
복사한다.
cp values.yaml mgmt.yaml
mgmt.yaml
# yaml-language-server: $schema=values.schema.json
nginxGateway:
kind: deployment
gatewayClassName: nginx-gateway
gatewayControllerName: gateway.nginx.org/nginx-gateway-controller
replicaCount: 1
# The configuration for leader election.
leaderElection:
enable: true
image:
# -- The NGINX Gateway Fabric image to use
repository: ghcr.io/nginx/nginx-gateway-fabric
tag: 1.6.2
pullPolicy: IfNotPresent
snippetsFilters:
enable: true
nginx:
image:
# -- The NGINX image to use.
repository: ghcr.io/nginx/nginx-gateway-fabric/nginx
tag: 1.6.2
pullPolicy: IfNotPresent
service:
create: true
type: LoadBalancer
externalTrafficPolicy: Local
loadBalancerIP: "10.10.10.62"
ports:
- port: 80
targetPort: 80
protocol: TCP
name: http
- port: 443
targetPort: 443
protocol: TCP
name: https
metrics:
enable: true
- loadbalancer ip 는 본인이 사용할 ip를 넣어주면 된다.
GatewayClass + Gateway
# gateway.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: nginx-gateway
spec:
controllerName: gateway.nginx.org/nginx-gateway-controller
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: game-gateway
namespace: default
spec:
gatewayClassName: nginx-gateway
listeners:
- name: http
port: 80
protocol: HTTP
allowedRoutes:
namespaces:
from: All
또는 아래와 같이 설정도 가능하다. (보안 설정)
# gateway.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: nginx-gateway
spec:
controllerName: gateway.nginx.org/nginx-gateway-controller
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: game-gateway
namespace: default
spec:
gatewayClassName: nginx-gateway
listeners:
- name: http
port: 80
protocol: HTTP
allowedRoutes:
namespaces:
from: Selector
selector:
matchLabels:
allow-gateway: "true"
그리고 네임스페이스에 추가해준다.
kubectl create ns mario-ns
kubectl create ns tetris-ns
kubectl label namespace mario-ns allow-gateway=true
kubectl label namespace tetris-ns allow-gateway=true
kubectl label ns default allow-gateway=true
HTTPRoute
# httproute.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: game-route
namespace: default
spec:
parentRefs:
- name: game-gateway
hostnames:
- game.example.com
rules:
- matches:
- path:
type: PathPrefix
value: /mario
filters:
- type: URLRewrite
urlRewrite:
path:
type: ReplaceFullPath
replaceFullPath: /
backendRefs:
- name: mario
namespace: mario-ns
port: 80
- matches:
- path:
type: PathPrefix
value: /tetris
filters:
- type: URLRewrite
urlRewrite:
path:
type: ReplaceFullPath
replaceFullPath: /
backendRefs:
- name: tetris
namespace: tetris-ns
port: 80
ReferenceGrant 생성
Gateway API는 보안에 민감하게 설계되어 있어서,
네임스페이스 간 리소스 참조는 반드시 ReferenceGrant로 명시적으로 허용해야 한다.
이게 바로 Ingress보다 더 강력한 RBAC 기반 L7 라우팅 컨트롤이 가능한 이유 중 하나이다.
tetris-refer.yaml
apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata:
name: allow-tetris-service
namespace: tetris-ns
spec:
from:
- group: gateway.networking.k8s.io
kind: HTTPRoute
namespace: default
to:
- group: ""
kind: Service
mario-refer.yaml
apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata:
name: allow-mario-service
namespace: mario-ns
spec:
from:
- group: gateway.networking.k8s.io
kind: HTTPRoute
namespace: default
to:
- group: ""
kind: Service
Deployments & Services
# mario-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mario
namespace: mario-ns
spec:
replicas: 1
selector:
matchLabels:
app: mario
template:
metadata:
labels:
app: mario
spec:
containers:
- name: mario
image: pengbai/docker-supermario
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: mario
namespace: mario-ns
spec:
selector:
app: mario
ports:
- port: 80
targetPort: 8080 # mario 컨테이너는 8080 포트 사용
type: ClusterIP
# tetris-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: tetris
namespace: tetris-ns
spec:
replicas: 1
selector:
matchLabels:
app: tetris
template:
metadata:
labels:
app: tetris
spec:
containers:
- name: tetris
image: bsord/tetris
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: tetris
namespace: tetris-ns
spec:
selector:
app: tetris
ports:
- port: 80
targetPort: 80
type: ClusterIP
문제 발생시 확인
httproute 확인
kubectl get httproute -n default game-route -o yaml |grep conditions -A12
- conditions:
- lastTransitionTime: "2025-03-21T07:32:12Z"
message: The route is accepted
observedGeneration: 1
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: "2025-03-21T07:32:12Z"
message: All references are resolved
observedGeneration: 1
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
- 전부
status
가True
여야 한다.
nginx-fabric-controller 확인
kubectl logs -n nginx-gateway deployment/ngf-nginx-gateway-fabric -c nginx
kubectl logs -n nginx-gateway deployment/ngf-nginx-gateway-fabric -c nginx-gateway
- nginx는 실제 요청 처리하는 데이터 플레인이고, nginx-gateway는 컨트롤 플레인 역할이다.
정리(삭제)
# app 삭제
kubectl delete -f mario-deployment.yaml
kubectl delete -f tetris-deployment.yaml
# 나머지 삭제
kubectl delete -f httproute.yaml
kubectl delete -f gateway.yaml
kubectl delete -f mario-refer.yaml
kubectl delete -f tetris-refer.yaml
helm delete ngf -n nginx-gateway
kubectl kustomize https://github.com/nginx/nginx-gateway-fabric/config/crd/gateway-api/standard | kubectl delete -f -
kubectl kustomize https://github.com/nginx/nginx-gateway-fabric/config/crd/gateway-api/experimental | kubectl delete -f -
kubectl delete ns nginx-gateway
kubectl delete ns mario-ns
kubectl delete ns tetris-ns
마무리: Gateway API의 미래는?
Gateway API는 단순히 Ingress의 대체제가 아니다. 다음과 같은 특징으로 현대 클라우드 아키텍처의 핵심 네트워크 표준으로 자리잡고 있다.
- 멀티 프로토콜 지원 (HTTP/gRPC/TCP/TLS)
- 멀티 테넌시 및 RBAC 기반 트래픽 제어
- 컨트롤러 벤더와 무관한 표준화
- Helm/Kustomize 등과 잘 어울리는 선언적 구성
앞으로 Istio, Envoy, GKE Gateway, AWS VPC Lattice 등 다양한 환경에서 Gateway API를 중심으로 서비스 메시 + API Gateway + LoadBalancer 통합 전략이 본격화될 것이다.
Reference
- Kubernetes Gateway API 공식 문서
- NGINX Kubernetes Gateway Controller
- Istio Gateway API 지원
- cert-manager + Gateway API 예제
- https://gateway-api.sigs.k8s.io/guides/http-redirect-rewrite/
'Container Orchestration > Kubernetes' 카테고리의 다른 글
Kubernetes에 static-file-server 생성하기 (0) | 2025.03.24 |
---|---|
Kubernetes IPVS vs iptables (0) | 2025.02.03 |
Helm Base App Chart 생성(With ArgoCD) (0) | 2025.01.06 |
Helm Chart 생성 및 패키징 (gh-pages) (2) | 2024.12.20 |
Kubernetes Operator(CRD, CR) 생성(With kubebuilder) (0) | 2024.12.17 |