Search
Duplicate
📌

Istio overview: Observability

Category
as S/W 엔지니어
Tags
Service Mesh
Istio
Observability
OpenTelemetry
Prometheus
Created time
2024/05/29

Introduction

대표적 Service Mesh 제품인 Istio에 대한 overview로 Kubernetes를 배경으로 설명한다.
Istio overview: Architecture, Traffic Management 에 이어 Observability feature에 대해 다룬다(이후 Istio overview: Security, Istio overview: Extensibility, Etc. 로 이어 진다).

Summary

Istio는 Observability의 주요 signal인 MLT(Metrics, Logs, Traces) 모두를 지원한다.
Istio는 Logs와 Traces에 대해서 OpenTelemetry를 지원하고, Metrics는 Prometheus만을 지원한다.
Metrics, Logs와는 달리 Traces는 application 의존성이 존재하여, application에서 trace propagation을 위해 ingress request의 trace header를 egress request header에 넣어야 한다.

Overview

Observability 데이터(signal)는 일반적으로 metrics, logs, traces으로 나뉘는데, Service Mesh는 app에 대한 이들 데이터 모두를 수집하여 각 signal 별 backend로 전한다. 수집은 app과 별개의 process로 동작하는 이상, app이 노출하는 endpoint 수준에서 이루어진다.
위 그림은 Istio component 종류 별 수집 대상 Observability signal 및 각 signal backend로의 전달 방법을 나타낸다. Metrics는 Prometheus의 수집 방법(scraping; PULL 방식) 그대로를 사용하고, traces는 Istio가 직접 trace backend로 전달하며, Log는 stdout으로 보내어 이후 Fluent-bit 등이 log backend로 보내는 것이 일반적이다.

Metrics

Metrics는 시스템, 애플리케이션 및 인프라의 성능, 상태 및 동작을 모니터링하고 이해하기 위해 수집되고 사용되는 정량적 데이터로, Istio는 4개의 golden signal(Latency, Traffic, Errors, Saturation) 모두를 지원한다.
Metrics에 대응하는 Istio의 signal backend는 Prometheus로서, logs와 traces와는 달리 OpenTelemetry 지원이 없다. OpenTelemetry 환경에서 조차 일반적으로 metric backend이 사용됨을 감안하면 이는 큰 문제가 아니나, Traces와 Logs와의 연계 분석을 위한 Exemplars 지원이 없다는 점은 상당히 아쉬운 점이다(Metrics, Logs, Traces 간 상호연관 참고).
Istio/Envoy의 Exemplars 지원에 관하여
Prometheus뿐 아니라 Prometheus metric format에서 출발한 open 표준인 OpenMetrics 역시 Exemplars를 지원한다.
Envoy의 이에 대한 지원의 경우 아래와 같이 오래 전에 요청이 있었는데, 24.05.29 기준으로 며칠 전에야 이를 구현하겠다는 contributer가 나타난 상황이다.
22621
issues
아래는 이들 4개 signal 각각에 대한 Istio 표준 목록 중 대표적인 metrics이다.
istio_request_duration_milliseconds: Latency에 해당하는 metric으로, 응답 지연을 뜻한다.
istio_requests_total: Traffic 및 Errors에 해당하는 metric으로, RPS(request per second) 및 response_code label을 통해 Errors 산출이 가능하다.
istio_tcp_connections_opened_total: Saturation에 해당하는 metric. 열려있는 connection 개수를 의미하여 클 수록 부하를 많이 받고 있음을 의미한다.

Logs

Istio의 access log는 무엇보다 pod 수준에서 남긴다는데 의미가 있는데, security 및 compliance를 위한 주요 audit 장치가 될 뿐 아니라, 이를 활용함으로 application 내 log의 상당 부분을 차지하는 request / response log code를 제거 가능하기 때문이다.
또한, OpenTelemetry를 지원하여 이 경우 log 전달은 위 그림 상의 stdout 이 아닌 OTLP / OpenTelemetry Collector을 통하게 될 것이다(OTLP Collector 참고).
위 Envoy 문서에서 보이듯이 Istio는 JSON 형식 지원 뿐 아니라 logging 항목 지정이 가능하여, 이들 항목에는 일반적인 reverse proxy의 access log의 것 이외에도 상당히 다양하다. 아래는 application log 대체 시 관심을 가질 만한 추가 항목의 예이다.
Request / response body logging에 관하여
Request / response body는 EnvoyFilter resource를 통한 Lua script나 WebAssembly를 통해서만 가능하다. 이는 body의 적지 않은 크기를 고려한다면 이해 못할 것만은 아니다.
%REQ({header name})% : {header name} 의 request header를 넣을 수 있다. 다만 header 각각을 지정해야 한다. 참고로, 다수의 custom header가 trace용으로 사용된다면, W3C 표준의 baggage header를 사용하여 단일 header 내에 다수의 항목을 넣는 것도 고려해볼만 하다.
%RESP({header name})%: REQ가 request header를 의미한다면 RESP는 response header에 해당한다.
%DURATION% : 처리 지연 시간으로, request 인입 시간부터 response의 최종 byte가 나간 시간까지의 간격이다.
%RESPONSE_FLAGS% / %RESPONSE_FLAGS_LONG%: response의 상세 정보로 무려 28개나 있다. 오류 발생 시 원인 파악에 유용하다.
아래는 Istio의 기본 format이다(각 항목에 대한 자세한 설명은 상기 Istio와 Envoy의 문서를 참고한다).
[%START_TIME%] \"%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%\" %RESPONSE_CODE% %RESPONSE_FLAGS% %RESPONSE_CODE_DETAILS% %CONNECTION_TERMINATION_DETAILS% \"%UPSTREAM_TRANSPORT_FAILURE_REASON%\" %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% \"%REQ(X-FORWARDED-FOR)%\" \"%REQ(USER-AGENT)%\" \"%REQ(X-REQUEST-ID)%\" \"%REQ(:AUTHORITY)%\" \"%UPSTREAM_HOST%\" %UPSTREAM_CLUSTER% %UPSTREAM_LOCAL_ADDRESS% %DOWNSTREAM_LOCAL_ADDRESS% %DOWNSTREAM_REMOTE_ADDRESS% %REQUESTED_SERVER_NAME% %ROUTE_NAME%\n
YAML
복사

Distributed tracing

Distributed tracing은 특정 request에 관계된 여러 microservice의 상태를 단일 뷰로 상호 관계지어 확인 가능하게 한다. 아래 그림은 Jaeger를 trace backend로 하여 Istio 기반의 distributed tracing을 구현한 모습으로, 3개의 microservices(gateway, dockebi, dockebi-storage )에 대한 duration 및 상호 관계를 보여주고 있다.
Grafana에서의 Distributed trace view
유의할 점으로 distributed tracing은 타 Istio feature와는 달리 app에 대한 의존성을 가진다. App 내에서 trace 전파 로직을 구현해야 하는데 이는 Istio를 포함한 Service mesh가 out of process 모델이란 구조적 한계에 기인한다. 다만 trace 전파 로직은 단순하여 ingress request의 trace header를 egress request header에 넣는 것 뿐이다.
Istio가 기본으로 채택하는 분산 추적 프로토콜은 B3 propagation이지만 OpenTelemetry가 채택한 형식, 즉 W3C Trace Context 역시 지원한다. 자세한 사항은Istio Distributed Tracing w/ OpenTelemetry 을 참고한다.
Istio overview: Security 으로 이어집니다.

References

본 글 작성에 주로 참조한 문서이다.