Service_Mesh/Istio
[Istio-4주차] Observability: Grafana, Jaeger, and Kiali (이론, 실습)
lati-tech
2025. 5. 4. 08:12
8장 관찰가능성 Observability : Visualizing network behavior with Grafana, Jaeger, and Kiali
들어가며
배경 설명: 종합적으로 시각화 진행 (Prometheus로는 부족하며, 서비스 동작을 더욱 잘 이해하기 위함)
- 그라파나를 사용해 메트릭을 시각적으로 관찰하기 Using Grafana to observe metrics visually
- 예거를 사용한 분산 트레이싱 계측하기 Distributed tracing instrumentation with Jaeger
- 키알리로 네트워크 호출 그래프 시각화하기 Visualizing the network call graph with Kiali
8.1 Using Grafana to visualize Istio service and control-plane metrics 그라파나로 이스티오 서비스와 컨트롤 플레인 메트릭 시각화
- 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
- Istio-in-actions 도서 제공 소스 코드에 대시보드를 추가 설정 or 공개 대시보드에서 검색 - Link , Search
- 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등 활용)
- 7장에서 컨트롤 플레인을 긁어가도록 ServiceMonitor 리소스 설정함.
- 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
- 그라파나 대시보드 → Istio Service Dashboard 선택 : webapp.. 등 특정 서비스를 선택 가능
8.2 Distributed tracing 분산 트레이싱
- 들어가며 : 분산 트레이싱 필요성
- 왜 필요한가?
- 마이크로서비스 환경이 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 사용 시 - 개발자가 직접 구현해야 하는 부담을 크게 덜어줄 수 있으며 분산 트레이싱을 서비스 메시의 일부로 제공
- 요청에 주석을 붙이는 작업이 포함됨
- 왜 필요한가?
- 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가 제공하는 분산 트레이싱 기능이 요청 호출 그래프 전체에 걸쳐 작동 가능
애플리케이션은 반드시 트레이싱 헤더 전파 필요 - 그렇지 않으면 요청의 스팬 전부가 손실됨 - 요청이 들어온다.
- 오! 트레이싱 헤더가 없는 것을 보니 새로운 요청이다.
- 요청이 서비스 사이를 오가는 과정을 추적할 수 있도록 트레이스 헤더를 생성해두자
- 트레이스 헤더가 요청 헤더에 추가됐다. x-request-id: c9421…
- 애플리케이션이 다른 서비스를 호출할 때 트레이스 헤더를 전파해야 한다.
- 트레이스 헤더를 전파한다. x-request-id: c9421…
- 이스티오 프록시는 기존 트레이스 헤더를 애플리케이션으로 전파한다.
- 만약 애플리케이션이 요청 헤더를 전파하지 않으면… (ex. 서비스 B가 무시하고 헤더를 제거한다던가)
- 요청에 트레이스 헤더가 누락된다. 앱이 전파하지 않았기 때문이다.
- Istio 는 어떤 호출이 어떤 수신 요청의 결과물인지 모르기 때문
- 애플리케이션이 반드시 이런 헤더를 전파하는 역할 수행 필요
- 그래야 업스트림 호출과 서비스로 들어온 호출을 올바르게 연결 가능
- 각 애플리케이션은 자신이 하는 모든 호출에 트레이싱 헤더를 전파해야 함 - 그래야 Istio가 제공하는 분산 트레이싱 기능이 요청 호출 그래프 전체에 걸쳐 작동 가능
- 오픈트레이싱을 활용한 분산 트레이싱(가장 단순한 형태)
- 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 설정 적용된 포트 확인
- 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%. 1일 경우 100번 호출하면 100번 호출 건 중에 1건이 트레이싱 엔진에 전달이 되고 기록이 남는다라고 보면 된다. 100이므로 모든 호출건확인 - sampling: 100 추가
- 예를 들어 집킨 호환형인 예거를 사용하려면 다음과 같이 설정 → 실습 설정
- 방법 2 : istio configmap 설정 - MeshConfig 를 이용한 트레이싱 설정
# kubectl edit cm -n istio-system istio ...
- 메시 범위의 기본 설정은 어떤 것이라도 defaultConfig.tracing 부분에서 업데이트 가능
- 메시 범위의 기본 설정은 어떤 것이라도 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를 자동으로 주입한다는 것을 보여주기 위함
- 실습 상세
- httpbin.istioinaction.io 요청 시 외부 서비스 http://httpbin.org 를 호출.
- http://httpbin.org 은 simple HTTP 테스트 서비스로 응답 시 헤더 정보를 출력.
- 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 확인됨
- Istio IngressGateway를 사용해 외부 httpbin 서비스 호출 → 요청 헤더를 표시하는 엔드포인트 호출
- 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
- 애플리케이션 코드가 요청을 받아 처리를 시작할 때, 이 헤더와 그 값을 저장했다가 애플리케이션이 수행해야 하는 모든 발신 요청에 삽입해야 한다는 것
- 이 작업은 프록시에서 자동으로 수행 불가능
- 스팬이 예거(혹은 기타 오픈트레이싱 엔진)로 보내질 때, 트레이스 및 관련 스팬을 쿼리하고 볼 수 있는 방법이 필요
- 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에서 샘플링 비율 대로 수집되는지 확인
수집 빈도 감소 확인 가능
- 트레이싱 설정 중 sampling을 10으로 조정 - istio-system 네임스페이스에 있는 istio configmap 의 MeshConfig 를 수정
- 클라이언트에서 트레이싱 강제하기 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 확인되지 않음
- JAEGER 대시보드 확인 : webapp 추적 시 collectorEndpoint 에 잘못된 경로 설정으로 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 대시보드 확인
- JAEGER 대시보드 확인
- configmap 에서 튜닝하고자 하는 설정 스니펫을 지정
- 분산 트레이싱 및 스팬 수집은 시스템에 상당한 성능 저하를 초래할 수 있음
8.3 Visualization with Kiali 키알리를 이용한 시각화 - https://kiali.io/
- 들어가며 : Kiali - The Console for Istio Service Mesh
- Istio에서 활용 가능, 강력한 시각화 대시보드 제공. 서비스 메시 파악에 도움
- 프로메테우스와 기반 플랫폼에서 많은 양의 메트릭을 가져와 메시 내 구성 요소의 런타임 그래프를 구성
- 그래프를 통해 서비스 간의 통신 상황을 시각적으로 이해 가능
- 이슈 발생 여지가 있는 영역을 파고들어 어떤 동작을 하고 있는 지 자세히 확인 가능.
- Kiali와 그라파나 다른 점
- Kiali: 실시간으로 갱신되는 메트릭을 사용, 서비스가 서로 어떻게 통신하는지에 대한 방향 그래프 directed graph 를 구축하는데 집중
- Grafana: 게이지, 카운터, 차트 등이 포함된 대시보드. 클러스터 내 서비스에 대한 상호작용형 그림이나 지도를 보여주지는 않음
- 8.3.1 Installing Kiali 키알리 설치하기 (실습)
- Istio에서 기본 제공하는 Kiali 샘플 버전 사용
- 실제 배포 시에는 Kiali Operator 사용 권장 (Istio 및 Kiali 팀 - https://github.com/kiali/kiali-operator )
- 공식 설치 가이드 - 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
- 서비스 하위 집합을 찾을 수 없음
- Workloads 메뉴
- Istio에서 기본 제공하는 Kiali 샘플 버전 사용