1. prometheus 로 웹서비스 모니터링 하기 – blackbox_exporter 연계하기

특정 웹서비스를 모니터링 하는 과정을 기록.

pulling metrics

회사에서 운영하는 대외 서비스의 서비스를 모니터링 하기 위해 그 유명하다는 prometheus 를 사용해 보았다. 공식 홈페이지의 기본 예제로 진행해 보았다. 내 식대로 이해해보면 prometheus 는 단순히 metric 이라는 것을 긁어서 저장하는 크롤링 서버다. (pull metrics)

무엇을 크롤링 하는가? 프로메테우스가 이해하기 좋은 형태의 시시각각 새로고침 되는 상태 정보다. 프로메테우스 설정에 등록된 모든 서버들에 프로메테우스가 주기적으로 접속해서 내용을 계속 긁어온다.

exporter

프로메테우스가 데이터를 잘 긁어갈 수 있도록 준비된 서버들이 필요하다. 이것을 보통 exporter 라고 부르며 이것이 준비 되어야 프로메테우스가 긁는 역할을 담당할 수 있다. exporter 는 독립실행형 프로그램이므로 프로메테우스를 설치 하기 전에 실행 할 수 있다. 따라서 잠시 프로메테우스에 대해서 잊도록 하자.

프로메테우스에게 긁힐만한 정보를 가진 서버들은 xx_exporter 라 불리우는 “추출기” 서비스가 기동되어 있어야 한다. 그 서비스의 포트로 프로메테우스가 주기적으로 접속해서 내용들을 주기적으로 가져간다. 물론 xx_exporter 는 계속 내용을 갱신하기 때문에 프로메테우스는 시시각각 변하는 서버의 정보를 끊임없이 모을 수 있게 된다.

공식 아키텍쳐. Retrieval 프로세서가 계속 긁어간다.

아래와 같이 프로메테우스에 등록된 어떤 URL 이 있다고 할 때 그 metric 지표는 아래와 같이 plain_text_key value 쌍으로 구성된 단순 text 여러줄의 모음이다. 중간에 주석이 많은데 그냥 고마운 설명이라 생각하고 넘어가자.

http://somehost.com:9115/metric

# HELP probe_dns_lookup_time_seconds Returns the time taken for probe dns lookup in seconds
# TYPE probe_dns_lookup_time_seconds gauge
# plain_text_key value
probe_dns_lookup_time_seconds 0.199540841
# HELP probe_duration_seconds Returns how long the probe took to complete in seconds
# TYPE probe_duration_seconds gauge
probe_duration_seconds 2.299759862 # 웹서버의 응답시간

이런 정보가 프로메테우스에 수집되면 그 plain_text_key 키값 그대로 검색을 할 수 있고 시시각각 변하는 값이 그래프로 나타나게 된다.

blackbox_exporter

프로메테우스에게 데이터를 모두 주기위해서 많은 서버들이 스스로 exporter 가 작동하는 등의 노력을 할 수도 있겠지만 내가 관리 할 수 없는 특정 API 의 상태를 체크 하고 싶다면 그 API 를 찔러보는 서버를 대상 서버 밖의 다른 곳에 두는 수 밖에 없다. 따라서 blackbox_exporter 를 이용하면 부족하나마 서비스를 모니터링 할 수 있다.

blackbox.yml

modules:
  http_2xx:
    prober: http
    timeout: 5s
    http:
      preferred_ip_protocol: "ip4" # 이 설정이 매우 중요
      method: GET
      valid_status_codes: [200, 302]
      headers:
        User-Agent: "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.55 Mobile Safari/537.36 Edg/96.0.1054.34"
  http_post_2xx:
    prober: http
    http:
      method: POST

여기에는 어떤 서버를 모니터링 할지는 안 나와 있고 blackbox_exporter 자체의 속성만 편집한다. 여기서

  preferred_ip_protocol: "ip4"

가 매우 중요한데, ipv6 를 지원하지 않는 서버의 상태를 조회 할 때 저것을 명시 하지 않으면 조회하지 못한다는 에러가 난다. (보통 다 그럴 것이다)

proxy

blackbox_exporter 는 일종의 proxy 이다. 프로메테우스는 blackbox_exporter 를 경유해서 서버의 상태를 조회하며, blackbox_exporter 는 서버의 상태를 프로메테우스가 이해하기 쉬운 형태로 그 결과를 변환 해 준다.

target 서버를 뭘로 인자를 주느냐에 따라서 그 서버의 http 상태 정보를 추출할 수 있다. prometheus 의 영어 사전을 리턴하는 네이버의 응답 속도를 모니터링 하고 싶다면

blackbox_exporter 의 probe API 에 target 인자로 그 URL 을 주면 된다. 이렇게 target 인자를 프로메테우스가 필요에 따라 설정할 수 있도록 하면 된다.

Prometheus 에서 조회 대상 target 설정

  1. prometheus 에서 조회 대상 설정
  2. blackbox_exporter 서버가 대신 조회
  3. 응답을 prometheus 용으로 생성
  4. prometheus 가 시시각각 변하는 metric 지표를 저장

prometheus

드디어 prometheus 를 시작해보다. 기본 설정에서 blackbox_exporter 관련 설정만 추가 한다.

scrape_configs:
  - job_name: "blackbox_exporter"
    metrics_path: /probe
    params:
       module: [ http_2xx ]  # Look for a HTTP 200 response.
    static_configs:
      - targets:
         - https://nz.pe.kr

         - https://curious.com/api/someapi?hello=world
    relabel_configs:
           - source_labels: [__address__] # 1
             target_label: __param_target
           - source_labels: [__param_target] # 2
             target_label: instance
           - target_label: __address__ # 3
             replacement: localhost:9115 # The blackbox exporter.

localhost:9115 에 떠 있는 blackbox_exporter 에게 targets 에 명시된 서버들을 조회하라는 설정이다. relabel 을 prometheus 의 유연성 중 하나로 언급되기도 한다.

이 설정은 blackbox_exporter 와 연계하여 호환 설정하는 내용이 아님을 명심하자. 사실 prometheus 는 blackbox_exporter 가 주는 값만 중요할 뿐이지 blackbox_exporter 인지는 중요하지 않다.

이 설정은 단지 job_name (배치 job?) 에 대한 시시각각 변경되는 값을 가져오기 위해서 URL 을 어떻게 조합해 갈 것인가에 대한 트릭이 담겨있는 설정이다. 위와 같이 설정하고 나면 prometheus 는 아래와 같이 target 에 명시된 URL 을 크롤링 하기 위한 blackbox_exporter 용 URL 을 생성하여 그것을 pulling 한다.


* localhost:9115/probe?module=http_2xx&target=https://nz.pe.kr # target 뒤의 값은 URL encoding 된다.
* localhost:9115/probe?module=http_2xx&target=https://curious.com/api/someapi?hello=world

#1 여기서 __address__ 는 target 내의 서비스들을 말하는데 [] 로 감싸져있어 배열이다. (그래서 labels 도 복수형) 이것이 __param_ 이 된다. 즉 blackbox_exporter 의 target 파라미터로 대체되어 들어간다.

#2 또한 그 target 들은 prometheus 의 instance label 이 된다. 표시되는 그래프에서 구별해 볼 수 있는 구분자 라벨이다. 즉 #1의 target_label 은 __param_ 이 prefix 이므로 파라미터로 전환되는 것이고 #2는 prefix 가 없으므로 그대로 label이 된다.

#3 마지막으로 마지막으로 __address__ 즉 조회할 서버 (target_label) 의 주소는 localhost:9115 로 대체된다.

targets 정제하기

static_configs:
  - targets:
     - https://nz.pe.kr/too/too/too/too/so/so/long/user?hello=world#GET_USER
     - https://nz.pe.kr/too/too/too/too/so/so/long/and/again/long/point?hello=world#GET_POINT
relabel_configs:
       - source_labels: [__address__]
         target_label: __param_target
       - source_labels: [__param_target]
         regex: .*(#.*)
         replacement: $1
         target_label: instance
       - target_label: __address__
         replacement: localhost:9115 # The blackbox exporter.

너무 target 이 길면 나중에 prometheus 에서 조회한 URL 이 너무 길고 나중나중에 grafana 로 연계 할 때도 안 좋기 때문에 (#.*) # 뒤에 오는 것을 $1번 변수에 담아서 instance 라는 라벨에 할당할 수 있다. 나중에 화면 볼때 쓸데 없이 긴 라벨이 없어 깔끔하다.

서비스별 응답시간

여기까지 prometheus 에 웹서버의 상태를 표시하기 위한 여정을 마친다. metric 을 쭑 훑어보면 웹서버의 응답 시간을 나타내는 probe_duration_seconds 를 찾을 수 있고 최종적으로는 등록된 API 들에 대한 측정치를 확인 할 수 있다.

다음은 응답시간을 받아올 수 없을 때, 즉, blackbox_exporter 의 조회 API 인 probe API 의 조회 실패 케이스 probe_success 0 일 때 slack 으로 알림을 받는 방법을 알아본다.

댓글 남기기

이메일 주소는 공개되지 않습니다.