[서비스] 3천원으로 실내 곰팡이 방지한 후기 -2

2024. 1. 27. 05:29WEB

지난 글에서 곰팡이가 발생하는 원인과, 이를 방지하기 위한 기초적인 모니터링 시스템을 구축해 보았습니다.

이번 글에서는 수집된 데이터를 보기 좋게 시각화하고, 습도가 올라가면 외부로 알림을 전송하는 로직을 만들어보겠습니다.

이전 글은 아래에서 참고할 수 있습니다.

 

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으로 동일합니다.

 

대시보드 설정
시각화를 위한 대시보드 설정
대시보드 설정
create Dashboard
데이터 소스 가져오기
데이터 소스 설정

대시보드에 표시될 데이터 소스를 가져와야 합니다.

데이터 소스 - 프로메테우스
데이터 소스 설정
데이터 소스 설정
데이터 소스 설정

kubectl을 통해 prometheus와 grafana 서비스의 정보를 얻었는데, 쿠버네티스의 CoreDNS를 통해 간단하게 서비스 명과 포트로 접근할 수 있습니다.

그꾸

이제 이 데이터를 통해 대시보드를 꾸밀 수 있습니다.

임계점
기준이 되는 임계점을 70, 80으로 잡고 표시해줍니다.

이제 쿼리를 통해 프로메테우스로부터 데이터를 가져옵니다.

그래프
우선 습도를 표시
그래프
온도도 표시

변화를 한눈에 보기 위한 그래프를 저장해 주고, 현재 값을 한눈에 볼 수 있는 패널을 하나 더 만들어 줍시다.

게이지
페라리인줄〰️

온도도 그냥 하나 더 만들면 깔끔하지만, 저는 그냥 합쳤습니다.

대시보드
홈 대시보드 완성
홈 설정
들어오자마자 바로 볼 수 있도록 설정

아래 Users and access 등을 통해 viewer 권한의 서비스 계정 등을 만들 수 있습니다.

이제 해당 그라파나 서비스를 호스팅 해서 외부에서도 확인할 수 있게 되었습니다.

 

하지만, 이것만 계속 보고 있을 수는 없겠죠?

창문을 열어서 5분 정도만 환기시켜 줘도 습도가 40% 대로 떨어지곤 하는데, 계속 그래프, 게이지만 지켜보고 있는 건 너무 비효율적입니다.

습도가 너무 높아졌을 때마다 한 번씩 창문을 열어주면 2시간 정도는 습도가 40-60% 사이에서 유지됩니다.

 

AlertManager

프로메테우스 서버는 크게 

  • 메트릭의 수집
  • 메트릭의 저장
  • 알림 발생을 위한 메트릭의 평가
  • grafana 등 외부 툴을 위한 메트릭의 노출

을 수행합니다.

 

프로메테우스는 알림을 생성하고 Alertmanager로 전달하는데, Alertmanager는 외부로 알림을 전송하는 웹훅의 역할 이외에도 알림의 그룹화, 중복 제거 및 억제 등 추가적인 역할을 수행합니다.

 

알림은 slack, sms, 메일 또는 다른 웹훅으로 전달될 수 있지만, 저는 텔레그램을 사용해 받도록 설정하겠습니다.
먼저 프로메테우스에서 메트릭을 평가하고 알림을 발생할 수 있도록 rule을 설정합니다.

PrometheusRule
PrometheusRule

해당 리소스는 PrometheusRule라는 Prometheus Operator의 CRD이지만, Prometheus의 Config을 기반으로 만들어졌기 때문에 프로메테우스 Config을 구성할 때도 참고하시면 좋을 듯합니다.

 

간단하게 룰을 설명하자면, HumidAlert70과 HumidAlert80은 humid라는 그룹으로 묶이며, humid라는 레이블을 가집니다.
promQL의 수행결과인 습도가 5분 동안 70 이상이면 HumidAlert70, 80 이상이면 HumidAlert80이 발생합니다.

 

룰을 설정했으니 AlertManager 서버도 띄워줍니다.

Alertmanager yaml
Label selector

이따가 AlertmanagerConfig이라는 리소스를 등록할 때, alert=humid 라벨을 달아놓으면 Alertmanager의 config으로 적용됩니다.

해당 리소스도 CRD이며, 해당 리소스를 등록하면 Prometheus Operator가 해당 리소스를 찾아서 StatefulSet, Service 등 필요한 리소스를 생성해 줍니다.

생성된 Alertmanager
생성된 Alertmanager

이제 해당 AlertRule과 AlertManager를 연결하기 위해 Prometheus 서버를 수정해 줍니다.

프로메테우스 서버 yaml
서버 설정

ruleSelector에서 prometheus=alert-rule이라는 라벨을 가진 룰을 찾고, monitoring namespace의 alertmanager-operated:web을 통해 알림을 전송합니다.

프로메테우스 서버로 가서 적용된 것을 확인해 봅시다.

프로메테우스 룰
룰 적용 완료
Alertmanager 적용 완료

이제 프로메테우스에서 메트릭을 평가해 알림을 생성하고, 이를 Alertmanager에게 전달할 수 있게 되었습니다.

 

이제 Alertmanager에서 알림을 받았을 때 어떻게 처리할지를 설정할 차례입니다.
저는 텔레그램을 통해 알림을 전달할 것이라 텔레그램 봇을 먼저 만들도록 하겠습니다.


텔레그램 봇

봇파더
botFather

봇 생성을 위해 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는 채팅을 전달받을 목적지로 유저는 양수, 그룹은 음수로 구분됩니다.

그룹 생성
다수에게 뿌리기 위해 그룹을 만들어줍니다.

그룹에 봇을 초대해 줍니다.

봇 초대
아까 만든 봇 이름
집사봇
나의 집사봇

만들어둔 봇이 그룹 초기멤버로 설정되었으니 아무 메시지나 하나 날려줍니다.

ACK
ping

이제 봇으로 메시지가 온 것을 확인해야 하는데,

https://api.telegram.org/bot<TOKEN>/getUpdates

로 요청을 보내면 채팅을 보여줍니다.

응답
chat id

응답으로 어디서 누가 메시지를 보냈는지 확인할 수 있습니다.

57로 시작하고 1로 끝나는 chat_id에 하나
-41로 시작하고 0으로 끝나는 chat_id에 하나

sendMessage API로 chat_id와 text 파라미터를 채워서 보내봅니다.

갠톡
갠톡 잘 왔고
그룹톡
그룹에도 잘 왔네요

너무 멀리 돌아온 것 같지만, 이제 이 토큰과 chat_id를 이용해 Alertmanager가 대신 알림을 메시지로 보내줄 겁니다.

 

AlertmanagerConfig

인코딩
토큰을 base64 인코딩

암호화된 토큰을 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%가량 줄어든 것을 볼 수 있습니다.

그래프
2분 열어두면 습도 약 20% 감소
10분 열기
10분 열어두었을 때, 습도 약 35% 감소

창문을 열어두는 시간과 온도, 습도 등의 데이터로 GPT를 파인튜닝해서 최적의 창성비를 찾는 것도 재미있을 것 같네요.

사실 이렇게 알림을 통해 최적의 창문열기를 수행하지 않고, 스마트 제습기를 누군가에게 선물 받고 싶습니다.

 

따봉

캐리어, LG, 롯데알미늄, 위닉스, 홈플래닛, 한경희에게 본 포스팅을 바칩니다.

반응형