• VictoriaMetrics Stack 완전해부 - 1

    2026. 6. 9.

    by. Daramu

     

    이전 포스팅으로 설치에 대한 내용을 진행했었는데, 그때는 길이와 몇가지 사정으로 설치 yaml만 던져주고 끝났었다.

    이번 포스팅에서는 각 설정파일이 어떠한 동작을 하는지, 또 필요한 수정이 있다면 어떻게 진행하면 되는지 등 좀 자세한 설정을 볼 것이다.

     

    설치 과정이 궁금하다면 포스팅 참고:https://daramu.tistory.com/94

     

     

    앞서 말하고 싶은 내용은, 데이터 수집은 전적으로 Otel Collector가 담당한다는 것이다.

    뒤의 log, trace, metric을 담당하는 여러 요소는 "백엔드"로 통칭할 것이며, 각 백엔드의 역할은 데이터 저장과 쿼리문을 제공하여 Grafana에서 조회가가능 하도록 하는 역할이다. 파이프의 중간 라인이라고 보는것도 좋다.

     

     

    1.  VictoriaMetrics Operator values

    처음부터 시작하여 가장 먼저 "vm-operator-values.yaml" 을 작성했다.

    해당 파일은"VictoriaMetrics라는 모니터링 시스템을 관리하는 '관리자(Operator)'의 행동 지침서" 이다.

    enable_converter_ownership: true

    해당 설정은 Prometheus 설정을 VictoriaMetrics용으로 자동 변환하는 역할을 한다.

    모니터링 대상을 자동으로 탐지하고 연동하는 기능을 하며, Prometheus의 설정방식을 그대로 읽어서 가신의 것으로 Convert할 수 있게 허용하는 것이다.

    watchNamespaces: []

    이 설정은 모니터링 대상 범위 지정이다.

    어디까지 감시할 것인지를 정의하는 문서로, 빈 배열([])을 둔다면 모든 네임 스페이스를 감시하겠다는 선언이다. 어떠한 네임스페이스든 모니터링 켜달라는 요청을 받는다면 이 오퍼레이터가 바는하여 VictoriaMetrics 모니터링 본체를 띄운다.

     

     

    2. vmsingle-values.yaml

    이건 앞에 있는 Operator처럼 관리자 봇이 아니라, 실제로 모니터링 데이터를 수집하고 저장할 수 있는 VictoriaMetrics 모니터링 본체이다.

     

    VMagent가 수집한 데이터 저장 담당할 것이며,

    yaml표기는 VMSingle이지만 가장 위 그림의 VictoriaMetrics과 별도의 서비스가 아니다.

     

    "동일한 시스템을 부르는 명칭의 범위 차이"일 뿐이다. 이전 포스팅에 있던 yaml은 "VictoriaMetrics를 설치할 때 "서버 1대짜리 싱글 노드(Single) 버전으로 설치하겠다" 라는 내용인 것이다. 

     

    즉, VictoriMetrics 자리에 실제 쿠버네티스 pod로 뜬 서비스의 이름이 VMSingle 인 것이다.

     

    YAML
    server:
      retentionPeriod: 3

     

    수집된 메트릭 데이터를 "몇 개월동안 디스크에 유지할 것인가"를 정의한다. 3이라면 3개월이고, 3달전 데이터는 자동으로 삭제하겠다는 선언이다.

     

      persistentVolume:
        enabled: true
        size: 20Gi
        # storageClassName: "" # 필요시 지정

     

    외부 디스크의 연결 크기를 정한다. enable: true는 PV를 사용하곘다는 선언이고, Size는 그 크기를 정의한다.

    만약 EKS나 NKS를 사용한다면 storageClassName을 지정할 수 있다. 가령 gp3같은 특정 스토리지 클래스를 지정하여 고성능 EBS를 붙이는 등의 방법도 있다. NCP의 경우 기본이 SSD이기 때문에 주석처리했다.

     

    그렇기에 위의 파일 적용시, "kubectl get pvc"를 입력하면 아래 그림처럼 실제 볼륨이 붙은걸 볼 수 있다.

     

    3. vmagent-values.yaml

    설치는 다른 순서였지만, 이해를 쉽게 하기 위해 다음으로 실제 메트릭을 Scrape 하고 VMSingle이라는 창고로 배달하는 VMagent를 살펴볼 것이다.

    remoteWrite:
      - url: http://vmsingle-victoria-metrics-single-server.monitoring.svc.cluster.local:8428/api/v1/write

     

    위에서 설정하였던 VictoriaMetrics를 저장소로 쓰기 위한 기본 설정과 보관주소에 대한 정의다.

     

    monitoring 네임스페이스에 있는 VMSingle 서비스의 8428 포트로 데이터를 넣겠다는 것으로, 위 설정으로 VMAgent와 VMSingle(VictoriaMetrics)이 연결된다.

     

    실제로 "kubectl get service -n monitoring" 을 입력하면 아래 처럼 이전 설정하였던 서비스가 8428 포트로 떠있는걸 볼 수 있다. 이곳으로 데이터를 보내겠다는 정의다.

     

    알겠지만, 쿠버네티스 내부에서 서비스를 찾아가는 자체 DNS(FQDN)의 규칙은 아래와 같다.

    {service_name}.{namespace.svc}.cluster.local:{service_port}

     

    config:
      global:
        scrape_interval: 30s

    아래 수집 대상 목록을 어느정도 주기로 Scrape할거냐는 설정이다.

    yaml파일에는 30초로, 30초 마다 한번씩 데이터를 긁어가서 VMSingle에 저장한다.

     

     scrape_configs:

    위에 수집목록을 정의하는게 이 configs 내부의 값이다.

    여기에 정의된 데이터를 30초마다 긁어갈 것이다.

     

        - job_name: kubernetes-nodes
          scheme: https
    ...(생략)

    워커 노드(서버)의 자체 상태를 가져온다. kubelet API를 통해 노드가 살아있는지, 커널 수준의 에러는 없는지를 확인하다.

    보안에 걸려있기 때문에 쿠버네티스 내부의 토큰(bearer_token_file)과 인증서(ca_file)을 들고 HTTPS 통신으로 안전하게 긁어 오겠다는 뜻이다.

     

       - job_name: kubernetes-pods
          kubernetes_sd_configs:
            - role: pod
          relabel_configs:
            - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
    ...(생략)

    직접 배포한 애플리케이션(Spring Boot, Node.js, Go...etc...)의 내부 메트릭을 가져온다.

    예로 JVM 메모리, HTTP 요청 수 등이 있다.

     

    밑에 설정으로 모든 데이터를 가져오는게 아니라, pod 설정에 "prometheus.io/scrape: "true" 라는 annotation이 있어야만 수집한다. annotation이 있다면 /actuator/prometheus 또는 /metrics로 찾아가 데이터를 긁어간다.

     

    쉽게 말해 VMagent는 "당신이 어떠한 프레임워크를 쓰든 상관 없이, 나는 prometheus 표준 규격으로 메트릭을 뱉어주는 주소만 있으면 돼." 이다.

    만약 Spring Boot라면 java 코드로 직접 /metric 이라는 RestController API 를 직접 만들어 표준 규격 텍스트로 return하도록 만들면, 작동한다는 것이다.

     

    하지만 보통은 아래 두가지 의존성을 넣어 수집과 prometheus 규격 텍스트로 변환하는 작업을 한다.

    // 1. 애플리케이션의 상태와 메트릭 수집
    implementation("org.springframework.boot:spring-boot-starter-actuator")
    // 2. Actuator가 수집한 숫자를 'Prometheus/VMAgent 규격 텍스트'로 변환
    implementation("io.micrometer:micrometer-registry-prometheus")
    
    // applicatin.yaml에서 엔드포인트 오픈
    management:
      endpoints:
        web:
          exposure:
            include: "prometheus"
            
    //deployemt(혹은 pod)의 yaml에서 annotation
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: spring-boot-app
      namespace: default
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: spring-boot-app
      template:
        metadata:
          labels:
            app: spring-boot-app
          #이곳!
          annotations:
            prometheus.io/scrape: "true"
            prometheus.io/path: "/actuator/prometheus"
            prometheus.io/port: "8080"

    마지막 deployment에서 annotation을 넣는 이유는 pod 정의에서

    "- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]" 이 문구를 넣었기 때문이다.

    이 설정으로 Pod의 주석(Annotation) 중 'prometheus.io/scrape' 값만 가져오겠다고 정의했기 때문이다.

     

    물론 그것이 싫다면 아래처럼 수정으로 모든 데이터를 긁어올 수 있다.

    # 지정된 데이터만
       - job_name: kubernetes-pods
          kubernetes_sd_configs:
            - role: pod
          relabel_configs:
            - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
            
    # 모든 데이터
      - job_name: kubernetes-pods
            kubernetes_sd_configs:
              - role: pod

    근데 모든 데이터를 긁어오면, nginx, db 등 무의미한 데이터를 모두 수집하기에 말 그대로 쓰레기 에러 로그로 가득차게 될 것이다.

    그 안전장치라고 보면 된다.

     

        - job_name: kubernetes-nodes-cadvisor
          scheme: https
          tls_config:
    ...(생략)

    각 pod 내부 컨테이너의 cpu와 메모리를 얼마나 차지하고 있는지를 가져온다.

    kubelet에 내장된 cAdvisor 라는 모듈의 엔드포인트(/metrics/cadvisor)를 찔러서 가져온다.

     

        - job_name: node-exporter
          kubernetes_sd_configs:
    ...(생략)

    서버 리눅스 OS 레벨의 디스크 I/O 속도, 네트워크 대역폭 사용량, 실제 물리 메모리 잔여량 등을 가져온다. 클러스터에 설치된 prometheus-node-exporter 의 엔드포인트를 타겟으로 삼는다. 

     

    이 동작을 위해 설치 단계에서 vmagent전에, 아래 헬름 명령어로 node export를 설치한 것이다.

    물론 사용하지 않다면, 둘 다 삭제하면 된다.

    helm install node-exporter prometheus-community/prometheus-node-exporter \
      -n monitoring

     

        - job_name: kube-state-metrics
          static_configs:
            - targets:
    ...(생략)

    지금 deployment 가 정상적으로 동작중인지, pod가 몇개나 pending 상태인지등 쿠버네티스 오브젝트들의 메타데이터를 가져오고, 이건 주소가 변하지 않음으로 targets가 고정된 주소로 되어있는걸 볼 수 있다.

     

    포스팅이 길어지니, 이 다음은 2편으로 찾아가겠다.

    댓글