Grafana 2026.09.10 6 min read

23개 Target과 21개 Rule로 운영 상태를 증명하기까지

Prometheus 수집 대상 23개와 알림 규칙 21개를 점검했다. 설정 파일 불일치, Grafana 로그인 문제, Telegram 알림 검증과 애플리케이션 관측의 한계를 정리했다.

장애가 나면 어느 서버와 서비스부터 확인할지 알 수 있도록 모니터링을 구성했다. CPU 사용률뿐 아니라 DB 복제, 백업 시각, NFS 상태와 로그를 함께 볼 필요가 있었다.

별도 모니터링 서버에 Prometheus, Grafana, Alertmanager, Loki, Alloy를 배치했다. 각 노드와 서비스에서 필요한 지표와 로그를 모았다.

Target을 역할별로 나눴다

최종 점검 때 Prometheus가 수집한 대상은 23개였다.

node_exporter: 10
cAdvisor: 6
mysqld_exporter: 2
Prometheus: 1
Alertmanager: 1
Grafana: 1
Loki: 1
Alloy: 1
Total: 23

Node exporter는 Ubuntu 10대의 CPU, 메모리, 파일시스템, 네트워크 지표를 수집했다. cAdvisor는 Docker가 실행되는 노드의 컨테이너 자원 사용량을, mysqld_exporter는 Primary와 Replica의 상태를 수집했다.

NFS 서버의 journald 로그는 Alloy를 거쳐 Loki로 보냈다. 자원 사용량과 상태값은 지표로 확인하고, 해당 시각에 무슨 일이 있었는지는 로그에서 찾도록 나눴다.

Host 설정과 container 설정이 달랐던 문제

호스트의 Prometheus YAML을 수정했는데 새 수집 대상이 나타나지 않았다. 내용을 다시 확인해도 이상이 없어 컨테이너 내부 파일과 비교했다. 컨테이너가 읽는 파일과 호스트에서 편집한 파일의 inode가 달랐다.

편집기가 임시 파일을 만든 뒤 기존 파일과 교체해 저장하면, bind mount 중인 컨테이너는 이전 inode를 계속 참조할 수 있다. 호스트와 컨테이너 내부 파일의 해시를 비교해 이 차이를 확인했다.

컨테이너가 실제로 읽는 경로에서 설정 문법을 검사하고 서비스를 재생성했다. 그 뒤 Target API에 새 대상이 나타났고 상태가 up으로 바뀌었다.

Exporter에 직접 요청했을 때 응답하는 것과 Prometheus가 해당 주소를 등록해 수집하는 것은 따로 확인해야 했다. 이때부터 두 결과를 각각 점검했다.

curl: (23)을 exporter 장애로 오해하지 않았다

지표 출력을 grep -m1에 연결하자 curl: (23) Failure writing output이 나왔다. 첫 번째 일치를 찾은 grep이 종료하면서 파이프가 닫혔고, curl은 남은 응답을 쓸 수 없었다.

이 경우에는 지표를 읽던 명령이 먼저 종료된 것이었다. HTTP 응답 코드, 수집 대상 상태, 필요한 지표의 조회 결과를 따로 확인했다.

Grafana를 질문 중심으로 구성했다

대시보드는 세 개로 나눴다.

  • Infrastructure Command Center
  • Container Operations
  • NFS System Logs

Infrastructure 화면에는 노드 10대, MySQL 2대, 복제 지연, 최근 백업 시각, NFS 사용량과 알림을 모았다. Container 화면에서는 App, Redis, cloudflared, NPM의 상태와 자원 사용량을 확인했다. NFS 로그 화면에서는 두 저장소 서버의 journald를 비교했다.

최종 화면에서 노드 10대와 MySQL 2대가 온라인이었고 복제 지연은 0초였다. Prometheus API에서도 수집 대상 23/23 UP, 알림 규칙 21/21 healthy, 발생 중인 알림 0개를 확인했다.

Grafana 비밀번호가 .env 변경으로 바뀌지 않은 이유

운영 중 Grafana 관리자 비밀번호를 잊어 .env를 수정했지만 로그인은 계속 실패했다. 관리자 초기화 환경변수는 DB를 처음 만들 때 사용된다. 이미 DB에 저장된 사용자의 비밀번호는 환경변수를 바꿔도 갱신되지 않았다.

공식 관리자 비밀번호 초기화 절차로 계정을 복구한 뒤 API 응답을 확인했다. 이후에는 초기화에 쓰는 환경변수와 DB에 저장된 계정 정보를 구분해서 확인했다.

Alert는 FIRING과 RESOLVED를 모두 확인했다

Telegram 알림이 실제로 전달되는지 보려고 검증용 알림을 Alertmanager에 제출했다. group_wait가 지난 뒤 Telegram 전송 성공 카운터가 늘어나는지 확인했다. 알림을 해제한 다음에는 활성 알림이 0개로 돌아오는지도 확인했다.

전송 성공 카운터는 증가했고 실패는 0건이었다. 해제 후 활성 알림도 0개였다. 운영 알림 규칙 21개는 모두 healthy 상태였다.

Dashboard가 보여 주지 못하는 것

노드와 프록시 지표가 정상이어도 로그인과 Presence에는 문제가 남아 있었다. STOMP CONNECTED 비율이 낮아 인프라 지표만으로 실시간 기능의 상태를 판단하기 어려웠다.

애플리케이션 상태를 확인하려면 아래 항목을 더 수집해야 했다.

  • Spring Boot 요청 지연과 응답 코드별 발생 비율
  • JVM, 커넥션 풀, 스레드 풀 지표
  • OAuth 콜백 성공·실패 횟수
  • STOMP CONNECT/CONNECTED와 재접속 지표
  • 외부 사용자 경로를 따라가는 로그인·Presence 점검
  • 추적 정보와 요청 ID를 이용한 로그 연결

이번 구성으로 서버 자원, 복제, 백업, NFS 상태를 나눠 확인할 수 있게 됐다. 사용자 기능까지 보려면 위 항목을 더 연결해야 한다. 서비스 통신을 유지하며 계정과 iptables를 적용한 과정은 별도 글에 정리했다.

실제 검증 화면

  1. Prometheus API 집계에서 전체 23개, 정상 23개, 중단 0개를 확인했다.
  2. 시연과 최종 점검에 사용한 통합 대시보드다. 노드 상태와 자원 사용률을 함께 배치했다.
  3. MySQL 가용성, 쿼리, 연결 수, 복제 스레드와 쓰기 보호 상태를 확인한 영역이다.
  4. NFS 사용량과 백업 이력, 최근 백업 시각, 노드 가동 시간을 모았다.
  5. 알림 규칙 21개가 모두 healthy였고 점검 시점에 발생 중인 알림은 0개였다.
    Prometheus 수집 대상 23개가 모두 up이고 down은 0개인 API 조회 결과

노드 10개와 MySQL 2개가 온라인이고 발생 알림 0개, 복제 지연 0초인 Grafana 통합 대시보드

MySQL Primary와 Replica의 가용성, 쿼리량, 연결 사용률과 실행 중인 복제 스레드를 보여주는 Grafana 화면

두 NFS의 사용률 5.10%와 마지막 백업 후 경과 시간 13.5시간을 표시한 Grafana 저장소·백업 화면

Prometheus 알림 규칙 21개 중 unhealthy와 firing이 모두 0개인 조회 결과

SEARCH JOURNAL

기록 검색

글 제목, 요약, 태그에서 찾습니다.

검색을 준비하고 있어요.

검색어를 입력해 주세요.

    Ctrl/⌘ K 검색 Esc 닫기 결과 이동