2024. 1. 27. 05:29ㆍWEB
지난 글에서 곰팡이가 발생하는 원인과, 이를 방지하기 위한 기초적인 모니터링 시스템을 구축해 보았습니다.
이번 글에서는 수집된 데이터를 보기 좋게 시각화하고, 습도가 올라가면 외부로 알림을 전송하는 로직을 만들어보겠습니다.
이전 글은 아래에서 참고할 수 있습니다.
2024.01.26 - [WEB] - [서비스] 3천원으로 실내 곰팡이 방지한 후기 -1
[서비스] 3천원으로 실내 곰팡이 방지한 후기 -1
겨울철이 되면 실내와 바깥의 온도 차이로 인해 결로현상이 발생하고, 실내 습도가 올라가 곰팡이가 번식하기 좋은 환경이 됩니다. 물론 제 방도 예외는 아니구요. 한 2주 전부터 초기 값을 (0, 0,
youngmon.tistory.com
바로 수집한 데이터를 시각화하기 위한 Grafana 설정을 시작하겠습니다.
기존 쿠버네티스 클러스터에 grafana 리소스를 만들어줍니다.
그라파나는 옵션이므로 굳이 안 볼 것 같으면 넘어가도 괜찮을 듯합니다.
Grafana
그라파나는 시계열 데이터의 분석과 시각화를 위한 오픈소스 툴로, 프로메테우스 이외에도 다양한 메트릭 수집 툴과 연결할 수 있으며, 지원하는 다양한 패널과 대시보드를 통해, 데이터 소스의 데이터를 다양한 방식으로 표시할 수 있습니다.
# deployment Pod Template
image: grafana/grafana:latest
---
apiVersion: v1
kind: Service
metadata:
name: grafana
namespace: monitoring
spec:
ports:
- port: 3000
protocol: TCP
targetPort: web
selector:
app: grafana
역시 쿠버네티스에 적용하며, 프로메테우스와 동일한 네임스페이스에 생성했습니다.
grafana에 접속해 봅니다.
초기 username과 password는 둘 다 admin으로 동일합니다.
대시보드에 표시될 데이터 소스를 가져와야 합니다.
kubectl을 통해 prometheus와 grafana 서비스의 정보를 얻었는데, 쿠버네티스의 CoreDNS를 통해 간단하게 서비스 명과 포트로 접근할 수 있습니다.
그꾸
이제 이 데이터를 통해 대시보드를 꾸밀 수 있습니다.
이제 쿼리를 통해 프로메테우스로부터 데이터를 가져옵니다.
변화를 한눈에 보기 위한 그래프를 저장해 주고, 현재 값을 한눈에 볼 수 있는 패널을 하나 더 만들어 줍시다.
온도도 그냥 하나 더 만들면 깔끔하지만, 저는 그냥 합쳤습니다.
아래 Users and access 등을 통해 viewer 권한의 서비스 계정 등을 만들 수 있습니다.
이제 해당 그라파나 서비스를 호스팅 해서 외부에서도 확인할 수 있게 되었습니다.
하지만, 이것만 계속 보고 있을 수는 없겠죠?
창문을 열어서 5분 정도만 환기시켜 줘도 습도가 40% 대로 떨어지곤 하는데, 계속 그래프, 게이지만 지켜보고 있는 건 너무 비효율적입니다.
습도가 너무 높아졌을 때마다 한 번씩 창문을 열어주면 2시간 정도는 습도가 40-60% 사이에서 유지됩니다.
AlertManager
프로메테우스 서버는 크게
- 메트릭의 수집
- 메트릭의 저장
- 알림 발생을 위한 메트릭의 평가
- grafana 등 외부 툴을 위한 메트릭의 노출
을 수행합니다.
프로메테우스는 알림을 생성하고 Alertmanager로 전달하는데, Alertmanager는 외부로 알림을 전송하는 웹훅의 역할 이외에도 알림의 그룹화, 중복 제거 및 억제 등 추가적인 역할을 수행합니다.
알림은 slack, sms, 메일 또는 다른 웹훅으로 전달될 수 있지만, 저는 텔레그램을 사용해 받도록 설정하겠습니다.
먼저 프로메테우스에서 메트릭을 평가하고 알림을 발생할 수 있도록 rule을 설정합니다.
해당 리소스는 PrometheusRule라는 Prometheus Operator의 CRD이지만, Prometheus의 Config을 기반으로 만들어졌기 때문에 프로메테우스 Config을 구성할 때도 참고하시면 좋을 듯합니다.
간단하게 룰을 설명하자면, HumidAlert70과 HumidAlert80은 humid라는 그룹으로 묶이며, humid라는 레이블을 가집니다.
promQL의 수행결과인 습도가 5분 동안 70 이상이면 HumidAlert70, 80 이상이면 HumidAlert80이 발생합니다.
룰을 설정했으니 AlertManager 서버도 띄워줍니다.
이따가 AlertmanagerConfig이라는 리소스를 등록할 때, alert=humid 라벨을 달아놓으면 Alertmanager의 config으로 적용됩니다.
해당 리소스도 CRD이며, 해당 리소스를 등록하면 Prometheus Operator가 해당 리소스를 찾아서 StatefulSet, Service 등 필요한 리소스를 생성해 줍니다.
이제 해당 AlertRule과 AlertManager를 연결하기 위해 Prometheus 서버를 수정해 줍니다.
ruleSelector에서 prometheus=alert-rule이라는 라벨을 가진 룰을 찾고, monitoring namespace의 alertmanager-operated:web을 통해 알림을 전송합니다.
프로메테우스 서버로 가서 적용된 것을 확인해 봅시다.
이제 프로메테우스에서 메트릭을 평가해 알림을 생성하고, 이를 Alertmanager에게 전달할 수 있게 되었습니다.
이제 Alertmanager에서 알림을 받았을 때 어떻게 처리할지를 설정할 차례입니다.
저는 텔레그램을 통해 알림을 전달할 것이라 텔레그램 봇을 먼저 만들도록 하겠습니다.
텔레그램 봇
봇 생성을 위해 BotFather를 검색해 줍니다. 짭이 많은데 블루첵 봇파더가 진짜입니다.
봇을 생성하려고 하면 봇의 이름을 정하라고 하는데, 봇의 이름은 기존 봇들의 이름과 중복되지 않으면서 마지막에 bot으로 끝나야 합니다.
봇을 만드는 데 성공하면 API를 사용하기 위한 토큰과, API 문서의 링크를 줍니다.
봇을 통해 메시지를 받아야하니 메세지를 보내는 방법을 알아봅시다.
문서를 보면 메세지를 보내기 위해
https://api.telegram.org/bot<TOKEN>/METHOD_NAME
으로 요청하라고 쓰여있습니다.
https://core.telegram.org/bots/api#sendmessage
Telegram Bot API
The Bot API is an HTTP-based interface created for developers keen on building bots for Telegram. To learn how to create…
core.telegram.org
sendMessage를 보내기 위해 chatID와 text 파라미터는 필수라고 나오는군요
chatID는 채팅을 전달받을 목적지로 유저는 양수, 그룹은 음수로 구분됩니다.
그룹에 봇을 초대해 줍니다.
만들어둔 봇이 그룹 초기멤버로 설정되었으니 아무 메시지나 하나 날려줍니다.
이제 봇으로 메시지가 온 것을 확인해야 하는데,
https://api.telegram.org/bot<TOKEN>/getUpdates
로 요청을 보내면 채팅을 보여줍니다.
응답으로 어디서 누가 메시지를 보냈는지 확인할 수 있습니다.
sendMessage API로 chat_id와 text 파라미터를 채워서 보내봅니다.
너무 멀리 돌아온 것 같지만, 이제 이 토큰과 chat_id를 이용해 Alertmanager가 대신 알림을 메시지로 보내줄 겁니다.
AlertmanagerConfig
암호화된 토큰을 Secret으로 등록해 줍니다.
apiVersion: monitoring.coreos.com/v1alpha1
kind: AlertmanagerConfig
metadata:
name: amconfig
namespace: monitoring
labels:
alert: humid # 위 Alertmanager에 등록해둔 label
spec:
inhibitRules:
- sourceMatch:
- name: humid
value: '80'
targetMatch:
- name: humid
value: '70'
equal:
- job
receivers:
- name: telegram
telegramConfigs:
- chatID: $CHAT_ID
sendResolved: false
botToken:
name: telegram
key: token
message: |-
{{ range .Alerts }}
{{ .Annotations.summary }}
{{ .Annotations.description }}
{{ end }}
route:
groupBy: [topic]
groupWait: 10s
groupInterval: 10s
receiver: telegram
repeatInterval: 1h
크게 route와 receivers, inhibitRule로 나뉘어 있는 것을 볼 수 있습니다.
route에서는 topic을 기준으로 알림 들을 그룹화하고, 습도 70임을 알리는 알림이 전달된 후 바로 습도 80짜리 알림이 전달되지 않도록 10초 동안 알림이 더 안 오나 기다렸다가 telegram이라는 receiver를 호출합니다.
receivers의 telegram 리시버는 알림의 Annotation을 통해 메시지를 생성하고, chatID와 봇 토큰을 통해 텔레그램으로 메세지를 전송합니다.
inhibitRule은 알림을 억제하는 역할을 하는데, 만약 습도가 80% 이상이 된다면 PrometheusRule 리소스에 정의한 expr인
- $value > 70
- $value > 80
을 모두 만족하게 되어 두 알림이 모두 전송되게 됩니다.
이 경우 하위 레벨의 Alert인 HumidAlert70를 억제하기 위해, humid:80인 Alert가 있을 경우 해당 Alert는 무시되게 설정합니다.
적용
이제 위 리소스까지 적용하면, 습도가 임계점 이상으로 높아졌을 때 텔레그램으로 알려주게 됩니다.
창문을 열어 실내 온도가 낮아지는 것을 최소화하면서 습도가 일정 수준 이상으로 올라가지 않게끔 유지할 수 있습니다.
창문을 약 2분 정도 열어놓고 변화량을 보니 실내 온도는 0.3도 떨어졌고, 습도는 약 20%가량 줄어든 것을 볼 수 있습니다.
창문을 열어두는 시간과 온도, 습도 등의 데이터로 GPT를 파인튜닝해서 최적의 창성비를 찾는 것도 재미있을 것 같네요.
사실 이렇게 알림을 통해 최적의 창문열기를 수행하지 않고, 스마트 제습기를 누군가에게 선물 받고 싶습니다.
캐리어, LG, 롯데알미늄, 위닉스, 홈플래닛, 한경희에게 본 포스팅을 바칩니다.
'WEB' 카테고리의 다른 글
[서비스] 3천원으로 실내 곰팡이 방지한 후기 -1 (4) | 2024.01.26 |
---|---|
[서비스] AI 요리 블로거 챗종원 개발기 -完 (2) | 2023.10.28 |
[서비스] AI 요리 블로거 챗종원 개발기 -6 (0) | 2023.10.27 |
[서비스] AI 요리 블로거 챗종원 개발기 -5 (2) | 2023.10.27 |
[서비스] AI 요리 블로거 챗종원 개발기 -4 (5) | 2023.10.27 |