← 목록

홈 서버에 Prometheus + Grafana 모니터링 스택 올리기

#monitoring#prometheus#grafana#docker

집에 미니PC 한 대를 굴리고 있다. 그런데 이게 지금 잘 돌고 있는건지 아닌지를 알 방법이 없었다. CPU가 언제 튀는지, 디스크가 언제 차는지, 컨테이너가 죽었는지 살았는지... 다 문제가 생기고 나서야 아는 식이었다. 감으로 서버를 운영하는게 영 찝찝해서, 일단 상태를 눈으로 볼 수 있게 만들기로 했다.

전부 Docker Compose로 묶었다. 설정을 파일로 남겨둬야 나중에 서버를 다시 세울 일이 생겨도 그대로 복구할 수 있기 때문이다.

뭘 올렸나

  • Prometheus: 지표를 수집하고 저장한다. 보존기간은 30일로 잡았음
  • Grafana: 그 지표를 대시보드로 본다.
  • Alertmanager: 알림을 라우팅한다. 나는 Discord로 받게 했음
  • node_exporter: 호스트 하드웨어랑 OS 지표를 뽑는다.
  • cAdvisor: 컨테이너별 리소스를 본다.
  • 서비스 몇 개는 헬스체크용 exporter를 따로 붙였음

일단 밖에서 안 보이게

홈 서버는 인터넷에 노출되는 순간부터 골치가 아파진다. 그래서 Grafana나 Prometheus를 0.0.0.0에 열지 않고, WireGuard VPN 인터페이스에만 바인딩했다.

grafana:
  ports:
    - "10.100.0.1:3000:3000"   # VPN IP에만

이렇게 하면 VPN에 붙어야만 대시보드가 열린다. 방화벽(UFW)도 VPN 인터페이스에서 오는 트래픽만 허용하도록 해뒀다. 서버를 지켜보려고 올린 도구 때문에 오히려 서버가 더 노출되면 안되니까, 여기는 신경 써서 막았다.

문서만 봐선 모르는 것들

세팅하면서 몇 번 막혔는데, 문서만 봐선 모르고 직접 겪어야 아는 것들이었다.

Alertmanager가 자꾸 재시작을 반복했다. 로그를 보니 no private IP address found 였다. 노드가 하나뿐인데 gossip 클러스터를 켜려다 IP를 못 찾고 죽는 거였음. --cluster.listen-address= 를 빈 값으로 줘서 클러스터 기능 자체를 꺼버리니 해결됐다. 어차피 단일 노드라 클러스터가 필요 없다.

Discord webhook도 한참 헤맸다. 알림이 안 오길래 봤더니 Alertmanager 컨테이너의 uid가 webhook 파일을 못 읽고 있었다. 그런데 에러를 뱉지도 않고 조용히 실패해서 원인 찾는 데 시간이 좀 걸렸다... 파일은 644, 디렉토리는 755로 맞춰주니 됐음

Grafana는 데이터소스 UID 때문에 크래시가 났다. 기존 볼륨에 자동생성된 UID가 남아있는 상태에서 uid: prometheus 로 고정 프로비저닝을 하니 충돌한 거였다. 볼륨을 새로 초기화해서 넘어갔다.

그래서

이제 서버가 이상해지면 Discord로 먼저 알림이 온다. 대시보드 하나에 하드웨어, 컨테이너, 서비스 상태가 다 모여있어서 뭔가 이상하면 바로 확인할 수 있다.

다음엔 이 서버가 실제로 공격당했던 얘기를 정리해보려고 한다.

← 목록으로
오늘 0·전체 0