InfluxDB 와 Grafana 를 이용한 FreeNAS 모니터링

FreeNAS 11.3 으로 올라가면서 몇가지 바뀐 점이 있습니다. 그 중 두드러지는 건 레거시 인터페이스가 사라졌다는 겁니다. 초창기 맴버이던 그는 이제 우리 곁을 떠났습니다. 묵묵히 제 일을 다 해준 레거시 인터페이스에게 묵념을…

이 문제가 아니라 레포트가 사라졌습니다. 새로운 인터페이스에도 레포트 기능이 있기는 합니다만, 여러 모로 불편한 점이 많습니다. 반응이 레거시 인터페이스보다는 느리고 한 눈에 보기 힘들고 보고자 하는 요소를 하나하나 다 선택해 줘야 하고 롱텀 데이터 보기 힘들고… 늘어놓자니 끝이 없네요. 그러니 모니터링을 할 다른 방법이 필요한데, 전 바로 떠오른 것이 NetData 였습니다. 그런데, NetData 도 제거되었습니다. 장기 실행시 메모리 누수가 생긴다는 것이 문제였습니다. 큰 문제 맞군요. iXsystems 에서는 대안으로 TrueCommand 를 추천합니다만…. TrueCommand 는 FreeBSD 기반의 FreeNAS 관리 시스템으로서 FreeNAS 의 루트 계정을 등록해서 API를 통해 관리합니다. 몇번 만지작대보니 FreeNAS 서버가 2개 이상 있으면 확실히 좋겠다 싶긴 한데, FreeNAS 서버는 1개 뿐이고, 서버 모니터링을 위해서 서버를 하나 더 굴리는건 배보다 배꼽이 더 큰 일 아닌가 싶었습니다.

그래서 좀더 조사를 해 보았습니다. rrdtools 를 그대로 쓸 방법이나, 레거시 인터페이스의 레포트를 쓸 방법, 그것도 아니면 더 깔쌈한 어떤 방법을 찾아나섰죠. 그러다보니 상당히 좋은 것을 건졌습니다. 바로 InfluxDBGrafana 입니다.

용어 설명

InfluxDB

InfluxDB 는 시계열 데이터베이스입니다. 특정한 시간에 측정된 데이터를 저장하는 데이터베이스죠. GO 언어로 작성되었고, 시계열 데이터를 효율적으로 다루는데 중점을 두었기 때문에 읽기와 쓰기가 매우 빠른 반면 업데이트나 랜덤 읽기는 비효율적입니다. (시계열 데이터에서 랜덤 읽기나 업데이트를 할 일이 뭐가 있겠냐 싶긴 합니다만) 그리고 SQL-like 명령을 쓸 수 있습니다. 거기에 의존성이 없어 설치가 매우 간편합니다. 현재 가장 인기 있는 시계열 데이터베이스입니다.

Grafana

Grafana 는 InfluxDB 나 Graphite 등의 데이터베이스에서 데이터를 읽어와 그래프로 그려 주는 프로그램입니다. Grafana 를 이용하면 코드를 작성하지 않고도 깔쌈한 대시보드를 만들 수 있습니다.

Graphite

Graphite 는 InfluxDB 같은 시 계열 데이터베이스입니다.

dataset 만들기

Data/DB/InfluxDB

influxdb 의 데이터가 저장될 데이터셋입니다.

Jail 구성하기

Jail의 이름은 InfluxDB

고정 IP 잡아 주시고

자동 시작 설정해 주세요.

패키지 설치

iocage console -F InfluxDB

감옥에 로그인 해 줍니다.

pkg install grafana6 influxdb

Grafana 와 InfluxDB 둘다 단일 패키지라서 설치가 굉장히 간단합니다.

설정 파일 수정하기

InfluxDB

vi /usr/local/etc/influxdb.conf

수정해 주어야 할 부분은 아래와 같습니다.

[data]
dir = "/mnt/influxdb/data"
wal-fsync-delay = "1s"
index-version = "tsi1"
cache-max-memory-size = "1g"
cache-snapshot-memory-size = "125m"
cache-snapshot-write-cold-duration = "10m"
compact-full-write-cold-duration = "4h"
max-concurrent-compactions = 0
compact-throughput = "48m"
compact-throughput-burst = "48m"
tsm-use-madv-willneed = false
max-index-log-file-size = "1m"
[retention]
enabled = true
check-interval = "6h"
[monitor]
store-enabled = true
store-database = "_internal"
store-interval = "10s"
[http]
enabled = true
bind-address = ":8086"
auth-enabled = true
log-enabled = true
max-row-limit = 0
max-connection-limit = 0
unix-socket-enabled = false
max-body-size = 25000000
max-concurrent-write-limit = 0
max-enqueued-write-limit = 0
enqueued-write-timeout = 0

해당되는 부분을 찾아 수정해 주세요.

WAL 은 미리 쓰기 로그라 해서 임시 쓰기 파일로 이해하시면 편합니다. 빠른 읽기 쓰기가 필요하기 때문에 SSD 를 사용하는게 좋습니다.

Data 는 데이터가 저장됩니다. WAL 에 비해 적은 읽기쓰기 속도가 필요하고 많은 용량을 차지함으로 HDD 에 저장하셔도 무방합니다. 필자는 HDD 를 마운트 할 것이나, WAL 과 같은 디스크를 사용해도 부하가 적은 환경에서는 무방합니다.

InfluxDB 에 Graphite 형식 데이터 받기 설정

InfluxDB 는 Grphite 형식의 데이터를 받을 수 있습니다. FreeNAS 는 Graphite 형식의 데이터를 보내니, 해당 데이터를 받을 수 있도록 설정하겠습니다.

influxdb.conf 를 이어서 수정합니다.

기존 [[graphite]] 아래 내용을 지우고 아래 설정을 입력해 주세요.

[[graphite]]
   enabled = true
   database = "graphite"
   bind-address = ":2003"
   protocol = "tcp"
   templates = [
     # CPU usages
     "*.*.*.cpu-idle host.host.type.measurement",
     "*.*.*.cpu-interrupt host.host.type.measurement",
     "*.*.*.cpu-nice host.host.type.measurement",
     "*.*.*.cpu-system host.host.type.measurement",
     "*.*.*.cpu-user host.host.type.measurement",
     # system load
     "*.*.load.load.* host.host..measurement.type",
     # dev temperature (CPU + HDD)
     "*.*.*.temperature host.host.dev.measurement",
     # memory usages
     "*.*.memory.* host.host.measurement.type",
     # SWAP
     "*.*.swap.* host.host.measurement.type",
     # uptime
     "*.*.uptime.* host.host.measurement.uptime",
     # Interface info
     "*.*.*.*.rx host.host.interface.type.measurement",
     "*.*.*.*.tx host.host.interface.type.measurement",
     # Processes
     "*.*.processes.* host.host.measurement.type",
     # ZFS ARC Info
     "*.*.zfs_arc.* host.host.measurement.type",
     # ZFS ARC v2 Info
     "*.*.zfs_arc_v2.* host.host.measurement.type",
     # Disk Info 1
     "*.*.*.disk_io_time.* host.host.dev.measurement.type",
     "*.*.*.disk_octets.* host.host.dev.measurement.type",
     "*.*.*.disk_ops.* host.host.dev.measurement.type",
     "*.*.*.disk_time.* host.host.dev.measurement.type",
     "*.*.*.disk_octets-0-0.* host.host.dev.measurement.type",
     "*.*.*.disk_ops-0-0.* host.host.dev.measurement.type",
     "*.*.*.disk_time-0-0.* host.host.dev.measurement.type",
     # Disk geom Info
     "*.*.geom_stat.* host.host.measurement.type",
     "*.*.geom_stat.*.* host.host.measurement.type.rwd",
     # Disk partition
     "*.*.*.df_complex-free host.host.partition.measurement",
     "*.*.*.df_complex-reserved host.host.partition.measurement",
     "*.*.*.df_complex-used host.host.partition.measurement",
     # RRDcached Info
     "*.*.rrdcached.* host.host.measurement.type",
     # Default
     "host.host.measurement*"
]

templates은 들어오는 데이터를 처리하는 방법입니다. Graphite 에서 보내는 데이터의 형태는 name 만 있어서 servers.hostname.cpu.cpu-0.idle 같은 형태라 InfluxDB 에서 사용하기 적절치 않습니다. 그래서 name=idle, hostname=servers.hostname,  type=cpu-0  같은 식으로 정리해 주는 것입니다.

모두 작성했다면 저장하고 나와 주세요.

Grafana

vi /usr/local/etc/grafana.conf

수정해 주어야 할 부분은 아래와 같습니다.

app_mode = production
instance_name = ${HOSTNAME}
[server]
protocol = http
http_addr = grafana가 설치된 jail 의 IP
http_port = 3000
domain = grafana.example.com
enforce_domain = false
root_url = https://grafana.example.com
[database]
type = mysql
host = mariadb_address:3306
name = grafanadb
user = grafana_user
password = SuperStrowngPassword!
[security]
admin_user = admin
admin_password = admin
secret_key = D2Cmsc0934kamvjsaf83    #secret_key 는 이 값을 그대로 붙여 넣지 말고 앞의 주석 (;) 만 제거해 주세요.
disable_brute_force_login_protection = false
cookie_secure = true
[users]
allow_sign_up = false
allow_org_create = false
auto_assign_org = true
auto_assign_org_role = Viewer
login_hint = email or username
password_hint = password
default_theme = dark
viewers_can_edit = false
editors_can_admin = false
[auth]
login_cookie_name = grafana_session
login_maximum_inactive_lifetime_days = 7
login_maximum_lifetime_days = 30
token_rotation_interval_minutes = 10
disable_login_form = false
disable_signout_menu = false
[auth.anonymous]
enabled = false
[log]
mode = console file
level = info
[alerting]
enabled = true
execute_alerts = true
[explore]
enabled = true

여기서 [database] 섹션은 사용자 설정 등을 저장할 데이터베이스를 말하는데, MySQL 을 데이터베이스로 사용할 경우, MySQL 설정을 해 주어야 합니다. 그렇지 않을 경우, SQLite 를 사용하게 되고 이 경우 특별한 설정이 필요치 않습니다.

마운트 포인트 설정

감옥 정지해 주시고

/mnt/Data/DB/InfluxDB/mnt/influxdb/data

마운트 포인트 잡아 줍니다.

FreeNAS 설정

FreeNAS 호스트네임

Network-Global configuration 에서 hostnamedomain 을 입력해 주세요. 만약 FreeNAS 의 주소가 nas.lan 이라면 hostnamenas, domainlan 입니다.

FreeNAS Graphite 설정

system – reporting 에서 Remote Graphite Server HostnameInfluxDB 가 설치된 감옥의 IP를 입력합니다. FreeNAS 가 InfluxDB로 데이터를 보내도록 설정한 것입니다.

서비스 자동 시작

iocage console -F InfluxDB

sysrc influxdb_enable="YES"
sysrc grafana_enable="YES"
service influxd start
service grafana start

InfluxDB 설정

기초 설정

influx

influx 콘솔로 접속합니다. SQL-Like 명령을 쓸 수 있습니다.

CREATE USER admin WITH PASSWORD 'SuperStrowngPasswrodForadmin' WITH ALL PRIVILEGES

admin 이라는 관리자를 만들었습니다. 비밀번호는 SuperStrowngPasswrodForadmin를 쓰지 말고 강력한 것을 사용해 주세요.

auth

로그인 하는 명령어입니다. 앞서 만든 관리자로 로그인하겠습니다.

CREATE DATABASE graphite

graphite 데이터베이스를 만들었습니다. 오류가 뜰 수도 있는데, 그럼 이미 graphite 데이터베이스가 이미 있는 것입니다.

CREATE USER grafana WITH PASSWORD 'SuperStrowngPasswrodForGrafana'

grafana 유저를 만들었습니다. Grafana 에서 사용할 유저입니다.

GRANT READ ON "graphite" TO "grafana"

graphite 데이터베이스의 읽기 권한만 grafana 에게 주었습니다.

rp와 cq 설정

influxDB에 쌓이는 데이터는 상당히 큽니다. 당장은 문제가 되지 않더라도 그게 1달이 쌓이고 1년이 쌓이면 문제가 되겠죠. 여기서 한 가지 생각해 볼 수 있습니다. “최근 한 시간, 또는 최근 하루 정도는 10초마다 기록한 데이터가 필요할 지도 모르지만, 1년 전의 데이터까지 10초마다 기록한 데이터를 저장하고 있어야 하나?” 일반적으로 아니겠죠. 최근 하루는 10초마다 기록한 데이터만 저장하고, 1달이 지나면 1분 1년이 지나면 1시간마다 기록된 데이터의 텀을 늘려 놓으면 디스크 공간을 크게 절약할 수 있을 것입니다.

influxDB는 그것을 위해 rpcq 라는 기능을 지원합니다.

rp 는 retention policy 는 보존 정책이라 하여 데이터를 얼마동안 유지할지를 설정합니다.

cq 는 continuous query 연속 질의라 하여 원본 데이터에서 어덯게 낮은 해상도의 데이터를 뽑아낼지를 설정합니다.

use graphite

graphite 데이터베이스로 들어가서

alter retention policy "autogen" on "graphite" duration 24h shard duration 1h default
CREATE RETENTION POLICY "twoday" ON "graphite" DURATION 2d REPLICATION 1
CREATE RETENTION POLICY "week" ON "graphite" DURATION 7d REPLICATION 1
CREATE RETENTION POLICY "month" ON "graphite" DURATION 31d REPLICATION 1
CREATE RETENTION POLICY "year" ON "graphite" DURATION 366d REPLICATION 1
CREATE RETENTION POLICY "inf" ON "graphite" DURATION INF REPLICATION 1
CREATE CONTINUOUS QUERY "cq_twoday" ON "graphite" BEGIN SELECT mean(value) as value INTO "graphite"."twoday".:MEASUREMENT FROM /.*/ GROUP BY time(60s),* END
CREATE CONTINUOUS QUERY "cq_week" ON "graphite" BEGIN SELECT mean(value) as value INTO "graphite"."week".:MEASUREMENT FROM /.*/ GROUP BY time(300s),* END
CREATE CONTINUOUS QUERY "cq_month" ON "graphite" BEGIN SELECT mean(value) as value INTO "graphite"."month".:MEASUREMENT FROM /.*/ GROUP BY time(1800s),* END
CREATE CONTINUOUS QUERY "cq_year" ON "graphite" BEGIN SELECT mean(value) as value INTO "graphite"."year".:MEASUREMENT FROM /.*/ GROUP BY time(21600s),* END
CREATE CONTINUOUS QUERY "cq_inf" ON "graphite" BEGIN SELECT mean(value) as value INTO "graphite"."inf".:MEASUREMENT FROM /.*/ GROUP BY time(43200s),* END

위에서부터 차례대로

graphite 데이터베이스의 autogen (자동생성) rp 를 24시간동안 데이터를 저장하는것으로 변경

2일동안 데이터를 저장하는 twoday 라는 rp 를 생성

1주일동안 데이터를 저장하는 week 라는 rp 생성

1달, 1년, 그리고

무한히 데이터를 저장하는 inf 라는 rp 생성

60초마다 측정값의 평균을 뽑아 graphite 데이터베이스의 twoday 테이블에 저장하는 cq_twoday 라는 cq 를 생성합니다.

300초마다 week 테이블에, 1800초 마다 month 테이블에, 21600 초 마다 year 테이블에, 43200 초 마다 inf 테이블에 저장하는 cq 를 만들어줍니다.

모두 올바르게 입력했다면

exit

나가 줍니다.

Grafana 설정

리버스 프록시에 grafana 등록

grafana.example.com 을 grafana 가 이용할 주소라고 가정하겠습니다.

iocage console Nginx_WAF

리버스 프록시 감옥에 로그인 하고

vi /usr/local/etc/nginx/conf.d/grafana.conf

upstream grafana {
    server grafana감옥주소:3000;
    keepalive 32;
}

server {
    listen       443 ssl http2;
    server_name  grafana.example.com;

    include /usr/local/etc/nginx/options/*;

    location / {
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        include /usr/local/etc/nginx/otherconf/proxy.conf;
        proxy_pass http://grafana;
    }
}

이렇게 연결해 줍니다.

이제 grafana 에 https 로 접속할 수 있습니다.

초기 ID와 PW 는 admin 입니다. 접속하고 나서 바꿔 주세요.

비밀번호 바꾸라는 페이지가 바로 표시될텐데, 만약 표시되지 않는다면 왼쪽 구석에  Change Password 에서 비밀번호를 바꿀 수 있습니다.

이제 초기 설정을 해야 하는데, Grafana 가 친절하게 알려 줍니다. Welcome to Grafana 에서 Create a data source, 데이터소스를 추가하라는군요. 눌러 줍니다.

데이터소스 추가

추가해야 할 데이터베이스는 InfluxDB 입니다. 클릭

Name 은 원하는 대로 해 주시고

URL 은 http://InfluxDB주소:8086

Auth 에서 Basic auth 켜 주시면

Basic Auth Details 가 나타나는데, userpassword는 앞서 influxdb 에서 만들어 준 것입니다. 이 경우 grafanaSuperStrowngPasswrodForGrafana 가 되겠네요.

InfluxDB Details 에서

Databasesgraphite

userpassword 는 Influxdb 에서 만들어 준 grafana 유저의 것을 입력해 줍니다.

모두 입력하였다면 Save & Test 를 눌러 저장해 줍니다.

대시보드 추가

이제 대시보드를 만들어야 합니다… 만, grafana 는 다른 사람이 만든 대시보드를 grafana.com 에서 받아 올 수 있습니다. 그래서 저도 만들어서 올려 놓았습니다.

FreeNAS Dashboard

위 링크에서 ID 를 복사하거나 Json 파일을 다운로드 해 주세요.

다시 grafana 로 돌아가서 import 를 눌러 추가해 줍니다.

Grafana.com Dashboard 에 복사한 ID를 집어넣거나,

Upload .json file 을 눌러 다운로드 받은 json 파일을 업로드하면

위와 같은 화면이 나타납니다.

설명을 따라 변수를 작성해주시면 됩니다.

Name 은 대시보드의 이름

Folder 도 원하시는 Folder를 선택해 주시고 (기본적으로 General)

FreeNAS Data 에서 앞서 만든 데이터소스를 선택해 주시고

Host 에 자신의 hostname 을 입력해 주세요.

알려진 문제
hostname 은 둘중 하나입니다. nas.lan 또는 nas
FreeNAS 에 오류가 있어서, 호스트네임을 변경하거나 저장했을때는 hostname 으로 설정되고, 재부팅 하고 난 뒤부터는 hostname_domain 으로 저장됩니다.
그러니 nas_lan 으로 설정한 다음, FreeNAS 를 재부팅해주시는게 좋습니다.

RAM 은 서버의 램 크기

cores 는 CPU 코어(스레드)를 의미합니다.

그리고 나서 Import 해 주시면

이렇게 대시보드가 나타납니다.

유저 등록

관리자 계정으로 접속해 대시보드를 확인하는 것 보다는 일반 계정을 만들어서 그것으로 접속하는 것이 더 좋을 것입니다.

users 에서 유저를 추가할 수 있습니다.

New User 를 눌러서 Name, Username, Password 만 설정해주면 유저 생성 끝. 기본적으로 viewer 로 설정해놓았으니 viewer 권한의 유저가 생성됩니다.

대시보드를 기본 화면으로 등록

Grafana 에 로그인하면 기본적으로 Welcom to Grafana 화면입니다. 바로 FreeNAS 대시보드가 보이도록 하기 위해 기본 화면 설정을 하도록 하겠습니다.

기본 화면으로 등록하고자 하는 대시보드로 들어가서, Mark as favorite☆ 를 눌러 준 후

왼쪽 아래 구석에 를 눌러 Home Dashboard 를 FreeNAS 대시보드로 바꿔 주면 됩니다.

장기 데이터 보기

기본적으로 대시보드는 최근 1시간의 데이터를 보여줍니다.

만약 하루치 데이터를 보고 싶다면 Last 24 hours 을 선택하면 되고,

1주일치 데이터를 보고 싶다면 Last 7 days 를 선택한 후, 상단의 Retention Policy 에서 Week 를 선택해 주면 됩니다.

무슨 말인지 헷갈리시는 분이 있다면 대시보드를 가지고 놀아 보는 걸 추천드립니다. 재미있고 신비한 기능들을 발견할 수 있을 것입니다.

몇가지 문제

몇가지 문제점이 있는데…

첫 번째는 램 사용량이 정확하게 표시되지 않는다는 것입니다. 전체 사용량 – free 한 거라서 정확한 수치는 아닙니다.

두 번째는 CPU 사용량이 정확하게 표시가 안된다는 것입니다. 커널 시간을 리포트하기 때문이 아닌가 싶네요.

세 번째는 파티션이나 네트워크 인터페이스가 현재 없는 요소까지 보인다는 것입니다. Grafana 의 문제인데, 현재는 없는(N/A 데이터만 존재하는) 요소까지 모두 보여주기 때문입니다.

대시보드 상단의 Disk_PartitionsInterfaces 를 적절히 선택해서 보고자 하는 것을 선택해 주는 것이 좋습니다.

세 번째 문제는 해결해보려고 했는데, Grafana 에서 현재 지원하지 않는답니다. https://github.com/grafana/grafana/issues/4470

참고한 사이트

InfluxDB 공식 메뉴얼 https://docs.influxdata.com/influxdb/v1.7

Grafana 공식 메뉴얼 https://grafana.com/docs/grafana/latest/

여담

사실 이 내용은 한두달 전에 올리려고 했습니다. 그런데… DB를 터트려 버리는 바람에…

시리즈 네비게이션<< ZFS 스냅샷 백업

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다