LabHub
배우기 러닝패스 코스

Istio Service Mesh

Metrics, Access Logs and Traces — What the Proxy Gives You Free, and What It Does Not

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

한 줄 요약

메시는 요청이 프록시를 지나는 김에 메트릭·액세스 로그·스팬을 만들어 준다. 다만 트레이스만은 애플리케이션이 헤더를 넘겨주지 않으면 끊긴다.

Concept map: 메트릭·액세스 로그·스팬 · 정의가 서비스마다 다르다. · 계측되지 않은 서비스가 남는다. · 모든 서비스에서 같아진다.

왜 이게 필요했나

관측성을 애플리케이션에서 챙기면 두 가지가 어긋난다. 첫째, 정의가 서비스마다 다르다. 어떤 팀은 5xx 만 오류로 세고 어떤 팀은 4xx 도 센다. 어떤 팀은 클라이언트 기준으로, 어떤 팀은 서버 기준으로 지연을 잰다. 대시보드를 나란히 놓아도 비교가 안 된다. 둘째, 계측되지 않은 서비스가 남는다. 급하게 만든 내부 도구, 인수한 팀의 레거시, 외주로 받은 컴포넌트에는 계측이 없고 그게 늘 장애의 사각지대다.

메시는 이 문제를 "요청이 어차피 프록시를 지나가니 거기서 재자"로 푼다. 표준 메트릭의 이름과 라벨이 모든 서비스에서 같아진다. 이 균일성이 계측을 새로 붙이는 것보다 훨씬 큰 가치다.

어떻게 동작하나

메트릭. 각 사이드카는 포트 15090 에서 프로메테우스 형식으로 통계를 노출한다. 핵심은 세 가지다.

메트릭 종류 쓰는 곳
istio_requests_total 카운터 요청 수, 오류율
istio_request_duration_milliseconds 히스토그램 p50/p99 지연
istio_request_bytes / istio_response_bytes 히스토그램 페이로드 크기

라벨 중에 특히 알아 둘 것이 셋이다. reportersource(보낸 쪽 프록시)와 destination(받은 쪽 프록시)으로 나뉘는데, 같은 요청이 양쪽에서 각각 기록되므로 둘을 합치면 두 배로 센다. response_flags 는 액세스 로그의 플래그와 같은 값이라 503 의 성격을 메트릭만으로도 구분할 수 있다. connection_security_policymutual_tls 또는 none 이고, STRICT 전환의 완료 기준이 바로 이 라벨이 none 인 요청 0건이다.

한 가지 함정은 카디널리티다. 라벨에 요청 경로나 사용자 ID 같은 값을 넣으면 시계열이 폭발한다. 커스텀 태그는 값의 종류가 유한한 것만 넣어야 한다.

아키텍처가 바뀐 역사도 알아 둘 만하다. 예전에는 Mixer 라는 별도 서비스가 요청마다 호출되어 메트릭을 모았고, 그게 지연과 장애의 원인이었다. 지금은 프록시 내부의 필터가 직접 만든다(Telemetry API v2). 그래서 관측성 때문에 요청 경로에 홉이 추가되는 일은 더 이상 없다.

액세스 로그. 프록시가 요청마다 한 줄을 남긴다. 사람이 읽어야 할 부분은 응답 코드와 그 옆의 플래그다.

플래그 의미 첫 번째로 볼 것
UH 건강한 업스트림 없음 subset 라벨과 파드 라벨
UF 업스트림 연결 실패 한쪽만 STRICT 인 mTLS 불일치
UO 연결 풀 초과 서킷 브레이커 한도
NR 라우트 없음 catch-all 라우트 존재 여부
URX 재시도 소진 근본 원인은 다른 플래그와 함께
UAEX 외부 인가 거부 CUSTOM 정책과 인가기 상태

전량 로깅은 비싸다. Telemetry 리소스의 필터로 response.code >= 400 같은 조건을 걸어 실패만 남기는 구성이 흔하다.

분산 트레이싱. 여기가 "공짜가 아닌" 부분이다. 프록시는 스팬을 만들고 타이밍을 재고 수집기로 보내는 일까지 해 준다. 그런데 인바운드 요청의 트레이스 헤더(B3 계열 또는 W3C traceparent)를 아웃바운드 요청에 복사하는 일은 애플리케이션이 해야 한다. 이걸 안 하면 서비스마다 별개의 트레이스가 만들어져 호출 사슬이 끊긴다. "메시를 깔았는데 트레이스가 한 홉짜리로만 보인다"의 답은 거의 언제나 이것이다.

샘플링 기본값은 1% 다. 첫 프록시가 샘플링 여부를 정하고 헤더로 전파하므로 뒤쪽은 그 결정을 따른다. 디버깅할 때만 올리고 상시로 100% 를 두지는 않는다.

시각화. Kiali 는 프로메테우스 메트릭으로 서비스 그래프를 그리고, 쿠버네티스 API 와 Istio 설정을 읽어 참조 무결성까지 검사한다. 즉 Kiali 의 설정 검증은 istioctl analyze 와 같은 종류의 일을 화면으로 보여 주는 것이다.

현장에서 만나는 모습

첫째, source 와 destination 을 섞어 세는 대시보드. 요청 수가 정확히 두 배로 나오면 십중팔구 reporter 필터를 빠뜨린 것이다. 클라이언트 관점이면 source, 서버 관점이면 destination 하나로 고정해야 한다.

둘째, 메시 메트릭이 앱 메트릭을 대체하지는 못한다. 프록시는 "요청이 200 을 냈다"까지만 안다. 응답 본문이 틀렸는지, 주문이 실제로 저장됐는지는 모른다. 메시 관측성은 인프라 계층의 균일한 바닥이고, 도메인 지표는 여전히 애플리케이션이 내야 한다.

셋째, 사이드카 없는 경로는 보이지 않는다. 메시 밖 크론이나 주입되지 않은 네임스페이스의 트래픽은 그래프에 아예 나타나지 않는다. 그래프가 깨끗하다는 것이 트래픽이 없다는 뜻은 아니다.

다음 실습에서 할 것

먼저 정직하게 말해 둔다. 이 실습 환경에는 실제로 트래픽을 나르는 Envoy 가 없다. 사이드카가 붙은 파드가 Running 이 되어도 요청은 흐르지 않고, 15090 을 긁을 수도 15000 의 관리 API 를 두드릴 수도 없다. 그래서 메트릭 값이나 트레이스 그림을 만들어 내는 실습은 만들지 않았다.

대신 바로 뒤 실습에서 신호를 설계하는 쪽을 다룬다. 메시 전체에 기본 액세스 로그를 깔고, 응답 코드로 실패만 남기는 필터를 걸고, 워크로드 하나에 샘플링 비율과 리터럴 태그를 붙이고, 표준 메트릭 하나를 끈다. 그다음 카디널리티를 폭발시키는 태그를 배포 전에 거르는 검사기를 만들고, 셀렉터 없는 Telemetry 가 한 네임스페이스에 둘 있으면 istioctl analyze 가 오류로 잡는 것까지 본다. 값이 흐르지 않아도 설정이 유효한가와 범위가 올바른가는 그대로 검증되고, 현장에서 사람을 잡는 자리도 대개 그 둘이다.