PCA — Prometheus Certified Associate
Writing Eight PromQL Queries
한국어 원문으로 표시합니다.
목표
PromQL 쿼리 여덟 개를 파일로 작성하면서, rate 의 순서·le 보존·최소 트래픽 게이트 같은 실전 규율을 손에 붙입니다. 시험 비중이 28% 로 가장 큰 도메인이고, 여기서 나오는 실수는 대부분 에러 없이 틀린 답을 돌려주는 종류입니다.
왜 중요한가
PromQL 이 어려운 이유는 문법이 아니라 틀려도 조용하다는 점입니다. sum 을 rate 바깥에 두지 않으면 값이 낮게 나오고, by (le) 를 빼먹으면 분위수가 아니라 아무 숫자가 나오고, 최소 트래픽 게이트가 없으면 새벽 저트래픽 구간마다 유령 알림이 납니다. 셋 다 대시보드에서는 정상으로 보입니다. 그래서 쿼리는 "동작하는가"가 아니라 "어떤 조건에서 거짓말하는가"를 기준으로 검토해야 합니다. 이 실습은 그 검토 항목을 쿼리 하나하나에 심어 둡니다.
단계
/root/pca-promql/01-request-rate.promql에 라우트별 초당 요청률을 씁니다. 메트릭은http_requests_total, 윈도는[5m], 집계 레이블은route입니다./root/pca-promql/02-error-ratio.promql에 라우트별 5xx 에러율을 씁니다. 분자는status_class="5xx"로 필터한rate, 분모는 전체rate, 양쪽 모두by (route)로 집계해 나눕니다./root/pca-promql/03-p99-route.promql에 라우트별 p99 지연을 씁니다.histogram_quantile(0.99, ...)안에서http_request_duration_seconds_bucket에[5m]rate 를 걸고by (le, route)로 집계합니다./root/pca-promql/04-cardinality-topk.promql에 시계열이 가장 많은 메트릭 상위 10개를 뽑는 쿼리를 씁니다.topk(10, ...)안에서count by (__name__)을 쓰고, 대상 셀렉터는{__name__=~".+"}입니다./root/pca-promql/05-disk-predict.promql에 디스크 소진 예측을 씁니다.predict_linear(node_filesystem_avail_bytes{mountpoint="/data"}[6h], 4 * 3600) < 0에, 현재 여유 비율이< 0.2라는 조건(node_filesystem_avail_bytes를node_filesystem_size_bytes로 나눈 값)을and로 묶습니다./root/pca-promql/06-nan-guard.promql에 저트래픽 가드가 붙은 에러율 알림 표현식을 씁니다. 2단계와 같은 비율이> 0.01이고, 동시에sum(rate(http_requests_total[5m])) by (route) > 1을and로 묶습니다./root/pca-promql/07-scrape-health.promql에 스크레이프 건강 확인을 씁니다.up{job="checkout-api"} == 0과absent(up{job="checkout-api"})를or로 묶습니다./root/pca-promql/08-burn-rate.promql에 다중 윈도 번 레이트를 씁니다.job:slo_errors:ratio_rate1h{job="checkout-api"} > (14.4 * 0.001),job:slo_errors:ratio_rate5m{job="checkout-api"} > (14.4 * 0.001),job:http_requests:rate5m{job="checkout-api"} > 1세 항을and로 묶습니다.
참고
- 채점은 공백과
#주석을 무시하고 문자열을 대조합니다. 여러 줄로 예쁘게 써도 되지만 메트릭 이름·레이블·윈도·숫자는 지시한 그대로 쓰세요. - 흔한 실수 1:
rate(sum(...))순서. 채점이 이 형태를 명시적으로 거부합니다. - 흔한 실수 2: 3단계에서
by (route)만 쓰고le를 빠뜨리는 것. - 흔한 실수 3: 2단계에서 분자에만
by (route)를 붙이는 것. 나눗셈은 양쪽 레이블 셋이 매칭되어야 합니다.
라우트별 초당 요청률
/root/pca-promql/01-request-rate.promql 에 라우트별 초당 요청률을 씁니다. 메트릭은 http_requests_total, 윈도는 [5m], 집계 레이블은 route 입니다.
카운터는 그대로 그리면 우상향 직선입니다. rate 를 먼저 적용하고 그 결과를 집계하세요. 반대로 하면 파드 재시작 리셋이 보정되지 않습니다.
라우트별 5xx 에러율
/root/pca-promql/02-error-ratio.promql 에 라우트별 5xx 에러율을 씁니다. 분자는 status_class="5xx" 로 필터한 rate, 분모는 전체 rate, 양쪽 모두 by (route) 로 집계해 나눕니다.
비율이므로 분자와 분모가 각각 필요합니다. 두 벡터를 나누려면 레이블 셋이 매칭되어야 하므로 양쪽 모두 같은 차원으로 집계해야 합니다.
라우트별 p99 지연
/root/pca-promql/03-p99-route.promql 에 라우트별 p99 지연을 씁니다. histogram_quantile(0.99, ...) 안에서 http_request_duration_seconds_bucket 에 [5m] rate 를 걸고 by (le, route) 로 집계합니다.
버킷은 카운터라 rate 를 먼저 겁니다. 집계에서 le 를 잃으면 버킷이 뭉개져 에러 없이 무의미한 숫자가 나옵니다. 분위수를 평균 내는 형태는 절대 쓰지 마세요.
카디널리티 상위 10개 진단
/root/pca-promql/04-cardinality-topk.promql 에 시계열이 가장 많은 메트릭 상위 10개를 뽑는 쿼리를 씁니다. topk(10, ...) 안에서 count by (__name__) 을 쓰고, 대상 셀렉터는 {__name__=~".+"} 입니다.
메트릭 이름별로 시계열이 몇 개인지 세려면 count 를 name 으로 묶습니다. 모든 메트릭을 고르는 셀렉터는 이름 레이블에 정규식을 거는 방식입니다. topk 로 상위만 남깁니다.
디스크 소진 예측
/root/pca-promql/05-disk-predict.promql 에 디스크 소진 예측을 씁니다. predict_linear(node_filesystem_avail_bytes{mountpoint="/data"}[6h], 4 * 3600) < 0 에, 현재 여유 비율이 < 0.2 라는 조건(node_filesystem_avail_bytes 를 node_filesystem_size_bytes 로 나눈 값)을 and 로 묶습니다.
predict_linear 는 게이지의 최근 추세를 선형 회귀로 외삽합니다. 두 번째 인자는 초 단위입니다. 추세만 보면 여유가 충분한 디스크에서도 발화할 수 있으니 현재 여유 비율 조건을 AND 로 함께 겁니다.
저트래픽 유령 알림 막기
/root/pca-promql/06-nan-guard.promql 에 저트래픽 가드가 붙은 에러율 알림 표현식을 씁니다. 2단계와 같은 비율이 > 0.01 이고, 동시에 sum(rate(http_requests_total[5m])) by (route) > 1 을 and 로 묶습니다.
5분에 요청이 3건 들어오는 시간대에 1건이 실패하면 에러율은 33% 입니다. 비율 조건만으로는 새벽마다 알림이 납니다. 최소 트래픽 조건을 AND 로 붙이세요. 요청이 아예 0 이면 비율은 NaN 이 되어 조건이 조용히 사라집니다.
스크레이프 건강 확인
/root/pca-promql/07-scrape-health.promql 에 스크레이프 건강 확인을 씁니다. up{job="checkout-api"} == 0 과 absent(up{job="checkout-api"}) 를 or 로 묶습니다.
up 이 0 인 상황과 up 시계열 자체가 사라진 상황은 다릅니다. 후자는 값 비교로는 절대 잡히지 않습니다. 시계열이 없을 때 1 을 돌려주는 함수를 OR 로 묶으세요.
다중 윈도 번 레이트
/root/pca-promql/08-burn-rate.promql 에 다중 윈도 번 레이트를 씁니다. job:slo_errors:ratio_rate1h{job="checkout-api"} > (14.4 * 0.001), job:slo_errors:ratio_rate5m{job="checkout-api"} > (14.4 * 0.001), job:http_requests:rate5m{job="checkout-api"} > 1 세 항을 and 로 묶습니다.
긴 창은 '이 정도로 태우고 있는가'를, 짧은 창은 '지금도 진행 중인가'를 판정합니다. 짧은 창이 없으면 사고가 끝난 뒤에도 긴 창 길이만큼 알림이 남습니다. 여기에 최소 트래픽 게이트까지 세 항을 AND 로 묶습니다. 레코딩 룰 시계열 이름을 그대로 참조하세요.