Kubernetes Kubernetes Gateway API Envoy

NGINX Ingress EOL 대응: OCI에서 Envoy Gateway로 마이그레이션

NGINX Ingress Controller 지원 종료에 대비해 OCI Always Free 클러스터에서 Envoy Gateway로 마이그레이션한 경험을 공유합니다.

Ingress NGINX가 2026년 3월에 지원 종료된다는 소식을 듣고, Gateway API로 전환을 준비하고 있습니다.

홈랩에서는 이미 Cilium을 쓰고 있어서 Cilium Gateway API를 적용하려 했는데, L2Announce만으로는 외부 접근이 안 되고 BGP 설정이 필요했습니다. 문제는 홈랩 라우터가 BGP를 지원하지 않아서, BGP 지원 공유기를 주문해둔 상태입니다.

기다리는 동안 OCI Always Free 클러스터에서 먼저 Gateway API를 경험해보기로 했습니다. Envoy Gateway를 선택한 이유는 CNCF graduated 프로젝트이고, Gateway API 구현체 중 활발하게 개발되고 있어서입니다.


환경

OCI Always Free 티어로 운영 중인 Kubernetes 클러스터입니다.

항목
노드2대 (ARM64, 2 OCPU / 12GB)
IngressNGINX Ingress Controller
TLScert-manager + Let’s Encrypt
Secret 복제Reflector

n8n 워크플로우 자동화 플랫폼을 운영하고 있고, n8n.heeho.net으로 접근합니다.

OCI 제약사항

Always Free 티어는 LoadBalancer를 1개만 사용할 수 있습니다. NGINX Ingress와 Envoy Gateway를 동시에 운영하면 LoadBalancer가 2개가 되는데, 잠깐 동안은 괜찮습니다. 검증 후 빠르게 기존 것을 삭제하면 됩니다.


마이그레이션 전략

다운타임 없이 전환하기 위해 병렬 운영 후 DNS 전환 방식을 사용했습니다.

flowchart LR
subgraph before[AS-IS]
nginx[NGINX Ingress]
end
subgraph parallel[병렬 운영]
nginx2[NGINX]
envoy2[Envoy Gateway]
end
subgraph after[TO-BE]
envoy3[Envoy Gateway]
end
before -->|Envoy 설치| parallel
parallel -->|DNS 전환 + NGINX 제거| after

Envoy Gateway를 설치해도 기존 NGINX Ingress는 그대로 동작합니다. 새 LoadBalancer IP가 할당되면 curl --resolve로 테스트하고, 문제없으면 DNS를 전환합니다.


실행

Gateway API CRD 설치

Gateway API는 Kubernetes 표준 API입니다. CRD를 먼저 설치해야 합니다.

Terminal window
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.0/standard-install.yaml
customresourcedefinition.apiextensions.k8s.io/gatewayclasses.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/gateways.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/httproutes.gateway.networking.k8s.io created
...

Envoy Gateway 설치

Terminal window
helm install envoy-gateway oci://docker.io/envoyproxy/gateway-helm \
--version v1.2.0 \
--namespace envoy-gateway-system \
--create-namespace

GatewayClass도 생성합니다.

Terminal window
kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: eg
spec:
controllerName: gateway.envoyproxy.io/gatewayclass-controller
EOF

TLS Secret 복제

기존에 cert-manager가 발급한 와일드카드 인증서(*.heeho.net)를 Reflector로 복제하고 있었습니다. envoy-gateway-system 네임스페이스를 복제 대상에 추가합니다.

# Certificate의 secretTemplate에 추가
secretTemplate:
annotations:
reflector.v1.k8s.emberstack.com/reflection-allowed: "true"
reflector.v1.k8s.emberstack.com/reflection-allowed-namespaces: "n8n,envoy-gateway-system"
reflector.v1.k8s.emberstack.com/reflection-auto-enabled: "true"
reflector.v1.k8s.emberstack.com/reflection-auto-namespaces: "n8n,envoy-gateway-system"

Gateway 생성

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: oci-gateway
namespace: envoy-gateway-system
spec:
gatewayClassName: eg
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: All
- name: https
protocol: HTTPS
port: 443
tls:
mode: Terminate
certificateRefs:
- kind: Secret
name: wildcard.heeho.net
allowedRoutes:
namespaces:
from: All

적용하면 OCI가 새 LoadBalancer를 프로비저닝합니다.

Terminal window
$ kubectl get gateway -n envoy-gateway-system
NAME CLASS ADDRESS PROGRAMMED AGE
oci-gateway eg <NEW_IP> True 97s

HTTPRoute 생성

NGINX Ingress의 Ingress 리소스 대신 HTTPRoute를 사용합니다.

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: n8n
namespace: n8n
spec:
parentRefs:
- name: oci-gateway
namespace: envoy-gateway-system
hostnames:
- "n8n.heeho.net"
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: n8n
port: 5678

BackendTrafficPolicy (Timeout 설정)

기존 NGINX Ingress에서 annotation으로 설정하던 timeout을 BackendTrafficPolicy로 대체합니다.

apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
name: n8n-timeout
namespace: n8n
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: HTTPRoute
name: n8n
timeout:
http:
connectionIdleTimeout: 3600s
requestTimeout: 3600s

검증

DNS 전환 전에 curl --resolve로 새 IP를 테스트합니다.

Terminal window
$ curl -s -o /dev/null -w "%{http_code}" \
--resolve "n8n.heeho.net:443:<NEW_IP>" \
https://n8n.heeho.net
200

TLS 인증서도 확인합니다.

Terminal window
$ curl -v --resolve "n8n.heeho.net:443:<NEW_IP>" https://n8n.heeho.net 2>&1 | grep -E "subject|matched"
* subject: CN=heeho.net
* subjectAltName: host "n8n.heeho.net" matched cert's "*.heeho.net"

DNS 전환

Route 53에서 n8n.heeho.net을 새 IP로 변경합니다.

레코드이전이후
n8n.heeho.net146.56.118.148<NEW_IP>

NGINX Ingress 제거

DNS 전환 후 정상 동작을 확인하고 기존 리소스를 삭제합니다.

Terminal window
# 백업
kubectl get ingress -A -o yaml > ingress-backup.yaml
# 제거
kubectl delete ingress -n n8n n8n
helm uninstall ingress-nginx -n ingress-nginx
kubectl delete namespace ingress-nginx

NGINX Ingress vs Envoy Gateway

항목NGINX IngressEnvoy Gateway
리소스IngressGateway + HTTPRoute
TLS 설정Ingress tls 필드Gateway listener
Timeoutannotation (proxy-read-timeout)BackendTrafficPolicy
Body sizeannotation (proxy-body-size)기본 무제한
표준Ingress APIGateway API

설정 비교 예시

NGINX Ingress:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: n8n
annotations:
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
nginx.ingress.kubernetes.io/proxy-body-size: "0"
spec:
ingressClassName: nginx
tls:
- hosts:
- n8n.heeho.net
secretName: wildcard.heeho.net
rules:
- host: n8n.heeho.net
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: n8n
port:
number: 5678

Envoy Gateway:

# Gateway (클러스터 공유)
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: oci-gateway
spec:
gatewayClassName: eg
listeners:
- name: https
protocol: HTTPS
port: 443
tls:
certificateRefs:
- name: wildcard.heeho.net
---
# HTTPRoute (서비스별)
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: n8n
spec:
parentRefs:
- name: oci-gateway
hostnames:
- n8n.heeho.net
rules:
- backendRefs:
- name: n8n
port: 5678
---
# BackendTrafficPolicy (선택)
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
spec:
targetRefs:
- kind: HTTPRoute
name: n8n
timeout:
http:
requestTimeout: 3600s
  • Gateway: 인프라 담당 (포트, TLS)
  • HTTPRoute: 라우팅 담당 (호스트, 경로, 백엔드)
  • Policy: 세부 설정 (timeout, retry 등)

마무리

OCI 클러스터에서 NGINX Ingress를 Envoy Gateway로 전환했습니다.

얻은 것

  1. Gateway API 실전 경험 - 표준 API 사용법과 Envoy Gateway 특성 파악
  2. 무중단 전환 패턴 - 병렬 운영 + DNS 전환 방식 검증
  3. L4 라우팅 가능성 - TCPRoute로 데이터베이스 같은 non-HTTP 서비스도 노출 가능
  4. Helm 지원 미비 - 대부분의 Helm chart는 아직 HTTPRoute를 지원하지 않음. YAML로 HTTPRoute를 관리하는 방식으로 접근

홈 서버의 라우터가 도착하기 전까지 미리 Gateway API를 경험해보았습니다.


참고

관련 콘텐츠

댓글