• Grafana, Prometheus, node-exporter를 이용해서 시스템 메트릭을 모니터링할 수 있는 대시보드를 구축

Grafana, Prometheus, node-exporter 구성 인프라스트럭처


node-exporter란

  • UNIX 계열 커널을 가진 하드웨어와 OS 등 "시스템 메트릭"을 수집하는 Exporter
  • Prometheus 재단이 공식적으로 지원하고 있는 Exporter 중 하나
  • Prometheus로 모니터링 시스템을 구축 시 시스템 메트릭 수집을 위해 가장 우선적으로 고려되는 Exporter
  • node-exporter의 exporter의 의미
    1. 특정 메트릭을 수집해서 엔드포인트에 노출시키는 소프트웨어(software) 혹은 에이전트(agent)
    2. node-exporter가 UNIX 계열 서버의 cpu, memory 등의 메트릭을 수집할 수 있는 것처럼, DB, 하드웨어, 메세지 시스템, 저장소 등 여러 시스템에 대한 익스포터가 존재
    3. CollectD 등 기존의 서버 모니터링에 사용되는 에이전트들과 통합할 수 있는 익스포터도 존재

node-exporter 설치 (서버)

1. node-exporter 스크립트 명령어로 실행

# 현재 위치 확인
$ pwd
/root

# 설치하는 컴포넌트들의 관리를 더 쉽게 하기 위해서 디렉토리 생성
$ mkdir node

# 디렉토리 이동
$ cd /root/node

# 압축 파일 다운로드
$ wget https://github.com/prometheus/node_exporter/releases/download/v1.2.0/node_exporter-1.2.0.linux-amd64.tar.gz

# 설치한 node-exporter 바이너리 파일 확인
$ ls
node_exporter-1.2.0.linux-amd64.tar.gz

# 압축 파일 해제
$ tar zxvf node_exporter-1.2.0.linux-amd64.tar.gz
node_exporter-1.2.0.linux-amd64/
node_exporter-1.2.0.linux-amd64/LICENSE
node_exporter-1.2.0.linux-amd64/NOTICE
node_exporter-1.2.0.linux-amd64/node_exporter

# node_exporter 설치된 디렉토리로 이동
$ cd /root/node/node_exporter-1.2.0.linux-amd64

# node_exporter 실행 → 포그라운드로 실행하면 다른 작업이 불가능함으로 백그라운드로 실행(& 붙임)
$ ./node_exporter

2. node-exporter 서비스로 실행 → node-exporter 명령어를 systemd로 관리

# 현재 디렉토리 위치 확인
$ pwd
/root/node/node_exporter-1.2.0.linux-amd64

# user 추가
$ useradd --no-create-home --shell /bin/false node_exporter

# 생성한 prometheus 계정 확인
$ cat /etc/passwd | grep node_exporter
node_exporter:x:1001:1001::/home/node_exporter:/bin/false

# 실행 파일 /usr/local/bin/으로 경로 이동
$ cp ./node_exporter /usr/local/bin

# /usr/local/bin/node_exporter node_exporter 유저, 그룹 권한 주기
$ chown node_exporter:node_exporter /usr/local/bin/node_exporter

# 명령어 복사 및 사용 권환 변경 확인
$ ls -al /usr/local/bin/node_exporter
-rwxr-xr-x 1 node_exporter node_exporter 18494531 Nov 20 14:37 /usr/local/bin/node_exporter

# 서비스 파일 등록
$ cat << EOF | tee /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

[Install]
WantedBy=multi-user.target
EOF

# 데몬 리로드
$ systemctl daemon-reload

# 서비스 가동
$ systemctl restart node_exporter

# 서비스 상태 확인
$ systemctl status node_exporter
● node_exporter.service - Node Exporter
   Loaded: loaded (/etc/systemd/system/node_exporter.service; disabled; vendor preset: disabled)
   Active: active (running) since Sat 2021-11-20 14:39:30 KST; 11s ago
 Main PID: 19812 (node_exporter)
    Tasks: 5
   Memory: 8.4M
   CGroup: /system.slice/node_exporter.service
           └─19812 /usr/local/bin/node_exporter
[..생략..]

3. curl 명령어를 입력하여 node-exporter를 통해 수집되는 데이터가 있는지 확인

$ curl localhost:9100/metrics
# HELP go_gc_duration_seconds A summary of the pause duration of garbage collection cycles.
# TYPE go_gc_duration_seconds summary
go_gc_duration_seconds{quantile="0"} 0
go_gc_duration_seconds{quantile="0.25"} 0
go_gc_duration_seconds{quantile="0.5"} 0
go_gc_duration_seconds{quantile="0.75"} 0
go_gc_duration_seconds{quantile="1"} 0
go_gc_duration_seconds_sum 0
go_gc_duration_seconds_count 0
# HELP go_goroutines Number of goroutines that currently exist.
# TYPE go_goroutines gauge
go_goroutines 8



Prometheus 설정 변경 → node-exporter 정보 수집

  • Prometheus에서 node-exporter가 수집하고 있는 메트릭을 스크래이핑

  • Prometheus 설정 파일을 보면 scrape_config 밑에 아래와 같이 node-exporter 관련 job이 등록 된 것을 확인 가능

    1. static_configs 밑에 targets에서 node-exporter가 구동된 인스턴스들의 "[Node-Exporter IP]:9100"을 기록

    2. Prometheus가 scrape_interval에 설정된 주기마다 각 인스턴스들에서 수집되는 메트릭을 스크래이핑하여 저장

      $ vi /etc/prometheus/prometheus.yml
      # my global config
      global:
        scrape_interval:     15s # By default, scrape targets every 15 seconds.
        evaluation_interval: 15s # By default, scrape targets every 15 seconds.
      
      external_labels:
        monitor: 'kubernetes-monitoring'
      
      rule_files:
      # - 'alert.rules'
      # - "first.rules"
      # - "second.rules"
      
      # alert
      # alerting:
      #   alertmanagers:
      #   - scheme: http
      #     static_configs:
      #     - targets:
      #       - "alertmanager:9093"
      
      # A scrape configuration containing exactly one endpoint to scrape:
      # Here it's Prometheus itself.
      scrape_configs:
        - job_name: 'prometheus'
          scrape_interval: 5s
      
          static_configs:
            - targets: ['localhost:9090']
      
        - job_name: 'node-exporter'
          scrape_interval: 5s
      
          static_configs:
            - targets: ['[Node-Exporter IP]:9100']
  • Prometheus 구동
    $ systemctl daemon-reload
    $ systemctl restart prometheus
    $ systemctl status prometheus
    ● prometheus.service - Prometheus Server
    Loaded: loaded (/etc/systemd/system/prometheus.service; disabled; vendor preset: disabled)
    Active: active (running) since Sat 2021-11-20 15:10:51 KST; 23s ago
    Main PID: 4020 (prometheus)
    Tasks: 14
    Memory: 39.5M
    CGroup: /system.slice/prometheus.service
           └─4020 /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/pro...
    [...생략...]


Prometheus UI에서 다음 쿼리를 입력 → node-exporter 설치한 서버의 값 읽음

  • 설정한 node-exporter란 job_name으로 수집되고 있는 인스턴스들의 개수를 확인 가능



node-exporter를 모니터링하는 Grafana 대시보드 구축

  • 기본 Grafana 에서 대시보드를 설치하는 방법은 해당 URL을 통해 학습 필요
  • Grafana로 대시보드를 구축할 때 좋은 점은 node-exporter같이 많이 사용하는 Exporter에 대한 대시보드가 이미 공유
  • 손쉽게 사용 가능

1. node-exporter 그라파다 대시보드 복사 가능한 대시보드 ID 획득

  • node-exporter 그라파나 대시보드 복사 가능하게 하는 URL : https://grafana.com/grafana/dashboards/1860
  • 위 경로에 접속하면 아래 화면이 보이는데 "Copy ID to Clipboard"를 클릭하여 복사함

2. 그라파나 대시보드로 이동한 후, 왼쪽 탭의 두 번째 "+"의 "Import" 메뉴를 클릭



3. 위에서 복사한 대시보드 ID를 입력하고 "Load" 버튼을 클릭



4. "Datasource"에서 "Prometheus"를 선택한 뒤 "Import"를 클릭



5. 생성한 대시보드 화면 확인

  • 기본 설정된 값으로는 잘 안보일 수 있으니 우측 상단 메뉴에서 "Last 5 Minutes"를 설정하고, 리프레시 간격을 5s로 바꾸는 것이 좋음
  • 실 서버에서는 서버 부하가 걸릴 수 있으니 15분에 10초가 적당
  • 생성한 node-exporter 대시보드를 통해 확인할 수 있는 지표들
    1. CPU
    2. Memory
    3. Disk
    4. Network
    5. File System
    6. System Daemon
    7. Node Exporter
  • 각 패널마다 edit을 누르면, Grafana에서 Prometheus를 어떻게 쿼리하는지 확인 가능

참고 URL : https://gurumee92.tistory.com/225?category=933410

  • docker가 기본적으로 설치되어있어야함
  • docker 설치는 다른 페이지에서 참고

1. 프로메테우스 적용 yaml 파일 → 모니터링할 목록 정의

# 프로메테우스 yaml파일을 관리한 디렉토리 생성
$ mkdir /etc/prometheus

# prometheus.yml 파일 내용 정의
$ vi /etc/prometheus/prometheus.yml
global:
  scrape_interval: 15s
  scrape_timeout: 10s
  evaluation_interval: 15s
  external_labels:
    monitor: legacy

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets:
        - [서버 IP]:9090

2. 프로메테우스 인스턴스 시작

# 영구 볼륨(Persistent volumes)을 준비
$ mkdir -p /data/prometheus_data/

# 프로메테우스 인스턴스 배포
$ docker run -d --net=host --rm \
    -v /etc/prometheus:/etc/prometheus \
    -v /data/prometheus_data:/prometheus \
    -u root \
    --name prometheus\
    quay.io/prometheus/prometheus:v2.33.0 \
    --config.file=/etc/prometheus/prometheus.yml \
    --storage.tsdb.path=/prometheus \
    --storage.tsdb.retention=365d \
    --storage.tsdb.max-block-duration=1d \
    --storage.tsdb.min-block-duration=1d \
    --web.listen-address=:9090 \
    --web.enable-lifecycle \
    --web.enable-admin-api

3. 프로메테우스 배포 확인

  • docker 배포 확인
      $ docker ps
      CONTAINER ID                                 IMAGE                                   COMMAND                  CREATED             STATUS              PORTS               NAMES
      86205a98ec4d        quay.io/prometheus/prometheus:v2.33.0   "/bin/prometheus --c…"   14 seconds ago      Up 12 seconds                           prometheus

4. docker로 설치한 Prometheus의 관리 스크립트 내용

4.1. Prometheus.yml 파일 수정 후 Prometheus의 yaml 파일 내용 적용

```
$ source /etc/prometheus/cmd/Restart_Prometheus.sh

# 코드 내용
#! /bin/bash

container_id=`docker ps -a | grep -i prometheus | awk -F ' ' '{print $1}'`
docker restart $container_id
```

4.2. prometheus의 로그 삭제

```
$ source /etc/prometheus/cmd/Log_Clear.sh

# 코드 내용
#! /bin/bash

container_id=`docker ps -a | grep -i prometheus | awk -F ' ' '{print $1}'`
Log_file=$(docker inspect --format='{{.LogPath}}' "$container_id")

log_file_volume=`ls -al $Log_file | awk -F ' ' '{print $5}'`
if [[ $log_file_volume == 0 ]]; then
  echo "Log File is alrealy zero"
else
  truncate -s 0 $Log_file
  echo "Prometheus Log Clear"
fi
```

4.3. prometheus의 로그 보기

```
$ source /etc/prometheus/cmd/View_Log.sh

# 코드 내용
#! /bin/bash

container_id=`docker ps -a | grep -i prometheus | awk -F ' ' '{print $1}'`
docker logs -f $container_id
```

  • RedHat 계열의 CentOS 서버에서 Prometheus를 설치하고 systemd로 관리
  • Security Group, Firewall 등으로 9090번 포트에 대한 방화벽 해제가 필요

1. Prometheus 설치

  • 설치하고 싶은 Prometheus 버전의 경로를 잘 확인하여 다운받으면 됨

  • systemd를 사용하지 않고 /root/apps/prometheus-2.22.0.linux-amd64/pometheus를 실행해도 Prometheus 사용 가능

    $ pwd
    /root
    
    # 설치하는 컴포넌트들의 관리를 더 쉽게 하기 위해서 디렉토리 생성
    $ mkdir apps
    
    # 디렉토리 이동
    $ cd /root/apps
    
    # Prometheus 바이너리 파일이 들어 있는 압축 파일 설치
    $ wget https://github.com/prometheus/prometheus/releases/download/v2.22.0/prometheus-2.22.0.linux-amd64.tar.gz
    
    # 설치한 Prometheus 바이너리 파일 확인
    $ ls
    prometheus-2.22.0.linux-amd64.tar.gz
    
    # 압축 파일 해제
    $ tar zxvf prometheus-2.22.0.linux-amd64.tar.gz
    prometheus-2.22.0.linux-amd64/
    prometheus-2.22.0.linux-amd64/NOTICE
    prometheus-2.22.0.linux-amd64/prometheus
    prometheus-2.22.0.linux-amd64/consoles/
    prometheus-2.22.0.linux-amd64/consoles/node-cpu.html
    prometheus-2.22.0.linux-amd64/consoles/prometheus-overview.html
    prometheus-2.22.0.linux-amd64/consoles/node.html
    prometheus-2.22.0.linux-amd64/consoles/node-overview.html
    prometheus-2.22.0.linux-amd64/consoles/index.html.example
    prometheus-2.22.0.linux-amd64/consoles/prometheus.html
    prometheus-2.22.0.linux-amd64/consoles/node-disk.html
    prometheus-2.22.0.linux-amd64/console_libraries/
    prometheus-2.22.0.linux-amd64/console_libraries/prom.lib
    prometheus-2.22.0.linux-amd64/console_libraries/menu.lib
    prometheus-2.22.0.linux-amd64/promtool
    prometheus-2.22.0.linux-amd64/LICENSE
    prometheus-2.22.0.linux-amd64/prometheus.yml



2. Prometheus를 서비스로 생성하여 관리 → prometheus 실행을 systemd로 관리

  • Prometheus를 리눅스 systemd를 통해 서비스로 등록

    $ pwd
    /root/apps/prometheus-2.22.0.linux-amd64
    
    # 디렉토리 프로비저닝
    $ useradd --no-create-home --shell /bin/false prometheus
    
    # 생성한 prometheus 계쩡 확인
    $ cat /etc/passwd | grep prometheus
    prometheus:x:1001:1001::/home/prometheus:/bin/false
    
    # prometheus를 관리할 디렉토리 생성 및 명령어 복사
    $ mkdir /etc/prometheus
    $ mkdir /var/lib/prometheus
    $ cp ./prometheus /usr/local/bin/
    $ cp ./promtool /usr/local/bin/
    $ cp ./prometheus.yml /etc/prometheus/
    $ cp -r ./consoles /etc/prometheus
    $ cp -r ./console_libraries /etc/prometheus
    
    # 명령어 복사 확인
    $ ls /usr/local/bin/
    prometheus  promtool
    
    # prometheus 관련 내용 복사
    $ ls /etc/prometheus
    console_libraries  consoles
    
    # 유저:그룹 설정 -> prometheus 사용자 계정이 관리할 수 있도록 권한 변경
    $ chown prometheus:prometheus /etc/prometheus
    $ chown prometheus:prometheus /var/lib/prometheus
    $ chown prometheus:prometheus /usr/local/bin/prometheus
    $ chown prometheus:prometheus /usr/local/bin/promtool
    $ chown -R prometheus:prometheus /etc/prometheus/consoles
    $ chown -R prometheus:prometheus /etc/prometheus/console_libraries
    
    # 서비스 파일 등록
    $ cat << EOF | tee /etc/systemd/system/prometheus.service
    [Unit]
    Description=Prometheus Server
    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
    
    [Install]
    WantedBy=multi-user.target
    EOF
  • 서비스 데몬 리로딩
    $ systemctl daemon-reload
  • prometheus 서비스 시작
    $ systemctl start prometheus
  • prometheus 서비스 상태 확인

    $ systemctl status prometheus
    ● prometheus.service - Prometheus Server
     Loaded: loaded (/etc/systemd/system/prometheus.service; disabled; vendor preset: disabled)
     Active: active (running) since Sat 2021-11-20 02:55:12 KST; 11h ago
    Main PID: 11780 (prometheus)
      Tasks: 14
     Memory: 48.4M
     CGroup: /system.slice/prometheus.service
             └─11780 /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_...
    
    Nov 20 12:00:03 [서버 IP] prometheus[11780]: level=info ts=2021-11-20T03:00:03.377Z caller=head.go:889 component=tsdb msg="WAL checkpoint complete" first=2 last=3 duration=29.052021ms
    Nov 20 12:00:03 [서버 IP] prometheus[11780]: level=info ts=2021-11-20T03:00:03.425Z caller=compact.go:440 component=tsdb msg="compact blocks" count=3 mint=1637344800000 maxt=1637366400000 ulid=01FMXMJQ5RJ914...ration=41.7039ms
    Nov 20 12:00:03 [서버 IP] prometheus[11780]: level=info ts=2021-11-20T03:00:03.431Z caller=db.go:1152 component=tsdb msg="Deleting obsolete block" block=01FMX6V8HX8WMN15F7H841AKH0
    Nov 20 12:00:03 [서버 IP] prometheus[11780]: level=info ts=2021-11-20T03:00:03.432Z caller=db.go:1152 component=tsdb msg="Deleting obsolete block" block=01FMXDPZSXA1G1VCYYE6JTVAQN
    Nov 20 12:00:03 [서버 IP] prometheus[11780]: level=info ts=2021-11-20T03:00:03.433Z caller=db.go:1152 component=tsdb msg="Deleting obsolete block" block=01FMWZZH9W1MH7PN1NZBT06CG9
    Nov 20 14:00:03 [서버 IP] prometheus[11780]: level=info ts=2021-11-20T05:00:03.321Z caller=compact.go:494 component=tsdb msg="write block" mint=1637373600000 maxt=1637380800000 ulid=01FMXVEE9X21CFW66VFRRZNAK...tion=59.826896ms
    Nov 20 14:00:03 [서버 IP] prometheus[11780]: level=info ts=2021-11-20T05:00:03.329Z caller=head.go:809 component=tsdb msg="Head GC completed" duration=2.347334ms
    Nov 20 14:00:03 [서버 IP] prometheus[11780]: level=info ts=2021-11-20T05:00:03.386Z caller=compact.go:440 component=tsdb msg="compact blocks" count=2 mint=1637344458250 maxt=1637366400000 ulid=01FMXVEEC8WEK8...tion=50.157896ms
    Nov 20 14:00:03 [서버 IP] prometheus[11780]: level=info ts=2021-11-20T05:00:03.393Z caller=db.go:1152 component=tsdb msg="Deleting obsolete block" block=01FMXMJQ5RJ914MKYP3J4QZ7WT
    Nov 20 14:00:03 [서버 IP] prometheus[11780]: level=info ts=2021-11-20T05:00:03.394Z caller=db.go:1152 component=tsdb msg="Deleting obsolete block" block=01FMWZNF1BR2H33QNDPE91K04T
    Hint: Some lines were ellipsized, use -l to show in full.



3. [서버 IP]:9090에 접속하여 prometheus의 UI 확인 가능

  • public IP:9090"에 접속하면 아래 UI를 확인 가능

  • Prometheus는 메트릭 수집, 시각화, 알림, 서비스 디스커버리 기능을 모두 제공하는 오픈 소스 모니터링 시스템
  • SoundCloud에서 Go언어로 개발하였으며, Apache 2.0 License를 따르고 있음
  • 2016년에 쿠버네티스에 이어 두 번째로 CNCF(Cloud Native Computing Foundation) 산하 프로젝트 멤버로 들어감
  • Grafana Labs에서 유지 보수를 메인으로 전담
  • Prometheus는 독립형 오픈소스 프로젝트이며 많은 회사들이 사용함
  • kubernetes에서 Prometheus를 사용하여 매트릭 수집 및 대시보드 구축하는 방식을 장려
  • Prometheus는 애초에 "스케일 아웃"을 고려하지 않고 설계
  • 데이터가 많으면 많을수록 Prometheus 클러스터링을 위한 Thanos, Cortex등 여러 오픈 소스가 개발되면서 클러스터링 구성 가능

Prometheus의 대표적인 기능

  1. 풀 방식의 메트릭 수집, 시계열 데이터 저장
  2. PromQL을 활용하여 저장된 시계열을 쿼리 및 집계
  3. 서비스 디스커버리
  4. 데이터 시각화

Prometheus 아키텍처

  • Prometheus의 아키텍쳐는 아래와 같이 구성

1. Prometheus

  • Prometheus는 시계열 데이터를 저장
  • Prometheus는 Exporter를 통해 다양한 서비스/시스템의 메트릭을 수집 → Node Exporter는 설치된 머신의 CPU, Memory 등의 메트릭 정보를 수집
  • Client Library는 애플리케이션 코드를 계측하기 위해 쓰인다.
  • Prometheus는 설정 파일(prometheus.yml)에 작성된 "Job"을 통해서 이들이 수집하는 메트릭을 가져와서 저장

2. Pushgateway

  • Pushgateway는 Polling방식이 아닌 프로메테우스에 메트릭을 매트릭을 푸시할 수 있도록 지원
  • Prometheus에서 제공하는 Pushgateway는 푸시된 매트릭을 프로메테우스에서 가져갈 수 있도록 중개자 역할을 수행
  • 즉, Pushgateway에 푸시된 매트릭을 Prometheus에서 가져갈 수 있음

3. Client Library

  • Client Library는 애플리케이션 코드를 계측하기 위해 사용됨
  • 서비스를 개발할 때 가장 좋은 방법은 프로메테우스 클라이언트 라이브러리를 사용해 메트릭을 코드 인라인 기반으로 직접 작성하고 계측함
  • 기본적으로 Go, Java(Scala), Python, Ruby 는 공식 라이브러리를 제공
  • 클라이언트 라이브러리 : https://prometheus.io/docs/instrumenting/clientlibs/

4. Exporter

  • Exporters는 실제로 매트릭을 수집하는 프로세스
  • Exporter가 매트릭을 수집하고 HTTP 통신을 통해 매트릭 데이터를 가져갈 수 있게 /metrics 라는 HTTP 엔드포인트를 제공
  • Prometheus가 Exporter의 엔드포인트로 HTTP GET 요청을 날려 매트릭 정보를 수집(Pull)함

5. Alertmanager

  • Alertmanager를 통해서 특정 메트릭이 임계치가 넘어가거나 경계에 잡혔을 때 이메일, 슬랙 등을 통해서 알림을 보내줄 수 가 있음
  • UI 기능이 있어 데이터를 시각화 가능 → 프로메테우스의 시각화 기능은 약한 편임
  • Prometheus의 Alertmanager 기능의 부족한 부분을 채우기 위해 Grafana 대시보드 툴로 Prometheus UI를 대체

6. Service Discovery

  • Service Discovery 기능을 제공
  • Service Discovery를 활용하면, 인스턴스는 다이나믹하게 스케일 인/아웃이 됨
  • Prometheus는 여러 Service Discovery와 통합 가능
  • 쿠버네티스 Service Discovery와 통합하여, 쿠버네티스 클러스터에 존재하는 모든 노드와 팟들의 메트릭을 수집 가능


Prometheus를 사용하기에 적합한 일, 적합하지 않은 일

  • Prometheus는 "메트릭"을 저장하기 위한 모니터링 시스템
  • 커널 스케줄링이나 데이터 수집 실패 같은 요소로 인해 약간의 부정확성과 레이스 컨디션을 피할 수 없는 운영 모니터링 환경을 위해 설계되었다.

1. Prometheus에 적합한 일

  1. 순수한 숫자 시계열을 기록하는 데 적합
  2. 메트릭 기반의 시계열 데이터 저장
  3. 동적인 혹은 마이크로 서비스의 인스턴스에 대한 메트릭을 수집

2. Prometheus에 적합하지 않은 일 → 다른 도구를 사용하여 Prometheus의 부족한 부분을 해결

  1. 이벤트 로그나 개별 이벤트를 저장하는 일
  2. 이메일 주소/사용자 이름과 같이 카디널리티가 높은 데이터를 저장하는 일
  3. 100%의 정확성이 요구되는 일

참고 URL : https://gurumee92.tistory.com/220
Pushgateway 참고 URL : https://kdevkr.github.io/using-pushgateway-to-monitor-private-network-instance/
Client Library 참고 URL : https://medium.com/nexclipper-io/prometheus-exporter-exporterhub-f29d63e0ae49


  • 터미널이나 윈도우 cmd 에서 작업 가능
  • 백업 등 프로그램들을 할때 shell을 통하여 업로드하면 편함


1. MinIO 설치

$ wget -P /usr/bin https://dl.min.io/client/mc/release/linux-amd64/mc
$ chmod +x /usr/bin/mc

# 기본 버전 확인
$ mc --version
mc version RELEASE.2022-02-02T02-03-24Z



2. 기본 커맨드

  1. Minio가 의도한 대로 작동하는지 확인 → http://[MinIO IP]:9000/
  2. 자격 증명을 입력
    • Access Key (액세스 키) : minio
    • Secret Key (비밀 키) : melovethanos

2.1. access key와 secret key를 MinIO client 등록

  • mc 모든 구성 정보를 ~/.mc/config.json파일에 저장
  • 는 단순히 클라우드 스토리지 서비스의 짧은 이름
  • S3 엔드포인트, 액세스 및 비밀 키는 클라우드 스토리지 제공업체에서 제공
    # set access key / secret key
    # 형식 : mc alias set my-storage http://192.168.0.30:9001 ROOT_ACCESS_KEY_CHANGE_ME SECRET_ACCESS_KEY_CHANGE_ME
    $ mc alias set hippo http://[MinIO IP]:9000 minio melovethanos
    mc: Configuration written to `/root/.mc/config.json`. Please update your access credentials.
    mc: Successfully created `/root/.mc/share`.
    mc: Initialized share uploads `/root/.mc/share/uploads.json` file.
    mc: Initialized share downloads `/root/.mc/share/downloads.json` file.
    Added `hippo` successfully.

2.2. MinIO client로 bucket 생성

## bucket 생성
$ mc mb hippo/mctest
Bucket created successfully `hippo/mctest`.

2.3. MinIO client로 bucket 리스트 확인

## bucket 리스트 확인
$ mc ls hippo
[2022-02-03 01:22:49 KST]     0B hello/
[2022-02-04 02:55:46 KST]     0B mctest/
[2022-02-04 02:00:24 KST]     0B thanos/

2.4. MinIO client로 bucket에 파일 및 디렉토리 업로드

# upload
# 형식 : mc cp SOURCE ALIAS/PATH
# 파일 복사
$ mc cp ./Prometheus_Restart.sh hippo/hello/Prometheus_Restart.sh

..._Restart.sh:  115 B / 115 B ┃▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓┃ 12.78 KiB/s 0s

# 성공적으로 파일 upload 확인
$ mc ls hippo/hello
[2022-02-04 03:04:44 KST]   115B STANDARD Prometheus_Restart.sh

# 디렉토리 복사
$ mc cp --recursive ./test hippo/hello/

..._Restart.sh:  578 B / 578 B ┃▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓┃ 58.30 KiB/s 0s

# 성공적으로 디렉토리 upload 확인
$ mc ls hippo/hello/test
[2022-02-04 03:13:27 KST]   348B STANDARD Prometheus_Log_Clear.sh
[2022-02-04 03:13:27 KST]   115B STANDARD Prometheus_Log_View.sh
[2022-02-04 03:13:27 KST]   115B STANDARD Prometheus_Restart.sh

2.5. MinIO client로 bucket에 파일 및 디렉토리 삭제

# 디렉토리 내 리스트 확인
$ mc ls hippo/hello/test
[2022-02-04 03:13:27 KST]   348B STANDARD Prometheus_Log_Clear.sh
[2022-02-04 03:13:27 KST]   115B STANDARD Prometheus_Log_View.sh
[2022-02-04 03:13:27 KST]   115B STANDARD Prometheus_Restart.sh

# 형식 : mc rm ALIAS/PATH
# 파일 삭제
$ mc rm hippo/hello/test/Prometheus_Restart.sh
Removing `hippo/hello/test/Prometheus_Restart.sh`.

# 성공적으로 파일 삭제 확인
$ mc ls hippo/hello/test
[2022-02-04 03:13:27 KST]   348B STANDARD Prometheus_Log_Clear.sh
[2022-02-04 03:13:27 KST]   115B STANDARD Prometheus_Log_View.sh

# 형식 : mc rm --recursive --force ALIAS/PATH
# 디렉토리 삭제
$ mc rm --recursive --force hippo/hello/test
Removing `hippo/test/Prometheus_Log_Clear.sh`.
Removing `hippo/test/Prometheus_Log_View.sh`.

# 성공적으로 디렉토리 삭제 확인 -> hippo/hello/test 디렉토리 없음을 확인
$ mc ls hippo/hello
[2022-02-04 03:04:44 KST]   115B STANDARD Prometheus_Restart.sh

2.6. minio client로 bucket에 파일 다운로드 → 업로드와 위치만 변경

# download
# 형식 : mc cp my-storage/test.zip ~/test.zip
#위 cp 예제에서 source/target을 위치를 바꿈.
$ mc cp hippo/hello/Prometheus_Restart.sh /Prometheus_Restart.sh

..._Restart.sh:  115 B / 115 B ┃▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓┃ 14.64 KiB/s 0s

# / 디렉토리 아래에 Prometheus_Restart.sh 파일 존재 확인
$ ls /Prometheus_Restart.sh
Prometheus_Restart.sh



3. 공유 파일 → 특정 파일을 특정일만 공유

  • 공유기간을 설정후 카피 버튼을 클릭해서 복사후 공유
  • 파일을 공유하기 위해 카피 버튼 클릭
  • Copy Link를 통해 접근 URL을 획득



4. 일반 웹서버처럼 공유 → 공유 기간을 무한정으로 설정

4.1. 버킷 자체를 public으로 설정

# 형식 : mc policy set public my-storage/test_bucket
$ mc policy set public hippo/hello
Access permission for `hippo/hello` is set to `public`

4.2. 버킷의 policy를 확인

$ mc policy get hippo/hello
Access permission for `hippo/hello` is `public`

4.3. 다운로드 테스트 → minio에서의 웹사이트 주소에는 minio client의 alias인 hippo는 제외

# minio 서버에 bucket 디렉토리가 바로 뒤로 붙음
$ wget http://[MinIO IP]:9000/hello/Prometheus_Restart.sh
--2022-02-04 03:33:43--  http://[MinIO IP]:9000/hello/Prometheus_Restart.sh
Connecting to [MinIO IP]:9000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 115 [application/x-sh]
Saving to: ‘Prometheus_Restart.sh’

    100%[===============================================>] 115         --.-K/s   in 0s

2022-02-04 03:33:43 (7.72 MB/s) - ‘Prometheus_Restart.sh’ saved [115/115]

1. 쿠버네티스를 통해 MinIO 설치

$ vi minio_install.yml
apiVersion: v1
kind: Namespace
metadata:
  name: minio
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: minio-local-persistent-volume
  namespace: minio
spec:
  capacity:
    storage: 6.9T
  accessModes:
  - ReadWriteMany
  volumeMode: Filesystem
  storageClassName: "minio-local-storage"
  local:
    path: /data
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - "Minio설치IP"

  claimRef:
    namespace: minio
    name: minio-local-persistent-volume-claim
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: minio-local-persistent-volume-claim
  namespace: minio
spec:
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 6.9T
  storageClassName: minio-local-storage
  volumeMode: Filesystem
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: minio-deployment
  namespace: minio
spec:
  selector:
    matchLabels:
      app: minio
  strategy:
    type: Recreate
  replicas: 1
  template:
    metadata:
      labels:
        app: minio
    spec:
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: minio-local-persistent-volume-claim
      containers:
      - name: minio
        image: minio/minio:latest
        args:
        - "server"
        - "--address=:9000"
        - "--console-address=:9001"
        - "/data"
        env:
        - name: MINIO_ACCESS_KEY
          value: "minio"
        - name: MINIO_SECRET_KEY
          value: "melovethanos"
        ports:
        - name: service
          containerPort: 9000
        - name: console
          containerPort: 9001
        volumeMounts:
        - name: data
          mountPath: /data
---
apiVersion: v1
kind: Service
metadata:
  name: minio-service-headless
  namespace: minio
spec:
  selector:
    app: minio
  ports:
  - name: service
    port: 9000
    targetPort: 9000
    protocol: TCP
  - name: console
    port: 9001
    targetPort: 9001
    protocol: TCP
  type: ClusterIP
  clusterIP: None
---
apiVersion: v1
kind: Service
metadata:
  name: minio-loadbalancer-service
  namespace: minio
spec:
  selector:
    app: minio
  ports:
  - name: service
    port: 9000
    targetPort: 9000
    protocol: TCP
  - name: console
    port: 9001
    targetPort: 9001
    protocol: TCP
  type: LoadBalancer



2. MinIO 생성 및 MinIO 생성 확인

# MinIO생성
$ kubectl apply -f minio_install.yml
namespace/minio created
persistentvolume/minio-local-persistent-volume created
persistentvolumeclaim/minio-local-persistent-volume-claim created
deployment.apps/minio-deployment created
service/minio-service-headless created
service/minio-loadbalancer-service created

# 생성 확인 → 내용이 많아 생략함
$ kubectl get -n minio all -o wide

# PV 생성 확인
$ kubectl get -n minio persistentvolume
NAME                                       CAPACITY  ACCESS MODES       RECLAIM POLICY   STATUS CLAIM            STORAGECLASS                                     REASON                       AGE
minio-local-persistent-volume     6900G          RWX                        Retain                  Bound    minio/minio-local-persistent-volume-claim       minio-local-storage              92s

# PVC 생성 확인
$ kubectl get -n minio persistentvolumeclaims
NAME                                              STATUS                   VOLUME                 CAPACITY   ACCESS MODES          STORAGECLASS              AGE
minio-local-persistent-volume-claim   Bound    minio-local-persistent-volume   6900G            RWX                  minio-local-storage          117s



3. headless 서비스 nslookup 확인

$ nslookup minio-service-headless.minio.svc.cluster.local
Server:         210.220.163.82
Address:        210.220.163.82#53

Non-authoritative answer:
Name:   minio-service-headless.minio.svc.cluster.local
Address: 218.38.137.27



4. MinIO 서비스의 Service IP를 통해 생성 확인 → Access Denied로 접근 불가

  • minio에 curl로 접근하면 Access Denied됨으로 다른 방법으로 접근

    # clusterIP 서비스를 통해 접근 가능
    $ curl 20.10.118.211:9000
    <?xml version="1.0" encoding="UTF-8"?>
    <Error><Code>AccessDenied</Code><Message>Access Denied.</Message><Resource>/</Resource><RequestId>16E0270B55D8E06A</RequestId><HostId>c2659a6e-1046-4fd9-8793-e756fbc033a2</HostId></Error>
    
    # LoadBalancer 할당 IP 서비스를 통해 접근 가능
    $ curl [LoadBalancer IP]:9000
    <?xml version="1.0" encoding="UTF-8"?>
    <Error><Code>AccessDenied</Code><Message>Access Denied.</Message><Resource>/</Resource><RequestId>16E026EBFCC13E44</RequestId><HostId>c2659a6e-1046-4fd9-8793-e756fbc033a2</HostId></Error>



5. MinIO 서비스에 Python으로 접근하여 확인

  • curl로 접근할 수 없기에 MinIO Client로 접근

    # minio 테스트에 사용할 파이썬3과 minio 패키지 설치
    $ yum install -y python3
    $ pip3 install minio
    
    # minio 접속 가능 테스트
    $ vi minio_api.py
    #!/bin/python3
    from minio import Minio
    
    if __name__ == '__main__':
       minioIP = "20.10.180.199:9000"     # serviceIP
       minioAccessKey = "minio"
       minioSecretKey = "melovethanos"
       client = Minio(minioIP, minioAccessKey, minioSecretKey, secure=False)
       print(client)
    
    # minio 접속 가능 테스트 실행 -> Minio Object 출력 시 이상 없음
    $ python3 minio_api.py
    <minio.api.Minio object at 0x7f2740e873c8>

  • 서버에 MinIO 설치
  • 로컬 디스크에 데이터를 유지하는 간단한 S3 호환 Minio 엔진을 시작

 

1. MinIO docker 설치

$ mkdir -p /data/minio
$ mkdir -p /var/log/minio/
$ touch /var/log/minio/minio.log

$ docker run -d --rm --name minio \
    -v /data/minio:/data \
    -v /var/log/minio/minio.log:/log/minio.log \
    -p 9000:9000 \
    -e "MINIO_ACCESS_KEY=minio" \
    -e "MINIO_SECRET_KEY=melovethanos" \
    -e "MINIO_HTTP_TRACE=/log/minio.log" \
    minio/minio:RELEASE.2019-01-31T00-31-19Z \
    server --anonymous --json /data

 

2. minio logrotate 작성

  1. 매주 생성
  2. gz으로 압축
  3. 압축파일에 날짜를 명시
  4. 수행 완료 후 minio 컨테이너 재실행
    $ vi /etc/logrotate.d/minio
    /var/log/minio/*.log {
    weekly
    rotate 5
    create 0644 root root
    missingok
    notifempty
    compress
    sharedscripts
    postrotate
       /bin/docker restart `docker ps | grep -i minio | awk -F ' ' '{print$1}'` > /dev/null 2>/dev/null || true
    endscript
    }

3. minio logrotate를 실행할 /etc/crontab 설정 및 logroate 적용

# logrotate 디버그
$ /usr/sbin/logrotate -d /etc/logrotate.d/minio
Allocating hash table for state file, size 15360 B

Handling 1 logs

rotating pattern: /var/log/minio/*.log  weekly (5 rotations)
empty log files are not rotated, old logs are removed
considering log /var/log/minio/minio.log
  log does not need rotating (log has been already rotated)not running postrotate script, since no logs were rotated

# logrotate 적용
$ /usr/sbin/logrotate -f /etc/logrotate.d/minio

# 압축 파일 생성 확인
$ ls /var/log/minio/
minio.log  minio.log.1.gz

# /etc/crontab 적용
# 매주 일요일 자정 logrotate 실행
$ vi /etc/crontab
00 00 * * 7 /usr/sbin/logrotate -f /etc/logrotate.d/minio

# log 확인
$ cat /var/lib/logrotate/logrotate.status  | grep minio
"/var/log/minio/minio.log" 2022-2-6-0:9:7  

 

4. thanos bucket(타노스 버킷) 생성

  • 향후 minio 오브젝트 스토리지에 thano 실행하기 위한 디렉토리 생성
    $ mkdir /data/minio/thanos

5. Minio 배포 확인

  1. Minio가 의도한 대로 작동하는지 확인 → http://[설치 서버IP]:9000
  2. 자격 증명을 입력
    • Access Key (액세스 키) : minio
    • Secret Key (비밀 키) : melovethanos

 

 

1. MinIO 다운로드

  • MinIO가 /usr/local/bin 아래에서 실행 될 수 있도록 /usr/local/bin으로 이동 후 MinIO을 다운 받음
    $ cd /usr/local/bin
    $ wget https://dl.min.io/server/minio/release/linux-amd64/minio
    $ chmod +x minio


2. minio.conf 설정

  • /etc 밑에 minio 폴더를 만든 다음, minio,.conf을 생성

    $ mkdir /etc/minio
    $ vi /etc/minio/minio.conf

  • /etc/minio/minio.conf 파일 내용

    $ vi /etc/minio/minio.conf
    MINIO_VOLUMES="/data"              # minio 의 파일들을 관리할 위치 (volumes)
    MINIO_OPTS="--address :9000"       # minio 서비스에 대한 연결 포트
    MINIO_ROOT_USER=root               # root
    MINIO_ROOT_PASSWORD=root           # root의 비밀번호
    MINIO_ACCESS_KEY= "minioadmin"     # minio 접속 아이디
    MINIO_SECRET_KEY= "minioadmin"     # minio 접속 비밀번호



3. Centos Systemd에 MinIO 서비스 등록

  • /usr/lib/systemd/system/ 디렉토리에 minio.service 설정

    $ vi /usr/lib/systemd/system/minio.service
    [Unit]
    Description=MinIO
    Documentation=https://docs.min.io
    Wants=network-online.target
    After=network-online.target
    AssertFileIsExecutable=/usr/local/bin/minio
    
    [Service]
    EnvironmentFile=/etc/minio/minio.conf
    ExecStartPre=/bin/bash -c "if [ -z \"${MINIO_VOLUMES}\" ]; then echo \"Variable MINIO_VOLUMES not set in /etc/default/minio\"; exit 1; fi"
    ExecStart=/usr/local/bin/minio server $MINIO_OPTS $MINIO_VOLUMES
    
    # Let systemd restart this service always
    Restart=always
    
    # Specifies the maximum file descriptor number that can be opened by this process
    LimitNOFILE=65536
    
    # Disable timeout logic and wait until process is stopped
    TimeoutStopSec=infinity
    SendSIGKILL=no
    
    [Install]
    WantedBy=multi-user.target
    # Built for ${project.name}-${project.version} (${project.name})

  • Systemd에 MinIO 서비스 적용

    $ systemctl daemon-reload

4. MinIO Service 실행

  • MinIO service 실행 및 영구 실행 적용

    $ systemctl start minio.service
    $ systemctl enable minio.service

  • MinIO service 상태 확인

    $ systemctl status minio.service



5. MinIO에 접속

  • IP:9000 접속하면 MinIO UI가 출력


  • MinIO UI에 로그인하면 아래와 같이 접속


+ Recent posts