본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.
본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.
이미지 로딩 중...
AI Generated
2025. 11. 29. · 22 Views
Prometheus Grafana 모니터링 완벽 가이드
Kubernetes 환경에서 Prometheus와 Grafana를 활용한 모니터링 시스템 구축 방법을 초급 개발자도 이해할 수 있도록 단계별로 설명합니다. 메트릭 수집부터 대시보드 구성, 알림 설정까지 실무에 바로 적용할 수 있는 내용을 담았습니다.
목차
1. Prometheus 아키텍처
어느 날 김개발 씨가 운영 중인 서비스에서 갑자기 응답 시간이 느려졌다는 CS 문의가 들어왔습니다. 로그를 뒤져봐도 원인을 알 수 없었고, 서버에 접속해서 직접 확인하느라 한 시간을 허비했습니다.
선배 박시니어 씨가 다가와 물었습니다. "혹시 모니터링 시스템은 구축되어 있어요?"
Prometheus는 한마디로 시스템의 상태를 숫자로 기록하고 조회하는 모니터링 도구입니다. 마치 자동차 계기판이 속도, 연료량, 엔진 온도를 실시간으로 보여주는 것처럼, Prometheus는 서버의 CPU 사용량, 메모리, 요청 수 같은 지표를 수집하고 저장합니다.
이것을 제대로 이해하면 장애가 발생하기 전에 미리 감지하고 대응할 수 있습니다.
다음 코드를 살펴봅시다.
# Prometheus 아키텍처 구성 요소 (prometheus.yml)
global:
scrape_interval: 15s # 메트릭 수집 주기
evaluation_interval: 15s # 알림 규칙 평가 주기
# 알림 매니저 연동 설정
alerting:
alertmanagers:
- static_configs:
- targets: ['alertmanager:9093']
# 메트릭 수집 대상 정의
scrape_configs:
- job_name: 'kubernetes-pods'
kubernetes_sd_configs:
- role: pod
김개발 씨는 입사 6개월 차 주니어 개발자입니다. 지금까지는 문제가 생기면 서버에 직접 접속해서 top 명령어로 CPU를 확인하고, 로그 파일을 뒤지는 방식으로 대응해왔습니다.
하지만 서비스가 커지면서 서버가 10대, 20대로 늘어나자 이 방식은 한계에 부딪혔습니다. 박시니어 씨가 화이트보드 앞으로 김개발 씨를 이끌었습니다.
"Prometheus 아키텍처를 한번 그려볼게요. 이걸 이해하면 모니터링의 전체 그림이 보일 거예요." 그렇다면 Prometheus 아키텍처란 정확히 무엇일까요?
쉽게 비유하자면, Prometheus는 마치 건강검진 센터와 같습니다. 건강검진 센터에서는 여러분이 직접 찾아가지 않아도 정기적으로 연락이 와서 검진을 받으라고 합니다.
그리고 검진 결과를 기록해두었다가, 이상 수치가 발견되면 바로 알려줍니다. Prometheus도 마찬가지로 서버들에게 "지금 상태가 어때?"라고 주기적으로 물어보고, 그 결과를 저장해둡니다.
Prometheus가 없던 시절에는 어땠을까요? 개발자들은 각 서버에 직접 접속해서 상태를 확인해야 했습니다.
서버가 3대일 때는 괜찮았지만, 30대가 되자 불가능에 가까워졌습니다. 더 큰 문제는 과거 데이터를 볼 수 없다는 것이었습니다.
"어제 오후 3시에 CPU가 얼마였지?"라는 질문에 답할 방법이 없었습니다. 바로 이런 문제를 해결하기 위해 Prometheus가 등장했습니다.
Prometheus의 핵심은 Pull 방식입니다. 대부분의 모니터링 시스템이 에이전트가 중앙 서버로 데이터를 보내는 Push 방식인 것과 달리, Prometheus는 중앙 서버가 직접 대상에게 데이터를 가져옵니다.
마치 기자가 직접 현장에 찾아가 취재하는 것과 비슷합니다. 아키텍처의 핵심 구성 요소를 살펴보겠습니다.
첫 번째는 Prometheus Server입니다. 이것이 모든 것의 중심입니다.
메트릭을 수집하고, 시계열 데이터베이스에 저장하며, PromQL 쿼리를 처리합니다. 두 번째는 Exporter입니다.
각 서버나 애플리케이션에서 실행되며, Prometheus가 이해할 수 있는 형식으로 메트릭을 노출합니다. 세 번째는 AlertManager입니다.
특정 조건이 충족되면 슬랙, 이메일 등으로 알림을 보내는 역할을 합니다. 실제 현업에서는 어떻게 활용할까요?
예를 들어 쇼핑몰 서비스를 운영한다고 가정해봅시다. 결제 서버, 상품 서버, 회원 서버가 각각 존재합니다.
Prometheus는 15초마다 이 서버들에게 "지금 CPU 몇 퍼센트야? 메모리는?
처리 중인 요청은 몇 개야?"라고 물어봅니다. 이 데이터가 쌓이면 "매일 오후 2시에 트래픽이 급증하는구나"라는 패턴을 발견할 수 있습니다.
하지만 주의할 점도 있습니다. Pull 방식이기 때문에 Prometheus 서버가 모든 대상에 접근할 수 있어야 합니다.
네트워크가 분리된 환경에서는 Pushgateway라는 중간 다리를 놓아야 합니다. 또한 대상이 너무 많아지면 수집 주기를 조절해야 할 수도 있습니다.
다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨의 설명을 들은 김개발 씨는 고개를 끄덕였습니다.
"그래서 서버에 직접 접속하지 않아도 상태를 알 수 있는 거군요!" Prometheus 아키텍처를 제대로 이해하면 수십, 수백 대의 서버도 한눈에 파악할 수 있습니다. 다음 장에서는 실제로 Kubernetes에 Prometheus를 설치하는 방법을 알아보겠습니다.
실전 팁
💡 - Prometheus는 Pull 방식이므로 방화벽에서 9090 포트 접근을 허용해야 합니다
- scrape_interval은 15초가 기본이며, 서버 부하를 고려해 조절하세요
- 고가용성이 필요하면 Prometheus를 2대 이상 운영하는 것을 권장합니다
2. kube-prometheus-stack 설치
김개발 씨가 Prometheus를 직접 설치하려고 문서를 찾아보았습니다. Prometheus Server, AlertManager, Grafana, 각종 Exporter...
설치해야 할 것이 한두 개가 아니었습니다. "이걸 언제 다 설정하지?" 한숨을 쉬던 그때, 박시니어 씨가 웃으며 말했습니다.
"kube-prometheus-stack 하나면 전부 해결돼요."
kube-prometheus-stack은 한마디로 Prometheus 생태계의 올인원 패키지입니다. 마치 컴퓨터를 살 때 운영체제, 오피스, 백신이 모두 설치된 패키지 상품을 사는 것처럼, 이 Helm 차트 하나로 Prometheus, Grafana, AlertManager, 각종 Exporter가 모두 설치됩니다.
이것을 사용하면 복잡한 설정 없이 10분 만에 완전한 모니터링 환경을 구축할 수 있습니다.
다음 코드를 살펴봅시다.
# Helm 저장소 추가 및 업데이트
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
# 네임스페이스 생성
kubectl create namespace monitoring
# kube-prometheus-stack 설치
helm install prometheus prometheus-community/kube-prometheus-stack \
--namespace monitoring \
--set grafana.adminPassword=admin123 \
--set prometheus.prometheusSpec.retention=15d \
--set alertmanager.enabled=true
# 설치 확인
kubectl get pods -n monitoring
김개발 씨는 Prometheus 공식 문서를 읽으며 막막해하고 있었습니다. ConfigMap 작성, ServiceAccount 생성, RBAC 권한 설정, PersistentVolume 구성...
하나하나 설정해야 할 것들이 끝이 없어 보였습니다. 박시니어 씨가 모니터 앞에 앉았습니다.
"직접 다 설정할 수도 있지만, 실무에서는 거의 대부분 kube-prometheus-stack을 써요. 커뮤니티에서 수년간 다듬어온 베스트 프랙티스가 담겨 있거든요." 그렇다면 kube-prometheus-stack이란 정확히 무엇일까요?
쉽게 비유하자면, kube-prometheus-stack은 마치 이케아 가구 패키지와 같습니다. 책상 하나를 만들려면 상판, 다리, 서랍, 나사가 필요합니다.
각각 따로 사면 호환이 안 될 수도 있고, 조립 방법도 제각각입니다. 하지만 이케아 패키지를 사면 필요한 부품이 모두 들어 있고, 설명서대로 조립하면 됩니다.
kube-prometheus-stack도 마찬가지로 Prometheus 모니터링에 필요한 모든 구성 요소가 호환성 있게 패키징되어 있습니다. 개별 설치 방식의 문제는 무엇이었을까요?
Prometheus와 Grafana 버전이 맞지 않아 대시보드가 깨지는 일이 빈번했습니다. AlertManager 설정을 잘못해서 알림이 안 오는 경우도 많았습니다.
무엇보다 Kubernetes의 버전이 올라갈 때마다 ServiceMonitor, PodMonitor 같은 CRD를 수동으로 업데이트해야 했습니다. 바로 이런 문제를 해결하기 위해 kube-prometheus-stack이 만들어졌습니다.
이 Helm 차트에는 Prometheus Operator가 포함되어 있습니다. Operator는 Kubernetes의 컨트롤러 패턴을 활용해 Prometheus 관련 리소스를 자동으로 관리해줍니다.
새로운 서비스가 배포되면 자동으로 모니터링 대상에 추가되고, 삭제되면 제거됩니다. 위의 설치 명령어를 한 줄씩 살펴보겠습니다.
먼저 helm repo add로 prometheus-community 저장소를 추가합니다. 이 저장소에는 Prometheus 관련 Helm 차트들이 모여 있습니다.
다음으로 monitoring이라는 네임스페이스를 생성합니다. 모니터링 관련 리소스를 별도 공간에 격리하는 것이 관리하기 편합니다.
마지막으로 helm install 명령어로 실제 설치를 진행합니다. 설치 옵션들도 살펴봅시다.
grafana.adminPassword는 Grafana 관리자 비밀번호입니다. 기본값은 prom-operator인데, 보안을 위해 반드시 변경해야 합니다.
prometheus.prometheusSpec.retention은 메트릭 데이터 보관 기간입니다. 15d는 15일간 보관한다는 의미입니다.
디스크 용량과 상의해서 결정하면 됩니다. 실제 현업에서는 어떻게 활용할까요?
대부분의 회사에서는 values.yaml 파일을 별도로 작성해서 관리합니다. 개발 환경에서는 리소스를 적게, 운영 환경에서는 고가용성 설정을 추가하는 식입니다.
GitOps를 도입한 팀이라면 ArgoCD나 Flux와 연동해서 선언적으로 관리하기도 합니다. 하지만 주의할 점도 있습니다.
kube-prometheus-stack은 상당히 많은 리소스를 생성합니다. 작은 클러스터에서는 리소스 요청량을 조절해야 할 수 있습니다.
또한 업그레이드 시 CRD 변경사항이 있으면 별도로 적용해야 하는 경우가 있으니 릴리스 노트를 꼭 확인하세요. 다시 김개발 씨의 이야기로 돌아가 봅시다.
helm install 명령어 한 줄을 실행하고 5분을 기다리자, kubectl get pods 결과에 prometheus, grafana, alertmanager가 모두 Running 상태로 나타났습니다. "와, 진짜 한 번에 다 설치되네요!" kube-prometheus-stack을 활용하면 모니터링 인프라 구축에 드는 시간을 획기적으로 줄일 수 있습니다.
다음 장에서는 이렇게 설치된 Prometheus가 어떻게 메트릭을 수집하는지 알아보겠습니다.
실전 팁
💡 - 운영 환경에서는 반드시 values.yaml을 별도로 관리하세요
- 설치 전 kubectl get crd 명령어로 기존 CRD가 있는지 확인하세요
- Grafana 접속은 kubectl port-forward svc/prometheus-grafana 3000:80 -n monitoring으로 테스트할 수 있습니다
3. 메트릭 수집 원리
kube-prometheus-stack 설치를 마친 김개발 씨는 궁금해졌습니다. "그런데 Prometheus가 어떻게 우리 서버의 CPU, 메모리 정보를 아는 거죠?
마법이라도 부리는 건가요?" 박시니어 씨가 웃으며 대답했습니다. "마법이 아니라 과학이에요.
Exporter와 ServiceMonitor가 그 비밀입니다."
메트릭 수집 원리는 한마디로 "노출-발견-수집"의 3단계 과정입니다. 마치 편의점 본사가 각 지점의 매출을 파악하는 것과 같습니다.
각 지점(Exporter)이 매출 데이터를 정해진 양식으로 준비해두면, 본사 시스템(Prometheus)이 정기적으로 조회해서 가져갑니다. 이 과정에서 어떤 지점을 조회할지 목록(ServiceMonitor)이 필요합니다.
다음 코드를 살펴봅시다.
# ServiceMonitor 예시 - 특정 서비스의 메트릭 수집 설정
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: my-app-monitor
namespace: monitoring
spec:
selector:
matchLabels:
app: my-application # 이 라벨을 가진 Service를 대상으로
endpoints:
- port: metrics # metrics라는 이름의 포트에서
interval: 30s # 30초마다 수집
path: /metrics # /metrics 경로로 요청
namespaceSelector:
matchNames:
- production # production 네임스페이스에서
김개발 씨는 Prometheus 웹 UI에 접속해서 up 쿼리를 실행해봤습니다. 화면에 수십 개의 타겟이 나타났습니다.
node-exporter, kube-state-metrics, kubelet... "이것들이 다 뭐죠?
제가 설정한 적이 없는데요." 박시니어 씨가 화면을 가리키며 설명을 시작했습니다. "kube-prometheus-stack이 기본으로 여러 Exporter를 설치해뒀어요.
각각이 무슨 역할인지 알아야 커스텀 메트릭도 수집할 수 있어요." 그렇다면 메트릭 수집 원리란 정확히 무엇일까요? 쉽게 비유하자면, 메트릭 수집은 마치 건강검진 과정과 같습니다.
먼저 각 검사실(Exporter)에서 혈압, 혈당, 체중 같은 수치를 측정합니다. 이 데이터는 정해진 양식(Prometheus 메트릭 포맷)으로 작성됩니다.
그러면 건강검진 센터의 코디네이터(ServiceMonitor)가 "이 환자는 내과, 외과, 안과를 돌아야 해"라고 안내합니다. 마지막으로 중앙 시스템(Prometheus)이 각 검사실을 돌며 결과를 수집해 종합 기록부에 저장합니다.
메트릭은 어떤 형식으로 노출될까요? Prometheus 메트릭 포맷은 매우 단순합니다.
텍스트 기반이며, 사람이 읽을 수 있는 형태입니다. 예를 들어 http_requests_total{method="GET", status="200"} 1234는 GET 요청 중 200 응답이 1234건이라는 의미입니다.
중괄호 안의 method, status는 라벨이라고 부르며, 같은 메트릭을 다양한 차원으로 구분할 수 있게 해줍니다. Exporter의 종류를 알아봅시다.
node-exporter는 서버의 하드웨어 및 OS 메트릭을 수집합니다. CPU, 메모리, 디스크, 네트워크 사용량이 여기서 나옵니다.
kube-state-metrics는 Kubernetes 오브젝트의 상태를 메트릭으로 변환합니다. Pod 개수, Deployment 상태, Node 조건 등이 포함됩니다.
kubelet은 각 노드에서 실행되며 컨테이너 관련 메트릭을 제공합니다. ServiceMonitor는 무엇일까요?
ServiceMonitor는 Prometheus Operator가 도입한 Custom Resource입니다. "이 라벨을 가진 Service의 이 포트에서 메트릭을 수집해라"라고 선언적으로 정의합니다.
Prometheus가 직접 설정 파일을 수정할 필요 없이, ServiceMonitor만 생성하면 자동으로 수집 대상에 추가됩니다. 위의 ServiceMonitor 코드를 살펴보겠습니다.
selector.matchLabels는 어떤 Service를 대상으로 할지 지정합니다. app: my-application 라벨을 가진 Service만 선택됩니다.
endpoints 부분은 실제 수집 설정입니다. metrics라는 이름의 포트에서, 30초 간격으로, /metrics 경로를 호출합니다.
namespaceSelector는 대상 Service가 있는 네임스페이스를 지정합니다. 실제 현업에서는 어떻게 활용할까요?
애플리케이션에 /metrics 엔드포인트를 추가하면 커스텀 메트릭을 수집할 수 있습니다. Node.js라면 prom-client, Python이라면 prometheus_client, Go라면 promhttp 라이브러리를 사용합니다.
예를 들어 주문 처리 시간, 결제 성공률 같은 비즈니스 메트릭을 직접 정의할 수 있습니다. 하지만 주의할 점도 있습니다.
메트릭의 카디널리티를 조심해야 합니다. 라벨 값이 무한히 늘어날 수 있는 경우, 예를 들어 user_id를 라벨로 사용하면 메모리가 폭발할 수 있습니다.
또한 수집 주기(interval)를 너무 짧게 설정하면 Prometheus 서버에 부하가 걸립니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.
"아, 그래서 /metrics 엔드포인트만 만들면 자동으로 수집되는 거군요!" 김개발 씨는 자신의 애플리케이션에 메트릭 엔드포인트를 추가하기로 결심했습니다. 메트릭 수집 원리를 이해하면 어떤 데이터든 Prometheus로 가져올 수 있습니다.
다음 장에서는 이렇게 수집된 데이터를 조회하는 PromQL을 배워보겠습니다.
실전 팁
💡 - 새로운 Exporter를 추가할 때는 ServiceMonitor도 함께 생성하세요
- 카디널리티가 높은 라벨(user_id, request_id 등)은 피하세요
- curl http://localhost:9090/metrics로 로컬 테스트가 가능합니다
4. PromQL 기초
김개발 씨가 Prometheus 웹 UI에서 이것저것 클릭해보다가 Expression 입력란을 발견했습니다. 뭔가 입력해야 할 것 같은데, SQL처럼 생긴 것도 아니고 낯선 문법이었습니다.
"up이라고 치면 뭔가 나오긴 하는데... 이게 뭐하는 건지 모르겠어요." 박시니어 씨가 자리로 다가왔습니다.
"PromQL을 알아야 진정한 모니터링이 시작되는 거예요."
PromQL(Prometheus Query Language)은 한마디로 시계열 데이터를 조회하고 가공하는 전용 언어입니다. 마치 스프레드시트에서 수식을 사용해 평균, 합계를 구하는 것처럼, PromQL을 사용하면 수집된 메트릭에서 원하는 정보를 추출하고 계산할 수 있습니다.
SQL이 관계형 데이터베이스의 언어라면, PromQL은 시계열 데이터베이스의 언어입니다.
다음 코드를 살펴봅시다.
# 기본 메트릭 조회
up{job="kubernetes-pods"}
# 특정 네임스페이스의 컨테이너 CPU 사용률 (%)
sum(rate(container_cpu_usage_seconds_total{namespace="production"}[5m])) by (pod) * 100
# 메모리 사용률 계산
container_memory_usage_bytes / container_spec_memory_limit_bytes * 100
# HTTP 요청 에러율 (5xx 비율)
sum(rate(http_requests_total{status=~"5.."}[5m]))
/ sum(rate(http_requests_total[5m])) * 100
# 90번째 백분위 응답 시간 (히스토그램)
histogram_quantile(0.9, rate(http_request_duration_seconds_bucket[5m]))
김개발 씨는 모니터링 대시보드를 보면서 항상 궁금했습니다. "CPU 사용률 80%라는 숫자는 도대체 어떻게 계산되는 걸까?" 단순히 어딘가에서 80이라는 값을 가져오는 줄 알았는데, 실제로는 복잡한 계산이 필요했습니다.
박시니어 씨가 화이트보드에 그래프를 그리기 시작했습니다. "PromQL을 이해하려면 먼저 시계열 데이터가 뭔지 알아야 해요." 그렇다면 시계열 데이터란 무엇일까요?
쉽게 비유하자면, 시계열 데이터는 마치 주식 차트와 같습니다. 삼성전자 주가를 보면 시간대별로 가격이 기록되어 있습니다.
09:00에 70,000원, 09:15에 70,100원, 09:30에 69,900원... 이처럼 시간에 따라 변하는 값을 기록한 것이 시계열 데이터입니다.
Prometheus의 메트릭도 마찬가지로 15초마다 CPU 값이 기록됩니다. PromQL의 기본 문법부터 알아봅시다.
가장 단순한 쿼리는 메트릭 이름만 입력하는 것입니다. up을 입력하면 모든 수집 대상의 상태가 나옵니다.
1이면 정상, 0이면 다운입니다. 여기에 중괄호로 라벨을 필터링할 수 있습니다.
up{job="node-exporter"}는 node-exporter 잡의 상태만 조회합니다. rate 함수가 왜 중요할까요?
counter 타입 메트릭은 계속 증가만 합니다. http_requests_total이 1000에서 1100이 됐다면, 그 자체로는 의미가 없습니다.
우리가 알고 싶은 건 "초당 몇 건의 요청이 들어오는가"입니다. rate 함수는 일정 시간 동안의 증가율을 계산해줍니다.
rate(http_requests_total[5m])은 최근 5분간의 초당 평균 요청 수를 반환합니다. 코드의 CPU 사용률 쿼리를 분석해봅시다.
container_cpu_usage_seconds_total은 컨테이너가 사용한 CPU 시간(초)의 누적값입니다. rate()로 최근 5분간 초당 CPU 사용 시간을 구합니다.
1초 동안 1초의 CPU를 사용했다면 100%입니다. sum() by (pod)로 컨테이너별이 아닌 Pod별로 합산합니다.
마지막으로 100을 곱해 퍼센트로 변환합니다. 집계 연산자도 알아야 합니다.
sum은 합계, avg는 평균, max는 최댓값, min은 최솟값입니다. by 절로 그룹화할 수 있습니다.
sum(cpu) by (pod)는 Pod별로 합산합니다. without 절은 반대로 특정 라벨을 제외하고 그룹화합니다.
실제 현업에서는 어떻게 활용할까요? SRE 팀에서는 SLI(Service Level Indicator)를 PromQL로 정의합니다.
"99%의 요청이 200ms 이내에 처리되어야 한다"라는 SLO가 있다면, histogram_quantile(0.99, ...)로 99번째 백분위 응답 시간을 계산합니다. 이 값이 200ms를 넘으면 알림이 발생하도록 설정합니다.
하지만 주의할 점도 있습니다. rate 함수의 범위(예: [5m])는 수집 주기(scrape_interval)의 최소 4배 이상이어야 정확합니다.
15초 주기라면 최소 [1m] 이상을 권장합니다. 또한 sum과 rate의 순서도 중요합니다.
여러 시리즈의 비율을 합치려면 sum(rate(...))처럼 rate를 먼저 해야 합니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.
"아, 그래서 단순히 숫자를 조회하는 게 아니라 계산을 하는 거군요!" 김개발 씨는 직접 PromQL을 작성해보며 데이터를 탐색하기 시작했습니다. PromQL을 익히면 수집된 메트릭에서 무궁무진한 인사이트를 얻을 수 있습니다.
다음 장에서는 이 쿼리 결과를 시각화하는 Grafana 대시보드를 구성해보겠습니다.
실전 팁
💡 - rate 함수의 범위는 scrape_interval의 4배 이상으로 설정하세요
- increase 함수는 rate와 비슷하지만 절대 증가량을 반환합니다
- Prometheus 웹 UI의 Graph 탭에서 쿼리를 테스트해보세요
5. Grafana 대시보드 구성
김개발 씨가 PromQL로 여러 쿼리를 실행해보니 숫자들이 쏟아져 나왔습니다. CPU 사용률 0.73, 메모리 사용량 1073741824...
"이걸 매번 수동으로 확인해야 하나요? 그래프로 볼 수는 없나요?" 박시니어 씨가 새 브라우저 탭을 열며 대답했습니다.
"Grafana에 오신 것을 환영합니다."
Grafana는 한마디로 데이터를 아름답게 시각화하는 도구입니다. 마치 회계사가 엑셀 숫자를 파워포인트 차트로 변환해 경영진에게 보고하는 것처럼, Grafana는 Prometheus의 메트릭을 직관적인 그래프, 게이지, 테이블로 변환합니다.
대시보드 하나로 서비스 전체 상태를 한눈에 파악할 수 있게 됩니다.
다음 코드를 살펴봅시다.
# Grafana 대시보드 JSON 구조 예시 (패널 정의)
{
"panels": [
{
"title": "CPU 사용률",
"type": "timeseries",
"datasource": "Prometheus",
"targets": [
{
"expr": "sum(rate(container_cpu_usage_seconds_total{namespace=\"production\"}[5m])) by (pod) * 100",
"legendFormat": "{{pod}}"
}
],
"fieldConfig": {
"defaults": {
"unit": "percent",
"thresholds": {
"steps": [
{ "value": 0, "color": "green" },
{ "value": 70, "color": "yellow" },
{ "value": 90, "color": "red" }
]
}
}
}
}
]
}
김개발 씨가 처음 Grafana에 접속했을 때, 이미 여러 대시보드가 준비되어 있었습니다. kube-prometheus-stack이 Kubernetes 모니터링용 기본 대시보드를 함께 설치해둔 것입니다.
클릭 한 번에 클러스터 전체 상태가 눈앞에 펼쳐졌습니다. 박시니어 씨가 대시보드를 스크롤하며 설명했습니다.
"이런 기본 대시보드도 좋지만, 결국 우리 서비스에 맞는 커스텀 대시보드가 필요해요." 그렇다면 좋은 대시보드란 무엇일까요? 쉽게 비유하자면, 대시보드는 마치 자동차 계기판과 같습니다.
운전 중에 필요한 정보만 한눈에 보여야 합니다. 속도, 연료, 엔진 경고등이면 충분합니다.
RPM 그래프나 타이어 공기압 수치까지 메인 화면에 있으면 오히려 방해가 됩니다. 마찬가지로 모니터링 대시보드도 핵심 지표만 배치해야 합니다.
대시보드의 기본 구성 요소를 알아봅시다. Panel은 개별 시각화 단위입니다.
하나의 그래프, 하나의 게이지가 각각 패널입니다. Row는 패널들을 묶는 행입니다.
관련 있는 패널들을 한 줄에 배치합니다. Variable은 대시보드를 동적으로 만드는 변수입니다.
네임스페이스, Pod 이름 등을 드롭다운으로 선택할 수 있게 합니다. 패널 타입은 어떤 것들이 있을까요?
Time series는 시간에 따른 변화를 보여주는 꺾은선 그래프입니다. CPU, 메모리, 요청 수 같은 메트릭에 적합합니다.
Gauge는 현재 값을 원형 게이지로 표시합니다. 디스크 사용률처럼 백분율 데이터에 좋습니다.
Stat은 단일 숫자를 크게 표시합니다. 현재 활성 사용자 수 같은 지표에 사용합니다.
Table은 여러 값을 표 형태로 보여줍니다. Pod 목록과 각각의 상태를 나열할 때 유용합니다.
위의 JSON 코드를 살펴보겠습니다. targets 배열에 PromQL 쿼리를 정의합니다.
이 쿼리 결과가 그래프로 그려집니다. legendFormat은 범례 표시 방식입니다.
"{{pod}}"는 Pod 이름을 범례로 사용한다는 뜻입니다. thresholds는 임계값 색상 설정입니다.
70% 미만은 초록색, 70-90%는 노란색, 90% 이상은 빨간색으로 표시됩니다. 실제 현업에서는 어떻게 활용할까요?
보통 RED 메서드를 따릅니다. Rate(초당 요청 수), Errors(에러율), Duration(응답 시간)을 기본 지표로 삼습니다.
또는 USE 메서드도 있습니다. Utilization(사용률), Saturation(포화도), Errors(에러)를 모니터링합니다.
이 지표들을 상단에 배치하고, 세부 지표는 아래에 배치하는 것이 일반적입니다. Dashboard as Code 방식도 알아두세요.
Grafana 대시보드는 JSON으로 내보내기/가져오기가 가능합니다. 이 JSON을 Git에 저장하면 대시보드도 버전 관리가 됩니다.
더 나아가 Grafonnet이라는 라이브러리를 사용하면 Jsonnet 언어로 대시보드를 프로그래밍 방식으로 생성할 수 있습니다. 하지만 주의할 점도 있습니다.
너무 많은 패널을 하나의 대시보드에 넣으면 로딩이 느려집니다. 쿼리가 복잡할수록 렌더링 시간도 길어집니다.
또한 시간 범위를 너무 길게 설정하면 데이터 포인트가 많아져 브라우저가 버벅거릴 수 있습니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.
김개발 씨는 첫 커스텀 대시보드를 완성했습니다. 서비스의 요청 수, 에러율, 평균 응답 시간이 한 화면에 표시됩니다.
"이제 서버에 접속하지 않아도 상태를 알 수 있겠어요!" Grafana 대시보드를 잘 구성하면 장애 감지부터 용량 계획까지 데이터 기반 의사결정이 가능해집니다. 다음 장에서는 문제가 발생했을 때 자동으로 알림을 보내는 AlertManager를 설정해보겠습니다.
실전 팁
💡 - 대시보드는 목적별로 분리하세요 (개요용, 디버깅용, 비즈니스용)
- Variable을 활용해 하나의 대시보드로 여러 서비스를 모니터링하세요
- grafana.com/grafana/dashboards에서 커뮤니티 대시보드를 참고하세요
6. AlertManager 알림 설정
한밤중 3시, 김개발 씨의 휴대폰이 울렸습니다. 고객센터에서 전화가 온 것입니다.
"지금 서비스가 안 된다는 CS가 밀려오고 있어요!" 황급히 노트북을 열어보니 서버가 2시간 전부터 다운되어 있었습니다. "왜 아무도 몰랐지?" 다음 날 박시니어 씨가 말했습니다.
"AlertManager를 제대로 설정했으면 2시간 전에 알았을 거예요."
AlertManager는 한마디로 문제가 생겼을 때 사람에게 알려주는 알림 시스템입니다. 마치 집에 화재 경보기를 설치하는 것과 같습니다.
연기가 감지되면 자동으로 경보가 울리고, 경비실에 연락이 갑니다. AlertManager도 메트릭이 임계값을 넘으면 슬랙, 이메일, PagerDuty 등으로 알림을 보냅니다.
24시간 대시보드를 지켜볼 필요가 없어집니다.
다음 코드를 살펴봅시다.
# PrometheusRule 예시 - 알림 규칙 정의
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: my-app-alerts
namespace: monitoring
spec:
groups:
- name: my-app
rules:
- alert: HighCPUUsage
expr: sum(rate(container_cpu_usage_seconds_total{namespace="production"}[5m])) by (pod) > 0.8
for: 5m
labels:
severity: warning
annotations:
summary: "Pod {{ $labels.pod }}의 CPU 사용률이 80%를 초과했습니다"
description: "현재 CPU 사용률: {{ $value | humanizePercentage }}"
- alert: PodNotReady
expr: kube_pod_status_ready{condition="true"} == 0
for: 3m
labels:
severity: critical
annotations:
summary: "Pod {{ $labels.pod }}가 Ready 상태가 아닙니다"
김개발 씨는 그날의 장애를 복기하며 자책했습니다. 대시보드는 잘 만들어뒀는데, 정작 문제가 생겼을 때 아무도 보고 있지 않았습니다.
모니터링의 진정한 가치는 실시간 감시가 아니라 이상 상황의 자동 감지에 있다는 것을 깨달았습니다. 박시니어 씨가 AlertManager 설정 파일을 열며 설명했습니다.
"알림 시스템은 두 부분으로 나뉘어요. 언제 알림을 보낼지 정하는 규칙과, 어디로 보낼지 정하는 라우팅이요." 그렇다면 알림 규칙이란 무엇일까요?
쉽게 비유하자면, 알림 규칙은 마치 체온계의 기준점과 같습니다. "체온이 38도를 넘으면 열이 있는 것"이라는 기준이 있습니다.
마찬가지로 "CPU가 80%를 5분 이상 넘으면 경고"라는 기준을 정합니다. 이 기준을 PromQL 표현식으로 작성하는 것이 알림 규칙입니다.
PrometheusRule 구조를 살펴봅시다. alert는 알림의 이름입니다.
나중에 이 이름으로 알림을 식별합니다. expr은 PromQL 표현식입니다.
이 쿼리 결과가 0보다 크면 알림이 발생합니다. for는 지속 시간입니다.
5m이면 5분 동안 조건이 유지되어야 알림이 발생합니다. 일시적인 스파이크에 알림이 발생하는 것을 방지합니다.
labels와 annotations의 차이는 무엇일까요? labels는 알림의 메타데이터입니다.
severity: critical처럼 알림의 심각도를 표시합니다. 이 라벨을 기준으로 라우팅을 다르게 할 수 있습니다.
annotations는 알림의 내용입니다. 사람이 읽을 설명을 담습니다.
{{ $labels.pod }}처럼 템플릿 문법으로 동적 값을 포함할 수 있습니다. AlertManager 라우팅도 설정해야 합니다.
라우팅은 어떤 알림을 어디로 보낼지 정합니다. severity: critical은 PagerDuty로, severity: warning은 슬랙으로 보내는 식입니다.
또한 팀별로 담당 서비스가 다르다면, namespace 라벨을 기준으로 다른 채널로 보낼 수도 있습니다. 알림 그룹핑이라는 개념도 있습니다.
서버 100대가 동시에 다운되면 알림이 100개 발생할까요? 그렇게 되면 알림의 홍수에 빠져서 정작 중요한 정보를 놓칠 수 있습니다.
AlertManager는 비슷한 알림을 하나로 묶어줍니다. "서버 100대에서 동일한 문제 발생"이라고 요약해서 알려줍니다.
실제 현업에서는 어떻게 활용할까요? 보통 알림을 계층화합니다.
정보성 알림은 슬랙 채널에, 경고는 담당자 DM에, 긴급은 전화까지 가도록 설정합니다. 또한 업무 시간 외 알림을 별도로 설정하기도 합니다.
새벽 3시의 minor 알림은 무시하고, critical만 전화가 가도록 합니다. 하지만 주의할 점도 있습니다.
알림 피로(alert fatigue)를 조심해야 합니다. 알림이 너무 많으면 사람들이 무시하게 됩니다.
의미 있는 알림만 보내도록 임계값을 신중하게 설정하세요. 또한 테스트 환경에서 발생한 알림이 운영팀에 가지 않도록 네임스페이스 필터링도 필요합니다.
다시 김개발 씨의 이야기로 돌아가 봅시다. AlertManager 설정을 마친 후, 의도적으로 CPU 부하를 발생시켜 테스트해봤습니다.
5분 후, 슬랙 채널에 알림이 도착했습니다. "이제 한밤중에 전화 받는 일은 없겠네요!" AlertManager를 제대로 설정하면 장애 대응 시간을 획기적으로 줄일 수 있습니다.
모니터링 시스템의 완성은 대시보드가 아니라 알림입니다. 지금까지 배운 Prometheus, PromQL, Grafana, AlertManager를 조합하면 엔터프라이즈급 모니터링 환경을 구축할 수 있습니다.
실전 팁
💡 - for 절을 반드시 설정해 일시적 스파이크에 알림이 발생하지 않게 하세요
- severity 라벨을 일관되게 사용하세요 (info, warning, critical)
- 알림 내용에 런북(Runbook) 링크를 포함하면 대응이 빨라집니다
이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!
댓글 (0)
함께 보면 좋은 카드 뉴스
Istio 보안 완벽 가이드
마이크로서비스 환경에서 필수적인 Istio 보안 기능을 실무 중심으로 설명합니다. mTLS부터 인증, 인가까지 단계별로 학습하여 안전한 서비스 메시를 구축할 수 있습니다.
Istio 트래픽 관리 완벽 가이드
Istio의 트래픽 관리 기능을 마스터하는 완벽 가이드입니다. VirtualService와 DestinationRule을 활용한 라우팅부터 트래픽 분할, 헤더 기반 라우팅까지 실무에 필요한 모든 내용을 다룹니다.
Istio 설치와 구성 완벽 가이드
Kubernetes 환경에서 Istio 서비스 메시를 설치하고 구성하는 방법을 초급 개발자도 쉽게 이해할 수 있도록 실무 스토리와 비유로 풀어낸 가이드입니다. istioctl 설치부터 사이드카 주입까지 단계별로 학습합니다.
서비스 메시 완벽 가이드
마이크로서비스 간 통신을 안전하고 효율적으로 관리하는 서비스 메시의 핵심 개념부터 실전 도입까지, 초급 개발자를 위한 완벽한 입문서입니다. Istio와 Linkerd 비교, 사이드카 패턴, 실무 적용 노하우를 담았습니다.
Helm 마이크로서비스 패키징 완벽 가이드
Kubernetes 환경에서 마이크로서비스를 효율적으로 패키징하고 배포하는 Helm의 핵심 기능을 실무 중심으로 학습합니다. Chart 생성부터 릴리스 관리까지 체계적으로 다룹니다.