ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • prometheus.yml 환경 변수 이용해서 동적으로 설정하기
    Metric 2021. 4. 17. 21:39
    반응형

    개요

    최근 회사에서 모니터링 시스템을 구축 관련 IaC 작업을 하다가 생긴 일이다. 내가 직면했던 문제 상황은 다음과 같다.

     

    1. 현재 시스템 내에서 메트릭 수집은 Prometheus가 담당하고 있고 Consul 서비스 디스커버리 연동 기능을 통해서 시스템 내의 다른 서버 인스턴스들의 메트릭을 수집하고 있다.
    2. Terraform으로 AWS 리소스들을 자주 생성/삭제를 하게 된다. 따라서 EC2 인스턴스의 할당된 public IP도 고정되지 않고 자주 바뀐다. 
    3. 따라서 Prometheus는 동적으로 변경되는 Consul의 Control Plane Node 서버의 IP를 참조하여 설정되어야 한다.

    따라서 prometheus.yml이 동적으로 변경되는 IP를 참조할 수 있는 방법을 찾아보게 되었다.

    해결 방법의 종류

    아쉽게도 다음과 같이 일반적으로 yaml에서 환경 변수를 참조하는 방법으로는 해결이 안된다.

    # ...
    
    scrape_configs:
      - job_name: 'loki'
        scrape_interval: 5s
    
        consul_sd_configs:
          - server : ${CONSUL_ADDR}:8500
        relabel_configs:
          - source_labels: [__meta_consul_service]
            regex: loki-cluster
            action: keep
          - source_labels: [__meta_consul_address]
            replacement: '${1}:3100'
            target_label: __address__
    
    # ...

     

    relabel_configs에 replacement 처럼 "${}"를 써야하는 설정들이 있기 때문에 의도적으로 이 기능을 뺀것으로 보인다. 일단 공식 문서를 찾아봤지만 prometheus.yml을 동적으로 설정하는 방법은 없다. 내가 찾은 방법은 다음의 3가지다.

     

    1. consul control plane node 서버만 Terraform 관리 대상에서 제외시켜서 IP를 고정시킨다.
    2. external_labels 활용
    3. sed 등의 도구를 이용해서 실행 전 값 대체 
    참고! 설정 파일에서 환경 변수 대체 기능 지원에 대한 제안

    https://github.com/prometheus/prometheus/issues/2357를 보면 prometheus.yml에서 환경 변수를 대체하는 기능에 대한 토론을 살펴볼 수 있습니다. 원래는 위 기능에 대한 지원을 안하기로 했으나 최근 투표를 통해서 external_label에서 환경 변수를 대체할 수 있는 기능이 prometheus 2.27버전부터 들어가게 되었다는 것을 확인할 수 있습니다.

     

    일단 3가지 방식 모두 각각 단점들이 존재한다.

     

    먼저 첫 번째 방식은 consul control plane node 서버에 대한 리소스 관리를 수동으로 해야 한다라는 단점이 있다. 가장 쉽지만 수동으로 관리해야 하는 포인트가 늘어난다는 점에서 뭔가 깨림칙하다.

     

    두 번째 방식은 예제가 별로 없을 뿐더러 현재는 외부에서 ConfigMap을 따로 구성해야 한다라는 번거로움이 있다. 추후 2.27 버전을 사용하면 환경 변수를 이용하여 쉽게 대체할 수 있겠지만 21년 4월 기준, 아직 rc 버전조차 나오지 않았기 때문에 이 방법도 적절하지 않다라는 생각이 들었다..

     

    마지막으로 세 번째 방식은 위의 이슈에서 확인할 수 있는데 쿠버네티스등의 컨테이너 오케스트레이션을 사용하고 있을 때 컨테이너 별 단일 프로세스 모범 사례를 깬다라는 단점이 있다고 한다. 또한 개인적으로 참조해야 할 환경 변수가 많으면 많을수록 사용하기 번거로울 것 같다라는 생각이 든다.

    일단 내가 직면한 상황에서는 일단은 고려하지 않아도 될 것 같다라고 결론을 내렸고 세 번째 방식을 선택했다. 

    prometeus.yml 동적으로 설정하고 테스트해보기

    일단 promethes.yml을 다음과 같이 구성한다.

    # ...
    
    scrape_configs:
      - job_name: 'loki'
        scrape_interval: 5s
    
        consul_sd_configs:
    	# {{CONSUL_ADDR}}을 sed로 대체할 것임.
          - server : {{CONSUL_ADDR}}:8500
        relabel_configs:
          - source_labels: [__meta_consul_service]
            regex: loki-cluster
            action: keep
          - source_labels: [__meta_consul_address]
            replacement: '${1}:3100'
            target_label: __address__
    
    # ...

     

     

    그리고 터미널에서 Prometheus 실행 전에 다음을 입력한다.

    # consul conrol plane node private_ip 환경 변수 설정
    $ export CONSUL_ADDR=10.10.101.17
    
    # sed를 이용해서 {{CONSUL_ADDR}}을 consul control plane node의 private_ip로 대체 
    $ sudo sed -i "s/{{CONSUL_ADDR}}/${CONSUL_ADDR}/g" /home/ec2-user/apps/prometheus/prometheus.yml
    
    # prometheus 재시작
    $ sudo systemctl restart prometheus

     

     

    이 후 Prometheus UI(http://<monitoring server IP>:9090)를 접속한다. 그 후 상단 탭 Status > Service Discovery 메뉴를 클릭하면 서비스 디스커버리를 통해서 연동되는 인스턴스들을 확인할 수 있다. 

    그림에서 알 수 있듯이 위 설정을 통해서 Consul에서 인스턴스 메트릭들을 가져오는 것을 확인할 수 있다.

    'Metric' 카테고리의 다른 글

    알람 파이프라인 구축하기  (0) 2021.06.26
    Prometheus Query (1) PromQL 기본  (2) 2021.04.20
    Prometheus Label  (0) 2021.04.16
    Prometheus Metric Type  (2) 2021.04.09
    Cortex란 무엇인가  (2) 2021.03.23
Designed by Tistory.