記録ルールとアラートルール、そしてテスト
한국어 원문으로 표시합니다.
목표
레코딩 룰을 2단 계층으로 설계하고, 그 위에 알림 룰을 얹고, 기대값을 계산한 단위 테스트까지 작성합니다. 마지막으로 같은 내용을 Prometheus Operator 가 읽는 CR 형태로 옮깁니다.
왜 중요한가
레코딩 룰은 "쿼리를 빠르게 하는 캐시"가 아니라 계산 시점을 옮기는 설계 결정입니다. 쿼리 시점의 부하가 평가 시점으로 옮겨 가고, 그 대가로 새 시계열이 영구히 생깁니다. 그래서 만들기 전에 개수를 곱해 봐야 합니다. 라우트 120개에 윈도 5종이면 규칙 하나가 600 시계열이고, 규칙 50개면 3만 개입니다. 계층을 나누는 이유도 같습니다. 계층 1이 원본을 한 번 스캔해 두면 계층 2와 알림 룰은 그 결과만 읽으므로, 원본 스캔이 규칙 수만큼 반복되지 않습니다. 그리고 룰은 프로덕션 코드입니다. 프로덕션 코드는 테스트 없이 배포하지 않습니다.
단계
/root/pca-rules/recording.yml을 만들고groups아래 첫 그룹을name: http_sli,interval: 30s로 씁니다.- 그 그룹의
rules에 계층 1 규칙 두 개를 넣습니다.record: route:http_requests:rate5m는sum(rate(http_requests_total[5m])) by (route),record: route:http_requests_errors:rate5m는sum(rate(http_requests_total{status_class="5xx"}[5m])) by (route). - 계층 2 규칙
record: route:http_error_ratio:rate5m를 계층 1 아래에 추가합니다. 표현식은route:http_requests_errors:rate5m를route:http_requests:rate5m로 나눈 것이며, 원본http_requests_total을 다시 쓰면 안 됩니다. record: route:http_request_duration_seconds:p99_rate5m를 추가합니다. 표현식은histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket[5m])) by (le, route))입니다. 이 파일의 레코딩 룰은 총 4개가 됩니다./root/pca-rules/alerting.yml을 만들고 그룹name: http_alerts아래 알림CheckoutHighErrorRatio를 씁니다.expr은route:http_error_ratio:rate5m > 0.01,for: 5m,labels.severity: page,annotations에summary와runbook_url(http 로 시작하는 URL)./root/pca-rules/recording_test.yml에 promtool 단위 테스트를 씁니다.rule_files는recording.yml,evaluation_interval: 30s,tests[0].interval: 15s,input_series에 2xx(0+150x40)와 5xx(0+3x40) 두 시계열,promql_expr_test에expr: route:http_error_ratio:rate5m,eval_time: 8m,exp_samples의value는 3을 153으로 나눈 값(0.0196 으로 시작).- 네임스페이스
pca-rules를 만들고,/root/pca-rules/prometheusrule.yaml에 PrometheusRule 을 씁니다.apiVersion: monitoring.coreos.com/v1,kind: PrometheusRule,metadata.name: checkout-sli,metadata.namespace: pca-rules,metadata.labels.release: kube-prometheus-stack,spec.groups[0].name: checkout_sli, 그리고 그 안에record: route:http_error_ratio:rate5m와alert: CheckoutHighErrorRatio를 함께 넣습니다.
참고
expr은 한 줄로 써도 되고expr: |블록으로 여러 줄에 써도 됩니다. 채점은 공백을 무시합니다.- 6단계의 기대값은 직접 계산하세요. 15초 간격으로 2xx 가 150, 5xx 가 3씩 늘면 rate 비율은 3 / (150 + 3) 입니다.
- 흔한 실수 1: 계층 2를 계층 1보다 위에 쓰는 것. 같은 그룹은 위에서 아래로 평가됩니다.
- 흔한 실수 2: 레코딩 룰 이름에 콜론을 빼먹는 것. 콜론은 파생 시계열이라는 표시입니다.
- 흔한 실수 3: PrometheusRule 에
release레이블을 빠뜨리는 것. 오퍼레이터의 ruleSelector 가 이 레이블로 고릅니다.
룰 그룹 껍데기 만들기
/root/pca-rules/recording.yml 을 만들고 groups 아래 첫 그룹을 name: http_sli, interval: 30s 로 씁니다.
룰 파일의 최상위는 groups 리스트입니다. 각 그룹은 name 과 선택적 interval 을 가지며, interval 을 생략하면 global.evaluation_interval 이 쓰입니다. 같은 그룹의 규칙은 순서대로 평가됩니다.
계층 1 — 원본을 한 번만 스캔
그 그룹의 rules 에 계층 1 규칙 두 개를 넣습니다. record: route:http_requests:rate5m 는 sum(rate(http_requests_total[5m])) by (route), record: route:http_requests_errors:rate5m 는 sum(rate(http_requests_total{status_class="5xx"}[5m])) by (route).
record 필드에 새 시계열 이름을, expr 에 표현식을 씁니다. rate 를 sum 안쪽에 두는 순서를 지키고, 두 규칙 모두 같은 차원(route)으로 집계해야 나중에 나눌 수 있습니다.
계층 2 — 계층 1 만 참조
계층 2 규칙 record: route:http_error_ratio:rate5m 를 계층 1 아래에 추가합니다. 표현식은 route:http_requests_errors:rate5m 를 route:http_requests:rate5m 로 나눈 것이며, 원본 http_requests_total 을 다시 쓰면 안 됩니다.
비율 규칙이 원본 메트릭을 다시 스캔하면 계층을 나눈 의미가 없습니다. 앞서 만든 두 시계열 이름만 써서 나누세요. 그룹 안에서는 위에서 아래로 평가되므로 순서도 중요합니다.
p99 레코딩 룰
record: route:http_request_duration_seconds:p99_rate5m 를 추가합니다. 표현식은 histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket[5m])) by (le, route)) 입니다. 이 파일의 레코딩 룰은 총 4개가 됩니다.
이름은 수준:메트릭:연산 규약을 따릅니다. 콜론이 없는 이름은 원본 메트릭과 구분되지 않습니다. 표현식에서는 버킷에 rate 를 걸고 집계에서 le 를 반드시 남기세요.
알림 룰 파일
/root/pca-rules/alerting.yml 을 만들고 그룹 name: http_alerts 아래 알림 CheckoutHighErrorRatio 를 씁니다. expr 은 route:http_error_ratio:rate5m > 0.01, for: 5m, labels.severity: page, annotations 에 summary 와 runbook_url(http 로 시작하는 URL).
알림 룰은 record 대신 alert 필드를 씁니다. 표현식은 레코딩 룰 결과를 참조해야 매 평가마다 원본을 훑지 않습니다. for 는 조건이 연속으로 참인 시간이고 중간에 한 번이라도 거짓이면 타이머가 0 으로 돌아갑니다.
promtool 단위 테스트 파일
/root/pca-rules/recording_test.yml 에 promtool 단위 테스트를 씁니다. rule_files 는 recording.yml, evaluation_interval: 30s, tests[0].interval: 15s, input_series 에 2xx(0+150x40)와 5xx(0+3x40) 두 시계열, promql_expr_test 에 expr: route:http_error_ratio:rate5m, eval_time: 8m, exp_samples 의 value 는 3을 153으로 나눈 값(0.0196 으로 시작).
input_series 의 values 는 시작+증가x횟수 문법입니다. 15초 간격으로 2xx 가 150씩, 5xx 가 3씩 늘면 에러 비율은 3을 153으로 나눈 값입니다. 기대값을 직접 계산해 적어 두면 나중에 규칙 의미가 바뀔 때 CI 가 잡아냅니다.
PrometheusRule CR 로 옮기기
네임스페이스 pca-rules 를 만들고, /root/pca-rules/prometheusrule.yaml 에 PrometheusRule 을 씁니다. apiVersion: monitoring.coreos.com/v1, kind: PrometheusRule, metadata.name: checkout-sli, metadata.namespace: pca-rules, metadata.labels.release: kube-prometheus-stack, spec.groups[0].name: checkout_sli, 그리고 그 안에 record: route:http_error_ratio:rate5m 와 alert: CheckoutHighErrorRatio 를 함께 넣습니다.
오퍼레이터는 ruleSelector 로 CR 을 고르므로 레이블이 맞지 않으면 파일이 존재해도 무시됩니다. spec.groups 의 구조는 룰 파일과 같고, 하나의 CR 에 레코딩 룰과 알림 룰을 함께 담을 수 있습니다. CRD 가 없는 환경이므로 파일만 쓰고 네임스페이스만 실제로 만듭니다.