Skip to content

필사 모드: Istio 관찰성 내부 구현: 메트릭, 트레이싱, 로깅

한국어
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.
원문 렌더가 준비되기 전까지 텍스트 가이드로 표시합니다.

들어가며

관찰성(Observability)은 서비스 메시의 핵심 가치 중 하나입니다. Istio는 애플리케이션 코드 수정 없이 메트릭, 분산 트레이싱, 액세스 로깅을 자동으로 생성합니다.

이 글에서는 Istio가 어떻게 이러한 텔레메트리 데이터를 생성하고, Envoy 필터 체인에서 어떤 처리가 이루어지며, 외부 시스템과 어떻게 통합되는지 내부 구현을 분석합니다.

Envoy 통계 시스템

통계 타입

Envoy는 세 가지 타입의 통계를 생성합니다:

| 타입 | 설명 | 예시 |

| --------- | ------------------------ | ----------------------------- |

| Counter | 단조 증가하는 값 | 총 요청 수, 총 에러 수 |

| Gauge | 증가/감소 가능한 현재 값 | 활성 연결 수, 대기 중 요청 수 |

| Histogram | 값의 분포 | 요청 지연 시간, 응답 크기 |

필터 체인에서의 통계 생성

요청 흐름과 통계 생성 위치:

Listener (connection stats)

HTTP Connection Manager (request stats)

├── JWT Authn Filter → 인증 성공/실패 카운터

├── RBAC Filter → 인가 허용/거부 카운터

├── Fault Filter → 주입된 지연/중단 카운터

├── Stats Filter (istio.stats) → Istio 표준 메트릭 생성

└── Router Filter → 업스트림 요청 통계

Cluster (upstream stats)

Endpoint (connection/request stats)

Istio 표준 메트릭

핵심 HTTP 메트릭

**istio_requests_total** (Counter)

요청 수를 추적하는 핵심 메트릭:

istio_requests_total{

reporter="source", # 또는 "destination"

source_workload="frontend",

source_workload_namespace="prod",

source_principal="spiffe://cluster.local/ns/prod/sa/frontend",

destination_workload="reviews",

destination_workload_namespace="prod",

destination_principal="spiffe://cluster.local/ns/prod/sa/reviews",

destination_service="reviews.prod.svc.cluster.local",

destination_service_name="reviews",

destination_service_namespace="prod",

request_protocol="http",

response_code="200",

response_flags="-",

connection_security_policy="mutual_tls"

}

**istio_request_duration_milliseconds** (Histogram)

요청 처리 시간 분포:

istio_request_duration_milliseconds_bucket{

..., # 위와 동일한 라벨

le="1"

} 100

istio_request_duration_milliseconds_bucket{le="5"} 250

istio_request_duration_milliseconds_bucket{le="10"} 380

istio_request_duration_milliseconds_bucket{le="25"} 450

istio_request_duration_milliseconds_bucket{le="50"} 490

istio_request_duration_milliseconds_bucket{le="100"} 498

istio_request_duration_milliseconds_bucket{le="+Inf"} 500

**istio_request_bytes / istio_response_bytes** (Histogram)

요청/응답 크기 분포를 추적합니다.

TCP 메트릭

istio_tcp_sent_bytes_total # 전송된 바이트 총량

istio_tcp_received_bytes_total # 수신된 바이트 총량

istio_tcp_connections_opened_total # 열린 연결 수

istio_tcp_connections_closed_total # 닫힌 연결 수

메트릭 생성 위치: Source vs Destination

Frontend Pod Reviews Pod

[App] → [Envoy] ──────→ [Envoy] → [App]

│ │

reporter="source" reporter="destination"

(아웃바운드 측 기록) (인바운드 측 기록)

양쪽 Envoy 모두 메트릭을 생성하지만, reporter 라벨로 구분됩니다. 일반적으로 "source" 리포터를 사용하면 클라이언트 관점, "destination"을 사용하면 서버 관점의 메트릭을 얻습니다.

Telemetry API v2

아키텍처 진화

Istio 1.x (Mixer 기반):

App → Envoy → Mixer → Prometheus/Zipkin

(별도 서비스, 높은 레이턴시)

Istio 1.12+ (Telemetry API v2):

App → Envoy (내장 Stats/Trace 필터) → Prometheus/Zipkin

(프록시 내부 처리, 낮은 레이턴시)

Mixer가 제거된 후, 메트릭 생성은 Envoy 프록시 내부에서 직접 수행됩니다.

Telemetry 리소스

apiVersion: telemetry.istio.io/v1alpha1

kind: Telemetry

metadata:

name: mesh-default

namespace: istio-system # 메시 전체 적용

spec:

메트릭 설정

metrics:

- providers:

- name: prometheus

overrides:

- match:

metric: REQUEST_COUNT

mode: CLIENT_AND_SERVER

tagOverrides:

request_host:

operation: UPSERT

value: 'request.host'

트레이싱 설정

tracing:

- providers:

- name: zipkin

randomSamplingPercentage: 1.0

customTags:

environment:

literal:

value: 'production'

액세스 로깅 설정

accessLogging:

- providers:

- name: envoy

filter:

expression: 'response.code >= 400'

메트릭 커스터마이징

특정 메트릭 비활성화

spec:

metrics:

- providers:

- name: prometheus

overrides:

- match:

metric: REQUEST_BYTES

disabled: true

커스텀 태그 추가

overrides:

- match:

metric: REQUEST_COUNT

tagOverrides:

custom_tag:

operation: UPSERT

value: "request.headers['x-custom-tag']"

분산 트레이싱

트레이스 전파 메커니즘

Envoy가 자동으로 수행하는 것:

├── 인바운드 요청에서 트레이스 헤더 추출

├── 스팬(span) 생성 및 타이밍 기록

├── 스팬을 트레이스 수집기에 전송

└── 아웃바운드 요청에 트레이스 헤더 추가

애플리케이션이 해야 하는 것:

└── 인바운드 요청의 트레이스 헤더를 아웃바운드 요청에 복사

(이것을 하지 않으면 트레이스가 끊어짐)

지원하는 트레이스 헤더

**B3 헤더 (Zipkin):**

x-b3-traceid: 128비트 트레이스 ID

x-b3-spanid: 64비트 스팬 ID

x-b3-parentspanid: 64비트 부모 스팬 ID

x-b3-sampled: 샘플링 여부 (0 또는 1)

x-b3-flags: 디버그 플래그

**W3C TraceContext:**

traceparent: 00-TRACE_ID-SPAN_ID-FLAGS

tracestate: vendor-specific key=value pairs

**Envoy 내부 헤더:**

x-request-id: Envoy가 생성하는 UUID (트레이스와 연결)

스팬 생성 상세

Frontend → Reviews → Ratings 호출 시:

Frontend Envoy (아웃바운드):

Span: "reviews.prod.svc.cluster.local:9080/*"

├── Start: 요청 전송 시작

├── End: 응답 수신 완료

├── Tags: upstream_cluster, http.method, http.status_code

└── Parent: 인바운드 스팬

Reviews Envoy (인바운드):

Span: "reviews.prod.svc.cluster.local:9080/*"

├── Start: 요청 수신

├── End: 응답 전송

└── Tags: downstream_cluster, peer.address

Reviews Envoy (아웃바운드):

Span: "ratings.prod.svc.cluster.local:9080/*"

├── Start: 요청 전송 시작

├── End: 응답 수신 완료

└── Parent: 인바운드 스팬

트레이스 샘플링

MeshConfig에서 설정

meshConfig:

defaultConfig:

tracing:

sampling: 1.0 # 1% (기본값)

sampling: 100.0 # 100% (디버깅용)

또는 Telemetry API로 설정

apiVersion: telemetry.istio.io/v1alpha1

kind: Telemetry

metadata:

name: tracing

spec:

tracing:

- randomSamplingPercentage: 1.0

샘플링 결정은 첫 번째 Envoy에서 이루어지고, x-b3-sampled 헤더를 통해 전파됩니다. 이후 Envoy들은 이 결정을 따릅니다.

트레이스 수집기 통합

Zipkin 통합

meshConfig:

defaultConfig:

tracing:

zipkin:

address: zipkin.istio-system:9411

Jaeger 통합 (Zipkin 호환 엔드포인트 사용)

meshConfig:

defaultConfig:

tracing:

zipkin:

address: jaeger-collector.observability:9411

OpenTelemetry Collector 통합

meshConfig:

extensionProviders:

- name: otel

opentelemetry:

service: otel-collector.observability.svc.cluster.local

port: 4317

액세스 로깅

Envoy 액세스 로그 형식

기본 로그 형식:

[2026-03-20T10:30:00.000Z] "GET /api/reviews HTTP/1.1" 200 - via_upstream

- "-" 0 1234 5 3

"-" "curl/7.68.0" "abc-123-def"

"reviews.prod.svc.cluster.local:9080"

inbound|9080||reviews.prod.svc.cluster.local

10.244.1.5:9080 10.244.0.3:48292

outbound_.9080_.v1_.reviews.prod.svc.cluster.local default

로그 필드 설명

[타임스탬프] "메서드 경로 프로토콜" 상태코드 응답플래그

- "-" 요청바이트 응답바이트 처리시간(ms) 업스트림시간(ms)

"-" "User-Agent" "Request-ID"

"업스트림 호스트"

라우트 이름

다운스트림 주소 업스트림 주소

클러스터 이름 네임스페이스

응답 플래그 (Response Flags)

| 플래그 | 의미 |

| ------ | ------------------------------------- |

| - | 정상 응답 |

| UH | 업스트림 건강하지 않음 (모두 ejected) |

| UF | 업스트림 연결 실패 |

| UO | 업스트림 오버플로우 (서킷 브레이커) |

| NR | 라우트 없음 |

| URX | 리트라이 한도 초과 |

| DC | 다운스트림 연결 종료 |

| LH | 로컬 헬스 체크 실패 |

| UT | 업스트림 타임아웃 |

| RL | 레이트 리밋 |

| UAEX | 외부 인가 거부 |

| RLSE | 레이트 리밋 서비스 에러 |

조건부 로깅

Telemetry API를 사용한 조건부 액세스 로깅:

apiVersion: telemetry.istio.io/v1alpha1

kind: Telemetry

metadata:

name: access-log-errors

namespace: production

spec:

accessLogging:

- providers:

- name: envoy

filter:

expression: 'response.code >= 400 || connection.mtls == false'

CEL(Common Expression Language) 표현식을 사용하여 로깅 조건을 세밀하게 제어할 수 있습니다.

Kiali: 서비스 메시 시각화

Kiali 아키텍처

Kiali 데이터 소스:

├── Prometheus → 메트릭 기반 서비스 그래프

├── Kubernetes API → 워크로드, 서비스 정보

├── Istio Config API → VirtualService, DestinationRule 등

└── Jaeger/Tempo → 분산 트레이스 (선택사항)

Kiali가 제공하는 정보

1. 서비스 그래프 (Topology)

├── 서비스 간 트래픽 흐름

├── 요청 성공/실패 비율

├── 초당 요청 수

└── 응답 시간

2. 워크로드 건강 상태

├── 에러율 기반 건강 점수

├── 인바운드/아웃바운드 메트릭

└── Pod 상태

3. Istio 구성 검증

├── VirtualService 유효성

├── DestinationRule 충돌 감지

├── 참조 무결성 (존재하지 않는 host 등)

└── 베스트 프랙티스 위반

4. 트래픽 분석

├── 시간별 트래픽 추이

├── 에러 패턴 식별

└── 레이턴시 분포

Prometheus 통합

메트릭 수집 구성

Istio는 Prometheus의 서비스 디스커버리를 활용합니다:

Prometheus scrape 구성

scrape_configs:

- job_name: 'envoy-stats'

metrics_path: /stats/prometheus

kubernetes_sd_configs:

- role: pod

relabel_configs:

- source_labels: [__meta_kubernetes_pod_container_name]

action: keep

regex: istio-proxy

- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_port]

action: replace

target_label: __address__

regex: (.+)

replacement: 'target:15090'

각 Envoy 프록시는 포트 15090에서 Prometheus 메트릭을 노출합니다.

유용한 PromQL 쿼리

서비스별 요청 성공률 (최근 5분)

sum(rate(istio_requests_total{

response_code!~"5.*",

reporter="destination"

}[5m])) by (destination_service_name)

/

sum(rate(istio_requests_total{

reporter="destination"

}[5m])) by (destination_service_name)

P99 레이턴시

histogram_quantile(0.99,

sum(rate(istio_request_duration_milliseconds_bucket{

reporter="source"

}[5m])) by (le, destination_service_name)

)

서비스별 초당 요청 수

sum(rate(istio_requests_total{

reporter="destination"

}[5m])) by (destination_service_name)

Grafana 대시보드

Istio 표준 대시보드

Istio는 다음 Grafana 대시보드를 제공합니다:

1. Mesh Dashboard

└── 메시 전체 요약 (서비스 수, 에러율, 트래픽)

2. Service Dashboard

└── 서비스별 상세 (인바운드/아웃바운드, 에러율, 레이턴시)

3. Workload Dashboard

└── 워크로드별 상세 (파드 단위 메트릭)

4. Control Plane Dashboard

└── istiod 성능 (xDS 푸시 수, 응답 시간, 에러)

5. Performance Dashboard

└── Envoy 리소스 사용량 (메모리, CPU, 연결 수)

Jaeger/Zipkin/Tempo 통합

분산 트레이싱 백엔드

지원하는 트레이싱 백엔드:

Zipkin

├── 경량, 간단한 설치

├── 인메모리 또는 Cassandra/Elasticsearch 저장

└── Istio 기본 지원

Jaeger

├── Zipkin 호환 API

├── 다양한 스토리지 백엔드 지원

├── Spark 기반 분석

└── 프로덕션 권장

Tempo (Grafana)

├── 오브젝트 스토리지 기반 (S3, GCS)

├── 높은 확장성

├── Grafana와 네이티브 통합

└── 비용 효율적

트레이스 데이터 흐름

[1] 요청이 메시 진입

[2] 첫 번째 Envoy가 트레이스 ID 생성

(기존 헤더가 없는 경우)

[3] 각 Envoy가 스팬 생성 및 수집기에 전송

├── Zipkin: HTTP POST /api/v2/spans

├── Jaeger: UDP/gRPC

└── OTLP: gRPC (OpenTelemetry)

[4] 수집기가 스팬을 트레이스로 조합

[5] UI에서 트레이스 조회

디버깅 팁

메트릭 확인

특정 파드의 Envoy 메트릭 직접 확인

kubectl exec PODNAME -c istio-proxy -- \

curl -s localhost:15090/stats/prometheus | grep istio_requests

Envoy 관리 API로 통계 확인

kubectl exec PODNAME -c istio-proxy -- \

curl -s localhost:15000/stats | grep -E "^cluster\."

Envoy 서버 정보

kubectl exec PODNAME -c istio-proxy -- \

curl -s localhost:15000/server_info

트레이싱 확인

트레이스 헤더 전파 확인

kubectl exec PODNAME -c istio-proxy -- \

curl -s localhost:15000/config_dump | python3 -c "

config = json.load(sys.stdin)

for c in config.get('configs', []):

if 'tracing' in str(c):

print(json.dumps(c, indent=2))

"

액세스 로그 확인

실시간 액세스 로그 확인

kubectl logs PODNAME -c istio-proxy -f | grep -v healthz

에러 응답만 필터링

kubectl logs PODNAME -c istio-proxy | grep -E '"[45][0-9]{2}"'

마무리

Istio의 관찰성은 Envoy 프록시의 풍부한 텔레메트리 기능 위에 구축됩니다. 핵심 포인트를 정리하면:

1. **메트릭**: Envoy의 Stats 필터가 istio_requests_total 등 표준 메트릭을 생성하고, Prometheus가 수집

2. **트레이싱**: Envoy가 자동으로 스팬을 생성하지만, 애플리케이션이 트레이스 헤더를 전파해야 end-to-end 트레이싱이 가능

3. **로깅**: Envoy 액세스 로그가 모든 요청/응답을 기록하며, Telemetry API로 조건부 로깅 가능

4. **시각화**: Kiali가 Prometheus 메트릭을 기반으로 서비스 그래프를 생성

Istio Internals 시리즈를 통해 컨트롤 플레인, 트래픽 관리, 보안, Ambient Mesh, 관찰성의 내부 동작을 살펴보았습니다. 이러한 내부 이해가 실무에서 서비스 메시를 효과적으로 운영하는 데 도움이 되길 바랍니다.

현재 단락 (1/340)

관찰성(Observability)은 서비스 메시의 핵심 가치 중 하나입니다. Istio는 애플리케이션 코드 수정 없이 메트릭, 분산 트레이싱, 액세스 로깅을 자동으로 생성합니다.

작성 글자: 0원문 글자: 8,894작성 단락: 0/340