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 |