ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 분산 트레이싱 트러블슈팅: NetworkPolicy, Zipkin, OpenTelemetry
    이코에코(Eco²) 제작 문서 및 리포트/Troubleshooting 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시간

    참고 자료

    댓글

ABOUT ME

🎓 부산대학교 정보컴퓨터공학과 학사: 2017.03 - 2023.08
☁️ Rakuten Symphony Jr. Cloud Engineer: 2024.12.09 - 2025.08.31
🏆 2025 AI 새싹톤 우수상 수상: 2025.10.30 - 2025.12.02
🌏 이코에코(Eco²) 백엔드/인프라 고도화 중: 2025.12 - Present

Designed by Mango