이코에코(Eco²) Knowledge Base/Troubleshooting

분산 트레이싱 트러블슈팅: NetworkPolicy, Zipkin, OpenTelemetry

mango_fr 2025. 12. 18. 11:48

 

개요

Jaeger UI에서 "No service dependencies found" 메시지가 표시되고, 서비스 간 호출 관계가 보이지 않는 문제를 해결한 과정입니다.

문제 증상

관찰된 현상

  1. 앱의 OTEL SDK 트레이스는 Jaeger에 정상 수집됨
  2. Istio Ingress Gateway 트레이스도 일부 수집됨
  3. 하지만 서비스 간 Dependencies가 표시되지 않음
  4. 각 서비스의 sidecar(Envoy)가 생성한 트레이스가 누락됨

Jaeger UI 스크린샷 (문제 상황)

Services: auth-api, character-api, chat-api, ...
Dependencies: "No service dependencies found"

진단 과정

1단계: 트레이싱 아키텍처 이해

Istio Sidecar(Envoy)는 Zipkin 프로토콜(port 9411)을 사용하고, 앱의 OTEL SDK는 OTLP(port 4317)를 사용.

2단계: 각 지점별 데이터 확인

Point A: Ingress Gateway → Jaeger

# Ingress Gateway의 zipkin 클러스터 stats 확인
IG_POD=$(kubectl get pods -n istio-system -l app=istio-ingressgateway -o jsonpath="{.items[0].metadata.name}")
kubectl exec -n istio-system $IG_POD -- pilot-agent request GET clusters | grep "9411.*rq_total"

결과:

outbound|9411||jaeger-collector-clusterip...::rq_total::61

✅ 정상 전송

Point B: App Sidecar → Jaeger

# auth-api sidecar의 zipkin 클러스터 stats 확인
AUTH_POD=$(kubectl get pods -n auth -l app=auth-api -o jsonpath="{.items[0].metadata.name}")
kubectl exec -n auth $AUTH_POD -c istio-proxy -- pilot-agent request GET clusters | grep "9411.*rq_total"

결과:

outbound|9411||jaeger-collector-clusterip...::rq_total::0

전송 없음!

Point C: App OTEL SDK → Jaeger

# OTLP 클러스터 stats 확인
kubectl exec -n auth $AUTH_POD -c istio-proxy -- pilot-agent request GET clusters | grep "4317.*rq_total"

결과:

outbound|4317||jaeger-collector-clusterip...::rq_total::109

✅ 정상 전송

3단계: 병목 지점 식별

 
병목 지점: App Pod의 Sidecar → Jaeger Collector (port 9411)

4단계: NetworkPolicy 확인

kubectl get networkpolicy allow-jaeger-egress -n auth -o yaml
# 발견된 설정
spec:
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: istio-system
      podSelector:
        matchLabels:
          app.kubernetes.io/name: jaeger
    ports:
    - port: 4317  # OTLP gRPC ✅
    - port: 4318  # OTLP HTTP ✅
    # port: 9411 ❌ 누락!

근본 원인

 
원인: NetworkPolicy에서 Istio Sidecar(Envoy)가 사용하는 Zipkin 포트(9411)가 허용되지 않음

프로토콜별 포트 정리

OTLP gRPC4317App OTEL SDK✅ 허용됨
OTLP HTTP4318App OTEL SDK✅ 허용됨
Zipkin9411Istio Sidecar누락

해결 방법

수정 파일

workloads/network-policies/base/allow-jaeger-egress.yaml

변경 내용

# Before (문제)
spec:
  egress:
  - ports:
    - port: 4317
      protocol: TCP
    - port: 4318
      protocol: TCP

# After (해결)
spec:
  egress:
  - ports:
    - port: 4317
      protocol: TCP
    - port: 4318
      protocol: TCP
    - port: 9411        # ✅ Zipkin 포트 추가
      protocol: TCP

적용 범위

모든 앱 네임스페이스에 동일하게 적용:

for ns in auth character chat scan my location image; do
  kubectl apply -f allow-jaeger-egress.yaml -n $ns
done

검증

수정 후 Sidecar Stats

# Before
outbound|9411||jaeger-collector-clusterip...::rq_total::0

# After
outbound|9411||jaeger-collector-clusterip...::rq_total::38

Jaeger Dependencies 확인

flowchart LR
    IG[istio-ingressgateway<br/>istio-system]

    AUTH[auth-api.auth]
    CHAR[character-api.character]
    CHAT[chat-api.chat]
    SCAN[scan-api.scan]
    MY[my-api.my]
    LOC[location-api.location]
    IMG[image-api.image]

    IG --> AUTH
    IG --> CHAR
    IG --> CHAT
    IG --> SCAN
    IG --> MY
    IG --> LOC
    IG --> IMG

    style IG fill:#3498db
    style AUTH fill:#2ecc71
    style CHAR fill:#2ecc71
    style CHAT fill:#2ecc71
    style SCAN fill:#2ecc71
    style MY fill:#2ecc71
    style LOC fill:#2ecc71
    style IMG fill:#2ecc71

최종 결과

auth✅ 38회✅ auth-api.auth
character✅ 19회✅ character-api.character
chat✅ 33회✅ chat-api.chat
scan✅ 33회✅ scan-api.scan
my✅ 1회✅ my-api.my
location✅ 33회✅ location-api.location
image✅ 20회✅ image-api.image

교훈

1. Istio 트레이싱 프로토콜 이해

Istio의 Envoy sidecar는 기본적으로 Zipkin 프로토콜을 사용하여 트레이스를 전송합니다.

# Envoy tracing config
provider:
  name: envoy.tracers.zipkin
  typed_config:
    collector_cluster: "outbound|9411||jaeger-collector..."
    collector_endpoint: "/api/v2/spans"

2. 앱 OTEL SDK vs Istio Sidecar

App OTEL SDKOTLP4317/4318Deployment env
Istio SidecarZipkin9411MeshConfig

두 경로가 모두 동작해야 완전한 분산 트레이싱이 가능합니다.

3. NetworkPolicy 설계 시 고려사항

분산 트레이싱을 위한 egress NetworkPolicy는 두 가지 경로를 모두 허용해야 합니다.

ports:
  - port: 4317   # App → Jaeger (OTLP gRPC)
  - port: 4318   # App → Jaeger (OTLP HTTP)
  - port: 9411   # Sidecar → Jaeger (Zipkin)

4. 진단 방법

Envoy의 cluster stats를 확인하면 원인파악에 유용합니다.

# rq_total::0 이면 트래픽이 차단되고 있음
kubectl exec -n <namespace> <pod> -c istio-proxy -- \
  pilot-agent request GET clusters | grep "jaeger.*rq_total"

관련 커밋

  • 2a27a2e6 - fix(netpol): Zipkin 포트(9411) egress 허용 추가

소요 시간

작성일: 2025-12-18
해결 시간: 약 2시간

참고 자료