CNPE — 클라우드 네이티브 플랫폼 엔지니어 (전문가) · 규칙은 저장됐는데 알림은 왜 안 올까 · 이론
발화한 알림과 도착한 알림을 분리해서 읽기
한 줄 요약
Prometheus의 firing, Alertmanager의 수신, 웹훅의 도착, 업무의 복구는 다른 증거입니다.
알림 이름이 같더라도 다른 파드의 복구를 이번 장애의 복구로 세면 안 됩니다.
왜 이게 필요했나
발급 플랫폼의 규칙을 드디어 로드했습니다. 이번에는 Prometheus가 firing을 보여 줍니다.
운영자는 '이제 알림은 정상'이라고 보고서를 닫았지만 통지 서버에는 요청이 오지 않았습니다.
Prometheus가 Alertmanager로 보내는 구성이 없었기 때문입니다. 연결을 고치자 이번에는
Alertmanager API에 알림이 생겼습니다. 그래도 웹훅에는 아무것도 오지 않았습니다.
선택된 receiver가 실제 전송 대상을 갖지 않는 빈 수신 구성이었습니다.
앞 경계에서 성공했다는 근거로 뒤 경계까지 승인하는 습관은 배포에서도, 알림에서도
똑같이 문제를 만듭니다. 이번에는 장애를 더 크게 만들거나 임계값을 낮출 필요가 없습니다.
알림이 마지막으로 확인된 위치와 처음 사라진 위치 사이를 조사하는 것이 먼저입니다.
어떻게 동작하나
규칙의 표현식이 어떤 라벨 집합에 대해 결과를 내면 그 대상의 알림이 활성 상태가 됩니다.
for를 지정했다면 조건이 평가 때마다 지속되는지 기다린 뒤 firing으로 넘어갑니다.
따라서 for: 10s는 단순히 설치 명령 뒤 10초를 잰다는 뜻이 아닙니다. 처음 유효한 평가가
언제 있었는지도 영향을 줍니다. pending과 firing의 관계는
[Prometheus 규칙 문서](https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/)를 참고하세요.
Prometheus에서 Alertmanager로의 연결과 Alertmanager에서 실제 수신자로의 통지는
별도로 설정합니다. Alertmanager는 묶음, 억제, 침묵 처리와 전송을 담당합니다.
이 구분은 [공식 알림 개요](https://prometheus.io/docs/alerting/latest/overview/)에 나옵니다.
실습에서는 외부 메신저 대신 개인 VM 안의 HTTP 웹훅을 사용해 실제 요청이 들어왔는지
확인합니다. 도구의 설정 화면이나 성공 메시지가 아니라 수신한 요청의 내용을 봅니다.
진단 순서를 질문으로 적어 보면 다음과 같습니다.
| 마지막으로 확인한 것 | 아직 없는 것 | 우선 조사할 경계 |
| --- | --- | --- |
| 규칙이 저장됨 | 실행 인스턴스의 규칙 그룹 | 선택 범위와 구성 반영 |
| Prometheus firing | Alertmanager의 해당 대상 | 연결·발견 권한·접근 경로 |
| Alertmanager 수신 | 웹훅 요청 | route·receiver·전송 실패 |
| 웹훅 firing 도착 | 같은 대상의 복구와 업무 성공 | 의존성 복구·새 평가·복구 전송 |
수신자가 없다면 빈 receiver도 유효한 구성일 수 있습니다. 문법상 올바른 구성이 업무상
원하는 전송을 수행하는지 별도로 시험해야 합니다. Secret을 쓸 때는 이름과 내부 키가
소비자가 기대하는 계약과 맞아야 합니다. 이 실습의 구성에는 비밀값이 없지만 실제로
API 키나 비밀번호를 넣는 경우에는 소스·스크린샷·관측 기록에 복사하지 않습니다.
현장에서 만나는 모습
준비 실험에서 앱을 새 파드로 바꾼 뒤 같은 장애를 다시 만들었습니다. 웹훅 한 그룹 안에
새 파드의 firing과 이전 파드의 resolved가 함께 들어왔습니다. 알림 이름과 lab 라벨은
같았습니다. 'resolved가 하나라도 있으면 복구'라는 판정은 이 순간 틀립니다.
현재 파드의 라벨을 기준으로 각각의 alerts 항목을 비교해야 했습니다.
그룹의 status 한 값과 그룹 안 개별 알림의 status도 구분합니다. 여러 대상이 한 그룹에
묶이면 그룹의 상태 하나로 모든 대상의 상태를 대표할 수 없습니다. 실제 환경에서는
어떤 라벨을 사건의 식별자로 삼을지, 재시작 전후의 사건을 연결할지 분리할지도 계약으로
정해야 합니다. 이번 과제는 rule UID와 pod UID를 관측 파일에 넣어 다른 실행의 기록을
실수로 재사용하지 않게 합니다. 이는 파일의 진본성을 증명하는 전자서명이 아닙니다.
관측 공백에도 이름을 붙입니다. API 오류 뒤 빈 객체를 정상으로 해석하면 '장애가 없다'는
허위 결론이 만들어집니다. 입력이 없거나 서로 모순되면 unknown으로 반환하고 필요한
조회부터 다시 수행합니다. 숫자 0과 실제 불리언 False를 같은 것으로 다루지 않는 이유도
여기에 있습니다. 잘못된 데이터 형식이 우연히 맞는 상태처럼 보이지 않게 합니다.
과거의 장애 기록과 현재 상태는 용도가 다릅니다. 복구한 뒤 현재 API에는 활성 알림이
없을 수 있지만, 사고 보고서에는 앞서 발화하고 수신했던 기록이 남아 있어야 합니다.
저장한 JSON을 현재 상태로 전부 덮어쓰면 원인을 설명할 자료가 사라집니다. 반대로
옛 정상 JSON만 들고 현재 서비스가 정상이라고 말해서도 안 됩니다. 마지막 복구 단계는
보존한 기록뿐 아니라 현재 업무 응답과 활성 알림 상태를 다시 확인합니다.
다음 실습에서 할 것
발급 의존성을 고장 내고 Prometheus 발화만 있는 시점, Alertmanager까지만 도달한 시점,
웹훅 수신과 복구 시점을 각각 남깁니다. 마지막에는 엄격한 불리언 계약으로 상태를 분류하는
진단기를 만듭니다. 성공 사례 하나만 넣지 않고 누락·모순·잘못된 타입을 넣어 거절되는지
확인합니다. 외부 통지 발송, 다중 노드 고가용성, 운영 SLO 달성은 이번 실습의 증명 범위가 아닙니다.