Information Security Study

federation 심화 - 인스턴스별로 라벨처리하기 본문

네트워크 캠퍼스/3차 프로젝트

federation 심화 - 인스턴스별로 라벨처리하기

gayeon_ 2024. 8. 16. 15:28

federation 심화 - 인스턴스별로 라벨처리하기

 

Instance 구분과 외부 라벨

  • Instance Label (instance): Prometheus의 기본적인 라벨로 보통 모니터링하는 대상의 주소(예: localhost:8080)가 들어간다. 이 라벨은 특정 인스턴스를 구분하는 데 사용된다.

 

하지만 Federation의 동작 원리는 Instance 구분을 어렵게 한다.

  • Federation에서 상위 Prometheus는 하위 Prometheus에서 특정 시리즈(메트릭)를 가져온다. 이때, 하위 Prometheus에서 데이터가 상위 Prometheus로 전달될 때 하위 Prometheus의 instance 라벨 값이 유지되지 않거나 localhost로 통일되는 경우가 발생할 수 있다. 이는 하위 Prometheus 서버가 자신의 scrape 대상 인스턴스를 localhost로 수집하고 그 데이터를 상위 Prometheus에 전달할 때 그대로 보내기 때문이다.

=> 그래서 external_labels 또는 relabel_configs 를 사용한다.

 

Federation 에 따라 instance Label 의 값이 localhost:8080 으로 통일된 경우 추가 Label(app_name, instance_id) 을 사용해야 각 인스턴스별 Metric 쿼리 가능!

 

External Labels

  • Federation과 같은 대규모 모니터링 쿼리 플랜에서 데이터 소스를 구분하기 위해 하위 Prometheus에서 상위 조회 단위로 데이터를 보낼 때 설정하는 추가 라벨이다. 
  • external_labels는 주로 데이터 출처(예: 데이터 센터, 클러스터, 지역)를 구분하기 위해 사용된다.
  • 외부 라벨을 통해 instance 라벨을 덮어쓰지 않는 한 상위 Prometheus는 하위 Prometheus가 수집한 원본 instance 값을 그대로 받게 된다. 그러나 일반적으로 external_labels에 설정된 값만이 상위 Prometheus에서의 데이터 구분을 위한 주요 정보로 사용된다.

 

External Lables 예시

global:
  scrape_interval: 15s
  evaluation_interval: 15s

  external_labels:
      monitor: 'application01'

 

prometheus.yml에 위와 같이 external_labels를 추가 해 주면 같은 instance 라벨로 잡힌 인스턴스 지표도

구분되어서 표현할 수 있다.

 

 

Relabel Configs

  • Relabeling은 Prometheus에서 메트릭을 수집할 때 메트릭의 라벨을 동적으로 수정하거나 추가하는 방법이다. 이를 통해 특정 라벨의 값을 변경하거나 새로운 라벨을 추가함으로써 상위 Prometheus로 전송될 때 메트릭의 구성을 조정할 수 있다.
  • Instance 라벨 수정: relabel_configs를 사용하여 instance 라벨을 수정할 수 있다.
  • 예를 들어 하위 Prometheus에서 수집한 메트릭의 instance 라벨이 localhost:8080으로 설정되어 있을 경우 상위 Prometheus로 전송되기 전에 이를 특정한 값으로 변경할 수 있다.

 

Relabel Configs 예시

scrape_configs:
  - job_name: 'spring_app'
    static_configs:
      - targets: ['localhost:8080']

    relabel_configs:
      - source_labels: [__your_specific_source_address__]
        target_label: instance
        replacement: 'spring_app_instance'

 

localhost:8080으로 설정된 instance 라벨이 spring_app_instance로 변경된다. 이를 통해 상위 Prometheus에서 수집한 메트릭이 명확하게 구분될 수 있다.

 

 

honor_labels와 relabel_configs 설정의 상호작용 이해

 

1) honor_labels의 역할

  • honor_labels: true: 이 설정은 Prometheus가 타겟에서 수집한 메트릭의 기존 라벨을 "존중"하게 한다. 즉, 타겟에서 이미 설정된 라벨 값이 있을 경우 상위 Prometheus에서 이 값을 덮어쓰지 않고 그대로 유지한다.
  • 하위 Prometheus에서 instance 라벨이 localhost:8080으로 설정되어 있다면 상위 Prometheus는 이를 그대로 유지한다.

 

2) relabel_configs의 역할

  • relabel_configs: 이 설정은 수집한 메트릭의 라벨을 변경하거나 추가, 삭제할 수 있는 규칙을 정의한다. relabel_configs는 여러 가지 방식으로 동작할 수 있으며 새로운 라벨을 추가하거나 기존 라벨을 덮어쓸 수 있다.

 

두 설정의 상호작용

  • honor_labels: true와 relabel_configs는 서로 상충될 수 있다. honor_labels가 true로 설정되어 있는 경우, 원칙적으로는 하위 Prometheus에서 이미 설정된 라벨(예: instance)을 상위 Prometheus가 변경하지 않도록 해야 한다.
  • 하지만 relabel_configs는 이 라벨을 덮어쓸 수 있는 기능을 가지고 있다. 따라서 relabel_configs가 특정 라벨을 덮어쓰도록 설정되어 있다면 그 라벨에 대해서는 honor_labels 설정이 무시될 수 있다. 즉, relabel_configs는 라벨 변경이 명시적으로 정의된 경우 honor_labels보다 우선이다.

 

 

honor_labels:true와 relabel_configs 설정 상호작용 예제

honor_labels: true

relabel_configs:
  - source_labels: [__address__]
    target_label: instance
    replacement: 'new-instance-name'

 

 

honor_labels: true 설정이 있다면 하위 Prometheus에서 설정된 instance 라벨이 존중되어야 한다.

그러나 relabel_configs에서 instance 라벨을 new-instance-name으로 덮어쓰도록 설정되어 있으므로 이 규칙이 우선되어 instance 라벨이 new-instance-name으로 변경된다.

 

 

결론

  • external_labels는 계층화된 모니터링 구조에서 상위 구조에 보여줄 식별자가 된다.
  • honor_labels는 기본적으로 타겟에서 수집된 라벨을 유지하려고 한다.
  • relabel_configs는 명시적으로 정의된 경우 이 라벨을 수정하거나 덮어쓸 수 있다.

 

 

 

모니터링 인스턴스 하위에 있는 앱 인스턴스들은 프로메테우스와 cpu, 메모리, 디스크 사용량 등을 수집하기 위해 node_export를 실행해줘야 한다.

모니터링 인스턴스는 cpu, 메모리 등의 사용량은 하위 앱들에서 집계만 하기 때문에 node_export가 필요 없다.

 

하위 Prometheus에서 node_exporter 메트릭을 수집하고 상위 Prometheus가 하위 Prometheus의 메트릭을 집계하도록 구성할 것이다.

 

하위 app2의 prometheus.yml

# my global config
global:
  scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
  evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
  # scrape_timeout is set to the global default (10s).

  external_labels:
        monitor: 'application02'
        instance_id: 'node2'
# Alertmanager configuration
alerting:
  alertmanagers:
    - static_configs:
        - targets:
          # - alertmanager:9093

# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
  # - "first_rules.yml"
  # - "second_rules.yml"

# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
  # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
  - job_name: "prometheus"
    # metrics_path defaults to '/metrics'
    # scheme defaults to 'http'.
    static_configs:
      - targets: ["localhost:9090"]

  - job_name: 'node'
    static_configs:
      - targets: ['localhost:9100']
    relabel_configs:
      - source_labels: [__address__]
        target_label: instance
        replacement: 'app2'

 

 

  • global: 모든 스크랩 구성에서 사용할 전역 설정
  • external_labels: 메트릭에 추가할 라벨
  • scrape_configs: 메트릭을 수집할 타겟을 정의
    • job_name: "prometheus": Prometheus 자체의 메트릭을 수집
    • job_name: 'node': node_exporter로부터 메트릭을 수집하고 instance 라벨을 'app2'로 변경

 

 

 

상위 모니터링 prometheus.yml

# my global config
global:
  scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
  evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
  # scrape_timeout is set to the global default (10s).

  external_labels:
    monitor: 'application02'
    instance: 'monitoring_prometheus_instance'
# Alertmanager configuration
alerting:
  alertmanagers:
    - static_configs:
        - targets:
          # - alertmanager:9093

# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
  # - "first_rules.yml"
  # - "second_rules.yml"

# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
  # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
  - job_name: "prometheus"

    # metrics_path defaults to '/metrics'
    # scheme defaults to 'http'.

    static_configs:
      - targets: ["localhost:9090"]

  - job_name: 'node'
    static_configs:
      - targets: ['localhost:9100']

  - job_name: 'app-health'
    scrape_interval: 5s
    metrics_path: '/app-health'
    static_configs:
      - targets: ['app1의 ip:8080']

  - job_name: 'federate'
    honor_labels: true
    metrics_path: '/federate'
    params:
      'match[]':
        - '{job="node"}'
        - '{__name__=~"job:.*"}'
    static_configs:
      - targets:
        - 'app1의 ip:9090'   # 하위 서버 1의 Prometheus
        - 'app2의 ip:9090'   # 하위 서버 2의 Prometheus

 

 

  • global: 모든 스크랩 구성에서 사용할 전역 설정
  • external_labels: 메트릭에 추가할 라벨
  • scrape_configs: 메트릭을 수집할 타겟을 정의
    • job_name: "prometheus": 상위 Prometheus 자체 메트릭을 수집
    • job_name: 'node': 상위 Prometheus는 node_exporter 메트릭을 직접 수집할 필요 없음
    • job_name: 'app-health': 어플리케이션의 상태 메트릭을 수집
    • job_name: 'federate': 하위 Prometheus에서 메트릭을 수집 (federate 엔드포인트 사용)

 

 

 

설정파일 변경 후 프로메테우스를 재시작해야 적용된다.

 

 

 

Label filtersd에서 instance를 선택하면 하위 프로메테우스 설정파일에서 지정한 replacement 값이 목록에 뜨며 메트릭도 잘 적용이 되어 cpu 사용량을 수집한다.