# NFS Usage Exporter NFS PV 사용량을 측정하여 Prometheus 메트릭으로 노출하는 Flask 기반 exporter. ## 개요 Kubernetes에서 NFS 기반 PV(PersistentVolume)의 실제 디스크 사용량을 `du` 명령어로 측정하고, Prometheus가 수집할 수 있는 메트릭 형태로 제공합니다. ## 프로젝트 구조 ``` nas-metrics-prometheus/ ├── app.py # Flask 애플리케이션 (메인) ├── requirements.txt # Python 의존성 ├── Dockerfile # 컨테이너 이미지 빌드 └── chart/ # Helm Chart ├── Chart.yaml ├── values.yaml └── templates/ ├── deployment.yaml ├── service.yaml └── networkpolicy.yaml ``` ## 주요 기능 - `/usage/` - PV 디렉토리명으로 사용량 조회 (JSON 응답) - `/metrics` - Prometheus 메트릭 엔드포인트 - 캐시 TTL 300초 (동일 PV 반복 조회 시 du 재실행 방지) - `threading.Lock`으로 동시 du 실행 방지 (NFS I/O 부하 제한) - `ionice -c 3`, `nice -n 19`로 I/O/CPU 우선순위 최저 설정 ## 메트릭 | 메트릭 | 설명 | 라벨 | |---|---|---| | `nfs_pv_usage_bytes` | PV 사용량 (bytes) | `pv_name`, `request_name` | | `nfs_pv_last_check_timestamp` | 마지막 측정 시각 (unix timestamp) | `pv_name`, `request_name` | ### 라벨 설명 - `pv_name`: 실제 PV 이름 (예: `pvc-2af1e8be-8cd9-4219-8cef-dc4dc1e0b06d`) - `request_name`: NFS 디렉토리 전체 이름 (예: `ns-pvcname-pvc-2af1e8be-8cd9-4219-8cef-dc4dc1e0b06d`) 디렉토리명에서 UUID 패턴(`pvc-[8-4-4-4-12]`)을 정규식으로 추출하여 `pv_name`으로 사용합니다. ## API 사용법 ### 사용량 조회 ```bash curl http://nfs-usage-exporter.nas-metrics.svc:8080/usage/<디렉토리명> ``` 응답 예시: ```json { "pv_name": "pvc-2af1e8be-8cd9-4219-8cef-dc4dc1e0b06d", "request_name": "nas-metrics-test-pvc-20gi-pvc-2af1e8be-8cd9-4219-8cef-dc4dc1e0b06d", "bytes": 21474836480 } ``` ### Prometheus 메트릭 ```bash curl http://nfs-usage-exporter.nas-metrics.svc:8080/metrics ``` 응답 예시: ``` nfs_pv_usage_bytes{pv_name="pvc-2af1e8be-...",request_name="ns-mypvc-pvc-2af1e8be-..."} 2.147483648e+10 nfs_pv_last_check_timestamp{pv_name="pvc-2af1e8be-...",request_name="ns-mypvc-pvc-2af1e8be-..."} 1.707200000e+09 ``` ## 배포 방법 ### 1. Docker 이미지 빌드 및 Push ```bash # Harbor 로그인 echo '' | sudo docker login harbor.inje-private.com -u admin --password-stdin # 이미지 빌드 sudo docker build -t harbor.inje-private.com/infra/nfs-usage-exporter:v1.1.0 . # 이미지 Push sudo docker push harbor.inje-private.com/infra/nfs-usage-exporter:v1.1.0 ``` ### 2. Helm Chart 패키지 및 Push ```bash # Helm OCI 로그인 echo '' | helm registry login harbor.inje-private.com -u admin --password-stdin # 패키지 helm package ./chart # Push helm push nfs-usage-exporter-1.2.0.tgz oci://harbor.inje-private.com/infra ``` ### 3. Helm 설치/업그레이드 ```bash # 최초 설치 helm install nfs-usage-exporter \ oci://harbor.inje-private.com/infra/nfs-usage-exporter \ --version 1.2.0 \ -n nas-metrics \ --create-namespace # 업그레이드 helm upgrade nfs-usage-exporter \ oci://harbor.inje-private.com/infra/nfs-usage-exporter \ --version 1.2.0 \ -n nas-metrics ``` ### 4. 배포 확인 ```bash # 파드 상태 확인 kubectl get pods -n nas-metrics # 롤아웃 확인 kubectl rollout status deployment/nfs-usage-exporter -n nas-metrics # 서비스 확인 kubectl get svc -n nas-metrics ``` ## Helm Chart 설정 (values.yaml) | 파라미터 | 기본값 | 설명 | |---|---|---| | `replicaCount` | `1` | 파드 수 | | `image.repository` | `harbor.inje-private.com/infra/nfs-usage-exporter` | 이미지 레포지토리 | | `image.tag` | `v1.1.0` | 이미지 태그 | | `service.type` | `ClusterIP` | 서비스 타입 | | `service.port` | `8080` | 서비스 포트 | | `resources.limits.cpu` | `500m` | CPU 제한 | | `resources.limits.memory` | `256Mi` | 메모리 제한 | | `nodeSelector.nodegroup` | `nd` | 노드 셀렉터 | | `nfs.server` | `192.168.0.54` | NFS 서버 IP | | `nfs.path` | `/GJ_SHARE_FS6/39197c35-...` | NFS 마운트 경로 | | `networkPolicy.enabled` | `true` | NetworkPolicy 활성화 | | `networkPolicy.allowedNamespaces` | `[gpulive, monitoring, nas-metrics]` | 접근 허용 네임스페이스 | ## 아키텍처 ``` Prometheus ──scrape──> Service (:8080/metrics) │ v nfs-usage-exporter Pod │ /mnt/pvs (ReadOnly) │ v NFS Server (192.168.0.54) /GJ_SHARE_FS6/... ``` - NFS 볼륨을 ReadOnly로 마운트하여 데이터 안전성 보장 - Service에 `prometheus.io/scrape: "true"` 어노테이션으로 Prometheus 자동 수집 - NetworkPolicy로 `gpulive`, `monitoring`, `nas-metrics` 네임스페이스에서만 접근 허용 ## Git 저장소 ```bash git clone https://gitea.inje-private.com/selee/nas-metrics-prometheus.git ```