Skip to main content

프로메테우스 모니터링 시스템 구축하기 1

인스턴스 보안 그룹 설정
  • 9115: blackbox exporter - 내 IP 허용
  • 9090: prometheus - 내 IP 허용
  • 22 - ssh - 내 IP 허용
  • 80 - http - any open (0.0.0.0/0)
  • 443 - https - any open (0.0.0.0/0)

Prometheus 설치

프로메테우스 컨테이너가 실행될 때, 프로메테우스 프로세스를 실행하는 유저가 누구인지를 정해줘야 합니다. 컨테이너에서 프로메테우스를 실행할 때, 보통은 'nobody:nobody'나 'prometheus:prometheus'와 같이 일반 사용자 권한으로 실행하는 것이 권장됩니다.

'/prometheus' 디렉토리의 소유자와 그룹이 호스트의 사용자 또는 그룹과 일치하지 않을 수 있습니다. 만약 호스트에서 이 디렉토리를 만들었다면 호스트의 사용자 또는 그룹으로 소유자 및 그룹이 설정됩니다.

그러나 프로메테우스 컨테이너에서 이 디렉토리를 사용하려면 소유자와 그룹을 프로메테우스가 실행되는 유저로 변경해야 합니다. chown -R 65534:65534 /prometheus 명령어를 실행하면 '/prometheus' 디렉토리와 그 하위 디렉토리 및 파일들의 소유자와 그룹을 'nobody:nobody'로 변경합니다. 65534는 Linux에서 일반적으로 할당되지 않은 사용자와 그룹 ID 중 하나입니다.

이렇게 소유자와 그룹을 변경하는 이유는 프로메테우스가 '/prometheus' 디렉토리 내의 파일 및 디렉토리에 액세스하고 데이터를 쓰거나 읽을 수 있도록 하기 위해서입니다. 만약 프로메테우스가 액세스 권한이 없는 디렉토리 내의 파일이나 디렉토리를 읽거나 쓰게 된다면 오작동이나 데이터 손실이 발생할 수 있습니다. 따라서 프로메테우스가 필요한 권한을 가지도록 '/prometheus' 디렉토리의 소유자와 그룹을 변경하는 것입니다.

chown -R 65534:65534 /prometheus
mkdir -p /prometheus/config /prometheus/data
vi /prometheus/config/prometheus.yaml
...
scrape_config:
- job_name: 'prometheus'
scrape_interval: 3s
scrape_timeout: 1s
static_configs:
- targets:
- localhost:9090

# 프로메테우스 컨테이너 실행
docker run --net=host -d --name=prometheus \
-v /prometheus/config:/etc/prometheus -v /prometheus/data:/data prom/prometheus:v2.29.2 \
--config.file=/etc/prometheus/prometheus.yaml \
--storage.tsdb.path=/data \
--web.enable-lifecycle --storage.tsdb.retention.time=20d \
--log.level=debug

blackbox_exporter 설치

vi /etc/prometheus/blackbox.yaml
...
modules:
www.google.com:
prober: dns
timeout: 5s
dns:
transport_protocol: "udp"
preferred_ip_protocol: "ip4"
query_name: "www.google.com"
query_type: "A"
valid_rcodes:
- NOERROR
ghdwlsgur.github.io:
prober: dns
timeout: 5s
dns:
transport_protocol: "udp"
preferred_ip_protocol: "ip4"
query_name: "ghdwlsgur.github.io"
query_type: "A"
valid_rcodes:
- NOERROR
http_2xx:
prober: http
http_edge:
prober: http
timeout: 3s
http:
method: GET
preferred_ip_protocol: "ip4"
valid_status_codes: [200, 206]
headers:
Range: bytes=0-1

docker run -d --name=blackbox_exporter --net=host --pid=host \
-v /prometheus/config:/etc/prometheus -v "/:/host:ro,rslave" quay.io/prometheus/blackbox-exporter:latest \
--config.file=/etc/prometheus/blackbox.yaml

# 포트 확인
ss -nltp

config 파일을 설정하지 않으면 기본으로 아래와 같은 blackbox.yml로 설정됩니다.

blackbox.yml

modules:
http_2xx:
prober: http
http_post_2xx:
prober: http
http:
method: POST
tcp_connect:
prober: tcp
pop3s_banner:
prober: tcp
tcp:
query_response:
- expect: "^+OK"
tls: true
tls_config:
insecure_skip_verify: false
grpc:
prober: grpc
grpc:
tls: true
preferred_ip_protocol: "ip4"
grpc_plain:
prober: grpc
grpc:
tls: false
service: "service1"
ssh_banner:
prober: tcp
tcp:
query_response:
- expect: "^SSH-2.0-"
- send: "SSH-2.0-blackbox-ssh-check"
irc_banner:
prober: tcp
tcp:
query_response:
- send: "NICK prober"
- send: "USER prober prober prober :prober"
- expect: "PING :([^ ]+)"
send: "PONG ${1}"
- expect: "^:[^ ]+ 001"
icmp:
prober: icmp
icmp_ttl5:
prober: icmp
timeout: 5s
icmp:
ttl: 5

blackbox_exporter 설정

cd /prometheus/config/
mv prometheus.yaml static_sd.yml

vim filed_sd.yml
...
scrape_configs:
- job_name: 'ghdwlsgur.github.io'
metrics_path: /probe
params:
module: [http_edge]
static_configs:
- targets:
- https://ghdwlsgur.github.io/img/logo.svg
- https://s3.ap-northeast-2.amazonaws.com/ghdwlsgur.github.io/blog/OpenSource/OpenSource_gostat1.png
scrape_interval: 1s
scrape_timeout: 1s
relabel_configs:
- source_labels: [__address__]
regex: ^((http[s]?|ftp):\/)?\/?([^:\/\s]+)((\/\w+)*\/)([\w\-\.]+[^#?\s]+)(.*)?(#[\w\-]+)?$
replacement: $3
target_label: domain
- source_labels: [__address__]
regex: .*:(.*)$
replacement: $1
target_label: instance
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: localhost:9115

- job_name: 'blackbox-http-monitor'
metrics_path: /probe
params:
module: [http_2xx]
static_configs:
- targets:
- https://www.google.com
- https://www.naver.com
- https://ghdwlsgur.github.io
scrape_interval: 3s
scrape_timeout: 1s
file_sd_configs:
- files:
- 'sd/*.yml'
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: localhost:9115

- job_name: 'blackbox-dns-monitor'
scrape_interval: 5s
metrics_path: /probe
relabel_configs:
- source_labels: [__address__]
regex: (.*):.*$
replacement: $1
target_label: domain
- source_labels: [__address__]
regex: .*:(.*)$
replacement: $1
target_label: instance
- source_labels: [__address__]
regex: .*:(.*)$
replacement: $1
target_label: __param_target
- source_labels: [domain]
target_label: __param_module
- target_label: __address__
replacement: localhost:9115
static_configs:
- targets:
- ghdwlsgur.github.io:8.8.8.8
- ghdwlsgur.github.io:1.1.1.1
- ghdwlsgur.github.io:9.9.9.9
- ghdwlsgur.github.io:164.124.101.2

# 프로메테우스 설정 파일과 심볼릭 링크 설정
ln -sf fild_sd.yml prometheus.yaml

# 수정사항 적용
curl localhost:9090/-/reload -XPOST -D /dev/stdout

# blackbox exporter 라벨링 작업
mkdir sd
vim sd/localhost.yml
...
- targets:
- localhost:9115
labels:
region: KR
tier: frontend
environment: development
disk: NVMe

# 적용
curl localhost:9090/-/reload -XPOST -D /dev/stdout

# 서비스 디스커버리 확인
curl -I http://133.186.210.167:9090/service-discovery -XGET
...
HTTP/1.1 200 OK
Date: Mon, 27 Mar 2023 11:50:53 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked

라벨링할 때 정규식을 사용하게 되는데 정규식이 익숙치 않다면 https://regex101.com 이 사이트를 유용하게 사용하실 수 있습니다.

Prometheus에서 "probe"란 특정 서비스나 엔드포인트의 상태를 주기적으로 검사하는 작업을 의미하며 이는 Prometheus가 모니터링하고 있는 대상의 상태를 지속적으로 감시하고 모니터링하는 대상에 문제가 발생할 경우 즉각적으로 대응할 수 있도록 도와줍니다.

보통 probe는 HTTP GET 요청을 보내고 해당 요청에 대한 응답을 분석하여 대상의 상태를 확인합니다. 이를 통해 Prometheus는 대상의 상태에 대한 메트릭을 수집하고 이를 시각화하거나 경고를 발생시키는 등의 작업을 수행할 수 있습니다.

예를 들어, Kubernetes에서는 Prometheus를 이용하여 각 노드와 컨테이너의 상태를 모니터링합니다. 이를 위해 각 노드와 컨테이너에 대한 probe를 설정하고 이를 통해 상태 정보를 수집합니다. 이를 바탕으로 Prometheus는 각 대상의 상태를 지속적으로 모니터링하고 필요한 경우에는 경고를 발생시키거나 자동으로 복구 작업을 수행합니다.