NGINX Gateway Fabric Tracing 구성

이 가이드에서는 OpenTelemetry Collector를 사용하여 NGINX Gateway Fabric에서 HTTPRoutes 추적을 활성화하는 방법을 설명합니다. Jaeger를 사용하여 추적을 처리하고 수집합니다.

NGINX Gateway Fabric은 OpenTelemetry를 사용하여 추적을 지원합니다 .

공식 NGINX OpenTelemetry 모듈은 NGINX 데이터 플레인을 계측하여 구성된 수집기로 추적 데이터를 내보냅니다. 추적 데이터는 OpenTelemetry Collector 와 같은 OpenTelemetry Protocol(OTLP) 내보내기 도구와 함께 사용할 수 있습니다 .

이 수집기는 Jaeger , DataDog 등과 같은 하나 이상의 상위 수집기로 데이터를 내보낼 수 있습니다 . 이를 에이전트 모델 이라고 합니다 .

목차

1. Collector 설치
2. Tracing 활성화
2-1. NGINX Gateway Fabric 및 글로벌 Tracing 구성
2-2. Application 생성 및 Route 생성
2-3. ObservabilityPolicy 리소스 생성
3. 결론

1. Collector 설치

첫번째로 Collector를 설치합니다.

NGINX Gateway Fabric은 OpenTelemetry로 Tracing 데이터를 전달하고 OpenTelemetry에서 Jaeger로 Tracing 데이터를 전달합니다. 아래의 YAML 파일을 사용하면 시각화 수집기(Jaeger) 를 다른 수집기로 교체하거나 NGINX Gateway Fabric을 구성하지 않고도 수집기를 추가할 수 있습니다. OpenTelemetry를 거치지 않고 Jaeger로 직접 보낼 수 있도록 구성할 수 있습니다.

Namespace를 생성합니다.

kubectl create namespace tracing

아래의 두가지 예제는 Product 용도가 아닌 데모용도입니다.

otel-collector.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: otel-collector-config
data:
otel-collector-config: |
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
processors:
extensions:
exporters:
otlp/jaeger:
endpoint: "jaeger.tracing.svc:4317"
tls:
insecure: true
service:
pipelines:
traces:
receivers: [otlp]
processors: []
exporters: [otlp/jaeger]
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: otel-collector
labels:
app.kubernetes.io/name: otel-collector
spec:
selector:
matchLabels:
app.kubernetes.io/name: otel-collector
replicas: 1
template:
metadata:
labels:
app.kubernetes.io/name: otel-collector
spec:
containers:
- name: otel-collector
image: otel/opentelemetry-collector:latest
command:
- /otelcol
- --config=/conf/otel-collector-config.yaml
ports:
- containerPort: 4317
volumeMounts:
- name: otel-collector-config
mountPath: /conf
volumes:
- name: otel-collector-config
configMap:
name: otel-collector-config
items:
- key: otel-collector-config
path: otel-collector-config.yaml
---
apiVersion: v1
kind: Service
metadata:
name: otel-collector
labels:
app.kubernetes.io/name: otel-collector
spec:
selector:
app.kubernetes.io/name: otel-collector
ports:
- name: otlp-grpc
port: 4317
jaeger.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: jaeger
labels:
app.kubernetes.io/name: jaeger
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: jaeger
template:
metadata:
labels:
app.kubernetes.io/name: jaeger
spec:
containers:
- name: jaeger
image: jaegertracing/all-in-one:latest
ports:
- containerPort: 16686
- containerPort: 4317
---
apiVersion: v1
kind: Service
metadata:
name: jaeger
labels:
app.kubernetes.io/name: jaeger
spec:
selector:
app.kubernetes.io/name: jaeger
ports:
- name: frontend
port: 16686
- name: collector
port: 4317

위의 리소스를 배포합니다.

kubectl apply -f otel-collector.yaml -f jaeger.yaml -n tracing

Pod가 실행 중인지 확인합니다.

kubectl -n tracing get pods
NAME READY STATUS RESTARTS AGE
jaeger-8469f69b86-bfpk9 1/1 Running 0 9s
otel-collector-f786b7dfd-h2x9l 1/1 Running 0 9s

실행 후 port-forwarding을 통해 Jaeger 대시보드에 엑세스 할 수 있습니다.

kubectl port-forward -n tracing svc/jaeger 16686:16686 &

port를 통해 jaeger를 확인할 수 있습니다.

2. Tracing 활성화

NginxProxy: 이 리소스는 NGINX 데이터 플레인과 관련된 전역 설정을 포함합니다.
이 리소스는 클러스터 운영자에 의해 생성 및 관리되며, GatewayClassparametersRef 필드에서 참조됩니다.
기본적으로, NginxProxy 리소스는 NGINX Gateway Fabric이 설치된 동일한 네임스페이스에 생성되며, GatewayClass에 연결됩니다.
nginx Helm 값 섹션에서 구성 옵션을 설정할 수 있으며, 해당 값들을 사용하여 리소스가 생성되고 연결됩니다.

Helm 차트를 사용하여 설치할 경우, NginxProxy 리소스의 이름은 <릴리스-이름>-proxy-config가 되며, 릴리스가 배포된 네임스페이스에 생성됩니다.

NginxProxy 리소스는 Collector에 대한 설정을 포함하고 있으며, GatewayClass 아래의 모든 Gateway Route에 적용됩니다.

이 리소스는 Tracing을 직접 활성화하진 않지만, 다음 단계 설정을 위한 전체 조건 입니다

참고

특정 Gateway에 대해 Tracing 설정을 따로 지정하고 싶다면, 개별 NginxProxy 리소스를 수동으로 생성하고 해당 Gateway에 연결함으로써 설정을 오버라이드할 수 있습니다.
이 가이드에서는 전역 Tracing 설정만을 다룹니다.

ObservabilityPolicy: 이 리소스는 HTTPRoute 또는 GRPCRoute를 대상으로 하는 Direct PolicyAttachment입니다.
이는 애플리케이션 개발자에 의해 생성되며, 특정 Route에 대해 Tracing을 활성화합니다.
Tracing 구성을 완료하려면 미리 NginxProxy 리소스가 존재해야 합니다.

이러한 리소스에 대한 모든 가능한 구성 옵션은 API Reference 문서를 참고하세요.

2-1. NGINX Gateway Fabric 및 글로벌 Tracing 구성

참고

Gateway API 리소스를 배포했는지 확인합니다.

이전에 배포한 Collector를 참조하여, NGINX Gateway Fabric 설치를 위한 다음의 values.yaml 파일을 생성하십시오

cat <<EOT > values.yaml
nginx:
config:
telemetry:
exporter:
endpoint: otel-collector.tracing.svc:4317
spanAttributes:
- key: cluster-attribute-key
value: cluster-attribute-value
EOT

해당 span 속성은 모든 tracing span에 추가됩니다.

배포합니다.

helm install ngf oci://ghcr.io/nginx/charts/nginx-gateway-fabric --create-namespace -n nginx-gateway -f values.yaml

구성을 확인 하기 위해 아래와 같이 진행합니다.

kubectl get nginxproxies.gateway.nginx.org ngf-proxy-config -n nginx-gateway -o yaml
apiVersion: gateway.nginx.org/v1alpha2
kind: NginxProxy
metadata:
name: ngf-proxy-config
spec:
telemetry:
exporter:
endpoint: otel-collector.tracing.svc:4317
spanAttributes:
- key: cluster-attribute-key
value: cluster-attribute-value

kubectl get gatewayclasses.gateway.networking.k8s.io nginx -o yaml
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: nginx
spec:
controllerName: gateway.nginx.org/nginx-gateway-controller
parametersRef:
group: gateway.nginx.org
kind: NginxProxy
name: ngf-proxy-config
status:
conditions:
- lastTransitionTime: "2024-05-22T15:18:35Z"
message: GatewayClass is accepted
observedGeneration: 1
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: "2024-05-22T15:18:35Z"
message: Gateway API CRD versions are supported
observedGeneration: 1
reason: SupportedVersion
status: "True"
type: SupportedVersion
- lastTransitionTime: "2024-05-22T15:18:35Z"
message: parametersRef resource is resolved
observedGeneration: 1
reason: ResolvedRefs
status: "True"
type: ResolvedRefs

이미 NGINX Gateway Fabric이 설치되어 있는 경우, Tracing 구성을 포함하도록 NginxProxy 리소스를 수정할 수 있습니다.

kubectl edit nginxproxies.gateway.nginx.org ngf-proxy-config -n nginx-gateway

2-2. Application 생성 및 Route 생성

Coffee Application을 생성합니다.

kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: coffee
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
spec:
ports:
- port: 80
targetPort: 8080
protocol: TCP
name: http
selector:
app: coffee
EOF

Gateway 리소스를 생성한 후, NGINX Gateway Fabric은 트래픽을 라우팅하기 위한 NGINX Pod와 이를 앞단에서 제공하는 Service를 프로비저닝합니다.

NGINX Service의 공인 IP 주소와 포트 번호를 쉘 변수에 저장하십시오.

GW_IP=XXX.YYY.ZZZ.III
GW_PORT=<port number>

애플리케이션으로 트래픽이 정상적으로 전달되는지 확인하십시오.

참고

cafe.example.com에 할당된 DNS 레코드가 있다면, 해당 호스트명으로 직접 요청을 보낼 수 있으며, 별도의 이름 해석 과정 없이 접근할 수 있습니다.

curl --resolve cafe.example.com:$GW_PORT:$GW_IP http://cafe.example.com:$GW_PORT/coffee

coffee Pod로부터 응답을 받아야 합니다.

Server address: 10.244.0.69:8080
Server name: coffee-6b8b6d6486-k5w5w
URI: /coffee

아직은 Jaeger 대시보드에서 어떠한 정보도 보이지 않아야 합니다.
이를 위해서는 ObservabilityPolicy를 생성해야 합니다.

2-3. ObservabilityPolicy 리소스 생성

coffee HTTPRoute에 대해 트레이싱을 활성화하려면, 다음 정책을 생성하십시오.

kubectl apply -f - <<EOF
apiVersion: gateway.nginx.org/v1alpha2
kind: ObservabilityPolicy
metadata:
name: coffee
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: HTTPRoute
name: coffee
tracing:
strategy: ratio
ratio: 75
spanAttributes:
- key: coffee-key
value: coffee-value
EOF

이 정책은 coffee HTTPRoute에 연결되어 있으며, 비율 기반 트레이싱을 활성화하여 전체 요청의 75%를 샘플링합니다.
span 속성은 이 정책에서 참조된 라우트의 span에만 포함됩니다.

정책의 상태를 확인하십시오.

kubectl describe observabilitypolicies.gateway.nginx.org coffee
Status:
Ancestors:
Ancestor Ref:
Group: gateway.networking.k8s.io
Kind: HTTPRoute
Name: coffee
Namespace: default
Conditions:
Last Transition Time: 2024-05-23T18:13:03Z
Message: Policy is accepted
Observed Generation: 1
Reason: Accepted
Status: True
Type: Accepted
Controller Name: gateway.nginx.org/nginx-gateway-controller

message 필드에 정책이 수락되었음을 나타내는 메시지가 표시됩니다.
새로운 트래픽을 생성하기 위해 다음 명령어를 여러 번 실행하십시오.

curl --resolve cafe.example.com:$GW_PORT:$GW_IP http://cafe.example.com:$GW_PORT/coffee

완료되면 Jaeger 대시보드를 새로 고침하십시오.
ngf:default:cafe라는 서비스 항목과 몇 개의 트레이스(trace)가 표시되어야 합니다.
기본 서비스 이름 형식은 다음과 같습니다.

ngf:<gateway-namespace>:<gateway-name>

트레이스를 선택하여 속성(attributes)을 확인하십시오.

해당 트레이스에는 전역 NginxProxy 리소스에서 설정한 속성
ObservabilityPolicy에서 설정한 속성이 모두 포함되어 있습니다.

3. 결론

이번 구성에서는 NGINX Gateway Fabric에서 OpenTelemetry Collector와 Jaeger를 활용해 HTTP 트래픽에 대한 분산 추적 환경을 구축하는 방법을 가이드로 기술하였습니다.

전역 설정(NginxProxy)을 통해 Collector로의 Export 경로를 정의하고, HTTPRoute에 ObservabilityPolicy를 붙여 세분화된 트레이싱 제어도 가능하게 만들었습니다. 실제로 Jaeger 대시보드에서 요청 흐름과 메타데이터를 시각화할 수 있었고, 이를 통해 서비스 간 호출 관계나 병목 지점을 파악할 수 있는 기반을 마련할 수 있었습니다.

NGINX Gateway Fabric을 사용하는 환경이라면, 이번 구성을 바탕으로 운영 관측성과 디버깅 효율을 크게 향상시킬 수 있습니다.

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

* indicates required