Telegraf, InfluxDB, Grafana 모니터링 구축
셀프호스팅하는 앱들이 몇개있는데 이 앱들을 운영하다 보면 항상 신경 쓰이는 게 있다.
- 네트워크 트래픽을 얼마나 쓰고 있는지
- CPU / 메모리 / 디스크 사용량이 정상 범위인지
- “문제 생기기 전에” 징후를 볼 수 있는지
Cpu, Mem, Disk, Network, Nginx를 모니터링하면 얼마나 어떤 요청이 들어오면 서버가 힘들어하는지 알 수 있을 것 같았고 각 메트릭 지표를 보고싶었다.
나는 프록시로 Oracle VM Free Tier 인스턴스하나 쓰고있다.
Nginx로 내 앱들을 리버스 프록시하고, front의 빌드된 정적파일들을 서빙하는 역할을 한다.
그리고 앱들은 Oracle VM이랑 ssh 리버스 포트터널링을 통해서 통신을 한다.
문제는 Oracle VM Free Tier는 메모리가 1GB라서 많은 메모리를 사용못한다. (현재 nginx, redis 등이 떠있음.)
그래서 목표를 제일 가볍게 모니터링을 해보자.라고 세웠다.
가용할 수 있는 서버는 Oracle VM, Mac Mini M4, Mac Book Air M1인데, 결과적으로 Mac Book Air M1을 중앙 모니터링 서버로 두고,
Mac + Oracle VM을 모두 감시하는 구조를 만들었다.
(Mac Mini 구매한지 얼마안되서 마이그레이션해야하는데 못함. 다음에는 마이그레이션 작업할 듯)
빠르게 진행해보자
설치
기본적으로 설치는 mac이라 homebrew를 사용해서 설치했습니다.brew install telegraf ... 와 같이 설치하면 시스템 서비스에도 등록해줘서 편하게 운영할 수 있음. 아닌 앱도 있지만 telegraf, lnfluxDB v2 (v3는 안됌), Grafana는 잘된다.
- Telegraf
- 메트릭을 읽어 DB에 저장하는 에이전트 역할.
- InfluxDB v2
- 시계열 데이터베이스. 에이전트가 데이터를 넣어준다.
- Grafana
- DB에 저장된 데이터를 시각화해주는 툴.
설정
공통 설정
- 수집 주기: 10s
- host 태그로 서버 구분
- 인터페이스 / 디스크는 반드시 명시적으로 제한
- 이거안하면 Mac에서
utun,lo0같은 가상 인터페이스가 섞이고, 디스크 사용량이 0으로 보이고 그런다...
- 이거안하면 Mac에서
Telegraf
아래와같이 설정 파일을 수정 후 서비스 재시작한다!
mac: /opt/homebrew/etc/telegraf.conf
linux: /etc/telegraf/telegraf.conf
[agent]
interval = "10s"
hostname = "macbook-air"
[[inputs.net]]
interfaces = ["en0"] # Linux: ["eth0"]
[[inputs.cpu]]
percpu = true
totalcpu = true
report_active = true
[[inputs.mem]]
[[inputs.disk]]
mount_points = ["/System/Volumes/Data"]
ignore_fs = ["devfs", "autofs"]
[[inputs.diskio]]
devices = ["disk0"]
skip_serial_number = true
[[outputs.influxdb_v2]]
urls = ["http://<MAC_IP>:8086"]
token = "<INFLUX_TOKEN>"
organization = "<ORG_NAME>"
bucket = "telegraf"
InfluxDB
Telegraf 설정과 동일하게 organization, bucket을 만들고, token을 받는다.
딱히 뭐 설정할건 없음. UI도 있고, 공식문서나 검색해서 다른 글들보면 너무 잘나와있어서 쉬움.
Grafana
InfluxDB 메트릭 시각화를 해야하니 연동하고 Dashboard의 Panel에 query를 부여해 Grafana가 InfluxDB를 조회하고 시각화할 수 있게 만들어주면된다.
그리고 장비 여러개할거니 보기좋게 host 변수도 설정해야함.
그리고 Panel은 그냥 숫자만 나오니 format?도 변경해서 읽기 좋게만들어줘야함.
Network는 Byte/s, 사용율은 %로 보여지게 유닛을 설정해야한다.
host 변수 설정
import "influxdata/influxdb/schema"
schema.tagValues(bucket: "telegraf", tag: "host")
Network (IN/OUT rate)
IN
from(bucket: "telegraf")
|> range(start: -30m)
|> filter(fn: (r) =>
r._measurement == "net" and
r._field == "bytes_recv" and
r.host == "$host"
)
|> aggregateWindow(every: 1m, fn: last, createEmpty: false)
|> derivative(unit: 1s, nonNegative: true)
OUT
from(bucket: "telegraf")
|> range(start: -30m)
|> filter(fn: (r) =>
r._measurement == "net" and
r._field == "bytes_sent" and
r.host == "$host"
)
|> aggregateWindow(every: 1m, fn: last, createEmpty: false)
|> derivative(unit: 1s, nonNegative: true)
CPU 사용률 (%)
from(bucket: "telegraf")
|> range(start: -30m)
|> filter(fn: (r) =>
r._measurement == "cpu" and
r._field == "usage_idle" and
r.cpu == "cpu-total" and
r.host == "$host"
)
|> aggregateWindow(every: 1m, fn: mean, createEmpty: false)
|> map(fn: (r) => ({ r with _value: 100.0 - r._value }))
Memory 사용률 (%)
from(bucket: "telegraf")
|> range(start: -30m)
|> filter(fn: (r) =>
r._measurement == "mem" and
r._field == "used_percent" and
r.host == "$host"
)
|> aggregateWindow(every: 1m, fn: mean, createEmpty: false)
Disk 사용률 (%)
from(bucket: "telegraf")
|> range(start: -6h)
|> filter(fn: (r) =>
r._measurement == "disk" and
r._field == "used_percent" and
r.host == "$host" and
r.path == "/System/Volumes/Data"
)
|> aggregateWindow(every: 5m, fn: mean, createEmpty: false)
Disk IO Throughput
from(bucket: "telegraf")
|> range(start: -30m)
|> filter(fn: (r) =>
r._measurement == "diskio" and
(r._field == "read_bytes" or r._field == "write_bytes") and
r.host == "$host" and
r.name == "disk0"
)
|> aggregateWindow(every: 1m, fn: last, createEmpty: false)
|> derivative(unit: 1s, nonNegative: true)
|> map(fn: (r) => ({
r with
_field: if r._field == "read_bytes" then "read_Bps" else "write_Bps"
}))
Flux와 InfluxQL을 혼동하거나, bucket 이름에 오타가 있다던가, 설정 수정 후 서비스 재시작을 누락한다던가, 네트워크 인터페이스 혼합같은 이슈때문에 약간의 삽질을 했고 이렇게 구축하니 간단하지만 나름 서버들을 모니터링할 수 있게되었다.
임계치가 넘으면 알람같은 기능은 아직없지만, 사용하다가 필요하게되면 그때 구축하는 것으로 하자.