13년차의 서버실

서버, 인프라, 홈랩 기술 블로그

[태그:] Grafana 연동

  • [k8s] Prometheus Operator vs 직접 설정: Kubernetes 모니터링 실전 비교 분석

    [k8s] Prometheus Operator vs 직접 설정: Kubernetes 모니터링 실전 비교 분석

    Prometheus Operator vs 직접 설정: Kubernetes 모니터링 실전 비교 분석

    쿠버네티스 운영을 조금만 해보면 결국 만나게 되는 질문이 있습니다. Prometheus Operator vs 직접 설정, 대체 뭐가 더 낫냐는 거죠. 저도 처음엔 “Prometheus(프로메테우스, 시계열 메트릭 모니터링 시스템)면 그냥 띄우면 되는 거 아닌가?” 싶었는데, 실제로 홈랩과 운영 환경에서 둘 다 굴려보니 생각보다 차이가 꽤 크더라고요. 특히 Kubernetes 모니터링을 제대로 붙이려면 서비스 디스커버리(Service Discovery, 대상 자동 발견), 알림 규칙(Alerting Rules, 경고 조건), 그리고 Grafana 연동까지 자연스럽게 이어져야 하거든요.

    이번 글에서는 제가 직접 삽질했던 경험을 바탕으로, Prometheus Operator 방식과 직접 설정 방식을 현실적으로 비교해보겠습니다. 단순히 “이게 더 최신이라 좋다” 같은 얘기는 빼고, 실제 운영 관점에서 어디가 편하고 어디서 귀찮아지는지 정리해볼게요.

    Prometheus Operator와 직접 설정 방식이 쿠버네티스 클러스터 안에서 어떻게 다르게 배치되는지 보여주는 아키텍처 이미지입니다.

    왜 이 비교가 중요한가: Kubernetes 모니터링에서 운영 비용이 갈립니다

    모니터링은 처음 붙일 때보다 나중에 유지보수할 때 진가가 드러납니다. 초반에는 둘 다 잘 돌아가는 것처럼 보여요. 근데 클러스터가 커지고, 애플리케이션이 늘고, 팀원이 늘어나면 설정 방식의 차이가 운영 비용으로 바로 튀어나옵니다.

    • 직접 설정은 구조를 깊게 이해하기 좋고, 제어권이 높습니다.
    • Operator 방식은 선언형(Declarative, 원하는 상태를 정의하는 방식) 운영이 편하고 확장성이 좋습니다.
    • 작은 홈랩에서는 직접 설정이 빠를 때도 있지만, 팀 단위 운영에서는 Operator가 훨씬 덜 피곤한 경우가 많습니다.

    제가 처음 직접 설정으로 시작했을 때는 설정 파일 하나만 고치면 끝날 줄 알았거든요. 근데 대상 서비스가 늘어나고 scrape job이 많아지니까, 어느 순간 prometheus.yml이 점점 거대해졌습니다. 그때부터 “아 이건 사람이 계속 손으로 관리할 구조가 아니구나” 싶더라고요.

    쉽게 말해: Prometheus Operator vs 직접 설정의 핵심 차이

    쉽게 말해, Prometheus Operator는 Prometheus 자체를 쿠버네티스 리소스(Custom Resource, 사용자 정의 리소스)로 관리하게 해주는 방식입니다. 반대로 직접 설정은 Deployment, ConfigMap, ServiceAccount 같은 리소스를 직접 만들고, scrape 설정도 내가 직접 관리하는 방식입니다.

    항목 Prometheus Operator 직접 설정
    설정 관리 ServiceMonitor, PodMonitor, PrometheusRule 같은 CRD 기반 prometheus.yml 직접 수정
    초기 진입 난이도 처음엔 다소 생소함 개념만 알면 바로 시작 가능
    확장성 매우 좋음 대상이 많아질수록 불편
    운영 자동화 높음 낮음
    문제 추적 리소스 구조 이해 필요 설정 파일 기준으로 단순함
    팀 협업 표준화하기 좋음 작성자 의존도가 높아짐

    여기서 중요한 포인트! 둘 중 하나가 절대적으로 우월하다기보다는, 클러스터 규모와 운영 방식에 따라 유리한 선택이 달라집니다. 저도 작은 테스트 클러스터에서는 직접 설정을 아직도 씁니다. 빠르게 확인하기 좋거든요.

    언제 어떤 방식을 고르면 좋은가

    Prometheus Operator가 잘 맞는 경우

    • 여러 네임스페이스(namespace, 논리적 격리 단위)의 워크로드를 지속적으로 모니터링해야 할 때
    • 팀원이 늘어나서 모니터링 리소스를 표준화해야 할 때
    • Alertmanager(알림 관리자), Grafana, rules 관리를 함께 묶고 싶을 때
    • Helm(헬름, 쿠버네티스 패키지 매니저) 기반 운영에 익숙할 때

    직접 설정이 잘 맞는 경우

    • 학습 목적이나 홈랩처럼 단순한 구조일 때
    • Prometheus 내부 설정을 세밀하게 직접 다루고 싶을 때
    • CRD를 추가하고 싶지 않을 때
    • 문제 발생 시 설정 파일 한 장으로 빠르게 디버깅하고 싶을 때

    사실 처음 배울 때는 직접 설정이 개념 잡기 좋습니다. Prometheus가 어떻게 scrape하고, 어떤 target을 찾고, 어떤 식으로 저장하는지 몸으로 익히게 되거든요. 반대로 운영 단계에서는 Operator가 진짜 편해집니다. 이거 써보면 “아, 사람이 yaml 몇 천 줄 들고 싸우면 안 되는구나” 싶습니다 ㅎㅎ

    실전 구현 1: Prometheus Operator로 Kubernetes 모니터링 구성

    제가 보통 가장 무난하게 시작하는 방식은 kube-prometheus-stack 차트를 쓰는 겁니다. Prometheus, Alertmanager, Grafana를 한 번에 올리기 좋고, 커뮤니티에서 널리 쓰는 편이라 자료도 많습니다.

    1. 모니터링 전용 네임스페이스를 생성합니다.
    2. Helm 저장소를 추가합니다.
    3. 차트를 설치합니다.
    4. ServiceMonitor로 수집 대상을 선언합니다.
    kubectl create namespace monitoring
    helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
    helm repo update
    helm install monitoring prometheus-community/kube-prometheus-stack -n monitoring

    설치가 끝나면 Prometheus와 Grafana가 함께 배포됩니다. 여기까지는 꽤 부드럽게 갑니다. 진짜 체감 포인트는 그 다음부터예요. 애플리케이션 하나 추가할 때마다 prometheus.yml을 직접 안 만지고, ServiceMonitor만 선언하면 되거든요.

    apiVersion: monitoring.coreos.com/v1
    kind: ServiceMonitor
    metadata:
      name: sample-app
      namespace: monitoring
    spec:
      selector:
        matchLabels:
          app: sample-app
      namespaceSelector:
        matchNames:
          - app-space
      endpoints:
        - port: metrics
          path: /metrics
          interval: 30s

    이 방식의 장점은 명확합니다. 애플리케이션 쪽 Service에 라벨만 잘 붙어 있으면, 모니터링 설정이 애플리케이션 배포 흐름에 자연스럽게 붙습니다. GitOps(Git옵스, Git 기반 선언형 운영) 하시는 분들이 Operator를 좋아하는 이유가 여기 있습니다.

    ServiceMonitor가 서비스 라벨을 기준으로 메트릭 수집 대상을 찾아가는 흐름을 보여주는 구성 다이어그램입니다.

    실전 구현 2: Prometheus 직접 설정으로 구성하기

    이번엔 직접 설정입니다. 이 방식은 Prometheus가 어떻게 동작하는지 이해하기엔 정말 좋습니다. 저도 처음 구조를 배울 때는 이 방법으로 오래 굴렸습니다. 다만 규모가 커지면 금방 손이 많이 가더라고요.

    1. Prometheus 설정을 담을 ConfigMap을 만듭니다.
    2. RBAC(Role-Based Access Control, 역할 기반 권한 제어)를 설정합니다.
    3. Deployment와 Service를 배포합니다.
    4. targets 페이지에서 수집 상태를 확인합니다.
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: prometheus-config
      namespace: monitoring
    data:
      prometheus.yml: |
        global:
          scrape_interval: 30s
        scrape_configs:
          - job_name: 'kubernetes-pods'
            kubernetes_sd_configs:
              - role: pod
            relabel_configs:
              - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
                action: keep
                regex: true
              - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
                action: replace
                target_label: __metrics_path__
                regex: (.+)
              - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
                action: replace
                regex: ([^:]+)(?::\d+)?;(\d+)
                replacement: $1:$2
                target_label: __address__
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: prometheus
      namespace: monitoring
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: prometheus
      template:
        metadata:
          labels:
            app: prometheus
        spec:
          serviceAccountName: prometheus
          containers:
            - name: prometheus
              image: prom/prometheus
              args:
                - --config.file=/etc/prometheus/prometheus.yml
              ports:
                - containerPort: 9090
              volumeMounts:
                - name: config
                  mountPath: /etc/prometheus
          volumes:
            - name: config
              configMap:
                name: prometheus-config

    직접 설정의 핵심은 relabel_configs를 이해하는 겁니다. 이 부분이 처음엔 진짜 벽처럼 느껴집니다. 저도 여기서 꽤 오래 멈췄었어요. 왜 target이 안 잡히는지 몰라서 annotation(어노테이션, 메타데이터) 오타 하나 찾겠다고 한참 봤던 기억이 납니다.

    대신 이 방식은 구조가 명확합니다. 어떤 설정이 왜 들어갔는지 한 줄씩 따라갈 수 있어요. 학습용으로는 정말 좋습니다.

    Grafana 연동은 어떻게 보나

    Grafana 연동은 두 방식 모두 어렵지 않습니다. 차이는 연결보다도 대시보드와 데이터소스(Data Source, 데이터 공급원) 관리 방식에서 납니다. Operator 스택을 쓰면 Grafana가 함께 올라오는 경우가 많아서 시작이 빠릅니다. 직접 설정은 Prometheus만 먼저 올리고 Grafana를 따로 배포하는 흐름이 일반적입니다.

    kubectl port-forward svc/monitoring-grafana -n monitoring 3000:80
    kubectl port-forward svc/prometheus -n monitoring 9090:9090

    Grafana에서 Prometheus URL을 연결한 뒤, Kubernetes 관련 대시보드를 붙이면 CPU, 메모리, Pod 재시작 수, 노드 상태 등을 한눈에 볼 수 있습니다. 드디어 됐다! 하는 순간이 여기서 오죠. 숫자가 그래프로 보이기 시작하면, 그전까지는 안 보이던 병목이 갑자기 눈에 들어옵니다.

    ⚠️ 실제 겪었던 문제와 트러블슈팅

    여기서부터가 진짜 운영입니다. 설치보다 문제 해결이 더 중요하거든요.

    1. ServiceMonitor를 만들었는데 target이 안 잡힐 때

    • Service 라벨과 ServiceMonitor selector가 일치하는지 확인합니다.
    • metrics 포트 이름이 ServiceMonitor의 endpoints.port와 같은지 봅니다.
    • namespaceSelector가 실제 애플리케이션 네임스페이스를 포함하는지 체크합니다.

    이건 제가 꽤 자주 겪었습니다. 특히 포트 번호가 아니라 포트 이름으로 매칭한다는 걸 놓치면 한참 헤매게 됩니다.

    2. 직접 설정에서 scrape가 안 될 때

    • Pod annotation 키가 정확한지 봅니다.
    • RBAC 권한이 충분한지 확인합니다.
    • Prometheus UI의 Status > Targets에서 에러 메시지를 먼저 봅니다.

    처음엔 Prometheus 로그부터 뒤졌는데, 실제로는 Targets 화면이 더 빠르더라고요. 여기서 중요한 포인트! 모니터링 장애는 대개 설정 오타나 권한 누락에서 시작합니다.

    3. Grafana에 데이터가 안 보일 때

    • Prometheus 데이터소스 URL이 맞는지 확인합니다.
    • Prometheus 쿼리(PromQL, 프로메테우스 질의 언어)에서 메트릭이 실제로 조회되는지 먼저 봅니다.
    • 시간 범위(Time Range)가 너무 짧지 않은지 확인합니다.

    이건 별거 아닌데 은근 자주 나옵니다. 수집은 되고 있는데, 대시보드 시간 범위가 안 맞아서 “왜 빈 화면이지?” 하고 멍해지는 경우가 있거든요. 저도 몇 번 당했습니다 ㅎㅎ

    검증과 결과: 운영해보면 어떤 차이가 나나

    결론부터 말하면, Prometheus Operator vs 직접 설정은 단순한 기능 비교가 아니라 운영 방식의 선택에 가깝습니다.

    관점 Operator 직접 설정
    빠른 시작 Helm 기반으로 빠름 구성요소를 이해하면 빠름
    변경 관리 리소스 단위로 분리되어 편함 중앙 설정 파일이 비대해지기 쉬움
    문제 분석 CRD 구조 이해가 필요 설정 파일 기준으로 직관적
    확장 운영 유리함 점점 수동 작업 증가
    학습 가치 운영 패턴 학습에 좋음 Prometheus 내부 구조 학습에 좋음

    제가 실제로 써보니까, 작은 테스트 환경에서는 직접 설정이 부담이 적었습니다. 반면 운영 서비스가 두세 개를 넘어가고, 여러 네임스페이스에 exporter(exporter, 메트릭 노출 구성요소)가 붙기 시작하면 Operator 쪽이 확실히 편해집니다. 특히 팀원이 함께 건드리는 순간부터 차이가 커져요.

    Grafana 연동 결과로 Kubernetes 모니터링 대시보드를 보여주는 이미지

    Grafana 대시보드와 Prometheus 타깃 상태 화면을 함께 보여주는 결과 검증 이미지입니다.

    자주 묻는 질문 정리

    Q1. 입문자는 어떤 방식부터 시작하는 게 좋을까요?

    제가 추천하는 순서는 이렇습니다. 먼저 직접 설정으로 구조를 이해하고, 운영에는 Operator를 쓰는 방식입니다. 둘 중 하나만 알면 나중에 막힐 때 원인 파악이 어렵더라고요.

    Q2. 무조건 Operator가 정답인가요?

    그건 아닙니다. 싱글 클러스터 홈랩이나 짧은 실험 환경에서는 직접 설정이 더 가볍고 빠를 수 있습니다. 특히 CRD 추가를 최소화하고 싶다면 여전히 좋은 선택입니다.

    Q3. Grafana까지 꼭 같이 써야 하나요?

    필수는 아니지만, 실전에서는 거의 같이 갑니다. Prometheus가 수집과 저장을 담당하고, Grafana가 시각화를 담당하니까 역할이 깔끔하게 나뉘거든요.

    정리: 지금 선택해야 한다면 저는 이렇게 갑니다

    Kubernetes 모니터링을 장기적으로 운영할 계획이라면 저는 대체로 Operator를 권합니다. 선언형 리소스로 관리되고, 팀 협업에도 잘 맞고, 알림 규칙과 확장도 편하거든요. 반대로 학습 목적이 강하거나, 작은 홈랩에서 구조를 이해하고 싶다면 직접 설정으로 한 번 부딪혀보는 것도 아주 좋습니다. 저도 그렇게 배우면서 삽질 좀 했습니다. 근데 그 삽질 덕분에 지금은 문제가 생겨도 어디를 먼저 봐야 하는지 감이 오더라고요.

    혹시 지금 Prometheus Operator vs 직접 설정 사이에서 고민 중이시라면, 질문을 이렇게 바꿔보시면 결정이 쉬워집니다. “내가 지금 배우고 싶은가, 아니면 오래 운영하고 싶은가?” 이거거든요. 답이 전자면 직접 설정, 후자면 Operator 쪽이 보통 맞습니다.

    Prometheus Operator vs 직접 설정 선택 기준을 요약한 비교 이미지

    두 방식의 장단점과 추천 사용 시나리오를 한눈에 요약한 인포그래픽 이미지입니다.

    다음 글에서는 Alertmanager(알림 관리자)와 Slack 같은 채널 연동, 그리고 PromQL 기초 쿼리를 다뤄볼 예정입니다. 이전 글에서 exporter 구성 방법을 보셨다면 이번 내용이 더 잘 이어질 거예요. ✅

  • [Proxmox] Proxmox API 활용, Grafana 연동을 통한 자원 사용량 모니터링 및 자동화 사례

    [Proxmox] Proxmox API 활용, Grafana 연동을 통한 자원 사용량 모니터링 및 자동화 사례

    [인프라] Proxmox API Grafana 연동으로 자원 사용량 모니터링과 자동화 사례

    홈랩이나 소규모 가상화 환경을 굴리다 보면, 처음에는 Proxmox VE(프록스목스 가상화 환경) 웹 UI만 봐도 충분하다고 느끼실 수 있습니다. 저도 그랬거든요. 그런데 VM이 몇 대만 넘어가도 CPU, Memory(메모리), Storage(스토리지) 사용량이 순간적으로 튀는 구간이 보이고, 그때마다 사람이 직접 들어가 확인하는 방식은 금방 한계가 오더라고요. 그래서 이번 글에서는 Proxmox API Grafana 조합으로 자원 사용량을 한눈에 보고, 특정 조건에서는 자동화까지 연결한 실제 운영 패턴을 정리해보겠습니다. Proxmox 모니터링과 API 자동화, Grafana 연동이 왜 같이 가야 하는지, 제가 직접 해보면서 느낀 삽질 포인트까지 솔직하게 적어보겠습니다.

    특히 이런 분들께 잘 맞습니다. VM 수가 늘면서 자원 사용량을 장기적으로 보고 싶으신 분, 장애 직전의 징후를 미리 잡고 싶으신 분, 그리고 반복 확인 작업을 자동화하고 싶으신 분이요. 여기서 중요한 포인트! 단순히 대시보드만 예쁘게 만드는 게 목적이 아니라, 운영 판단 속도를 올리는 것이 핵심입니다.

    Proxmox API Grafana 연동 전체 흐름을 보여주는 아키텍처 예시입니다. Proxmox 노드, 메트릭 수집 스크립트, 시각화 계층의 관계를 한눈에 볼 수 있게 배치하면 이해가 훨씬 쉬워집니다.

    왜 Proxmox API Grafana 구성이 중요한가

    쉽게 말해 Proxmox API는 현재 상태를 꺼내오는 창구이고, Grafana는 그 상태를 사람이 판단하기 좋은 형태로 보여주는 대시보드입니다. 둘을 따로 보면 평범한데, 같이 묶으면 운영 품질이 꽤 달라집니다.

    예를 들어 웹 UI에서는 지금 CPU가 높은지 낮은지 바로 볼 수는 있어도, 지난 일주일 동안 특정 VM이 언제부터 메모리를 먹기 시작했는지, 백업 시간대와 I/O 부하가 겹쳤는지 같은 맥락은 금방 흐려집니다. 실제로 써보니까, 이 부분이 사람이 체감하는 운영 난이도를 크게 갈라놓더라고요.

    • Proxmox API: 노드, VM, 컨테이너(CT), 스토리지 상태를 JSON 형태로 조회
    • Grafana: 시계열 그래프, 표, 상태 패널로 이상 징후 시각화
    • 자동화: 임계치 초과 시 알림 또는 후속 작업 실행

    저는 초반에 “그냥 필요한 순간에 UI 들어가서 보면 되지 않을까?”라고 생각했었는데요. 막상 밤에 부하가 튀고, 다음 날 와서 원인을 보려니 이미 지나간 데이터는 감으로만 추적하게 되더라고요. 그때부터 API 기반 수집을 붙였습니다. 드디어 됐다 싶은 순간이 있었던 게, 장애가 나기 전에 패턴이 보이기 시작했다는 점이었습니다.

    핵심 개념 정리: API 자동화와 Proxmox 모니터링

    Proxmox API는 무엇을 주는가

    Proxmox VE는 REST API(레스트 API, HTTP 기반 관리 인터페이스)를 제공합니다. 이 API로 노드 목록, VM 상태, CPU 사용량, 메모리 점유, 디스크 상태 같은 정보를 조회할 수 있습니다. 인증은 보통 API Token(토큰 인증)이나 세션 기반으로 처리합니다.

    여기서 주의하실 점은, API가 만능은 아니라는 겁니다. 현재값(current) 조회에는 아주 편하지만, 장기 보관과 비교 분석은 별도 저장 계층이 있어야 합니다. 그래서 Grafana를 붙일 때도 대개는 중간에 메트릭 저장소나 수집 스크립트를 둡니다.

    Grafana는 어디서 빛나는가

    Grafana는 단순 그래프 툴이 아니라, 운영자가 “그래서 지금 뭘 해야 하지?”를 판단하게 해주는 시각화 도구에 가깝습니다. CPU 평균, 메모리 사용률, VM별 트렌드, 노드별 비교, 이상치 탐지에 강하거든요.

    구성 요소 역할 운영 포인트
    Proxmox API 실시간 상태 조회 인증과 요청 빈도 관리가 중요
    수집 스크립트 API 응답을 메트릭 형태로 변환 실패 시 재시도와 로그 필요
    Prometheus 시계열 메트릭 저장 스크랩 주기와 보존 기간 설계
    Grafana 대시보드/알림 운영자 시점 패널 구성 필요

    혹시 이런 경험 있으신가요? 숫자는 많은데, 막상 어떤 VM이 문제인지 바로 안 보이는 상황이요. 저는 딱 그랬습니다. 그래서 패널을 예쁘게 만드는 것보다, 노드 단위와 VM 단위를 분리해서 보는 구조가 더 중요하다는 걸 뒤늦게 배웠습니다.

    실전 구현 1: Proxmox API 토큰과 수집 흐름 만들기

    제가 실제로 안정적으로 썼던 방식은 이렇습니다. Proxmox API에서 값을 읽고, Python(파이썬) 스크립트로 필요한 필드만 정리한 뒤, Prometheus exporter(프로메테우스 익스포터, 메트릭 노출기) 형태로 내보내고, Grafana에서 이를 시각화하는 구조입니다. Grafana가 직접 API를 두드리는 방식도 가능은 하지만, 운영해보니 중간 계층을 두는 편이 훨씬 관리가 편하더라고요.

    1. Proxmox에서 읽기 전용 API Token 생성
    2. 수집 대상 노드와 VM 범위 정의
    3. Python 스크립트로 API 호출 및 메트릭 변환
    4. Prometheus가 주기적으로 수집
    5. Grafana 대시보드와 알림 정책 구성

    1. API 토큰 준비

    실서비스든 홈랩이든, 자동화에는 계정 분리가 기본입니다. 관리자 계정을 그대로 물리는 건 추천드리지 않습니다. 최소 권한 원칙(Principle of Least Privilege, 최소 권한 원칙)으로 읽기 전용 토큰을 따로 만드시는 게 좋습니다.

    export PVE_HOST="https://proxmox.example.local:8006"
    export PVE_TOKEN_ID="monitor@pve!grafana"
    export PVE_TOKEN_SECRET="YOUR_TOKEN_SECRET"
    

    환경 변수로 분리해두면 스크립트 수정 없이 운영하기 편합니다. 저는 처음에 토큰 문자열을 코드 안에 박아뒀다가, 나중에 회전(rotation)할 때 꽤 귀찮았거든요.

    2. API 확인

    먼저 가장 단순한 조회부터 붙여보면 감이 옵니다.

    curl -k -H "Authorization: PVEAPIToken=${PVE_TOKEN_ID}=${PVE_TOKEN_SECRET}" \
      "${PVE_HOST}/api2/json/nodes"
    

    응답은 JSON 형태로 오고, 여기서 노드 이름을 먼저 확인할 수 있습니다. 그다음 특정 노드의 상태를 조회합니다.

    NODE="pve01"
    curl -k -H "Authorization: PVEAPIToken=${PVE_TOKEN_ID}=${PVE_TOKEN_SECRET}" \
      "${PVE_HOST}/api2/json/nodes/${NODE}/status"
    

    이 단계에서 API 응답 구조를 손으로 한 번 읽어보시는 걸 추천드립니다. 제가 직접 해보니, 어떤 필드를 지표로 쓸지 이때 정리해두면 이후 Grafana 패널 설계가 훨씬 빨라집니다.

    Proxmox API 응답과 메트릭 수집 흐름을 보여주는 Grafana 연동 이미지

    API 응답 JSON에서 CPU, 메모리, 디스크 필드를 골라 메트릭으로 바꾸는 과정을 표현한 이미지 자리입니다. 중간 수집 계층의 역할을 보여주면 실전 흐름 이해에 도움이 됩니다.

    실전 구현 2: Python으로 메트릭 변환하고 Grafana 연동하기

    여기서는 예시로 간단한 Python 스크립트를 사용하겠습니다. 핵심은 Proxmox API 응답을 가져와서 Prometheus가 읽기 좋은 텍스트 포맷으로 내보내는 겁니다.

    import os
    import requests
    from flask import Flask, Response
    
    app = Flask(__name__)
    
    PVE_HOST = os.environ["PVE_HOST"]
    PVE_TOKEN_ID = os.environ["PVE_TOKEN_ID"]
    PVE_TOKEN_SECRET = os.environ["PVE_TOKEN_SECRET"]
    VERIFY_TLS = False
    
    
    def pve_get(path: str):
        headers = {
            "Authorization": f"PVEAPIToken={PVE_TOKEN_ID}={PVE_TOKEN_SECRET}"
        }
        r = requests.get(f"{PVE_HOST}{path}", headers=headers, verify=VERIFY_TLS, timeout=10)
        r.raise_for_status()
        return r.json()["data"]
    
    
    @app.route("/metrics")
    def metrics():
        lines = []
        nodes = pve_get("/api2/json/nodes")
    
        for node in nodes:
            node_name = node["node"]
            status = pve_get(f"/api2/json/nodes/{node_name}/status")
    
            cpu = status.get("cpu", 0)
            maxmem = status.get("memory", {}).get("total", 0) if isinstance(status.get("memory"), dict) else 0
            usedmem = status.get("memory", {}).get("used", 0) if isinstance(status.get("memory"), dict) else 0
    
            lines.append(f'proxmox_node_cpu_ratio{{node="{node_name}"}} {cpu}')
            lines.append(f'proxmox_node_memory_used_bytes{{node="{node_name}"}} {usedmem}')
            lines.append(f'proxmox_node_memory_total_bytes{{node="{node_name}"}} {maxmem}')
    
        body = "\n".join(lines) + "\n"
        return Response(body, mimetype="text/plain; version=0.0.4")
    
    
    if __name__ == "__main__":
        app.run(host="0.0.0.0", port=9108)
    

    여기서 한 가지 말씀드리면, 실제 API 응답 필드 구조는 환경에 따라 확인이 필요합니다. 그래서 처음부터 모든 리소스를 다 넣기보다, CPU와 메모리처럼 운영 판단에 바로 쓰이는 값부터 시작하는 편이 좋습니다. 저도 처음엔 욕심내서 디스크, 네트워크, VM 상태, 백업 작업까지 한 번에 넣으려다가 오히려 디버깅 시간이 길어졌습니다.

    Prometheus 스크랩 설정

    scrape_configs:
      - job_name: "proxmox-api-exporter"
        metrics_path: /metrics
        static_configs:
          - targets:
              - "proxmox-exporter.local:9108"
    

    이제 Grafana에서는 Prometheus 데이터 소스를 연결하고 패널을 만듭니다. 예를 들면 이런 쿼리들이 기본 뼈대가 됩니다.

    proxmox_node_cpu_ratio * 100
    
    (proxmox_node_memory_used_bytes / proxmox_node_memory_total_bytes) * 100
    

    Grafana 연동에서 중요한 건 패널 개수보다 뷰의 목적입니다. 저는 보통 아래처럼 나눕니다.

    • 상단: 노드별 CPU, 메모리 전체 상태
    • 중단: VM별 Top N 사용량
    • 하단: 지난 24시간 변화량과 이상 구간

    이 구성이 생각보다 편합니다. 문제를 위에서 아래로 좁혀 들어가기 좋거든요.

    실전 구현 3: API 자동화로 반복 작업 줄이기

    이제 대시보드가 보이기 시작하면, 다음 단계는 자동화입니다. 저는 처음에 알림만 붙였다가, 나중에는 특정 조건에서 후속 작업을 자동으로 실행하는 구조까지 확장했습니다. 여기서 말하는 자동화는 무조건 VM을 강제로 끄는 위험한 방식이 아니라, 안전한 선에서 운영자 개입을 줄이는 보조 자동화입니다.

    예를 들면 이런 식입니다.

    1. 특정 노드 메모리 사용률이 일정 시간 이상 높게 유지됨
    2. Grafana Alerting(알림) 또는 별도 스크립트가 Webhook(웹훅)을 호출
    3. Webhook 수신 스크립트가 Slack, 메일, 또는 내부 운영 채널로 통보
    4. 필요 시 사전 정의된 Ansible(앤서블, 자동화 도구) 작업 실행

    저는 여기서 “자동 복구”라는 말을 쉽게 쓰지 않습니다. 자동화는 편하지만, 잘못 걸면 장애를 키우거든요. 대신 알림 + 안전한 후속 조치 구조가 현실적이었습니다.

    import requests
    
    THRESHOLD = 0.90
    
    
    def notify_if_high(node_name, memory_ratio):
        if memory_ratio >= THRESHOLD:
            requests.post(
                "https://hooks.example.local/proxmox-alert",
                json={
                    "node": node_name,
                    "metric": "memory",
                    "ratio": memory_ratio,
                    "message": f"{node_name} memory usage is high"
                },
                timeout=5,
            )
    

    작게 시작하시는 걸 추천드립니다. 예를 들면 “임계치 초과 시 알림”까지만 먼저 붙여도 운영 피로도가 꽤 줄어듭니다. 그다음에 스냅샷 정리, 백업 전 상태 점검, 테스트 VM 정리 같은 보조 자동화를 단계적으로 넣는 게 안전합니다.

    Proxmox 모니터링과 Grafana 연동 결과를 보여주는 운영 대시보드 이미지

    노드 CPU, 메모리 추이 그래프와 임계치 초과 알림 흐름을 함께 보여주는 이미지 자리입니다. 결과가 머릿속에 바로 그려지게 만드는 용도로 좋습니다.

    ⚠️ 제가 겪었던 문제들: 인증, TLS, 지표 해석

    여기 구간은 정말 중요합니다. 문서만 보면 금방 될 것 같았는데, 실제로는 여기서 삽질을 좀 했습니다 ㅎㅎ

    1. API 인증은 되는데 일부 엔드포인트가 비어 보이는 문제

    원인은 대부분 권한 범위였습니다. 토큰이 살아 있어도 읽기 권한이 필요한 경로에 충분히 부여되지 않으면 응답이 제한적으로 보일 수 있습니다. 관리자 토큰으로 대충 해결하기보다, 어떤 리소스를 읽어야 하는지 먼저 정리하고 권한을 맞추시는 게 좋습니다.

    2. 사설 인증서(Private CA) 때문에 요청 실패

    홈랩에서는 TLS(전송 계층 보안) 인증서를 자체 서명으로 쓰는 경우가 많죠. 저도 처음엔 요청마다 인증서 검증 오류가 났습니다. 개발 단계에서만 검증을 끄고, 운영 단계에서는 신뢰할 수 있는 CA를 배포하는 쪽이 맞습니다. 검증 비활성화는 임시 조치라고 생각하셔야 합니다.

    3. CPU 비율과 메모리 절대값을 한 패널에 섞어놓은 실수

    이거 진짜 헷갈리더라고요. 초반엔 한 패널에 다 넣었다가 그래프 해석이 너무 어려웠습니다. 비율(%)과 절대값(Bytes)은 분리해서 보는 게 맞습니다. 운영자는 예쁜 그래프보다 빠른 판단이 중요하거든요.

    4. 스크랩 주기를 너무 짧게 잡은 문제

    수집 주기를 과하게 짧게 잡으면 API 요청 수만 늘고, 얻는 실익은 크지 않을 수 있습니다. 특히 홈랩처럼 자원이 넉넉하지 않은 환경에서는 더 그렇습니다. 저는 처음엔 촘촘하게 잡아야 정확할 줄 알았는데, 실제로는 운영 목적에 맞는 간격이 더 중요했습니다.

    • 실시간 장애 대응이 목적이면 짧은 주기
    • 용량 계획(capacity planning, 용량 계획)이 목적이면 중간 주기
    • 장기 추세 분석이 목적이면 보존 정책이 더 중요

    검증: 대시보드에서 무엇이 보이면 성공인가

    모니터링은 붙였다고 끝이 아닙니다. 검증 기준이 있어야 합니다. 제가 보는 기준은 아래와 같습니다.

    1. 노드별 CPU, 메모리 사용률이 시간 흐름으로 안정적으로 보이는가
    2. 특정 VM의 급격한 사용량 증가가 구분되는가
    3. 백업, 배치 작업, 업데이트 시간대와 부하 상관관계가 보이는가
    4. 임계치 초과 시 알림이 중복 없이 적절히 오는가

    이 정도만 확보돼도 Proxmox 모니터링 체계가 운영에 실제 도움이 되기 시작합니다. 숫자를 모으는 것과 운영에 쓰는 건 다르거든요. 저는 Grafana에서 하루 뷰, 7일 뷰, 30일 뷰를 나눠두니 체감이 확 달랐습니다. 하루 뷰는 장애 분석용, 7일 뷰는 패턴 확인용, 30일 뷰는 증설 판단용으로 쓰기 좋았습니다.

    그리고 의외로 유용했던 게 표(Table) 패널입니다. Top N VM 목록을 표로 뽑아두면, 그래프보다 바로 눈에 들어오는 경우가 많습니다. 특히 야간에 급한 상황에서는요.

    Proxmox API Grafana 기반 자원 사용량 시각화 결과 이미지

    Grafana에서 CPU, 메모리 추이를 시각화하고 VM별 Top N 표를 함께 보여주는 결과 예시 이미지 자리입니다. 모니터링 완성 상태를 전달하기 좋습니다.

    정리: 제가 다시 구성한다면 이렇게 하겠습니다

    지금 다시 처음부터 구성한다면, 저는 이렇게 갑니다.

    • 1단계: Proxmox API로 노드/VM 기본 지표만 수집
    • 2단계: Prometheus에 저장하고 Grafana에서 노드/VM 대시보드 분리
    • 3단계: 알림 추가
    • 4단계: 안전한 범위의 API 자동화 연결

    중요한 건 처음부터 모든 걸 다 하려 하지 않는 겁니다. 저도 처음엔 “이왕 하는 김에 완벽하게” 갔다가 시간이 꽤 들었어요. 그런데 운영은 결국 지속 가능해야 하더라고요. 작게 시작해서 점진적으로 확장하는 쪽이 훨씬 오래 갑니다.

    이번 글의 핵심을 짧게 정리하면 이렇습니다. Proxmox API Grafana 조합은 단순 시각화 도구가 아니라, 운영 판단 체계를 만드는 기반입니다. API 자동화는 반복 작업을 줄여주고, Grafana 연동은 문제를 더 빨리 보게 해줍니다. 둘이 합쳐질 때 가치가 커집니다.

    다음 글에서는 Proxmox 백업 작업과 알림 흐름을 더 세밀하게 묶는 방법, 그리고 장기 보존 지표를 기준으로 증설 시점을 판단하는 방법도 다뤄볼 예정입니다. 이전 글에서 홈랩 네트워크 분리와 스토리지 구성 이야기를 보셨다면, 이번 구성과 같이 연결해서 보시면 훨씬 이해가 잘 되실 겁니다.

    구성 요소, 장점, 주의사항, 자동화 확장 단계를 한 장으로 요약하는 인포그래픽 자리입니다. 글 마무리 직전에 넣으면 복습용으로 좋습니다.

    자주 묻는 질문

    Grafana가 Proxmox API를 직접 읽어야 하나요?

    반드시 그럴 필요는 없습니다. 제가 운영해보니 중간 수집 계층을 두는 편이 안정적이었습니다. API 응답을 바로 시각화하는 것보다 메트릭 구조를 정리한 뒤 보여주는 쪽이 관리가 쉽습니다.

    API 자동화는 어디까지 붙이는 게 좋을까요?

    처음에는 알림과 로그 수집 정도가 적당합니다. 운영 흐름이 충분히 검증된 뒤에 후속 작업 자동화를 넣는 게 안전합니다.

    Proxmox 모니터링에서 가장 먼저 볼 지표는 무엇인가요?

    노드 CPU, 메모리 사용률, 그리고 VM별 상위 사용량 목록부터 시작하시면 됩니다. 이 세 가지가 문제 파악 속도를 가장 많이 올려줍니다.