NGINX Gateway Fabric – 클라우드 환경 Traffic Shadowing

이번 포스트에서는 NGINX Gateway Fabric(NGF)를 활용하여 Kubernetes Gateway API 환경에서 클라우드 환경 Traffic Shadowing을 구현하는 방법을 소개합니다. Traffic Shadowing은 요청을 주요 백엔드에 전달하면서 동시에 다른 백엔드로 복제하여 보내는 기능으로, 새로운 서비스 테스트나 블루-그린 배포에 유용합니다.

NGINX Gateway Fabric은 Gateway API를 기반으로 한 고성능 게이트웨이 솔루션으로, HTTPRoute 필터를 통해 트래픽 섀도잉을 쉽게 설정할 수 있습니다. 섀도잉된 요청은 주요 백엔드의 응답에 영향을 주지 않으며, 응답은 무시됩니다. 이 기능을 통해 프로덕션 트래픽을 사용한 안전한 테스트가 가능하지만, 트래픽 증가와 잠재적 비용을 고려해야 합니다. 실제 구성 예시와 로그 분석을 통해 실전 적용 방안을 살펴보겠습니다.

목차

1. 클라우드 환경 Traffic Shadowing 개요
2. 클라우드 환경 Traffic Shadowing의 장점과 사용 사례

3. NGINX Gateway Fabric에서 Traffic Shadowing 구성 방법
4. 실제 구성 예시

4-1. 매니페스트 파일 구성
4-2. 로그 분석과 테스트 결과
5. 결론

1. 클라우드 환경 Traffic Shadowing 개요

클라우드 환경 Traffic Shadowing은 Kubernetes Gateway API의 HTTPRoute 리소스에서 지원되는 확장 기능으로, 요청을 주요 백엔드에 전달하면서 동시에 다른 백엔드로 복제하여 보냅니다. 섀도잉된 백엔드는 단일 엔드포인트로 제한되며, 그 응답은 무시되어 클라이언트에게 영향을 주지 않습니다.

NGINX Gateway Fabric에서 이 기능은 RequestMirror 필터를 통해 구현되며, HTTP 또는 gRPC 트래픽에 적용 가능합니다. 예를 들어, 프로덕션 서비스(foo-v1)에 요청을 보내면서 테스트 서비스(foo-v2)로 섀도잉하여 성능을 평가할 수 있습니다. 이는 Gateway API의 확장 지원 기능으로, 기본 설정 외에 NGINX의 강력한 트래픽 관리 기능을 활용합니다.

섀도잉은 블루-그린 배포나 A/B 테스트에서 특히 유용하지만, 추가 트래픽으로 인한 리소스 부하를 주의해야 합니다.

2. 클라우드 환경 Traffic Shadowing의 장점과 사용 사례

클라우드 환경 Traffic Shadowing의 주요 장점은 다음과 같습니다:

  • 안전한 테스트: 프로덕션 트래픽을 사용해 새 버전 서비스를 테스트할 수 있으며, 클라이언트 응답에 영향을 주지 않습니다.
  • 성능 평가: 실제 트래픽으로 애플리케이션 성능을 측정하여 배포 위험을 최소화합니다.
  • 쉬운 구현: Gateway API 필터로 간단히 설정 가능하며, NGINX Gateway Fabric에서 자연스럽게 지원됩니다.

단점으로는 추가 트래픽으로 인한 네트워크 및 컴퓨팅 비용 증가, 그리고 섀도잉 백엔드의 잠재적 과부하가 있습니다. 사용 사례로는 블루-그린 배포, 마이그레이션 테스트, 또는 로깅/모니터링 목적이 적합합니다.

3. NGINX Gateway Fabric에서 Traffic Shadowing 구성 방법

NGINX Gateway Fabric을 설치한 후, 백엔드 애플리케이션을 배포하고 GatewayHTTPRoute를 설정합니다. 예를 들어, coffee와 tea 애플리케이션을 생성한 후 HTTPRoute에 RequestMirror 필터를 추가하여 coffee 요청을 tea로 섀도잉합니다.

기본 Gateway 설정:

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: cafe
spec:
gatewayClassName: nginx
listeners:
- name: http
port: 80
protocol: HTTP

HTTPRoute 예시:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: mirror
spec:
parentRefs:
- name: cafe
sectionName: http
hostnames:
- "cafe.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /coffee
filters:
- type: RequestMirror
requestMirror:
backendRef:
name: tea
port: 80
backendRefs:
- name: coffee
port: 80

테스트 시 curl로 요청을 보내고, 섀도잉 백엔드 로그를 확인하여 동작을 검증합니다.

4. 실제 구성 예시

아래는 실제 환경에서 nginx-example-1과 nginx-example-2를 사용한 섀도잉 구성 예시입니다. 주요 백엔드는 nginx-example-1, 섀도잉 백엔드는 nginx-example-2입니다.

4-1. 매니페스트 파일 구성

HTTPRoute 구성:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: ho-ngf-httproute
namespace: ho-ngf
spec:
parentRefs:
- name: ho-ngf-gateway
sectionName: http
hostnames:
- "hocp-ngf.devopsshin.com"
rules:
- matches:
- path:
type: PathPrefix
value: /
filters:
- type: RequestMirror
requestMirror:
backendRef:
name: nginx-example-2
port: 80
backendRefs:
- name: nginx-example-1
port: 80

Deployment 및 Service 구성:

apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-example-1
namespace: ho-ngf
spec:
replicas: 1
selector:
matchLabels:
app: nginx-example-1
template:
metadata:
labels:
app: nginx-example-1
spec:
containers:
- name: nginx-example-1
image: nginxstore/webapp-example-1:latest
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-example-1
namespace: ho-ngf
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
name: http
selector:
app: nginx-example-1
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-example-2
namespace: ho-ngf
spec:
replicas: 1
selector:
matchLabels:
app: nginx-example-2
template:
metadata:
labels:
app: nginx-example-2
spec:
containers:
- name: nginx-example-2
image: nginxstore/webapp-example-2:latest
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-example-2
namespace: ho-ngf
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
name: http
selector:
app: nginx-example-2

4-2. 로그 분석과 테스트 결과

nginx-example-1 로그 (주요 백엔드):

10.129.6.27 - - [21/Jan/2026:05:03:52 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Whale/4.35.351.16 Safari/537.36" "192.168.201.167"
10.129.6.27 - - [21/Jan/2026:05:03:53 +0000] "GET / HTTP/1.1" 200 672 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Whale/4.35.351.16 Safari/537.36" "192.168.201.167"
10.129.6.27 - - [21/Jan/2026:05:03:53 +0000] "GET /css/app.2a75a3ab.css HTTP/1.1" 200 872 "http://hocp-ngf.devopsshin.com:30263/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Whale/4.35.351.16 Safari/537.36" "192.168.201.167"
10.129.6.27 - - [21/Jan/2026:05:03:53 +0000] "GET /js/app.c905b22c.js HTTP/1.1" 200 2849 "http://hocp-ngf.devopsshin.com:30263/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Whale/4.35.351.16 Safari/537.36" "192.168.201.167"
10.129.6.27 - - [21/Jan/2026:05:03:53 +0000] "GET /js/chunk-vendors.508fe844.js HTTP/1.1" 200 84822 "http://hocp-ngf.devopsshin.com:30263/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Whale/4.35.351.16 Safari/537.36" "192.168.201.167"
10.129.6.27 - - [21/Jan/2026:05:03:53 +0000] "GET /favicon.ico HTTP/1.1" 200 4286 "http://hocp-ngf.devopsshin.com:30263/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Whale/4.35.351.16 Safari/537.36" "192.168.201.167"

nginx-example-2 로그 (섀도잉 백엔드):

10.129.6.27 - - [21/Jan/2026:05:03:52 +0000] "GET / HTTP/1.1" 200 672 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Whale/4.35.351.16 Safari/537.36" "192.168.201.167"
10.129.6.27 - - [21/Jan/2026:05:03:53 +0000] "GET / HTTP/1.1" 200 672 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Whale/4.35.351.16 Safari/537.36" "192.168.201.167"
2026/01/21 05:03:53 [error] 21#21: *72 open() "/usr/share/nginx/dist/js/chunk-vendors.508fe844.js" failed (2: No such file or directory), client: 10.129.6.27, server: localhost, request: "GET /js/chunk-vendors.508fe844.js HTTP/1.1", host: "hocp-ngf.devopsshin.com:30263", referrer: "http://hocp-ngf.devopsshin.com:30263/"
10.129.6.27 - - [21/Jan/2026:05:03:53 +0000] "GET /js/chunk-vendors.508fe844.js HTTP/1.1" 404 555 "http://hocp-ngf.devopsshin.com:30263/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Whale/4.35.351.16 Safari/537.36" "192.168.201.167"
2026/01/21 05:03:53 [error] 23#23: *74 open() "/usr/share/nginx/dist/css/app.2a75a3ab.css" failed (2: No such file or directory), client: 10.129.6.27, server: localhost, request: "GET /css/app.2a75a3ab.css HTTP/1.1", host: "hocp-ngf.devopsshin.com:30263", referrer: "http://hocp-ngf.devopsshin.com:30263/"
10.129.6.27 - - [21/Jan/2026:05:03:53 +0000] "GET /css/app.2a75a3ab.css HTTP/1.1" 404 555 "http://hocp-ngf.devopsshin.com:30263/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Whale/4.35.351.16 Safari/537.36" "192.168.201.167"
2026/01/21 05:03:53 [error] 21#21: *73 open() "/usr/share/nginx/dist/js/app.c905b22c.js" failed (2: No such file or directory), client: 10.129.6.27, server: localhost, request: "GET /js/app.c905b22c.js HTTP/1.1", host: "hocp-ngf.devopsshin.com:30263", referrer: "http://hocp-ngf.devopsshin.com:30263/"
10.129.6.27 - - [21/Jan/2026:05:03:53 +0000] "GET /js/app.c905b22c.js HTTP/1.1" 404 555 "http://hocp-ngf.devopsshin.com:30263/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Whale/4.35.351.16 Safari/537.36" "192.168.201.167"
10.129.6.27 - - [21/Jan/2026:05:03:53 +0000] "GET /favicon.ico HTTP/1.1" 200 4286 "http://hocp-ngf.devopsshin.com:30263/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Whale/4.35.351.16 Safari/537.36" "192.168.201.167"

로그에서 주요 백엔드는 정상 응답(200/304)을 보이지만, 섀도잉 백엔드는 일부 파일(예: js/css)에 404 오류가 발생합니다. 이는 섀도잉 백엔드의 콘텐츠 불일치로 인한 것으로, 테스트 시 유의해야 합니다.

5. 결론

NGINX Gateway Fabric의 클라우드 환경 Traffic Shadowing은 Kubernetes 환경에서 안전하고 효과적인 트래픽 테스트를 가능하게 합니다. 블루-그린 배포나 성능 평가에 활용하세요. 그러나 트래픽 부하를 모니터링하고, 백엔드 일관성을 유지하는 것이 중요합니다.

더 궁금한 점이 있으시면 문의 주세요!

NGINX STORE를 통한 솔루션 도입 및 기술지원 무료 상담 신청

* indicates required