티스토리 뷰
Kubernetes Gateway API 실전 가이드: Kong Ingress에서 표준 API로 전환하기
pak2251 2025. 10. 27. 13:40작성일: 2025년 10월 27일
카테고리: Kubernetes, Gateway API, Kong
난이도: 중급
TL;DR
- 문제: Ingress는 각 컨트롤러마다 다른 annotation 문법을 사용하여 vendor lock-in 발생
- 해결: Kubernetes 표준 Gateway API로 전환하여 포터블하고 명시적인 설정 달성
- 결과: Kong 전용
KongPlugin→ 표준HTTPRoute로 전환 완료 - 핵심: Gateway API는 단순한 리소스 교체가 아닌, Kubernetes 네트워킹의 패러다임 전환
배경: Ingress의 파편화 문제
Ingress의 현실
Kubernetes에서 HTTP 라우팅을 설정하는 가장 일반적인 방법은 Ingress 리소스입니다. 하지만 실무에서는 큰 문제가 있습니다.
같은 기능, 세 가지 다른 문법:
# NGINX Ingress Controller
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/limit-rps: "100"
nginx.ingress.kubernetes.io/cors-allow-origin: "*"
---
# Kong Ingress Controller
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
konghq.com/plugins: rate-limiting-plugin
---
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
name: rate-limiting-plugin
config:
minute: 100
---
# HAProxy Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
haproxy.org/rate-limit: "100"
동일한 기능(rate limiting)을 구현하는데 세 개 컨트롤러 모두 문법이 다릅니다!
실무에서 겪는 문제
- Vendor Lock-in: NGINX에서 Kong으로 전환하려면 모든 Ingress 리소스를 재작성해야 함
- 학습 비용: 각 컨트롤러마다 annotation 문서를 따로 학습
- 표준 부재: "Kubernetes 표준"이 아닌 각 vendor의 확장에 의존
- 유지보수 어려움: 팀원마다 다른 컨트롤러 경험으로 인한 혼란
imprun.dev의 사례
저희 프로젝트에서도 동일한 문제를 겪었습니다:
# imprun.dev → portal.imprun.dev 리다이렉트 (Kong 전용)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: imprun-root-redirect
namespace: imprun-system
annotations:
konghq.com/plugins: imprun-root-redirect # Kong 전용!
---
apiVersion: configuration.konghq.com/v1 # Kong CRD
kind: KongPlugin
metadata:
name: imprun-root-redirect
config:
location: "https://portal.imprun.dev"
status_code: 301
plugin: redirect
문제점:
konghq.comannotation은 Kong에서만 작동KongPluginCRD는 Kong 전용- 향후 다른 Gateway로 전환 시 모두 재작성 필요
Gateway API: Kubernetes 네트워킹의 미래
Gateway API란?
Kubernetes SIG-NETWORK가 2019년부터 개발한 차세대 표준 네트워킹 API입니다.
핵심 개념:
- 표준화: 모든 구현체에서 동일한 리소스 타입 사용
- 역할 지향: 인프라 관리자(Gateway)와 개발자(Route) 역할 분리
- 확장성: L4/L7뿐 아니라 TCP, UDP, gRPC 지원
- 명시성: annotation 대신 명시적인 리소스 타입
왜 지금 Gateway API인가?
2024년 중요한 변화:
2019년: Gateway API 프로젝트 시작
2023년: Gateway API v1.0 GA (정식 릴리즈)
2024년: ingress-nginx maintenance mode 전환 발표 ⚠️
2025년: Gateway API가 사실상 표준Kubernetes 공식 문서에 따르면:
"With the emergence of the Kubernetes InGate project, the ingress-nginx project will transition to maintenance mode, with no new features from the core maintainers."
더 이상 Ingress는 발전하지 않습니다. 모든 신규 기능은 Gateway API에만 추가됩니다.
NGINX가 디펙토 스탠다드 아니었나?
맞습니다, "였습니다" (과거형).
2024년 현재 통계:
- 54%의 Kubernetes 워크로드가 NGINX Ingress Controller 사용
- 시장 점유율 1위
하지만:
- ingress-nginx는 더 이상 새 기능 개발 안 함
- 커뮤니티는 Gateway API로 이동 중
- Kong, Envoy, Istio 모두 Gateway API 지원
비유:
- Ingress = jQuery 시대 (각자 다른 플러그인)
- Gateway API = React/Vue 시대 (표준 컴포넌트 모델)
Gateway API 핵심 리소스
1. GatewayClass
Gateway 구현체를 정의합니다 (메타 리소스).
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: kong
spec:
controllerName: konghq.com/kic-gateway-controller
역할:
- 어떤 컨트롤러를 사용할지 선언
- Kong, NGINX, Envoy 등 구현체별로 하나씩 생성
- 클러스터 레벨 리소스 (namespace 없음)
2. Gateway
실제 Gateway 인스턴스를 정의합니다.
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: kong
namespace: kong-system
spec:
gatewayClassName: kong
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: All # 모든 namespace에서 Route 연결 가능
역할:
- Listener (포트 80, 443 등) 정의
- Cross-namespace 라우팅 허용 여부 설정
- 인프라 관리자 영역
3. HTTPRoute
실제 라우팅 규칙을 정의합니다.
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: my-route
namespace: my-app
spec:
parentRefs:
- name: kong
namespace: kong-system
hostnames:
- app.example.com
rules:
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: api-service
port: 8080
역할:
- 호스트, 경로 매칭
- 백엔드 서비스 지정
- 필터 (리다이렉트, 헤더 변환 등) 적용
- 개발자 영역
역할 분리의 장점
| 역할 | 리소스 | 권한 범위 |
|---|---|---|
| 인프라 관리자 | GatewayClass, Gateway | 클러스터 전체 |
| 개발자 | HTTPRoute | 본인 namespace |
보안 이점:
- 개발자는 Gateway 설정을 수정할 수 없음
- Gateway 관리자는 개별 Route를 관리할 필요 없음
- RBAC로 명확한 권한 분리
실전: Kong에서 Gateway API 사용하기
환경 정보
- Kubernetes: v1.28+
- Kong Ingress Controller: v3.9 (Gateway API GA 지원)
- Gateway API: v1.2.0
- 목표:
imprun.dev→portal.imprun.devHTTP 301 리다이렉트
1단계: Gateway API CRDs 설치
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.0/standard-install.yaml
설치되는 CRD:
- GatewayClass
- Gateway
- HTTPRoute
- GRPCRoute
- ReferenceGrant
2단계: Kong 설정 확인
Kong v3.0+는 Gateway API를 기본 지원합니다.
# kong-values.yaml
ingressController:
enabled: true
env:
# Kong이 Gateway 상태를 업데이트할 Service 지정
publish_service: kong-system/kong-kong-proxy
주의사항:
feature_gates: Gateway=true는 필요 없음 (v3.0+는 기본 활성화)publish_service는 실제 Kong proxy Service명과 일치해야 함
3단계: GatewayClass 생성
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: kong
annotations:
# Unmanaged mode: 기존 Kong deployment 재사용
konghq.com/gatewayclass-unmanaged: "true"
spec:
controllerName: konghq.com/kic-gateway-controller
description: Kong Ingress Controller for Gateway API
Unmanaged mode:
- 기존 Kong deployment를 재사용
- Gateway 리소스 생성 시 새 Pod를 만들지 않음
- 무중단 전환 가능
4단계: Gateway 생성
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: kong
namespace: kong-system
annotations:
konghq.com/publish-service: kong-system/kong-kong-proxy
spec:
gatewayClassName: kong
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: All
검증:
kubectl get gateway -n kong-system kong
# NAME CLASS ADDRESS PROGRAMMED AGE
# kong kong True 1m
PROGRAMMED: True가 나와야 성공!
5단계: HTTPRoute로 리다이렉트 구현
Before (Ingress + KongPlugin):
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
konghq.com/plugins: imprun-root-redirect
---
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
config:
location: "https://portal.imprun.dev"
status_code: 301
plugin: redirect
After (Gateway API - 표준):
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: imprun-root-redirect
namespace: imprun-system
spec:
parentRefs:
- name: kong
namespace: kong-system
sectionName: http
hostnames:
- imprun.dev
rules:
- filters:
- type: RequestRedirect
requestRedirect:
hostname: portal.imprun.dev
statusCode: 301
차이점:
- ❌
konghq.comannotation 제거 - ❌
KongPluginCRD 제거 - ✅ 표준
HTTPRoute+RequestRedirectfilter 사용 - ✅ 다른 Gateway 구현체에서도 동일하게 작동!
검증
# HTTPRoute 상태 확인
kubectl describe httproute -n imprun-system imprun-root-redirect
# Status:
# Conditions:
# Type: Accepted Status: True
# Type: ResolvedRefs Status: True
# Type: Programmed Status: True ✅
# 실제 리다이렉트 테스트
curl -I http://imprun.dev
# HTTP/1.1 301 Moved Permanently
# Location: https://portal.imprun.dev
트러블슈팅 실전 사례
Case 1: Gateway PROGRAMMED: Unknown
증상:
kubectl get gateway -n kong-system
# NAME CLASS PROGRAMMED AGE
# kong kong Unknown 5m
Kong 로그 확인:
kubectl logs -n kong-system -l app.kubernetes.io/name=kong -c ingress-controller
에러:
error: publish service reference "kong-system/kong-kong-proxy" from Gateway's
annotations did not match configured controller manager's publish services
("kong-system/kong-proxy")원인:
- Helm values의
publish_service와 Gateway annotation이 불일치 - 실제 Service명:
kong-kong-proxy - Helm values:
kong-proxy(잘못됨)
해결:
# kong-values.yaml
ingressController:
env:
publish_service: kong-system/kong-kong-proxy # 실제 Service명
Case 2: feature_gates 에러
증상:
Error: environment binding failed for variable CONTROLLER_FEATURE_GATES:
Gateway is not a valid feature원인:
- Kong v3.0+에서는 Gateway API가 기본 활성화됨
feature_gates: Gateway=true설정이 불필요하고 에러 발생
해결:
# kong-values.yaml
ingressController:
env:
# feature_gates: Gateway=true # 제거!
publish_service: kong-system/kong-kong-proxy
Case 3: hostNetwork 포트 충돌
증상:
0/3 nodes are available: 1 node(s) didn't have free ports for the
requested pod ports원인:
- hostNetwork 사용 시 Rolling Update 불가
- 기존 Pod가 80/443 포트 점유 중
임시 해결:
# 기존 Pod 수동 삭제
kubectl delete pod -n kong-system <old-pod-name>
근본 해결 (권장):
# MetalLB 설치 후
proxy:
type: LoadBalancer # hostNetwork 제거
deployment:
hostNetwork: false
autoscaling:
enabled: true # 이제 가능!
minReplicas: 2
Gateway API vs Ingress 비교
기능 비교
| 기능 | Ingress | Gateway API |
|---|---|---|
| HTTP/HTTPS 라우팅 | ✅ | ✅ |
| TCP/UDP 라우팅 | ❌ | ✅ (TCPRoute, UDPRoute) |
| gRPC 라우팅 | ❌ | ✅ (GRPCRoute) |
| 표준화된 설정 | ❌ (annotation 파편화) | ✅ |
| 역할 기반 접근제어 | ⚠️ (부분적) | ✅ (명확한 분리) |
| 헤더 변환 | ⚠️ (annotation) | ✅ (Filter) |
| 리다이렉트 | ⚠️ (annotation) | ✅ (RequestRedirect) |
| URL Rewrite | ⚠️ (annotation) | ✅ (URLRewrite) |
| 미러링 | ❌ | ✅ (RequestMirror) |
| 가중치 기반 라우팅 | ❌ | ✅ (BackendRef weights) |
마이그레이션 체크리스트
언제 전환해야 하나?
✅ 지금 바로 전환 권장:
- 새 프로젝트 시작
- Gateway 교체 예정 (vendor lock-in 회피)
- TCP/UDP 라우팅 필요
- 명시적인 설정 관리 선호
⚠️ 천천히 고려:
- 기존 Ingress가 안정적으로 작동 중
- 단순한 HTTP 라우팅만 사용
- 팀 학습 비용 고려 필요
❌ 아직 이르다:
- Kubernetes < v1.26 (Gateway API v1 미지원)
- Kong < v3.0 (Gateway API GA 미지원)
실전 활용 패턴
패턴 1: HTTPS 리다이렉트
HTTP → HTTPS 자동 리다이렉트:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: https-redirect
spec:
parentRefs:
- name: kong
sectionName: http
hostnames:
- app.example.com
rules:
- filters:
- type: RequestRedirect
requestRedirect:
scheme: https
statusCode: 301
패턴 2: 경로 기반 라우팅
/api → backend-api, /web → frontend:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: path-based-routing
spec:
parentRefs:
- name: kong
hostnames:
- app.example.com
rules:
# /api → backend
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: backend-api
port: 8080
# /web → frontend
- matches:
- path:
type: PathPrefix
value: /web
backendRefs:
- name: frontend
port: 3000
패턴 3: 가중치 기반 카나리 배포
90% → v1, 10% → v2 (카나리):
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: canary-deployment
spec:
parentRefs:
- name: kong
rules:
- backendRefs:
- name: app-v1
port: 8080
weight: 90
- name: app-v2
port: 8080
weight: 10
점진적 배포:
# Day 1: 90/10
# Day 2: 70/30
# Day 3: 50/50
# Day 4: 0/100 (완전 전환)
패턴 4: 헤더 기반 라우팅
X-Version: v2 헤더 → 새 버전:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: header-based-routing
spec:
parentRefs:
- name: kong
rules:
# X-Version: v2 → 새 버전
- matches:
- headers:
- name: X-Version
value: v2
backendRefs:
- name: app-v2
port: 8080
# 기본 → 기존 버전
- backendRefs:
- name: app-v1
port: 8080
성능 및 운영 고려사항
성능 비교
Ingress vs Gateway API:
- ✅ 동일한 처리 성능 (같은 Kong 엔진 사용)
- ✅ 동일한 메모리 사용량
- ✅ 추가 오버헤드 없음
Gateway API는 설정 방식만 다를 뿐, 실행 시 성능은 Ingress와 동일합니다.
운영 체크리스트
배포 전:
- Gateway API CRDs 버전 확인 (v1.2.0+)
- Kong 버전 확인 (v3.0+)
- Kubernetes 버전 확인 (v1.26+)
배포 후:
- Gateway
PROGRAMMED: True확인 - HTTPRoute
Accepted: True확인 - 실제 트래픽 테스트 (curl, 브라우저)
- Kong 로그 확인 (에러 없음)
모니터링:
# Gateway 상태 모니터링
kubectl get gateway -A -w
# HTTPRoute 상태 모니터링
kubectl get httproute -A -w
# Kong 메트릭 확인
kubectl top pod -n kong-system
마무리
핵심 요약
- Ingress의 한계: annotation 파편화로 vendor lock-in 발생
- Gateway API의 필요성: Kubernetes 표준, 명시적 리소스, 역할 분리
- 현재 상황: ingress-nginx maintenance mode, Gateway API가 미래
- 전환 방법: GatewayClass → Gateway → HTTPRoute 순서
- 주의사항: hostNetwork, publish_service, feature_gates 설정 확인
다음 단계
학습:
실습:
- 테스트 클러스터에서 Gateway API CRDs 설치
- 간단한 HTTPRoute 생성 (echo 서버)
- RequestRedirect 필터 실습
- 가중치 기반 라우팅 실습
프로덕션 적용:
- 새 서비스부터 Gateway API 사용
- 기존 Ingress는 점진적 전환
- 팀 교육 및 문서화
- 모니터링 대시보드 구축
실제 프로젝트에 적용하기
imprun.dev에서의 경험:
- ✅ Kong 전용 annotation 제거
- ✅ 표준 HTTPRoute로 리다이렉트 구현
- ✅ 무중단 전환 완료
- ✅ 향후 Gateway 교체 유연성 확보
소요 시간:
- CRD 설치: 1분
- 리소스 작성: 10분
- 배포 및 검증: 15분
- 트러블슈팅: 20분
- 총 소요: 약 46분
어려움:
- hostNetwork 포트 충돌 (Kong Pod 재시작 필요)
- publish_service 불일치 (Helm values 수정)
- feature_gates 에러 (불필요한 설정 제거)
얻은 것:
- Kubernetes 표준 API 사용
- Kong → 다른 Gateway 전환 가능성
- 명시적이고 관리하기 쉬운 설정
- Gateway API 실전 경험
참고 자료
공식 문서
관련 글
실습 자료
태그: #Kubernetes #GatewayAPI #Kong #Ingress #CloudNative #DevOps
"Gateway API는 단순한 Ingress의 대체가 아닙니다. Kubernetes 네트워킹의 패러다임 전환입니다."
🤖 이 블로그는 실제 프로덕션 환경에서 Gateway API를 전환한 경험을 바탕으로 작성되었습니다.
'실제 경험과 인사이트를 AI와 함께 정리한 글' 카테고리의 다른 글
| Kubernetes Gateway API 실전 가이드: Kong Ingress에서 표준 API로 전환하기 (1) | 2025.10.27 |
|---|---|
| Kubernetes에서 특권 포트 피하기: NodePort + iptables 포워딩 패턴 (0) | 2025.10.27 |
| frontend/CLAUDE.md (0) | 2025.10.27 |
| Claude AI와 함께하는 프론트엔드 개발: imprun.dev의 CLAUDE.md 가이드 공개 (0) | 2025.10.27 |
| Next.js를 버리고 순수 React로 돌아온 이유: 실무 관점의 프레임워크 선택 여정 (0) | 2025.10.27 |
- Total
- Today
- Yesterday
- LangChain
- SHACL
- Kubernetes
- architecture
- PYTHON
- ai 개발 도구
- AI agent
- workflow
- authorization
- Developer Tools
- 개발 도구
- Tailwind CSS
- claude code
- Claude
- Rag
- react
- api gateway
- AI Development
- frontend
- backend
- knowledge graph
- authentication
- troubleshooting
- Tax Analysis
- Next.js
- security
- Go
- LLM
- AI
- Ontology
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |
