CloudNet@ 가시다님이 진행하는 Istio 스터디 1기 - 4주차 정리 내용 입니다.
앞서 진행했던 주차를 보고 오시면 이해가 빠릅니다.
이번 글에서는 Istio의 Observability(관찰 가능성) 을 3가지 방법으로 살펴보겠습니다.
Grafana를 사용하여 메트릭 시각화
Jaeger를 사용하여 분산 트레이싱 계측
kiail를 사용하여 네트워크 호출 그래프 시각화
🖥️ Grafana를 사용하여 메트릭 시각화
우린 앞서 4주차 Observability 첫번째 글에서 실습환경을 구성해놓았습니다.
먼저 Grafana 대시보드에 접속 해줍니다.
ID: admin PW: prom-operator
그리고 메트릭 확인을 위한 반복 호출문 작동
🔧 반복 호출문
$ while true; do curl -s http://webapp.istioinaction.io:30000/api/catalog ; date "+%Y-%m-%d %H:%M:%S" ; sleep 1; echo; done
🔧 대시보드 추가 설정 및 공개 대시보드 검색
$ 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 Operator가 configmap(istio-dashboards)을 마운트(인식) 하도록 레이블 지정
$ kubectl label -n prometheus cm istio-dashboards grafana_dashboard=1
Grafana 접속해서 Dashboard 보면 아래와 같이 Istio Dashboard가 생성됩니다.
먼저 Control-Plane 대시보드를 살펴보겠습니다.
Pilot Version 확인
CPU, Memory, Disk, Goroutiones 리소스 사용량 확인
Pilot Push Infomation - Pilot Pushes: Pilot이 Envoy 프록시에게 전달한 xDS 리소스 수 - Pilot Errors: Push 중 발생한 에러 수 - Proxy Push Time: 프록시에게 Config를 푸시할 떄 걸린 시간 - Confilcts: config 충돌 여부
저희는 앞서 컨트롤 플레인의 메트릭을 긁어가도록 ServiceMonitor 리소스를 설정해두었습니다.
그리고 Pilot Pushes -> Explore 로 그래프를 만들어내는 데 사용되는 원본 쿼리를 살펴보겠습니다.
그래서 Prometheus 그래프에서 보면, 각 xDS 타입 별로 Push를 진행했던 횟수가 나옵니다.
이제 Data-Plane 메트릭을 살펴보겠습니다.
Grafana Dashboard에 접속해서 Istio Service Dashboard를 선택해줍니다.
빨간색 박스에서 원하는 서비스를 선택하여 살펴 볼 수 있습니다.
이제 분산 트레이싱에 대해 알아보겠습니다.
🖥️ Jaeger를 이용하여 분산 트레이싱 해보기
먼저 분산 트레이싱이 왜 필요한지 알아보겠습니다.
📌 분산 트레이싱이란?
하나의 요청이 여러 서비스에 걸쳐 처리될 때, 그 전체 흐름을 추적하는 기술입니다.
즉, 사용자가 어떤 요청을 보냈을 때,
어떤 서비스들이 호출되었고
각 서비스에서의 처리 시간은 얼마였고
어디에서 병목이 생겼는지 등을 시각적으로 보여줍니다.
📌 분산 트레이싱이 필요한 이유
✅ 마이크로서비스 환경의 복잡성 해결
하나의 요청이 여러 마이크로서비스를 거치며 처리됨
예: 프론트엔드 → API Gateway → 인증 서비스 → 결제 서비스 → DB
✅ 병목 및 오류 지점 식별
어느 구간에서 요청이 지연되는지 확인 가능
오류가 발생한 서비스나 호출 경로를 정확히 파악 가능
✅ 성능 개선
느린 서비스 탐지 → 성능 튜닝 포인트 확보
✅ 서비스 간 의존성 파악
서비스 호출 관계를 시각적으로 파악 → 아키텍처 분석에 유리
이제 분산 트레이싱은 어떻게 동작하는지 알아보겠습니다.
분산 트레이싱이 동작하는 방식은 기본적으로요청에 대한 고유한 추적 정보를 서비스 간에 전파하고, 각서비스에서 트레이스 데이터를 수집하여 분석하는 구조입니다.
📌 작동 원리 요약
1️⃣ Trace Context 생성
사용자의 요청이 처음 들어오는 지점(예: 프론트엔드, API Gateway) 에서 - Trace ID: 요청 전체를 식별하는 고유 ID - Span ID: 각 서비스 호출 단계를 구분하는 ID - Parent Span ID: 어떤 서비스로부터 호출되었는지를 나타냄 이 포함된 Trace Context를 생성함
2️⃣ Context 전달 (전파)
요청이 다음 서비스로 넘어갈 때, 이 Trace Context를 HTTP Header(예: traceparent, x-b3-traceid)에 포함시켜 전달함
이를 통해 모든 서비스가 같은 Trace ID 하에 묶임
3️⃣ 각 서비스에서 Span 기록
각 서비스는 요청 처리 시점에 Span 시작, 처리 후 종료
Span에는 다음 정보가 포함됨: - 시작/종료 시간 - 수행된 작업 이름 (예: DB 조회, 외부 API 호출) - 오류 여부 - 부모 Span과의 관계 (ParentSpanID)
4️⃣ 트레이싱 백엔드에 전송
각 Span은 백엔드 서버(Jaeger, Zipkin 등) 으로 전송됨
백엔드는 이를 기반으로 하나의 Trace 타임라인으로 시각화
Istio는 Span을 분산 트레이싱 엔진으로 보낼 수 있으므로, 별도의 언어 전용 라이브러리나 애플리케이션 전용 설정이 필요 없습니다.
Jaeger UI에서 확인해보면, custom_tag=Test Tag 가 추가된 것을 확인 할 수 있습니다.
백엔드 분산 트레이싱 엔진 커스터마이징하기
분산 트레이싱의 마지막으로 분산 트레이싱 엔진에 연결하는 백엔드 설정을 어떻게 수행하는지 알아보겠습니다.
🔧 집킨 기반 트레이싱 엔진의 기본 트레이싱 설정 알아보기
$ docker exec -it myk8s-control-plane bash
---
$ 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 으로 설정
span은 /api/v2/spans 으로 전달
json 엔드포인트로 처리
이제 설정을 커스터마이징 해보겠습니다.
🔧 부트스트랩 설정을 덮어 쓰려는 워크로드가 있는 네임스페이스에 configmap 적용
$ 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"
}
}
}
$ kubectl apply -n istioinaction -f ch8/istio-custom-bootstrap.yaml
🔧 변경된 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
$ kubectl apply -n istioinaction -f ch8/webapp-deployment-custom-boot.yaml
🔧 변경된 설정 확인
$ docker exec -it myk8s-control-plane bash
---
$ 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
호출 테스트를 하고 Jaeger UI에서 확인해보면 collectorEndpoint에 잘못된 경로 설정이 되어서webapp Span이 출력 되지 않습니다.
🔧 다음 실습을 위해 설정 원복
$ kubectl apply -n istioinaction -f services/webapp/kubernetes/webapp.yaml
🖥️ Kiail를 사용한 시각화
이제 kiail 를 사용하여서비스 간의 통신 상황을 시각적으로 확인해보겠습니다.
🔧 kiail 설치
🔧 helm repo 추가 및 설치
$ helm repo add kiali https://kiali.org/helm-charts
$ helm repo update
$ helm install --namespace kiali-operator --create-namespace --version 1.63.2 kiali-operator kiali/kiali-operator
🔧 kiail-operator 설치 확인
$ kubectl get pod -n kiali-operator
결과
NAME READY STATUS RESTARTS AGE
kiali-operator-584858fb7-xvq7s 1/1 Running 0 37s
🔧 앞서 배포했던 프로메테우스와 Jaeger에 연결할 수 있도록 설정
$ 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
🔧 kiail 대시보드 외부 접속하기 위해 Nodeport 변경
$ kubectl patch svc -n istio-system kiali -p '{"spec": {"type": "NodePort", "ports": [{"port": 20001, "targetPort": 20001, "nodePort": 30003}]}}'
🔧 트래픽 확인을 위한 반복 호출
$ while true; do curl -s http://webapp.istioinaction.io:30000/api/catalog ; date "+%Y-%m-%d %H:%M:%S" ; sleep 1; echo; done
이제 kiail 대시보드 접속 해보도록 하겠습니다.
URL에localhost:30003으로 들어가줍니다.
kiail에 접속해서 하나씩 살펴보면,
Overview dashboard: 각 네임스페이스에서 실행 중인 애플리케이션 표기
Graph: 서비스 메시의 트래픽 흐름을 보여주는 그래프 - 트래픽의 이동과 흐름 Traversal and flow of traffic - 바이트 수, 요청 개수 등 Number of bytes, requests, and so on - 여러 버전에 대한 여러 트래픽 흐름(예: 카나리 릴리스나 가중치 라우팅) - 초당 요청 수 Requests/second; 총량 대비 여러 버전의 트래픽 비율 - 네트워크 트래픽에 기반한 애플리케이션 상태 health - HTTP/TCP 트래픽 - 빠르게 식별할 수 있는 네트워크 실패
Workload: k8s 클러스터 내에서 실행 중인 서비스의 실제 실행 단위인 Pod 레벨의 리소스 상태를 보여줍니다.
그리고 Workload와 Applicatio의 차이점을 비교해보자면, 아래와 같습니다.
구분
Workload
Application
의미
Kubernetes에서 Pod을 생성하는 리소스 (예: Deployment)
동일 네임스페이스 내에서 동일한app라벨을 가진 Pod들의 논리적 집합
단위
개별 실행 단위 (1개의 Deployment, 1개의 StatefulSet 등)
서비스 관점의 묶음 (같은 앱 라벨을 갖는 여러 Workload 포함 가능)
기준
실제 Kubernetes 리소스 (컨트롤러 중심)
app라벨 값 중심의 논리적 그룹
예시
simple-webDeployment 1개
app=simple-web라벨을 가진 모든 Workload (v1, v2 등)
목적
리소스 수준에서 상태/트래픽 확인
서비스 수준에서 전체 흐름/메트릭 추적에 적합
사용 예
Pod 상태 확인, 사이드카 주입 여부 확인 등
트래픽 버전별 분포, Canary 분석 등
--------
--------------------------------------------
----------------------------------------------
🔎 쉽게 설명하면:
Workload는 실제로 Kubernetes에 배포된 실행 단위 - 예: Deployment/simple-web-v1, Deployment/simple-web-v2
Application은 같은 애플리케이션 이름(app)으로 묶인 그룹 - 예: app=simple-web 라벨이 붙은 모든 버전의 Pod
이렇게 kiail를 사용하면
서비스 메쉬의 가시성 확보
실시간 모니터링, 요청량, 지연 시간, 에러율 등 트래픽 메트릭 시각화
사이드카 누락, 사이클, 잘못된 라우팅 등 구조 문제 탐지 및 알림
Gateway, VirtualService, DestinationRule 등 istio 리소스를 한눈에 확인/편집 가능