📋 요약
이 글에서는 Kubernetes Ingress API의 지원 중단 배경과 Gateway API의 개념 및 활용 방식을 다룹니다.
클러스터 트래픽 관리의 표준 변화에 맞춰 운영 안정성과 확장성을 높이는 방향을 정리합니다.
#Kubernetes #Ingress #GatewayAPI #NginxGatewayFabric #HTTPRoute
지난 11월, kubernetes는 Ingress NGINX의 기술지원 중단을 발표했고, 이에 대한 대안책으로 Gateway API로 교체해서 사용할 것을 권장했습니다.
Ingress NGINX Retirement: What You Need to Know
To prioritize the safety and security of the ecosystem, Kubernetes SIG Network and the Security Response Committee are announcing the upcoming retirement of Ingress NGINX. Best-effort maintenance will continue until March 2026. Afterward, there will be no
kubernetes.io
현재 kt cloud의 Managed KS 상품에서는 F5 Nginx IngressController 설치/삭제 자동화 기능을 제공하고 있는데요, 이 오픈소스는 3rd party IngressController 로써 아직 EOS 발표가 없으므로 계속해서 기술지원 및 사용이 가능합니다.
하지만!! 혹시나 Gateway API를 사용해보고 싶은 사용자들을 위해 이번 시간에는 kubernetes Gateway API 를 설치 및 사용기를 준비해보았습니다.
(본 포스팅 내용은 곧 Managed KS 공식 매뉴얼에도 업로드 될 예정입니다)
1. 왜 Gateway API인가?
지난 수년간 Ingress는 kubernetes 서비스 노출(expose)의 표준이었습니다. 하지만 대규모 서비스의 경우 복잡한 라우팅을 구현하려면 Annotation에 의존해야 했고, 이는 곧 "Annotation 지옥"을 만드는 한계가 있었습니다.
Gateway API는 이를 해결하기 위해 등장한 차세대 kubernetes 표준입니다.
아래 표는 두 구성요소에 대한 비교 표 입니다.
| 구분 | Ingress | Gateway |
| 주요 컨트롤러 | Nginx Ingress Controller | Nginx Gateway Fabric |
| 추상화 계층 | IngressClass | GatewayClass |
| 진입점 객체 | Ingress (Host/Path 혼재) | Gateway (포트/TLS/IP 관리) |
| 라우팅 규칙 | Ingress (Annotation 지옥) | HTTPRoute (표준화된 필드) |
2. Gateway API의 핵심 장점
기존 Ingress와 비교했을 때 가장 큰 차별점은 다음과 같습니다.
- 역할 기반 관리 (Role-oriented): 인프라 관리자는 Gateway를 설정하고, 개발자는 HTTPRoute를 통해 본인 서비스의 라우팅만 관리합니다.
- 표준화된 기능: Ingress에서는 Annotation으로 처리하던 Header 조작, 트래픽 미러링, 가중치 기반 분산(Canary) 등이 API 자체 표준 기능으로 포함되었습니다.
- 유연한 프로토콜 지원: HTTP뿐만 아니라 gRPC, TCP, UDP 라우팅을 더 직관적으로 지원합니다.
- 공유 및 재사용: 하나의 Gateway를 여러 개의 네임스페이스에 있는 HTTPRoute가 공유할 수 있습니다.
- 미래 지향성: Gateway API는 향후 서비스 메시(Service Mesh)와의 통합까지 고려하는 아키텍처입니다.
![[기술 분석] kubernetes Ingress API의 중단. 그 뒤를 잇는 Gateway API 파헤치기](https://blog.kakaocdn.net/dna/trhhQ/dJMcacQIRAh/AAAAAAAAAAAAAAAAAAAAALe-ZUPev_PmcPWqVj3eBGp4aweZ6EUHdhcsjFAMIDMF/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1780239599&allow_ip=&allow_referer=&signature=7MxfYHdNQd6Pg3c%2BCTHnJVf43Hc%3D)
3. Gateway Controller 설치하기
- Gateway API를 사용하려면 이를 해석하고 물리적인 트래픽을 처리해 줄 'Gateway Controller'가 별도로 필요합니다.
- 기존의 Ingress Controller가 Ingress 리소스를 감시하듯, Gateway Controller는 Gateway와 HTTPRoute 리소스를 감시합니다.
- 다른 점은, 실 서비스 트래픽에 Gateway Controller는 관여하지 않습니다. Gateway 리소스가 생성되면 관련 Service와 Pod를 자동으로 배포하는 역할을 합니다.
- 본 포스팅에서는 F5에서 제공하는 오픈소스 Gateway Controller인 Nginx Gateway Fabric을 설치해서 사용해보겠습니다( F5 NGINX Gateway Fabric | NGINX Documentation )
- Nginx Ingress Controller: ingressClassName: nginx를 감시. 실 서비스 트래픽이 통과&제어에 관여
- Nginx Gateway Fabric: gatewayClassName: nginx를 감시. 실 서비스 트래픽 통과 X
- 참고로, 기존 Nginx Ingress Controller를 삭제하지 않고도 병행 설치가 가능합니다.
3-1) Gateway API CRD 설치
- 클러스터에 Gateway API 사용을 위한 CRD(Custom Resource Definitions)을 먼저 설치합니다.
- Gateway API 버전 별 비교: v1.4
# 버전 선택 후 설치
kubectl apply --server-side -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.4.1/standard-install.yaml
3-2) Nginx Gateway Fabric 설치
- helm 차트를 이용해 F5 Nginx Gateway Fabric를 배포합니다.
- nginx-gateway 네임스페이스에 설치하고, Application Service는 LoadBalancer타입으로 생성되게 옵션을 설정합니다.
- Nginx Gateway Fabric는 아래와 같이 두 가지 Service를 사용합니다.
- 컨트롤러 Service: 컨트롤러 자체의 메트릭이나 웹훅을 위한 Service (ClusterIP 타입)
- 데이터 플레인 Service: 실제 트래픽이 들어오는 Nginx Service (설치할 때 LoadBalancer 타입으로 지정)
# helm 으로 설치
helm install ngf oci://ghcr.io/nginx/charts/nginx-gateway-fabric --create-namespace --namespace nginx-gateway --set service.type=LoadBalancer
# 또는 values.yaml을 추출하여 수정 후 설치
helm show values oci://ghcr.io/nginxinc/charts/nginx-gateway-fabric > values.yaml
helm upgrade ngf oci://ghcr.io/nginxinc/charts/nginx-gateway-fabric -n nginx-gateway -f values.yaml
# 확인
# kubectl -nnginx-gateway get all
NAME READY STATUS RESTARTS AGE
pod/ngf-nginx-gateway-fabric-7454cfd85c-fr6td 1/1 Running 0 2m4s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/ngf-nginx-gateway-fabric ClusterIP 10.x.x.x <none> 443/TCP 2m5s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/ngf-nginx-gateway-fabric 1/1 1 1 2m5s
NAME DESIRED CURRENT READY AGE
replicaset.apps/ngf-nginx-gateway-fabric-7454cfd85c 1 1 1 2m4s
3-3) Gatewayclass 생성 확인
- 각 Gateway 리소스에서 참조할 Gatewayclass 가 함께 생성되었습니다.
#k get gatewayclasses
NAME CONTROLLER ACCEPTED AGE
nginx gateway.nginx.org/nginx-gateway-controller True 10m
4. 필수 요소 생성 (Gateway, HTTPRoute)
- Application으로 coffee 샘플을 배포해보겠습니다. ( Routing traffic to applications | NGINX Documentation )
4-1) Application 배포
- sample 이라는 Namespace를 생성하고, coffee Deployment를 우선 배포합니다.
# Namespace 생성
kubectl create ns sample
# Application 배포
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: coffee
namespace: sample
spec:
replicas: 2
selector:
matchLabels:
app: coffee
template:
metadata:
labels:
app: coffee
spec:
containers:
- name: coffee
image: nginxdemos/nginx-hello:plain-text
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: coffee
namespace: sample
spec:
ports:
- port: 80
targetPort: 8080
protocol: TCP
name: http
selector:
app: coffee
EOF
- 배포된 리소스를 확인합니다.
# kubectl -nsample get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
coffee 2/2 2 2 3m
# kubectl -nsample get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
coffee ClusterIP 10.x.x.1 <none> 80/TCP 3m
4-2) Gateway 설정
- 클러스터의 진입점인 Gateway 리소스를 생성합니다.
- TLS 인증서나 진입점 포트(80, 443), 도메인 등에 대한 부분을 설정합니다.
- Gateway 리소스에서 spec.listeners.hostname(도메인) 필드 정의는 필수는 아닙니다. 필드를 비워두면, 해당 포트로 들어오는 모든 호스트(IP 포함)의 트래픽을 일단 다 받게됩니다. 와일드카드(*) 도메인으로 정의할 수 있습니다.
kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: cafe
namespace: sample
spec:
gatewayClassName: nginx # (필수)앞서 설치된 gatewayclass를 지정
listeners:
- name: http
hostname: "*.example.com" # (옵션)이 Gateway로 처리할 도메인 정의
port: 80
protocol: HTTP
allowedRoutes:
namespaces:
from: All # (옵션)모든 네임스페이스에서 이 Gateway를 사용할 수 있도록 허용
EOF
생성된 Gateway 확인
#kubectl -nsample describe gateway cafe
Name: cafe
Namespace: sample
API Version: gateway.networking.k8s.io/v1
Kind: Gateway
#중략
Status:
Conditions:
Last Transition Time: 2026-02-07T14:22:35Z
Message: The Gateway is accepted # 상태 확인
Observed Generation: 1
Reason: Accepted
Status: True
Type: Accepted
# 중략
생성된 Gateway용 Service&Pod 확인
- Gateway를 생성하면 자동으로 이 Gateway 로 유입되는 모든 트래픽을 관찰하는 Service와 Pod가 생성됩니다.
- 앞서 Nginx Gateway Fabric 설치할 때, service.type을 LoadBalancer로 지정했기 때문에 이 타입의 svc가 생성됩니다.
# kubectl -nsample get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
cafe-nginx 1/1 1 1 17m # gateway 트래픽을 위한 Nginx Pod
coffee 2/2 2 2 33m
# kubectl -nsample get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
cafe-nginx LoadBalancer 10.x.x.2 211.x.x.x 80:30154/TCP 17m # gateway 트래픽을 위한 Nginx Service
coffee ClusterIP 10.x.x.1 <none> 80/TCP 33m
4-2) HTTPRoute 설정
- 특정 경로로 들어온 트래픽을 서비스로 보내는 기본 구성요소 HTTPRoute를 생성합니다.
- 들어온 트래픽을 어떤 서비스로 보낼지 세부 라우팅 규칙을 정합니다. (Path 기반, Header 기반 라우팅 등)
- Gateway와 HTTPRoute는 Gateway:HTTPRoute = 1:N 맵핑 구조를 가집니다.
kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: coffee
namespace: sample
spec:
parentRefs:
- name: cafe #(필수)앞서 생성한 gaetway 정의
hostnames:
- "cafe.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: coffee
port: 80
EOF
리소스 확인
- gateway와 httproute 리소스가 배포되었고, 잘 맵핑되었음을 확인할 수 있습니다.
# kubectl -nsample get gateway
NAME CLASS ADDRESS PROGRAMMED AGE
cafe nginx True 28m
# kubectl -nsample get httproute
NAME HOSTNAMES AGE
coffee ["cafe.example.com"] 75s
5. 트래픽 흐름 확인 (Traffic Flow)
- Gateway API 체제에서의 실 서비스 트래픽은 다음과 같은 흐름으로 전달됩니다.
✅ Client → Gateway (Gateway Service&Pod) → HTTPRoute → Service & Pod
- Gateway Controller는 서비스 트래픽에 관여하지 않는다는 점에서 Ingress Controller와 다릅니다.
- 앞서 배포한 coffee Application은 이렇게 테스트해볼 수 있습니다.
# /etc/hosts에 도메인에 대하여 cafe-nginx svc의 Cluster-IP 또는 External-IP 로 설정
echo 'cafe.example.com 10.x.x.2' >> /etc/hosts
# curl 테스트를 합니다.
curl -k http://cafe.example.com/
* Trying 10.x.x.2:80...
* Connected to cafe.example.com (10.x.x.2) port 80 (#0)
> GET / HTTP/1.1
> Host: cafe.example.com
> User-Agent: curl/7.81.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: nginx
- Gateway로의 access 로그는 자동 배포되는 Nginx Pod 로그를 통해 확인할 수 있습니다.
# kubectl -nsample logs -f cafe-nginx-878f86457-w5gzv
{"level":"info","ts":"2026-02-07T13:43:25Z","msg":"Starting the NGINX Gateway Fabric control plane","version":"2.4.1","commit":"da2fab61996fae45397afad7897e2467953b258d","date":"2026-02-06T17:47:15Z","dirty":"true"}
{"level":"info","ts":"2026-02-07T13:43:25Z","msg":"Starting manager"}
{"level":"info","ts":"2026-02-07T13:43:25Z","logger":"controller-runtime.metrics","msg":"Starting metrics server"}
{"level":"info","ts":"2026-02-07T13:43:25Z","msg":"starting server","name":"health probe","addr":"[::]:8081"}
192.100.74.192 - - [07/Feb/2026:16:22:50 +0000] "GET /api HTTP/1.1" 200 162 "-" "curl/7.81.0"
2026/02/07 16:22:50 [info] 363#363: *736 client 192.100.74.192 closed keepalive connection
결론
![[기술 분석] kubernetes Ingress API의 중단. 그 뒤를 잇는 Gateway API 파헤치기](https://blog.kakaocdn.net/dna/zZvdC/dJMcahR1keQ/AAAAAAAAAAAAAAAAAAAAAFVld8viXNgOhhZYRTUGZRskoDuZgtiUDR3zPd7F_MXs/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&expires=1780239599&allow_ip=&allow_referer=&signature=O2wsSua7BhOSkTFULCnCOfVnWfE%3D)
지금까지 Kubernetes의 차세대 표준인 Gateway API의 개념부터 Nginx Gateway Fabric 설치까지 함께 살펴보았습니다.
Gateway API는 역할 기반(Role-oriented) 관리, 확장된 프로토콜 지원, 리소스 재사용성이라는 강력한 무기를 통해 기존 Ingress의 고질적인 문제였던 ‘Annotation 지옥’을 명쾌하게 해결했습니다.
더욱 세밀한 트래픽 제어를 가능케 하는 Policy 객체 활용법은 내용이 방대한 만큼, 다음 포스팅에서 심도 있게 다뤄보도록 하겠습니다.
최근 Ingress API의 행보는 생태계에서의 퇴장이 아닌, 더 정교하고 유연한 도구인 Gateway API로의 진화를 의미합니다. 변화하는 표준에 맞춰 더 효율적인 클러스터 운영 환경을 구축해 보시길 바랍니다.
❓ 자주 묻는 질문 (FAQ)
📚 관련/출처