블록체인 노드 모니터링 해보기 Part 1(feat. Grafana, Prometheus)

Boom Labs는 Web 3 개발자들을 온보딩시키고, 생태계를 활성화시키기 위해 교육을 비롯한 여러 활동들을 하고 있습니다. 저희 비전에 공감하여 동참하고자 하는 분들은 Boom Labs의 문을 두드려주세요!

Disclaimer: 이 글은 정보 전달을 위한 목적으로 작성되었으며, 특정 프로젝트에 대한 투자 권고, 법률적 자문 등 목적으로 하지 않습니다. 모든 투자의 책임은 개인에게 있으며, 이로 발생된 결과에 대해 어떤 부분에서도 Boom Labs는 책임을 지지 않습니다. 본문이 포괄하는 내용들은 특정 자산에 대한 투자를 추천하는 것이 아니며, 언제나 본문의 내용만을 통한 의사결정은 지양하시길 바랍니다.

인트로

  • Near protocol에 관심을 가지게 되면서, 테스트로 chunk only producer 노드를 돌리게 될 기회가 있었습니다.
  • 블록체인 노드는 블록 생성을 위해서 노드가 항상 online 상태여야 하는데, 네트워크 병목, panic, 에러, cpu 과다 사용 등으로 노드가 꺼지거나 offline 상태가 되면 블록을 생성할 수 없고, 그 노드는 페널티를 받게 됩니다.
  • 따라서 정상적으로 노드를 운영하기 위해서는 모니터링이 필요했다고 판단했습니다. 간단한 모니터링 인프라를 구축하려면 무엇이 필요할지 찾아보다가 grafana + prometheus를 알게 되었는데요.
  • 이번 글의 목적은 블록체인 노드 모니터링이지만, 노드 운영 뿐만 아니라 서버를 관리하는 모든 개발자들에게 유용할 것이라 생각합니다.

왜 그라파나 & 프로메테우스?

인트로에서 얘기한 것처럼 노드 혹은 서버를 작동시키는 머신에서 하드웨어적으로 문제가 생기거나, 가용 리소스 보다 많은 리소스를 사용해 문제가 생기는 경우 등이 있습니다. 따라서 구축한 환경 자체를 모니터링하고, 문제가 생길 경우 적절한 조치를 빠르게 취해야 합니다.

모든 모니터링 순서는 수집 → 통합 → 시각화 구조로 되어있는데요.

우리는 모니터링을 위해 필요한 데이터를 수집하고, 수집한 정보를 한 곳에 모아(통합), 그 데이터들을 시각화 할 수 있어야 합니다.

위의 플로우를 도와주는 서비스들이 여럿 있는데요.

데이터 수집 도구에는 대표적으로 프로메테우스, 데이터독이 있습니다.

1. Prometheus

  • 시계열 DB를 내장하고 있고, 자체적인 쿼리 페이지가 존재하지만 시각화가 빈약함. 보통 시각화 서비스와 연계해서 사용
  • 중앙 서버에서 에이전트의 데이터를 수집하는 Pull 방식을 사용
  • 에이전트를 통해 내부의 지표를 외부에서도 접근할 수 있기 때문에 사용자가 수집 대상에 접속할 수만 있다면 어디서든 메트릭을 가져올 수 있음.
  • 오픈 소스이기 때문에 사용자 층이 넓고 자료가 풍부하며 각종 대시보드 도구나 메신저 등이 프로메테우스와의 연계를 지원하므로 직접 모니터링 시스템을 구축할 때 좋음

2. Datadog

  • APM, log, Infrastructure를 통합적으로 모니터링하고 관리하는 클라우드 모니터링 솔루션
  • 모든 클라우드 시스템과 연계 가능하고, 웹사이트에서 모니터링 대상을 관리할 수 있어 관리 부담이 적음
  • 모니터링 대상마다 요금을 부과하기 때문에 모니터링 대상이 늘면 비용이 커지는 단점이 존재

프로메테우스 등의 도구는 시각화 기능이 부족합니다. 그래서 부족한 시각화 기능을 보강하는 다음과 같은 도구를 사용하는데요.

1. Grafana

  • 다양한 수집 서비스 및 DB와 연계를 지원
  • 주로 시계열 데이터 시각화에 많이 사용됨.
  • 오픈 소스라서 사용자의 요구 사항에 맞게 수정 가능, 필요에 따라 설치형과 서비스형 모두 선택 가능

2. 키바나(Kibana)

  • ElasticSearch의 Elastic에서 만든 시각화 도구
  • ElasticSearch에 적재된 데이터를 시각화하거나 검색하는 데 사용
  • ElasticSearch 데이터만 시각화 할 수 있기 때문에 프로메테우스에서 사용하려면 Metricbeat라는 서비스를 사용해 ElasticSearch에 연동해야함.

그러면 왜 프로메테우스와 그라파나를 사용해야 되는 걸까요?

보통 모니터링 시스템을 구축하기 위해 고려하는 문제는 크게 두 가지입니다.

  1. 비용 : 대개 상용 솔루션을 사용하는 경우 모니터링 대상마다 License 관련 비용이 발생하고, 클라우드 같은 과금제 서비스를 이용하면 네트워크와 저장 공간에 따른 추가 비용이 발생합니다.
  2. 보안 : 서비스형 모니터링 도구들은 대부분 외부에 데이터를 저장합니다. 보안에 민감해서 내부에서 모든 데이터를 처리하는 경우에는 사용하기 어렵습니다.

이 중 비용은 의사결정 시 가장 큰 요소입니다. 프로메테우스와 그라파나는 무료인 오픈 소스인데다가 기능이 부족하지 않고, 보안, 확장성도 뛰어나기 때문에 가볍게 모니터링 시스템을 구축해보는 용도로 가장 적합하다고 할 수 있습니다.

프로메테우스 세팅

그럼 프로메테우스를 설치해보고 필요한 요소들을 세팅해보겠습니다.

먼저, 프로메테우스의 주요 요소들을 먼저 짚고 넘어가보겠습니다.

프로메테우스는 여러 요소를 설치합니다. 아래의 요소를 설치하며, 설치된 요소들로 모니터링에 필요한 데이터를 수집하고 저장합니다.

exporter

  • 모니터링 대상의 Metric 데이터를 수집하고 Prometheus가 접속했을 때 정보를 알려주는 역할을 합니다.

prometheus-server

  • 프로메테우스의 주요 기능을 수행하는 요소.
  • Expoter가 열어놓은 HTTP 엔드포인트에 접속해서 Metric을 수집합니다.(Pull 방식)

프로메테우스는 서비스 디스커버리를 활용해 프로메테우스 서버와 API 서버가 주기적으로 데이터를 주고받아 수집 대상을 자동으로 인식하고 필요한 정보를 수집합니다.

  1. 서버가 config map에 기록된 내용을 바탕으로 대상을 읽기
  2. 읽어온 대상에 대한 metric을 가져오기 위해 API 서버에 정보를 요청
  3. 요청으로 받아온 경로에서 metric 데이터를 수집.

Node exporter로 메트릭 수집

exporter 중에 가장 유명한 exporter로 node exporter가 있습니다. 이 글에서 사용할 exporter이기도 합니다.

node exporter는 노드 서버의 시스템 metric 정보를 HTTP로 공개합니다.

설치된 노드 서버에서 특정 파일들을 읽어, 이를 프로메테우스 서버가 수집할 수 있는 metric으로 변환한 후에 HTTP로 접근할 수 있게 합니다.

node exporter가 제공하는 주요 지표로는 node_cpu_seconds_total , node_memory_MemAvailable_bytes 등이 있습니다.

Near exporter로 메트릭 수집

이 글에서는 노드 모니터링을 위해 node exporter 뿐만 아니라 Near protocol의 노드 metric 정보도 수집해야 합니다. 따라서 exporter 하나를 추가로 더 사용합니다.

near노드 구현체를 보면 내부적으로 prometheus exporter를 구현해놨으며, localhost:3030/metrics 라는 엔드포인트로 노드 데이터에 접근할 수 있게 되어있습니다.

코드 : https://github.com/near/nearcore/blob/master/chain/jsonrpc/src/lib.rs#L1389

즉, Near metrics exporter는 노드에서 열어둔 3030 port 를 통해 데이터를 제공하고 있으며,

prometheus 서버가 노드의 port 로 접근하여 metric 데이터들을 수집해가는 구조입니다.

주요 metric은 이 파일에 정의되어 있습니다.

프로메테우스 & Exporter 설치 및 세팅

이제 prometheus 서버 설치 및 세팅을 진행해보겠습니다.

세팅에 사용할 환경은 Linux/Ubuntu 22.02 환경입니다. (보통 노드는 Linux에서 구축한다고 보시면 됩니다.)

이 글에서는 직접 설치하는 방법을 사용하겠습니다.

(도커 이미지를 이용하고싶다면, 이 링크를 참고하세요.)

prometheus와 node exporter 유저를 추가해줍니다.

sudo useradd --no-create-home --shell /usr/sbin/nologin prometheus
sudo useradd --no-create-home --shell /bin/false node_exporter

prometheus 폴더를 만들고 오너쉽을 설정해줍니다.

sudo mkdir /etc/prometheus
sudo mkdir /var/lib/prometheus
sudo chown prometheus:prometheus /etc/prometheus
sudo chown prometheus:prometheus /var/lib/prometheus

Prometheus 최신 버전을 다운로드 합니다.(LATEST VERSION 부분에 버전 숫자를 넣어주세요.)

wget https://github.com/prometheus/prometheus/releases/download/<LATEST VERSION>/prometheus-<LATEST VERSION>linux-amd64.tar.gztar xfz prometheus-<LATEST VERSION>linux-amd64.tar.gz
cd prometheus-<LATEST VERSION>linux-amd64/
sudo cp ./prometheus /usr/local/bin/
sudo cp ./promtool /usr/local/bin/
sudo chown prometheus:prometheus /usr/local/bin/prometheus
sudo chown prometheus:prometheus /usr/local/bin/promtool
sudo cp -r ./consoles /etc/prometheus
sudo cp -r ./console_libraries /etc/prometheus
sudo chown -R prometheus:prometheus /etc/prometheus/consoles
sudo chown -R prometheus:prometheus /etc/prometheus/console_libraries

설정을 위해 prometheus.yml 파일을 작성합니다.

sudo vim /etc/prometheus/prometheus.ymlglobal:
scrape_interval: 15s
evaluation_interval: 15s
rule_files:
# - "first.rules"
# - "second.rules"
scrape_configs:
- job_name: 'near_node'
scrape_interval: 5s
static_configs:
- targets: ['localhost:3030']

파일의 오너쉽을 변경해줍니다.

sudo chown prometheus:prometheus /etc/prometheus/prometheus.yml

background 실행을 위해 prometheus systemd service를 만들어줍니다. 포트는 19001로 해보겠습니다.

sudo vim /etc/systemd/system/prometheus.service

[Unit]
Description=Prometheus Monitoring
Wants=network-online.target
After=network-online.target
[Service]
User=prometheus
Group=prometheus
Type=simple
ExecStart=/usr/local/bin/prometheus \
--config.file /etc/prometheus/prometheus.yml \
--storage.tsdb.path /var/lib/prometheus/ \
--web.console.templates=/etc/prometheus/consoles \
--web.console.libraries=/etc/prometheus/console_libraries \
--web.listen-address=localhost:19001
ExecReload=/bin/kill -HUP $MAINPID
[Install]
WantedBy=multi-user.target

(프로메테우스 실행 커맨드 컨피그는 이 링크를 참고하세요.)

이제 프로메테우스 서비스를 시작합니다.

sudo systemctl daemon-reload
sudo systemctl enable prometheus
sudo systemctl start prometheus

이제 node exporter도 설치합니다.

wget https://github.com/prometheus/node_exporter/releases/download/<LATEST VERSION>/node_exporter-<LATEST VERSION>linux-amd64.tar.gztar xvf node_exporter-<LATEST VERSION>linux-amd64.tar.gzsudo cp node_exporter-<LATEST VERSION>linux-amd64/node_exporter /usr/local/bin
sudo chown node_exporter:node_exporter /usr/local/bin/node_exporter

node exporter service도 작성합니다. 포트는 19002로 설정합니다.

sudo vim /etc/systemd/system/node_exporter.service[Unit]
Description=Node Exporter
Wants=network-online.target
After=network-online.target
[Service]
User=node_exporter
Group=node_exporter
Type=simple
ExecStart=/usr/local/bin/node_exporter \
--path.procfs=/host/proc \
--path.sysfs=/host/sys \
--path.rootfs=/host \
--collector.filesystem.ignored-mount-points=^/(sys|proc|dev|host|etc|boot)($$|/) \
--web.listen-address=localhost:19002
[Install]
WantedBy=multi-user.target

node exporter 데이터도 수집하기 위해 prometheus.yml 파일을 수정합니다.

global:
scrape_interval: 15s
evaluation_interval: 15s
rule_files:
# - "first.rules"
# - "second.rules"
scrape_configs:
- job_name: 'near_node'
scrape_interval: 5s
static_configs:
- targets: ['localhost:3030']
- job_name: 'near.nost'
scrape_interval: 10s
static_configs:
- targets: ['localhost:19002']

node exporter, prometheus 서비스를 시작해줍니다.

sudo systemctl enable node_exporter
sudo systemctl start node_exporter
sudo systemctl restart prometheus

prometheus 세팅을 완료했습니다! 이제 모니터링을 위한 데이터 시각화 단계로 넘어가보겠습니다.

--

--