234 lines
8.0 KiB
Markdown
234 lines
8.0 KiB
Markdown
# Infra Report
|
|
|
|
Kubernetes 클러스터 인프라 모니터링 주간 리포트 시스템. Prometheus와 Kubernetes API에서 메트릭을 수집하여 웹 대시보드로 시각화합니다.
|
|
|
|
## 기능
|
|
|
|
- **CPU / Memory / Disk / NAS 사용률** 시계열 차트 및 통계 (avg, max, min)
|
|
- **Ingress / Istio Network Traffic** RX/TX 분리 차트 및 통계
|
|
- **노드별 상세 테이블** (CPU, Memory, Disk avg/max/min, 노드 스펙)
|
|
- **NAS / Ingress / Istio 상세 테이블** (mountpoint별, RX/TX별 avg/max/min)
|
|
- **주의 구간 자동 감지** (임계값 기반 + Z-score peak 감지)
|
|
- **기간 선택** (시작일/종료일 직접 설정 + 프리셋 버튼)
|
|
- **차트 인터랙션** (hover 시 전체 데이터 tooltip, 클릭 시 solo 모드)
|
|
- **PDF 내보내기**
|
|
|
|
## 기술 스택
|
|
|
|
| 구분 | 기술 |
|
|
|------|------|
|
|
| Frontend | Next.js 14 (App Router), React 18, TypeScript |
|
|
| 스타일링 | Tailwind CSS 3 |
|
|
| 차트 | Apache ECharts 6 (echarts-for-react) |
|
|
| 상태관리 | TanStack React Query 5 |
|
|
| 데이터 소스 | Prometheus HTTP API, Kubernetes API |
|
|
| PDF 생성 | html2canvas + jsPDF |
|
|
| 컨테이너 | Docker (multi-stage build, standalone output) |
|
|
| 패키지 관리 | Helm Chart (OCI) |
|
|
| CI/CD | Gitea Actions → Harbor (Docker + Helm OCI) |
|
|
| 배포 | ArgoCD (자동 sync, semver range `>0.0.0`) |
|
|
| 레지스트리 | Harbor |
|
|
|
|
## 프로젝트 구조
|
|
|
|
```
|
|
src/
|
|
├── app/
|
|
│ ├── page.tsx # 메인 대시보드 페이지
|
|
│ └── api/
|
|
│ ├── report/route.ts # 전체 리포트 API
|
|
│ ├── metrics/[type]/route.ts # 개별 메트릭 API
|
|
│ └── health/route.ts # 헬스체크
|
|
├── components/
|
|
│ ├── charts/
|
|
│ │ ├── TimeSeriesChart.tsx # CPU/Memory/Disk/NAS 차트
|
|
│ │ └── NetworkChart.tsx # Ingress/Istio 네트워크 차트
|
|
│ ├── report/
|
|
│ │ ├── SummaryCards.tsx # 상단 요약 카드 (5개)
|
|
│ │ ├── NodeTable.tsx # 노드별 상세 테이블
|
|
│ │ ├── NasTable.tsx # NAS mountpoint별 상세
|
|
│ │ ├── NetworkTable.tsx # Network RX/TX 상세
|
|
│ │ ├── AlertPanel.tsx # 주의 구간 패널 (CPU/Memory/Disk/NAS)
|
|
│ │ ├── NetworkAlertPanel.tsx # Network 주의 구간 패널
|
|
│ │ └── ReportHeader.tsx # 리포트 헤더 + PDF 버튼
|
|
│ └── ErrorBoundary.tsx # 에러 격리 컴포넌트
|
|
├── hooks/
|
|
│ └── useReport.ts # React Query 기반 데이터 fetch
|
|
├── lib/
|
|
│ ├── prometheus.ts # Prometheus API 클라이언트 + PromQL 쿼리
|
|
│ ├── kubernetes.ts # Kubernetes API 클라이언트
|
|
│ ├── analytics.ts # 통계 계산 + Z-score peak 감지
|
|
│ └── formatters.ts # 포맷팅 유틸 (bytes, percent, timestamp)
|
|
└── types/
|
|
└── metrics.ts # TypeScript 인터페이스 정의
|
|
|
|
charts/infra-report/ # Helm Chart
|
|
├── Chart.yaml
|
|
├── values.yaml
|
|
└── templates/
|
|
├── deployment.yaml
|
|
├── service.yaml
|
|
├── ingress.yaml
|
|
├── configmap.yaml
|
|
├── serviceaccount.yaml
|
|
├── clusterrole.yaml
|
|
└── clusterrolebinding.yaml
|
|
```
|
|
|
|
## 주의 구간 판단 기준
|
|
|
|
### 임계값 기반
|
|
|
|
| 메트릭 | Warning | Critical |
|
|
|--------|---------|----------|
|
|
| CPU | - | max > 90% |
|
|
| Memory | 80% < max ≤ 90% | max > 90% |
|
|
| Disk | 80% < max ≤ 90% | max > 90% |
|
|
| NAS | 80% < max ≤ 90% | max > 90% |
|
|
|
|
### Z-score Peak 감지
|
|
|
|
CPU, Memory, Ingress, Istio에 적용됩니다.
|
|
|
|
- **알고리즘**: 전체 데이터의 평균(mean)과 모표준편차(stddev)를 계산하고, 각 데이터 포인트의 Z-score `(값 - mean) / stddev`를 산출
|
|
- **Threshold**: `|Z-score| > 5` (평균에서 표준편차 5배 이상 벗어난 경우)
|
|
- **구간 병합**: 연속된 peak 포인트를 하나의 구간으로 묶어 시작/종료 시간, 최대값, 평균값 기록
|
|
- **차트 표시**: peak 구간은 차트에 빨간색 반투명 영역으로 표시
|
|
|
|
## 환경 변수 (ConfigMap)
|
|
|
|
`charts/infra-report/values.yaml`의 `config` 섹션에서 설정합니다.
|
|
|
|
| 변수 | 기본값 | 설명 |
|
|
|------|--------|------|
|
|
| `PROMETHEUS_URL` | `http://prometheus-server.monitoring` | Prometheus 서버 주소 |
|
|
| `REPORT_STEP` | `5m` | 데이터 수집 간격 |
|
|
| `REPORT_RANGE_DAYS` | `7` | 기본 조회 기간 (일) |
|
|
| `TZ` | `Asia/Seoul` | 타임존 |
|
|
| `QUERY_CPU` | `100 - (avg by (node)(...))` | CPU 사용률 PromQL |
|
|
| `QUERY_MEMORY` | `(1 - MemAvailable/MemTotal) * 100` | Memory 사용률 PromQL |
|
|
| `QUERY_DISK` | `(1 - avail/size) * 100` | Disk 사용률 PromQL |
|
|
| `QUERY_NAS` | NFS 기반 쿼리 | NAS 사용률 PromQL |
|
|
| `QUERY_INGRESS_RX/TX` | ingress-nginx 컨테이너 네트워크 | Ingress 트래픽 PromQL |
|
|
| `QUERY_ISTIO_RX/TX` | istio-system 컨테이너 네트워크 | Istio 트래픽 PromQL |
|
|
|
|
PromQL 쿼리를 변경하면 values.yaml 수정 후 Helm chart를 재배포하면 됩니다 (소스 코드 수정 불필요).
|
|
|
|
## 배포 방법
|
|
|
|
### 사전 요구사항
|
|
|
|
- Kubernetes 클러스터
|
|
- Prometheus (node-exporter 포함)
|
|
- Harbor 레지스트리
|
|
- ArgoCD
|
|
- Gitea (소스 저장소 + CI/CD)
|
|
|
|
### 1. Gitea 저장소 Secrets 등록
|
|
|
|
Gitea 저장소 Settings > Secrets에 다음을 등록합니다:
|
|
|
|
| Secret | 설명 |
|
|
|--------|------|
|
|
| `REGISTRY_URL` | Harbor 주소 (예: `harbor.example.com`) |
|
|
| `REGISTRY_USER` | Harbor 사용자 |
|
|
| `REGISTRY_PASSWORD` | Harbor 비밀번호 |
|
|
|
|
### 2. Harbor Pull Secret 생성
|
|
|
|
```bash
|
|
kubectl create secret docker-registry harbor-pull-secret \
|
|
--docker-server=harbor.example.com \
|
|
--docker-username=admin \
|
|
--docker-password='password' \
|
|
-n soo
|
|
```
|
|
|
|
### 3. ArgoCD Repository Secret 생성
|
|
|
|
```bash
|
|
kubectl apply -f - <<EOF
|
|
apiVersion: v1
|
|
kind: Secret
|
|
metadata:
|
|
name: harbor-helm-repo
|
|
namespace: argocd
|
|
labels:
|
|
argocd.argoproj.io/secret-type: repository
|
|
type: Opaque
|
|
stringData:
|
|
type: helm
|
|
name: harbor-infra
|
|
url: harbor.example.com/infra
|
|
enableOCI: "true"
|
|
username: admin
|
|
password: "password"
|
|
EOF
|
|
```
|
|
|
|
### 4. ArgoCD Application 생성
|
|
|
|
```bash
|
|
kubectl apply -f - <<EOF
|
|
apiVersion: argoproj.io/v1alpha1
|
|
kind: Application
|
|
metadata:
|
|
name: infra-report
|
|
namespace: argocd
|
|
spec:
|
|
project: default
|
|
source:
|
|
chart: infra-report
|
|
repoURL: harbor.example.com/infra
|
|
targetRevision: ">0.0.0"
|
|
helm:
|
|
releaseName: infra-report
|
|
destination:
|
|
server: https://kubernetes.default.svc
|
|
namespace: soo
|
|
syncPolicy:
|
|
automated:
|
|
prune: true
|
|
selfHeal: true
|
|
EOF
|
|
```
|
|
|
|
### 5. 코드 Push → 자동 배포
|
|
|
|
`main` 브랜치에 push하면:
|
|
1. **Gitea Actions**: Docker 이미지 빌드 → Harbor push
|
|
2. **Gitea Actions**: Helm chart 패키징 → Harbor OCI push (타임스탬프 기반 버전)
|
|
3. **ArgoCD**: 새 chart 버전 감지 → 자동 sync → 파드 재배포
|
|
|
|
> `.md` 파일만 변경된 push에서는 CI가 실행되지 않습니다 (`paths-ignore` 설정).
|
|
|
|
### 로컬 개발
|
|
|
|
```bash
|
|
npm install
|
|
npm run dev # http://localhost:3000
|
|
```
|
|
|
|
Prometheus 접근이 필요하므로 포트포워딩 또는 환경 변수 설정이 필요합니다:
|
|
```bash
|
|
PROMETHEUS_URL=http://localhost:9090 npm run dev
|
|
```
|
|
|
|
## 시간대 처리
|
|
|
|
- Prometheus는 항상 UTC로 데이터를 저장/반환합니다
|
|
- 프론트엔드에서 `Asia/Seoul` 타임존으로 변환하여 표시합니다
|
|
- `TZ` 환경 변수는 Prometheus 쿼리에 영향을 주지 않습니다
|
|
|
|
## Kubernetes RBAC
|
|
|
|
ServiceAccount `infra-report-sa`에 ClusterRole이 부여되어 노드 정보를 조회합니다:
|
|
- `nodes` 리소스에 대한 `get`, `list` 권한
|
|
|
|
## 이미지 태그 전략
|
|
|
|
- CI에서 `sha-<7자리 commit hash>` 형태로 태그 생성 (예: `sha-25c7d82`)
|
|
- `v*` 태그 push 시 태그 이름 그대로 사용 (예: `v1.0.0`)
|
|
- Helm chart의 `appVersion`에 이미지 태그가 자동 설정됨
|
|
- Deployment는 `appVersion` fallback으로 이미지 태그 결정
|