PCA — 프로메테우스 인증 어소시에이트 · 관측 가능성 기초 · 이론
메트릭·로그·트레이스는 서로 다른 질문에 답한다
한 줄 요약
메트릭은 언제, 얼마나에 답하고, 로그는 왜에, 트레이스는 어디에 답합니다. 셋은 서로의 상위 호환이 아니라 답할 수 있는 질문의 모양이 다른 도구입니다. 이 경계를 무시하고 메트릭에 요청 ID 를 붙이는 순간, 그것은 이미 메트릭이 아니라 압축률이 나쁜 이벤트 저장소가 됩니다.
왜 이게 필요했나
장애 대응 중에 대시보드를 엽니다. 패널이 40개 있습니다. CPU, 메모리, 스레드 수, GC 횟수, 커넥션 풀 크기, 힙 사용량, 초당 요청 수. 전부 그래프가 그려져 있습니다. 그런데 지금 알고 싶은 것은 하나입니다. "사용자가 실패를 겪고 있는가, 겪고 있다면 몇 퍼센트인가." 그 답이 40개 패널 어디에도 없습니다.
메트릭 설계의 문제는 데이터가 부족한 것이 아니라, 수집한 데이터로 답할 수 있는 질문과 답해야 하는 질문이 어긋나 있는 것입니다. 그래서 시작점은 메트릭 목록이 아니라 질문 목록입니다. 온콜이 새벽 3시에 던지는 질문 다섯 개를 먼저 적고, 그 다섯 개에 답하는 메트릭만 만듭니다.
어떻게 동작하나
| 질문 | 메트릭 | 로그 | 트레이스 |
| --- | --- | --- | --- |
| 언제부터 나빠졌는가 | 답한다 | 어렵다 | 못 한다 |
| 몇 퍼센트의 요청이 영향받았나 | 답한다 | 비싸다 | 못 한다 |
| 이 요청이 왜 실패했는가 | 못 한다 | 답한다 | 못 한다 |
| 느린 요청이 어느 서비스에서 시간을 썼나 | 못 한다 | 못 한다 | 답한다 |
메트릭이 못 하는 칸이 중요합니다. 그 칸을 메트릭으로 메우려고 레이블을 늘리는 순간 비용이 폭발합니다. 메트릭의 한계는 카디널리티가 정합니다.
그리고 시험에서 가장 자주 나오는 개념이 백분위입니다. 10,000건 중 9,900건이 50ms, 100건이 3,000ms 걸렸다고 하면 평균은 79.5ms 입니다. 실제로 79.5ms 에 응답받은 요청은 한 건도 없습니다. 더 나쁜 것은 민감도입니다. 느린 100건이 3,000ms 에서 6,000ms 로 두 배 나빠져도 평균은 79.5 에서 109.5 로 움직일 뿐이고, 30ms 상승은 어떤 알림 임계값도 넘지 않습니다.
여기서 두 가지가 따라옵니다.
첫째, p99 는 "사용자의 1%"가 아닙니다. 요청 100개 중 1개라는 뜻이므로 한 화면이 20개 API 를 부르면 그 화면이 p99 를 만날 확률은 18.2% 이고, 하루 200번 요청하는 사용자는 86.6% 확률로 하루 한 번은 최악 구간을 겪습니다.
둘째, 백분위는 합칠 수 없습니다. 서버 A 가 9,900건 전부 50ms, 서버 B 가 100건 전부 3,000ms 라면 p99 의 평균은 1,525ms, 요청 수 가중 평균은 79.5ms, 두 서버를 한 줄로 세운 진짜 p99 는 3,000ms 입니다. 세 숫자가 전부 다르고 앞의 둘은 아무 의미가 없습니다. 카운터는 더할 수 있고 백분위는 더할 수 없다 — 히스토그램이 존재하는 이유가 정확히 이것입니다.
SLI 는 측정 지표, SLO 는 그 목표값, SLA 는 법적 계약입니다. 30일 99.9% 목표라면 에러 버짓은 0.1%, 43,200분의 0.1% 인 43.2분입니다. 번 레이트는 그 예산을 태우는 속도의 배수라서, 14.4로 계속 태우면 50시간 만에 30일치 예산이 사라집니다.
현장에서 만나는 모습
저자의 7노드 홈랩(컨트롤 플레인 3 + GPU 워커 4)에는 kube-prometheus-stack 이 올라가 있고 Grafana 가 MetalLB 풀 10.0.0.200–215 안의 10.0.0.203 을 잡고 있습니다. 여기서 히스토그램 하나가 얼마나 비싼지를 계산해 보면 감이 옵니다.
http_request_duration_seconds_bucket route 120 × method 5 × le 11 × pod 40 = 264,000 시계열 여기에 _sum 과 _count: 120 × 5 × 40 × 2 = 48,000 ------------------------------------------------ 합계 약 312,000 시계열 — 메트릭 하나에서메트릭 하나가 30만 시계열을 씁니다. 시계열당 대략 8KB 로 잡으면 1,000만 시계열은 80GB 입니다. "일단 다 넣고 나중에 줄이자"가 왜 위험한지는 이 곱셈 하나로 끝납니다.
같은 클러스터에서 배운 교훈 하나를 덧붙이면 — KubeVirt 를 올렸을 때 컴포넌트 상태는 전부 AllComponentsReady 였는데 VM 은 뜨지 않았습니다. "상태가 Ready"와 "실제로 동작한다"는 다른 명제입니다. 관측 가능성은 Ready 라벨이 아니라 사용자가 겪는 증상을 재료로 삼아야 합니다.
다음 확인에서 볼 것
이 모듈은 개념 모듈이라 실습이 없습니다. 퀴즈로 세 신호의 경계와 백분위의 성질을 확인한 뒤, 다음 모듈에서 prometheus.yml 을 직접 쓰면서 "어떤 타깃이 살아남고 어떤 메트릭이 버려지는가"를 손으로 결정하게 됩니다.