Service_Mesh/Istio

[Istio-4주차] Observability: Grafana, Jaeger, and Kiali (이론, 실습)

lati-tech 2025. 5. 4. 08:12
  • 그라파나를 사용해 메트릭을 시각적으로 관찰하기 Using Grafana to observe metrics visually
  • 예거를 사용한 분산 트레이싱 계측하기 Distributed tracing instrumentation with Jaeger
  • 키알리로 네트워크 호출 그래프 시각화하기 Visualizing the network call graph with Kiali

  1. 8.1.1 Setting up Istio’s Grafana dashboards Istio의 그라파나 대시보드 설정하기 (실습)
    그라파나 웹 접속: admin / prom-operator
    # Grafana 접속 : admin / prom-operator
    open http://127.0.0.1:30002
    open http://127.0.0.1:30002/dashboards
    
    # 반복 호출 해두기
    while true; do curl -s http://webapp.istioinaction.io:30000/api/catalog ; date "+%Y-%m-%d %H:%M:%S" ; sleep 1; echo; done
    Grafana 접속
    Grafana의 Prometheus Data Source 설정 확인 - http://prom-kube-prometheus-stack-prometheus:9090/



    • Istio-in-actions 도서 제공 소스 코드에 대시보드를 추가 설정 or 공개 대시보드에서 검색 - Link , Search
      # 도서에서 제공한 소스코드로 대시보드 설정
      # 혹은 https://grafana.com/grafana/dashboards/?search=istio 에서 다운로드
      cd ch8
      
      kubectl -n prometheus create cm istio-dashboards \
      --from-file=pilot-dashboard.json=dashboards/\
      pilot-dashboard.json \
      --from-file=istio-workload-dashboard.json=dashboards/\
      istio-workload-dashboard.json \
      --from-file=istio-service-dashboard.json=dashboards/\
      istio-service-dashboard.json \
      --from-file=istio-performance-dashboard.json=dashboards/\
      istio-performance-dashboard.json \
      --from-file=istio-mesh-dashboard.json=dashboards/\
      istio-mesh-dashboard.json \
      --from-file=istio-extension-dashboard.json=dashboards/\
      istio-extension-dashboard.json
      
      # 확인
      cd ..
      kubectl describe cm -n prometheus  istio-dashboards
      
      # Grafana (오퍼레이터)가 configmap(istio-dashboards)을 마운트(인식) 하도록 레이블 지정
      kubectl label -n prometheus cm istio-dashboards grafana_dashboard=1
      
      # (참고) Grafana 대시보드 추가
      kubectl stern -n prometheus prom-grafana
      prom-grafana-d7f5cb646-555zp grafana-sc-dashboard [2025-04-27 05:58:21] File in configmap istio-extension-dashboard.json ADDED
      prom-grafana-d7f5cb646-555zp grafana-sc-dashboard [2025-04-27 05:58:21] File in configmap istio-mesh-dashboard.json ADDED
      prom-grafana-d7f5cb646-555zp grafana-sc-dashboard [2025-04-27 05:58:21] File in configmap istio-performance-dashboard.json ADDED
      prom-grafana-d7f5cb646-555zp grafana-sc-dashboard [2025-04-27 05:58:21] File in configmap istio-service-dashboard.json ADDED
      prom-grafana-d7f5cb646-555zp grafana-sc-dashboard [2025-04-27 05:58:21] File in configmap istio-workload-dashboard.json ADDED
      prom-grafana-d7f5cb646-555zp grafana-sc-dashboard [2025-04-27 05:58:21] File in configmap pilot-dashboard.json ADDED
      ...


      json ADDED 확인됨



      https://grafana.com/grafana/dashboards/?search=istio 에서 id 확인해서 대시보드 추가 가능

      대시보드 이름 살펴보기!

      Control Plane
      Mesh: 메시 통신 관련
      Performance: 퍼포먼트
      Service: 서비스
      Workload: 서비스
      Wasm Exterision


  2. 8.1.2 Viewing control-plane metrics 컨트롤 플레인 메트릭 보기 상세 메트릭 Blog 참고
    • 7장에서 컨트롤 플레인을 긁어가도록 ServiceMonitor 리소스 설정함.


      메트릭으로는 CPU, 메모리, 고루틴 등 확인 가능
    • 또한 컨트롤 플레인 오류, 설정 동기화 문제, 활성 데이터 플레인 커넥션 갯수 등에 대한 데이터 확인 가능
    • 그래프 중 하나의 세부 사항을 누르고 Explore 로 그래프를 만들어내는 데 사용하는 원본 쿼리 확인 가능
      sum(irate(pilot_xds_pushes{type="rds"}[1m]))
      pilot_xds_pushes 의 Explore
      prometheus 에서도 pilot_xds_pushes 조회 됨 (cds, eds, lds, rds)
      prometheus 에서도 pilot_xds_pushes 조회 됨 (그래프)

      메트릭은 Prometheus 등 잘 제공되어 있으나, 맞춤형 대시보드를 구성해야 할 때가 생긴다.
      구성이 막막할 떄는 잘 짜여져 있는 공식 홈페이지 대시보드를 커스텀해서 사용하는 것도 좋다. (LLM등 활용)

  3. 8.1.3 Viewing data-plane metrics 데이터 플레인 메트릭 보기 ⇒ 상세 메트릭 Blog 참고
    • 그라파나 대시보드 → Istio Service Dashboard 선택 : webapp.. 등 특정 서비스를 선택 가능
      service: webapp 선택
      service: catalog 선택
      Client Success Rate (non-5xx responses) explore 해보기
      Prometheus로 istio_request_total 찍어보기


    • 위 그래프들은 Istio 표준 메트릭으로 구성됨 (General)
      • 이를 변경하고 조정하거나 다른 메트릭에 대한 새 그래프를 추가 가능
      • 커스텀 메트릭이나 특정 엔보이 메트릭을 활성화 - Link

  • 들어가며 : 분산 트레이싱 필요성
    • 왜 필요한가?
      • 마이크로서비스 환경이 1개만 구성되어 있으면 상관 없다.
      • 만약 100개의 마이크로서비스 환경이 있고 환경 당 20개로 마이크로서비스를 쪼갰다고 하면 총 서비스는 2000개가 넘는다.
      • 이 때 서로 간 호출하고 연결되고 할 텐데, 어디가 문제인지 알기가 쉽지 않다.
      • 이를 더 쉽게 알 수 있도록 하는 것이 분산 트레이싱이다. (통찰력이라고도 한다.)
        • 요청 경로에서 문제가 발생하기 시작하면, 무슨 일이 일어나고 있는지 이해하는 것이 중요 - 그래야 빠르게 진단하고 고칠 수 있다.
    • 분산 트레이싱 개념 이 개념이 마이크로서비스 망을 통과할 때 오동작하는 요청을 진단하는 데 어떻게 도움이 되는 지 공부
      서비스는 종종 요청할 때 다중 홉을 가짐. 각 홉마다 얼마나 걸리는지 확인하는 것이 중요
    • 분산 트레이싱은 구글 대퍼 Google Dapper 논문 ‘Dapper, a LargeScale Distributed Systems Tracing Insfrastructure (2010)‘에서 도입한 개념.
      • 요청에 주석을 붙이는 작업이 포함됨
        • 이 때 붙이는 주석은 서비스 간 호출을 나타내는 상관관계 correlation ID와 서비스 간 호출 그래프를 거치는 특정 요청을 나타내는 트레이스 trace ID
      • Istio의 데이터 플레인은, 요청이 데이터 플레인을 통과할 때 이런 메타데이터를 요청에 추가할 수 있음
        • 인식할 수 없거외부 개체에서 온 메타데이터제거한다는 점이 중요
        • ex) istio 의 경우 (Jaeger/Zipkin) ~ x-request-id
      • 오픈트레이싱OpenTracing: 분산 트레이싱과 관련된 개념 및 API를 정의하는 사양 - archived
      • 오픈텔레메트리 OpenTelemetry 는 커뮤니티 주도 프레임워크로, 오픈트레이싱을 포함한다.
        • https://opentelemetry.io/ 
        • API, SDK 및 도구 모음
        • 원격 측정 데이터(메트릭, 로그 및 추적)를 계측, 생성, 수집 및 내보냄
          • 소프트웨어의 성능과 동작을 분석할 수 있음
      • 분산 트레이싱은 어느 정도 개발자에게 의존
        • 코드를 계측하는 작업이나 애플리케이션에서 요청을 처리하고 다른 시스템으로 새로운 요청을 보낼요청에 주석을 붙이는 작업이 필요하기 때문

        • 예) 모니터링을 위한 코드(instrumenting code) 삽입
        • 예) 요청에 어노테이션 (correlation id, trace Id 등) 추가
      • Istio 사용 시 - 개발자가 직접 구현해야 하는 부담을 크게 덜어줄 수 있으며 분산 트레이싱을 서비스 메시의 일부로 제공

 

  1. 8.2.1 How does distributed tracing work? 분산 트레이싱은 어떻게 작동하는가?
    • 오픈트레이싱을 활용한 분산 트레이싱(가장 단순한 형태)
      • 애플리케이션이 스팬을 생성 (요청 중 자신이 처리하는 부분)
      • 이를 오픈트레이싱 엔진과 공유
      • 뒤이어 호출하는 서비스로 트레이스 콘텍스트전파(Propagation) - 다른 서비스로
    • 스팬 span : 서비스나 구성 요소 내에서 작업 단위를 나타내는 데이터 모음
      • 작업 시작 시각, 종료 시각, 작업 이름, 태그 및 로그 집합 등이 포함
      • 스팬 ID트레이스 ID 포함
        • 서비스 간 작업 상관관계를 파악하는 데 사용
        • 서비스 간 전파 필요
    • 트레이스 trace : 스팬의 묶음으로, 서비스 간의 인과 관계를 의미
      • 방향, 타이밍과 기타 디버깅 정보를 보여줌
    • 분산 트레이싱 엔진은 스팬트레이스 콘텍스를 사용해 트레이스를 구축
    • 분산 트레이싱을 사용하면?
      • 네트워크 홉마다 스팬을 수집 → 스팬을 종합적인 트레이스에 담음    호출 그래프 내의 문제를 디버깅하는 데 사용

    • 오픈트레이싱 구현체 시스템
      • 예거 Jaeger
      • 집킨 Zipkin
      • 라이트스텝 Lightstep
      • 인스타나 Instana
    • Istio는 스팬을 분산 트레이싱 엔진으로 보낼 수 있음
      • span 및 trace용 언어 전용 라이브러리나 애플리케이션 전용 설정이 필요 없
    • 보통 집킨 트레이싱 헤더 Zipkin tracing header 라고 하는 HTTP 헤더요청에 덧붙이며, 예제에서도 사용함

    • 집킨 트레이싱 헤더
      • x-request-id
      • x-b3-traceid
      • x-b3-spanid
      • x-b3-parentspanid
      • x-b3-sampled
      • x-b3-flags
      • x-ot-span-context
    • Istio 트레이싱 기능 작동을 위한 전파
      • 애플리케이션은 자신이 하는 모든 호출에 트레이싱 헤더를 전파해야 함 - 그래야 Istio가 제공하는 분산 트레이싱 기능이 요청 호출 그래프 전체에 걸쳐 작동 가능
        애플리케이션은 반드시 트레이싱 헤더 전파 필요 - 그렇지 않으면 요청의 스팬 전부가 손실됨
        1. 요청이 들어온다.
        2. 오! 트레이싱 헤더가 없는 것을 보니 새로운 요청이다.
          • 요청이 서비스 사이를 오가는 과정을 추적할 수 있도록 트레이스 헤더를 생성해두자
        3. 트레이스 헤더가 요청 헤더에 추가됐다. x-request-id: c9421…
        4. 애플리케이션이 다른 서비스를 호출할 때 트레이스 헤더를 전파해야 한다.
        5. 트레이스 헤더를 전파한다. x-request-id: c9421…
        6. 이스티오 프록시는 기존 트레이스 헤더를 애플리케이션으로 전파한다.
        7. 만약 애플리케이션이 요청 헤더를 전파하지 않으면… (ex. 서비스 B가 무시하고 헤더를 제거한다던가)
        8. 요청에 트레이스 헤더가 누락된다. 앱이 전파하지 않았기 때문이다.
      • Istio 는 어떤 호출이 어떤 수신 요청의 결과물인지 모르기 때문
      • 애플리케이션이 반드시 이런 헤더를 전파하는 역할 수행 필요
        • 그래야 업스트림 호출과 서비스로 들어온 호출을 올바르게 연결 가능
  2. 8.2.2 Installing a distributed tracing system 분산 트레이싱 시스템 설치하기 (실습)
      • 사용 시스템: 예거 (jaeger)
      • 용이한 배포를 위해 Jaeger의 일체형 all-in-one 배포 샘플 사용
        • 이 샘플은 zipkin 쿠버네티스 서비스도 생성
        • Istio가 기대하는 기본 설정에 맞춰 생성되므로 바로 연결이 가능
      • 운영 환경 배포 단계는 문서를 참조 https://www.jaegertracing.io/docs/1.22/operator/#production-strategy


      •  예거 일체형 배포 설치
        # myk8s-control-plane 진입 후 설치 진행
        docker exec -it myk8s-control-plane bash
        -----------------------------------
        # 설치 파일 확인
        pwd
        ls istio-$ISTIOV/samples/addons
        cat istio-$ISTIOV/samples/addons/jaeger.yaml
        apiVersion: apps/v1
        kind: Deployment
        metadata:
          name: jaeger
          namespace: istio-system
          labels:
            app: jaeger
        spec:
          selector:
            matchLabels:
              app: jaeger
          template:
            metadata:
              labels:
                app: jaeger
                sidecar.istio.io/inject: "false"
              annotations:
                prometheus.io/scrape: "true"
                prometheus.io/port: "14269"
            spec:
              containers:
                - name: jaeger
                  image: "docker.io/jaegertracing/all-in-one:1.35"
                  env:
                    - name: BADGER_EPHEMERAL
                      value: "false"
                    - name: SPAN_STORAGE_TYPE
                      value: "badger"
                    - name: BADGER_DIRECTORY_VALUE
                      value: "/badger/data"
                    - name: BADGER_DIRECTORY_KEY
                      value: "/badger/key"
                    - name: COLLECTOR_ZIPKIN_HOST_PORT
                      value: ":9411"
                    - name: MEMORY_MAX_TRACES
                      value: "50000"
                    - name: QUERY_BASE_PATH
                      value: /jaeger
                  livenessProbe:
                    httpGet:
                      path: /
                      port: 14269
                  readinessProbe:
                    httpGet:
                      path: /
                      port: 14269
                  volumeMounts:
                    - name: data
                      mountPath: /badger
                  resources:
                    requests:
                      cpu: 10m
              volumes:
                - name: data
                  emptyDir: {}
        ---
        apiVersion: v1
        kind: Service
        metadata:
          name: tracing
          namespace: istio-system
          labels:
            app: jaeger
        spec:
          type: ClusterIP
          ports:
            - name: http-query
              port: 80
              protocol: TCP
              targetPort: 16686
            # Note: Change port name if you add '--query.grpc.tls.enabled=true'
            - name: grpc-query
              port: 16685
              protocol: TCP
              targetPort: 16685
          selector:
            app: jaeger
        ---
        # Jaeger implements the Zipkin API. To support swapping out the tracing backend, we use a Service named Zipkin.
        apiVersion: v1
        kind: Service
        metadata:
          labels:
            name: zipkin
          name: zipkin
          namespace: istio-system
        spec:
          ports:
            - port: 9411
              targetPort: 9411
              name: http-query
          selector:
            app: jaeger
        ---
        apiVersion: v1
        kind: Service
        metadata:
          name: jaeger-collector
          namespace: istio-system
          labels:
            app: jaeger
        spec:
          type: ClusterIP
          ports:
          - name: jaeger-collector-http
            port: 14268
            targetPort: 14268
            protocol: TCP
          - name: jaeger-collector-grpc
            port: 14250
            targetPort: 14250
            protocol: TCP
          - port: 9411
            targetPort: 9411
            name: http-zipkin
          selector:
            app: jaeger
            
        # 설치
        kubectl apply -f istio-$ISTIOV/samples/addons/jaeger.yaml
        deployment.apps/jaeger created
        service/tracing created
        service/zipkin created
        service/jaeger-collector created
        
        # 빠져나오기
        exit
        -----------------------------------
        
        # 설치 확인 : 예거는 집킨 형식과 호환됨 Jaeger is compatible with the Zipkin format.
        # https://www.jaegertracing.io/docs/1.22/features/#backwards-compatibility-with-zipkin
        kubectl get deploy,pod,svc,ep -n istio-system
        
        # NodePort 변경 및 nodeport tracing(30004) 변경
        kubectl describe svc -n istio-system tracing
        ...
        Port:                     http-query  80/TCP
        TargetPort:               16686/TCP
        NodePort:                 http-query  31345/TCP
        Endpoints:                10.10.0.20:16686
        ...
        
        kubectl patch svc -n istio-system tracing -p '{"spec": {"type": "NodePort", "ports": [{"port": 80, "targetPort": 16686, "nodePort": 30004}]}}'
        
        # tracing 접속 : 예거 트레이싱 대시보드
        open http://127.0.0.1:30004

        Jaeger 및 zipkin 설치 확인
        nodeport 30004 설정

        적용된 포트 확인
  3. 8.2.3 Configuring Istio to perform distributed tracing 분산 트레이싱을 수행하도록 이스티오 설정하기
    • Istio에서 분산 트레이싱은 메시 전체, 네임스페이스, 특정 워크로드 수준으로 설정 가능
    • 트레이싱 또한 텔레메트리 API를 통해 세분화된 설정 가능 - 로깅, 메트릭, 트레이싱

    • 설치 전 트레이싱 설정하기 (방법 1 사용)
      • Istio는 분산 트레이싱 백엔드를 지원 - 집킨, 데이터독, 예거(집킨 호환) 등
      • 방법 1 : Istio 를 설치할 때 IstioOperator 리소스를 사용하는 샘플 설정 (다양한 분산 트레이싱 백엔드를 설정)
        apiVersion: install.istio.io/v1alpha1
        kind: IstioOperator
        metadata:
          namespace: istio-system
        spec:
          meshConfig:
            defaultConfig:
              tracing:
                lightstep: {}
                zipkin: {}
                datadog: {}
                stackdriver: {}

          • 예를 들어 집킨 호환형인 예거를 사용하려면 다음과 같이 설정 → 실습 설정
            #
            cat ch8/install-istio-tracing-zipkin.yaml
            ---
            apiVersion: install.istio.io/v1alpha1
            kind: IstioOperator
            metadata:
              namespace: istio-system
            spec:
              meshConfig:
                defaultConfig:
                  tracing:
                    sampling: 100
                    zipkin:
                      address: zipkin.istio-system:9411
            
            # 기존 설정 확인
            kubectl get IstioOperator -n istio-system installed-state -o json        
            kubectl describe cm -n istio-system istio
            ...
            defaultConfig:
              discoveryAddress: istiod.istio-system.svc:15012
              proxyMetadata: {}
              tracing:
                zipkin:
                  address: zipkin.istio-system:9411
            ...
            
            # 적용
            docker exec -it myk8s-control-plane bash
            -----------------------------------
            # 
            cat << EOF > install-istio-tracing-zipkin.yaml
            apiVersion: install.istio.io/v1alpha1
            kind: IstioOperator
            metadata:
              namespace: istio-system
            spec:
              meshConfig:
                defaultConfig:
                  tracing:
                    sampling: 100
                    zipkin:
                      address: zipkin.istio-system:9411
            EOF
            
            istioctl install -y -f install-istio-tracing-zipkin.yaml
            
            exit
            -----------------------------------
            
            # 확인
            kubectl describe cm -n istio-system istio
            ...
              tracing:
                sampling: 100
                zipkin:
                  address: zipkin.istio-system:9411
            ...

            기존 설정 확인


            확인 - sampling: 100 추가
            sampling이 100%. 1일 경우 100번 호출하면 100번 호출 건 중에 1건이 트레이싱 엔진에 전달이 되고 기록이 남는다라고 보면 된다. 100이므로 모든 호출건


      • 방법 2 : istio configmap 설정 - MeshConfig 를 이용한 트레이싱 설정
        # 
        kubectl edit cm -n istio-system istio
        ...

        • 메시 범위의 기본 설정은 어떤 것이라도 defaultConfig.tracing 부분에서 업데이트 가능

      • 방법 3 : 워크로드별로 트레이싱 설정하기 : 파드 Spec에 애노테이션 설정
        # 
        apiVersion: apps/v1
        kind: Deployment
        ...
        spec:
          template:
            metadata:
              annotations:
                proxy.istio.io/config: |
                  tracing:
                    zipkin:
                      address: zipkin.istio-system:9411
        ...
    • 기본 트레이싱 헤더 살펴보기 : 헤더와 ID 자동 주입 확인
      • Istio IngressGateway를 사용해 외부 httpbin 서비스 호출 → 요청 헤더를 표시하는 엔드포인트 호출
        client (curl) → istio-ingress-gateway → httpbin.org (외부)
        • Istio가 오픈트레이싱 헤더상관관계 ID자동으로 주입한다는 것을 보여주기 위함
        • 실습 상세
      • Istio Gateway, VirtualService 리소스를 배포
        # Gateway, VirtualService 설정 확인
        cat ch8/tracing/thin-httpbin-virtualservice.yaml
        ---
        apiVersion: networking.istio.io/v1alpha3
        kind: Gateway
        metadata:
          name: coolstore-gateway
        spec:
          selector:
            istio: ingressgateway # use istio default controller
          servers:
          - port:
              number: 80
              name: http
              protocol: HTTP
            hosts:
            - "webapp.istioinaction.io"
            - "httpbin.istioinaction.io"
        ---
        apiVersion: networking.istio.io/v1alpha3
        kind: VirtualService
        metadata:
          name: thin-httbin-virtualservice
        spec:
          hosts:
          - "httpbin.istioinaction.io"
          gateways:
          - coolstore-gateway
          http:
          - route:
            - destination:
                host: httpbin.org
        ---        
        apiVersion: networking.istio.io/v1alpha3
        kind: ServiceEntry
        metadata:
          name: external-httpbin-org
        spec:
          hosts:
          - httpbin.org 
          ports:
          - number: 80
            name: http
            protocol: HTTP
          location: MESH_EXTERNAL
          resolution: DNS
        
        # Gateway, VirtualService 배포
        kubectl apply -n istioinaction -f ch8/tracing/thin-httpbin-virtualservice.yaml
        
        # 확인
        kubectl get gw,vs,serviceentry -n istioinaction
        
        # 도메인 질의를 위한 임시 설정 : 실습 완료 후에는 삭제 해둘 것
        echo "127.0.0.1       httpbin.istioinaction.io" | sudo tee -a /etc/hosts
        cat /etc/hosts | tail -n 5
        
        ## 윈도우에서 hosts 파일에 catalog 도메인 추가 (Powershell)***
        Add-Content -Path C:\Windows\System32\drivers\etc\hosts -Value "127.0.0.1       httpbin.istioinaction.io"
        Get-Content $env:SystemRoot\System32\drivers\etc\hosts | Select-Object -Last 5
        배포된 서비스 확인 serviceentry - httpbin.org는 MESH_EXTERNAL


      • 호스트에서 호출 시, 어떻게 외부 서비스로 전달되는지 보기
        • 원래 요청에서 사용된 헤더가 반환되어야 함
        • client (curl) → istio-ingress-gateway → httpbin.org (외부)
          #
          curl -s http://httpbin.istioinaction.io:30000/headers | jq
          {
            "headers": {
              "Accept": "*/*",
              "Host": "httpbin.istioinaction.io",
              "User-Agent": "curl/8.7.1",
              "X-Amzn-Trace-Id": "Root=1-680de9d9-33db643526404d6b0dc37527",
              "X-B3-Sampled": "1",
              "X-B3-Spanid": "3726f7dcb215ac12",
              "X-B3-Traceid": "9a4a7076cf8b5f633726f7dcb215ac12",
              "X-Envoy-Attempt-Count": "1",
              "X-Envoy-Decorator-Operation": "httpbin.org:80/*",
              "X-Envoy-Internal": "true",
              "X-Envoy-Peer-Metadata": "ChQKDkFQUF9DT05UQUlORVJTEgIaAAoaCgpDTFVTVEVSX0lEEgwaCkt1YmVybmV0ZXMKHAoMSU5TVEFOQ0VfSVBTEgwaCjEwLjEwLjAuMjIKGQoNSVNUSU9fVkVSU0lPThIIGgYxLjE3LjgKnAMKBkxBQkVMUxKRAyqOAwodCgNhcHASFhoUaXN0aW8taW5ncmVzc2dhdGV3YXkKEwoFY2hhcnQSChoIZ2F0ZXdheXMKFAoIaGVyaXRhZ2USCBoGVGlsbGVyCjYKKWluc3RhbGwub3BlcmF0b3IuaXN0aW8uaW8vb3duaW5nLXJlc291cmNlEgkaB3Vua25vd24KGQoFaXN0aW8SEBoOaW5ncmVzc2dhdGV3YXkKGQoMaXN0aW8uaW8vcmV2EgkaB2RlZmF1bHQKMAobb3BlcmF0b3IuaXN0aW8uaW8vY29tcG9uZW50EhEaD0luZ3Jlc3NHYXRld2F5cwoSCgdyZWxlYXNlEgcaBWlzdGlvCjkKH3NlcnZpY2UuaXN0aW8uaW8vY2Fub25pY2FsLW5hbWUSFhoUaXN0aW8taW5ncmVzc2dhdGV3YXkKLwojc2VydmljZS5pc3Rpby5pby9jYW5vbmljYWwtcmV2aXNpb24SCBoGbGF0ZXN0CiIKF3NpZGVjYXIuaXN0aW8uaW8vaW5qZWN0EgcaBWZhbHNlChoKB01FU0hfSUQSDxoNY2x1c3Rlci5sb2NhbAouCgROQU1FEiYaJGlzdGlvLWluZ3Jlc3NnYXRld2F5LTk5NmJjNmJiNi03bG5oNwobCglOQU1FU1BBQ0USDhoMaXN0aW8tc3lzdGVtCl0KBU9XTkVSElQaUmt1YmVybmV0ZXM6Ly9hcGlzL2FwcHMvdjEvbmFtZXNwYWNlcy9pc3Rpby1zeXN0ZW0vZGVwbG95bWVudHMvaXN0aW8taW5ncmVzc2dhdGV3YXkKFwoRUExBVEZPUk1fTUVUQURBVEESAioACicKDVdPUktMT0FEX05BTUUSFhoUaXN0aW8taW5ncmVzc2dhdGV3YXk=",
              "X-Envoy-Peer-Metadata-Id": "router~10.10.0.22~istio-ingressgateway-996bc6bb6-7lnh7.istio-system~istio-system.svc.cluster.local"
            }
          }
          
          # (참고) X-Envoy-Peer-Metadata 정보 디코딩 확인
          echo "ChQKDkFQUF9DT05UQUlORVJTEgIaAAoaCgpDTFVTVEVSX0lEEgwaCkt1YmVybmV0ZXMKHAoMSU5TVEFOQ0VfSVBTEgwaCjEwLjEwLjAuMjIKGQoNSVNUSU9fVkVSU0lPThIIGgYxLjE3LjgKnAMKBkxBQkVMUxKRAyqOAwodCgNhcHASFhoUaXN0aW8taW5ncmVzc2dhdGV3YXkKEwoFY2hhcnQSChoIZ2F0ZXdheXMKFAoIaGVyaXRhZ2USCBoGVGlsbGVyCjYKKWluc3RhbGwub3BlcmF0b3IuaXN0aW8uaW8vb3duaW5nLXJlc291cmNlEgkaB3Vua25vd24KGQoFaXN0aW8SEBoOaW5ncmVzc2dhdGV3YXkKGQoMaXN0aW8uaW8vcmV2EgkaB2RlZmF1bHQKMAobb3BlcmF0b3IuaXN0aW8uaW8vY29tcG9uZW50EhEaD0luZ3Jlc3NHYXRld2F5cwoSCgdyZWxlYXNlEgcaBWlzdGlvCjkKH3NlcnZpY2UuaXN0aW8uaW8vY2Fub25pY2FsLW5hbWUSFhoUaXN0aW8taW5ncmVzc2dhdGV3YXkKLwojc2VydmljZS5pc3Rpby5pby9jYW5vbmljYWwtcmV2aXNpb24SCBoGbGF0ZXN0CiIKF3NpZGVjYXIuaXN0aW8uaW8vaW5qZWN0EgcaBWZhbHNlChoKB01FU0hfSUQSDxoNY2x1c3Rlci5sb2NhbAouCgROQU1FEiYaJGlzdGlvLWluZ3Jlc3NnYXRld2F5LTk5NmJjNmJiNi03bG5oNwobCglOQU1FU1BBQ0USDhoMaXN0aW8tc3lzdGVtCl0KBU9XTkVSElQaUmt1YmVybmV0ZXM6Ly9hcGlzL2FwcHMvdjEvbmFtZXNwYWNlcy9pc3Rpby1zeXN0ZW0vZGVwbG95bWVudHMvaXN0aW8taW5ncmVzc2dhdGV3YXkKFwoRUExBVEZPUk1fTUVUQURBVEESAioACicKDVdPUktMT0FEX05BTUUSFhoUaXN0aW8taW5ncmVzc2dhdGV3YXk=" | base64 -d
          ...
          curl 로 접근시 httpbin.org:80 외부 서비스로 리다이렉션(전달) 시킴
          X-Envoy-Peer-Metadata 값 base64 디코딩

          • Istio IngressGateway를 호출했을 때 외부 URL(httpbin.org - 간단한 HTTP 테스트 서비스) 로 라우팅됨
          • 서비스 접근 및 헤더 플로우
            • /headers 엔드포인트로 GET 요청
            • 요청에 사용한 요청 헤더를 반환하여, x-b3-* 집킨 헤더요청에 자동으로 붙었음
            • 집킨 헤더들은 스팬을 만드는 데 쓰이며 예거로 보내
              istio-ingressgateway에 왔다가 바로 외부로 빠져나감

              upstream_cluster가 outbound|80|httpbin.org
              x-request-Id 확인됨
  4. 8.2.4 Viewing distributed tracing data 분산 트레이싱 데이터 보기 (예거 UI)
    • 스팬이 예거(혹은 기타 오픈트레이싱 엔진)로 보내질 때, 트레이스 및 관련 스팬을 쿼리하고 볼 수 있는 방법이 필요
      • 기본 예거 UI를 사용
      • Service 에서 istio-ingressgateway 를 선택
      • 좌측 하단에 Find Traces 클릭



      • 트레이스가 아무것도 보이지 않으면 curl 트래픽을 조금 발생시키기
        curl -s http://httpbin.istioinaction.io:30000/headers | jq
        curl -s http://httpbin.istioinaction.io:30000/headers | jq
        ...
        
        curl -s http://webapp.istioinaction.io:30000/api/catalog | jq
        curl -s http://webapp.istioinaction.io:30000/api/catalog | jq
        ...
        특정 트레이스를 클릭하면 트레이스를 구성하는 스팬과 같이 좀 더 세부적인 정보 확인 가능


      • 트레이스 콘텍스트 및 헤더 전파하기 Propagating trace context and headers : 올바른 동작을 위해 아래와 같은 헤더 전파 필요
        • x-request-id
        • x-b3-traceid
        • x-b3-spanid
        • x-b3-parentspanid
        • x-b3-sampled
        • x-b3-flags
        • x-ot-span-context
        • 애플리케이션 코드가 요청을 받아 처리를 시작할 때, 이 헤더와 그 값을 저장했다가 애플리케이션이 수행해야 하는 모든 발신 요청에 삽입해야 한다는 것
        • 이 작업은 프록시에서 자동으로 수행 불가능
  5. 8.2.5 Trace sampling, force traces, and custom tag* 트레이스 샘플링, 강제 트레이스, 커스텀 태그
    • 분산 트레이싱 및 스팬 수집은 시스템에 상당한 성능 저하를 초래할 수 있음
      • 서비스가 올바르게 실행 중일 때 분산 트레이싱 수집 빈도를 제한하도록 선택 가능
    • 예시로 설치한 Istio 프로필은 분산 트레이싱의 샘플링을 100%로 설정
    • 시스템에서 수집할 트레이스 비율을 설정함으로써 트레이스 샘플링을 제어 가능


    • 메시의 트레이스 샘플링 비율 조정하기 TUNING THE TRACE SAMPLING FOR THE MESH
      • 트레이싱 설정 중 sampling을 10으로 조정 - istio-system 네임스페이스에 있는 istio configmap 의 MeshConfig 를 수정
        # 
        KUBE_EDITOR="nano" kubectl edit -n istio-system cm istio
        ...
             sampling: 10  # <-- from 100
        ...
        
        # 샘플링 적용은 istio-ingressgateway 재배포 필요 참고.
        kubectl rollout restart deploy -n istio-system istio-ingressgateway
        ...


        • 이로써 서비스 메시 내 모든 워크로드에서 샘플링 비율이 전역적으로 10%로 바뀐다.
        • 전역 설정 대신 애노테이션으로 워크로드별로도 설정할 수 있다.
      • 트레이싱 설정을 포함하도록 디플로이먼트 파드 템플릿의 애노테이션을 편집
        #
        cat ch8/webapp-deployment-zipkin.yaml
        ...
          selector:
            matchLabels:
              app: webapp
          template:
            metadata:
              annotations:
                proxy.istio.io/config: |
                  tracing:
                    sampling: 10 # 퍼센트 직접 수정 후 적용 해보기!
                    zipkin:
                      address: zipkin.istio-system:9411
        ...
        
        # 적용 시 파드 재생성으로 위 애노테이션 적용
        kubectl apply -f ch8/webapp-deployment-zipkin.yaml -n istioinaction
        
        
        # 호출 테스트
        curl -s http://webapp.istioinaction.io:30000/api/catalog | jq
        curl -s http://webapp.istioinaction.io:30000/api/catalog | jq
        curl -s http://webapp.istioinaction.io:30000/api/catalog | jq
        ...



      • 호출 테스트 후 예거 UI에서 샘플링 비율 대로 수집되는지 확인
        수집 빈도 감소 확인 가능



    • 클라이언트에서 트레이싱 강제하기 FORCE-TRACING FROM THE CLIENT
      • 운영 환경에서는 트레이스의 샘플링 비율을 최소한으로 설정한 후 문제가 있을 때만 특정 워크로드에 대해 활성화하는 것이 적절 (부하 이슈)
      • Istio 에서는 특정 요청에만 트레이싱을 강제하도록 설정할 수 있음
      • ex) 애플리케이션에서 요청에 x-envoy-force-trace 헤더 추가
        • 요청이 만드는 호출 그래프의 스팬과 트레이스를 이스티오가 포착하도록 할 수 있음
      • 확인
        # x-envoy-force-trace 헤더를 추가한 curl 요청
        curl -s -H "x-envoy-force-trace: true" http://webapp.istioinaction.io:30000/api/catalog -v
        curl -s -H "x-envoy-force-trace: true" http://webapp.istioinaction.io:30000/api/catalog -v
        curl -s -H "x-envoy-force-trace: true" http://webapp.istioinaction.io:30000/api/catalog -v
        ...

        x-envoy-force-trace 헤더를 추가한 curl 요청
        샘플링 비율과 관계 없이 집계


    • 트레이스의 태그 커스터마이징하기 CUSTOMIZING THE TAGS IN A TRACE
      • 스팬에 태그를 추가하여 애플리케이션트레이스에 추가 메타데이터를 첨부(부여) 가능
      • 태그: 키-값 쌍 (애플리케이션 / 조직별 커스텀 정보 기재) 이며 스팬에 추가
      • 커스텀 태그 유형 (3가지)
        • 명시적으로 값 지정하기 Explicitly specifying a value
        • 환경 변수에서 값 가져오기 Pulling a value from environment variables
        • 요청 헤더에서 값 가져오기 Pulling a value from request headers
      • ex) webapp 서비스의 스팬에 커스텀 태그를 추가 (Deployment Annotation)
        # 커스텀 태그 부여 설정 확인
        cat ch8/webapp-deployment-zipkin-tag.yaml
        ...
          template:
            metadata:
              annotations:
                proxy.istio.io/config: |
                  tracing:
                    sampling: 100
                    customTags:
                      custom_tag: # 커스텀 태그의 키
                        literal:
                          value: "Test Tag" # 커스텀 태그의 값
                    zipkin:
                      address: zipkin.istio-system:9411
        ...
        
        # webapp 에 커스텀 태그 적용
        kubectl apply -n istioinaction -f ch8/webapp-deployment-zipkin-tag.yaml
        
        # 호출
        for in in {1..10}; do curl -s http://webapp.istioinaction.io:30000/api/catalog ; sleep 0.5; done
        for in in {1..10}; do curl -s http://webapp.istioinaction.io:30000/api/catalog ; sleep 0.5; done
        ...

        커스텀 태그 확인 가능



      • 커스텀 태그는 보고 reporting, 필터링 filtering, 트레이싱 데이터 탐색에 사용 가능
      • 스팬이나 트레이스에 포함되는 태그를 커스터마이징하는 방법 -  https://istio.io/v1.17/docs/tasks/observability/distributed-tracing/
    • 백엔드 분산 트레이싱 엔진 커스터마이징하기 CUSTOMIZING THE BACKEND DISTRIBUTED TRACING ENGINE
      • 분산 트레이싱 엔진에 연결하는 백엔드 설정 수행 방법 (심화)
      • 예거의 집킨 호환성을 사용하려면 예거 수집기의 특정 엔드포인트로 추적을 전송해야 함

      • 집킨 기반 트레이싱 엔진의 기본 트레이싱 설정
        # 
        docker exec -it myk8s-control-plane bash
        ----------------------------------------
        # deploy/webapp 트레이싱 설정 조회 : 현재 기본 설정
        istioctl pc bootstrap -n istioinaction deploy/webapp -o json | jq .bootstrap.tracing
        {
          "http": {
            "name": "envoy.tracers.zipkin",
            "typedConfig": {
              "@type": "type.googleapis.com/envoy.config.trace.v3.ZipkinConfig",
              "collectorCluster": "zipkin",
              "collectorEndpoint": "/api/v2/spans",
              "traceId128bit": true,
              "sharedSpanContext": false,
              "collectorEndpointVersion": "HTTP_JSON"
            }
          }
        }
        
        exit
        ----------------------------------------



        현재 기본 설정
        • tracing enging 은 Zipkin-based
        • Span 은 /api/v2/spans 로 전달
        • JSON 엔드포인트로 처리

      •  기본 설정은 커스텀 부트스트랩 설정으로 변경 가능
        • configmap 에서 튜닝하고자 하는 설정 스니펫을 지정
          # 해당 configmap 은 collectorEndpoint 를 변경한 설정 스니펫
          cat ch8/istio-custom-bootstrap.yaml
          apiVersion: v1
          kind: ConfigMap
          metadata:
            name: istio-custom-zipkin
          data:
            custom_bootstrap.json: |
              {
                "tracing": {
                  "http": {
                    "name": "envoy.tracers.zipkin",
                    "typedConfig": {
                      "@type": "type.googleapis.com/envoy.config.trace.v3.ZipkinConfig",
                      "collectorCluster": "zipkin",
                      "collectorEndpoint": "/zipkin/api/v1/spans",
                      "traceId128bit": "true",
                      "collectorEndpointVersion": "HTTP_JSON"
                    }
                  }
                }
              }
          
          # 이 부트스트랩 설정을 덮어 쓰려는 워크로드가 있는 네임스페이스에 configmap 을 적용할 수 있다.
          kubectl apply -n istioinaction -f ch8/istio-custom-bootstrap.yaml
          
          # 확인
          kubectl get cm -n istioinaction
          
          # 해당 configmap 을 참조하는 Deployment 리소스의 파드 템플릿에 애노테이션을 추가
          cat ch8/webapp-deployment-custom-boot.yaml
          ...
            template:
              metadata:
                annotations:
                  sidecar.istio.io/bootstrapOverride: "istio-custom-zipkin" # 부트스트랩 설정을 istio-custom-zipkin 사용
                  proxy.istio.io/config: |
                    tracing:
                      sampling: 10
                      zipkin:
                        address: zipkin.istio-system:9411
                labels:
                  app: webapp
          ...
          
          # 변경된 설정으로 webapp을 재배포 합니다
          kubectl apply -n istioinaction -f ch8/webapp-deployment-custom-boot.yaml
          
          
          #
          docker exec -it myk8s-control-plane bash
          ----------------------------------------
          # deploy/webapp 트레이싱 설정 조회 : 현재 기본 설정
          istioctl pc bootstrap -n istioinaction deploy/webapp -o json | jq .bootstrap.tracing
          {
            "http": {
              "name": "envoy.tracers.zipkin",
              "typedConfig": {
                "@type": "type.googleapis.com/envoy.config.trace.v3.ZipkinConfig",
                "collectorCluster": "zipkin",
                "collectorEndpoint": "/zipkin/api/v1/spans",
                "traceId128bit": true,
                "collectorEndpointVersion": "HTTP_JSON"
              }
            }
          }
          
          exit
          ----------------------------------------
          
          # 호출
          for in in {1..10}; do curl -s http://webapp.istioinaction.io:30000/api/catalog ; sleep 0.5; done
          for in in {1..10}; do curl -s http://webapp.istioinaction.io:30000/api/catalog ; sleep 0.5; done
          ...


          현재 설정



          • JAEGER 대시보드 확인 : webapp 추적 시 collectorEndpoint 에 잘못된 경로 설정으로 webapp Span이 출력되지 않음
            webapp span 확인되지 않음


        • 설정 원복
          # istio-custom-zipkin 어노테이션이 없는 webapp으로 재배포
          kubectl apply -n istioinaction -f services/webapp/kubernetes/webapp.yaml
          
          # 호출
          for in in {1..10}; do curl -s http://webapp.istioinaction.io:30000/api/catalog ; sleep 0.5; done
          for in in {1..10}; do curl -s http://webapp.istioinaction.io:30000/api/catalog ; sleep 0.5; done
          ...


          • JAEGER 대시보드 확인

 

 

 


  • 들어가며 : Kiali - The Console for Istio Service Mesh
    • Istio에서 활용 가능, 강력한 시각화 대시보드 제공. 서비스 메시 파악에 도움
    • 프로메테우스와 기반 플랫폼에서 많은 양의 메트릭을 가져와 메시 내 구성 요소의 런타임 그래프를 구성
      • 그래프를 통해 서비스 간의 통신 상황을 시각적으로 이해 가능
      • 이슈 발생 여지가 있는 영역을 파고들어 어떤 동작을 하고 있는 지 자세히 확인 가능.
    • Kiali와 그라파나 다른 점
      • Kiali: 실시간으로 갱신되는 메트릭을 사용, 서비스가 서로 어떻게 통신하는지에 대한 방향 그래프 directed graph 를 구축하는데 집중
      • Grafana: 게이지, 카운터, 차트 등이 포함된 대시보드. 클러스터 내 서비스에 대한 상호작용형 그림이나 지도를 보여주지는 않음

 

  1. 8.3.1 Installing Kiali 키알리 설치하기 (실습)
    • Istio에서 기본 제공하는 Kiali 샘플 버전 사용
    • 공식 설치 가이드 - https://v1-41.kiali.io/docs/installation/installation-guide/
    • Kiali Operator 설치 - 참고 Blog , Helm
      # helm repo
      helm repo add kiali https://kiali.org/helm-charts
      helm repo update 
      
      # kiali-operator install : 책은 1.40.1
      helm install --namespace kiali-operator --create-namespace --version 1.63.2 kiali-operator kiali/kiali-operator
      
      # kiali-operator 확인
      kubectl get pod -n kiali-operator
      NAME                             READY   STATUS    RESTARTS   AGE
      kiali-operator-584858fb7-zcjv2   1/1     Running   0          61s

      kiali Operator 설치 확인


    • istio-system 네임스페이스에 kiali 인스턴스 배포 : 웹 대시보드를 갖춘 실제 애플리케이션
      # 앞 절에서 배포했던 프로메테우스와 예거에 연결할 수 있게 설정
      cat ch8/kiali.yaml
      apiVersion: kiali.io/v1alpha1
      kind: Kiali
      metadata:
        namespace: istio-system
        name: kiali
      spec:
        istio_namespace: "istio-system"  
        istio_component_namespaces:
          prometheus: prometheus
        auth:    
          strategy: anonymous # 익명 접근 허용
        deployment:
          accessible_namespaces:
          - '**'
        external_services:    
          prometheus: # 클러스터 내에서 실행 중인 프로메테우스 설정
            cache_duration: 10
            cache_enabled: true
            cache_expiration: 300
            url: "http://prom-kube-prometheus-stack-prometheus.prometheus:9090"    
          tracing: # 클러스터 내에서 실행 중인 예거 설정
            enabled: true
            in_cluster_url: "http://tracing.istio-system:16685/jaeger"
            use_grpc: true
      
      # 키알리 인스턴스(대시보드) 설치
      kubectl apply -f ch8/kiali.yaml
      
      
      # 확인
      kubectl get deploy,svc -n istio-system kiali
      NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
      deployment.apps/kiali   1/1     1            1           36s
      
      NAME            TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)              AGE
      service/kiali   ClusterIP   10.200.1.179   <none>        20001/TCP,9090/TCP   35s
      
      # NodePort 변경 및 nodeport kiali(30003)
      kubectl patch svc -n istio-system kiali -p '{"spec": {"type": "NodePort", "ports": [{"port": 20001, "targetPort": 20001, "nodePort": 30003}]}}'
      
      # Kiali 접속 1 : NodePort
      open http://127.0.0.1:30003

      kiali 배포 확인 및 nodeport 패치 (30003)
      접속 확인


      • 프로메테우스와 예거 모두 기본적인 통신 보안 전략이 따로 있지는 않음. 다만 앞 단에 리버스 프록시를 둘 것을 권장
      • 키알리에서는 프로메테우스에 연결할 때 TLS와 기본적인 인증을 사용할 수 있음
    • 트래픽 확인을 위해서 반복 호출
      while true; do curl -s http://webapp.istioinaction.io:30000/api/catalog ; date "+%Y-%m-%d %H:%M:%S" ; sleep 1; echo; done
    • Overview dashboard : 네임스페이스와 각 네임스페이스에서 실행 중인 애플리케이션의 개수 표기 istioinaction 네임스페이스 선택
      app 클릭 시 해당 네임스페이스에 app 정보 페이지로 넘어감
    • Graph : 서비스 매시의 트래픽 흐름을 보여주는 방향 그래프 ⇒ Display 체크
      • 트래픽의 이동과 흐름 Traversal and flow of traffic
      • 바이트 수, 요청 개수 등 Number of bytes, requests, and so on
      • 여러 버전에 대한 여러 트래픽 흐름(예: 카나리 릴리스나 가중치 라우팅)
      • 초당 요청 수 Requests/second; 총량 대비 여러 버전의 트래픽 비율
      • 네트워크 트래픽에 기반한 애플리케이션 상태 health
      • HTTP/TCP 트래픽
      • 빠르게 식별할 수 있는 네트워크 실패


    •  Workloads → Traces 선택



    • 트레이스, 메트릭, 로그의 연관성 CORRELATION OF TRACES, METRICS, AND LOGS
      • Workloads 메뉴
        • Overview: 서비스 Pod, 서비스에 적용된 Istio 구성, 업스트림 및 다운스트림 그래프
        • Traffic: 인바운드 및 아웃바운드 트래픽의 성공률
        • Logs: 애플리케이션 로그, Envoy 액세스 로그, 그리고 서로 연관된 스팬
        • Traces: Jaeger에서 보고된 추적
        • Envoy: 클러스터, 리스너, 경로 등 워크로드에 적용된 Envoy 구성
          인바운드 메트릭으로 메트릭과 trace의 연관관계를 보여줌
        • Kiali workload vs. application 차이
          • 워크로드
            • 동일한 실행 복제본 집합으로 배포될 수 있는 실행 중인 바이너리
            • 예를 들어, 쿠버네티스에서는 배포의 Pod 부분이 워크로드
            • 세 개의 복제본이 있는 서비스 배포는 워크로드
          • 애플리케이션
            • 워크로드와 서비스 및 구성과 같은 관련 구성 요소의 그룹
            • 쿠버네티스에서는 서비스 A와 서비스 B, 그리고 데이터베이스가 될 수 있음
            • 각 서비스는 별도의 워크로드이며, 함께 Kiali 애플리케이션을 구성
        • Kiali is useful for service mesh operators Kiali가 운영에 도움을 주는 것
          • 존재하지 않는 게이트웨이를 가리키는 VirtualService
          • 존재하지 않는 대상으로의 라우팅
          • 동일한 호스트에 대한 두 개 이상의 VirtualService
          • 서비스 하위 집합을 찾을 수 없음