docs: 2026-04-27 모니터링 알림 추가 및 트러블슈팅 업데이트
Some checks failed
Build and Push Images / build-backend (push) Has been cancelled

This commit is contained in:
qorgh529
2026-04-27 20:07:22 +09:00
parent a024efbd3f
commit fc12243b1d

105
README.md
View File

@@ -627,6 +627,69 @@ git config --global user.name "계정명"
--- ---
### 14. Gitea Registry ImagePullBackOff — 토큰 인증 헤어핀 NAT 문제
**증상**
```
Failed to pull image: Error response from daemon:
Get "http://gitea-http.gitea.svc.cluster.local:3000/v2/token?...": context deadline exceeded
```
**원인** Docker Desktop 환경에서 kubelet이 이미지를 Pull할 때 Docker 데몬을 통해 수행하는데,
Docker 데몬은 K8s 내부 DNS(`gitea-http.gitea.svc.cluster.local`)를 해석하지 못함.
Gitea Registry가 토큰 인증을 내부 서비스명으로 리다이렉트하면 Docker 데몬이 접근 불가 → timeout 발생.
**해결**
이미지 주소와 Registry Secret을 외부 IP로 통일:
```bash
# yaml 이미지 주소 변경
sed -i "s|gitea-http.gitea.svc.cluster.local:3000|192.168.10.101:30000|g" k8s/04-backend.yaml
sed -i "s|gitea-http.gitea.svc.cluster.local:3000|192.168.10.101:30000|g" k8s/05-frontend.yaml
# Registry Secret 재생성 (외부 IP 기준)
kubectl delete secret gitea-registry-secret -n web-portal
kubectl create secret docker-registry gitea-registry-secret \
--namespace=web-portal \
--docker-server=192.168.10.101:30000 \
--docker-username=<계정> \
--docker-password=<패스워드>
# 적용
kubectl apply -f k8s/04-backend.yaml
kubectl apply -f k8s/05-frontend.yaml
kubectl rollout restart deployment/backend -n web-portal
kubectl rollout restart deployment/frontend -n web-portal
```
> ⚠️ Gitea ROOT_URL을 내부 서비스명으로 변경해도 Docker 데몬은 K8s 내부 DNS를 사용할 수 없으므로
> Docker Desktop 환경에서는 반드시 외부 IP(`192.168.10.101:30000`)를 사용해야 함.
---
### 15. 모니터링 알림 환경변수 미적용 (notifier skipping)
**증상**
```
[NOTIFIER] Discord webhook URL not set, skipping
[NOTIFIER] Gmail config not set, skipping
```
**원인** `kubectl set image` 명령어로 이미지를 변경하면 deployment의 환경변수 설정이 초기화됨.
또는 Secret 이름이 yaml과 다르게 생성된 경우.
**해결**
yaml의 Secret 이름(`notify-secrets`)과 key 이름을 확인 후 동일하게 Secret 재생성:
```bash
kubectl delete secret notify-secrets -n web-portal
kubectl create secret generic notify-secrets \
--namespace=web-portal \
--from-literal=discord-webhook-url="https://discord.com/api/webhooks/..." \
--from-literal=gmail-user="발송계정@gmail.com" \
--from-literal=gmail-app-password="xxxx xxxx xxxx xxxx" \
--from-literal=alert-email-to="수신계정@gmail.com"
kubectl rollout restart deployment/backend -n web-portal
```
yaml 변경 후에는 반드시 `kubectl apply -f k8s/04-backend.yaml` 로 재적용할 것.
---
## 📅 변경 이력 ## 📅 변경 이력
### 2026-04-06 (초기 구축) ### 2026-04-06 (초기 구축)
@@ -661,3 +724,45 @@ git config --global user.name "계정명"
- **gitea.cyanburu.com** → Gitea (Let's Encrypt 인증서 자동 발급) - **gitea.cyanburu.com** → Gitea (Let's Encrypt 인증서 자동 발급)
- **argo.cyanburu.com** → ArgoCD (Let's Encrypt 인증서 자동 발급) - **argo.cyanburu.com** → ArgoCD (Let's Encrypt 인증서 자동 발급)
- CoreDNS에 서브도메인 내부 IP 등록 (헤어핀 NAT 우회) - CoreDNS에 서브도메인 내부 IP 등록 (헤어핀 NAT 우회)
### 2026-04-27 (모니터링 알림 추가 + 장애 복구)
#### 기능 추가
- **Discord 알림**: Pod 이상/복구, 계정 잠금, 임시 비밀번호 발급 시 Discord Webhook 알림
- **Gmail 알림**: Pod 이상/복구, 인증서 만료 임박 시 이메일 알림
- **자동 모니터링 스케줄러**: Pod 상태 1분마다 체크, 인증서 만료 24시간마다 체크
- `notifier.py` — Discord/Gmail 알림 모듈 추가
- `monitor.py` — APScheduler 기반 모니터링 모듈 추가
- `main.py``asyncio.create_task()``await` 방식으로 수정 (동기함수 내 비동기 호출 오류 수정)
#### 알림 설정 방법
**1. Discord Webhook URL 발급**
Discord 서버 → 알림받을 채널 → ⚙️ 채널 설정 → 연동 → 웹후크 → 새 웹후크 생성 → URL 복사
**2. Gmail 앱 비밀번호 발급**
- Google 계정 → 보안 → 2단계 인증 활성화 (필수)
- `https://myaccount.google.com/apppasswords` → 앱 이름 입력 → 16자리 비밀번호 복사
**3. K8s Secret 등록**
```bash
kubectl create secret generic notify-secrets \
--namespace=web-portal \
--from-literal=discord-webhook-url="https://discord.com/api/webhooks/..." \
--from-literal=gmail-user="발송계정@gmail.com" \
--from-literal=gmail-app-password="xxxx xxxx xxxx xxxx" \
--from-literal=alert-email-to="수신계정@gmail.com"
```
**4. 알림 테스트**
브라우저 콘솔(F12)에서 실행:
```javascript
fetch('/api/admin/notify-test', {
headers: { 'Authorization': 'Bearer ' + localStorage.getItem('portal_token') }
}).then(r => r.json()).then(console.log)
```
#### 장애 복구 내용
- **backend ImagePullBackOff** — Gitea Registry 토큰 인증 문제로 발생, 외부 IP 방식으로 해결
- **backend/frontend 이미지 주소** — 내부 서비스명(`gitea-http.gitea.svc.cluster.local:3000`) → 외부 IP(`192.168.10.101:30000`)로 변경
- **notifier.py, monitor.py 누락** — Dockerfile에 파일이 있었으나 `--no-cache` 재빌드로 해결
- **notify-secrets** — 기존 Secret이 잘못된 값으로 등록되어 있어 재생성