집 서버 마크 운영 자동화 (DDNS, 모니터링, 알림 한글화)
마크 서버를 도메인으로 접속하게 해놨는데 집 회선은 공인 IP가 유동이다. IP가 바뀌면 DNS가 옛날 IP를 가리키고, 친구들한테 서버 터졌다고 연락이 온다. 이걸 사람이 챙기는건 말이 안 되니 자동화했다.
DDNS는 크론 하나
거창한 DDNS 클라이언트 안 깔고 쉘 스크립트 하나로 끝냈다. 5분마다 크론이 돈다.
- 공인 IP 조회. 1차는 Cloudflare whoami(DNS 조회라 빠름), 실패하면 ipify로 폴백
- 지난번 IP 적어둔 파일이랑 비교해서 같으면 그냥 끝. 그래서 평소 API 호출은 0회
- 바뀌었으면 Cloudflare API로 A레코드 갱신하고 디스코드 웹훅으로 알림
레코드 구조가 포인트다. apex(moon-core.com) 하나만 A레코드로 두고 mc. 같은 서브도메인은 전부 apex로 가는 CNAME으로 걸었다. 그러면 IP가 바뀌어도 갱신할 레코드는 딱 하나임. 서버 늘어날 때마다 스크립트 고칠 일이 없다.
집 안에서 도메인으로 접속하면 공유기 NAT를 한 바퀴 돌아야 하는 문제(헤어핀)도 있는데 이건 내부 DNS(AdGuard Home)에 리라이트 걸어서 집 안에서는 도메인이 바로 서버 내부 IP로 풀리게 했다.
모니터링에 편입
원래 Prometheus + Grafana + Alertmanager 스택이 돌고 있어서 마크 쪽은 mc-monitor(itzg) 익스포터만 붙이면 됐다. 서버 주소를 환경변수로 주면 마크 프로토콜로 핑을 쏴서 상태/접속자수/응답시간을 메트릭으로 내준다. 알림 규칙은 이거 하나면 충분
- alert: MinecraftServerDown
expr: minecraft_status_healthy == 0
for: 3m
labels: { severity: critical }
모드팩 서버를 새로 파고 감시 대상에 추가했는데 추가하자마자 디스코드에 빨간 알림이 떴다. 어? 하고 봤더니 오탐이 아니었음 마침 그 시간에 서버를 재시작하고 있었고 모드 305개짜리는 부팅이 오래 걸려서 그동안 진짜로 응답이 없던 거다. 부팅 끝나니까 초록색 해결 알림이 따라왔다. 첫 실전은 잘 돌았음
근데 해결됐다는데 왜 critical?
그 초록색 알림 보다가 잠깐 의심했다. RESOLVED라면서 본문에는 여전히 critical이니 "서버 응답 없음"이니 하는 문구가 박혀있다. 해결됐다면서 이게 왜 붙어있지? 버그인가??
버그가 아니고 Alertmanager 사양이다. 해결 알림에도 원래 알림의 라벨이랑 문구를 그대로 붙여서 보낸다. 어떤 알림이 풀렸는지 알려주려는 거지 지금 상태를 말하는게 아님 알고 나면 당연한데 모르고 보면 헷갈린다.
이럴 거면 한글로
기본 포맷이 저렇게 헷갈리니 템플릿을 직접 썼다. Alertmanager는 디스코드 알림 제목/본문을 Go 템플릿으로 바꿀 수 있다.
{{ if eq .Status "firing" }}🚨 문제 발생{{ else }}✅ 문제 해결됨{{ end }}
🔴 마인크래프트 서버 응답 없음 (:25585) -> 발생함
🟢 마인크래프트 서버 응답 없음 (:25585) -> 해결됨
07/17 15:25 ~ 16:06 동안 지속됨
발생함/해결됨을 문장으로 박아버리니 색깔 안 봐도 안 헷갈린다. 해결 알림엔 문제가 이어진 시간대도 같이 나오게 햇다.
시각은 KST로 나와야 해서 컨테이너에 TZ만 넣었는데 안 됐다. prom 계열 이미지는 tzdata가 없어서 TZ를 줘도 UTC로 나옴 호스트 /usr/share/zoneinfo를 읽기전용으로 마운트해주니 해결됐다.
덤으로 기본 알림에 붙던 Source 링크도 없앴다. http://af6c2d1d875f:9090 같은 컨테이너 ID 주소라 눌러봐야 아무데도 못 가는 링크였음
마치며
IP 갱신 자동, 다운 감지 자동, 알림도 한글. 이제 서버 터지면 친구보다 봇이 먼저 알려준다(친구들 미안...)