이 글에서 다루는 것

Pod 재시작 시 로그가 유실되지 않도록 NFS 기반 PV/PVC를 구성하고, Loguru로 구조화된 파일 로깅을 적용하여 FastAPI 서빙 로그를 영속화하는 과정을 다룹니다.

선수지식


이 단계에서 해결하려는 문제

FastAPI Pod가 재시작되거나 스케일 다운되면 컨테이너 내부에 쌓인 로그가 모두 사라진다. 핫스왑 이력, 예측 요청 기록, 에러 트레이스가 유실되면 장애 원인을 추적할 수 없다. Pod 라이프사이클과 독립적으로 로그를 보존하는 구조가 필요하다.


🎯 핵심 요약

  • NFS PV/PVC로 FastAPI 로그 디렉토리(/app/logs)를 Pod 외부에 영속화
  • Loguru로 파일 로테이션(일별 10MB) + retention(7일) + 구조화 포맷 적용
  • LOG_TO_STDOUT 환경변수로 콘솔 이중 출력 제어 (dev: true, prod: false)
  • dev/prod PVC 분리: fastapi-logs-pvc-dev / fastapi-logs-pvc-prod

1️⃣ 전체 구조

NFS Server (/mnt/nfs_share/mlops/fastapi-logs/)
    ├─ dev/    ← fastapi-logs-pvc-dev
    └─ prod/   ← fastapi-logs-pvc-prod

FastAPI Pod
    └─ /app/logs/ (PVC 마운트)
        ├─ fastapi.log          (현재 로그)
        ├─ fastapi.log.2025-08-07  (전일 로그)
        └─ ...

2️⃣ PV / PVC 구성

PersistentVolume (NFS)

# envs/dev/pv/fastapi-logs-pv-dev.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: fastapi-logs-pv-dev
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  nfs:
    server: 192.168.18.141
    path: /mnt/nfs_share/mlops/fastapi-logs/dev

PersistentVolumeClaim

# envs/dev/pvc/fastapi-logs-pvc-dev.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: fastapi-logs-pvc-dev
  namespace: fastapi-dev
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi
  volumeName: fastapi-logs-pv-dev

persistentVolumeReclaimPolicy: Retain — ArgoCD prune 시에도 로그 아티팩트 보호


3️⃣ Helm Values — 볼륨 마운트

# charts/fastapi/values/dev.yaml (발췌)
volumes:
  - name: logs
    persistentVolumeClaim:
      claimName: fastapi-logs-pvc-dev

volumeMounts:
  - name: logs
    mountPath: /app/logs

securityContext:
  fsGroup: 1000
  runAsUser: 1000

fsGroup / runAsUser 설정으로 NFS 디렉토리 쓰기 권한을 보장한다.


4️⃣ Loguru 설정

# charts/fastapi/app/utils/logger.py
import os
from loguru import logger
import sys

LOG_DIR = "/app/logs"
LOG_FILE = os.path.join(LOG_DIR, "fastapi.log")

# 파일 로깅: 일별 로테이션, 10MB 제한, 7일 보관
logger.add(
    LOG_FILE,
    rotation="10 MB",
    retention="7 days",
    compression="gz",
    format="{time:YYYY-MM-DD HH:mm:ss} | {level:<8} | {name}:{function}:{line} | {message}",
    level="INFO",
    enqueue=True,  # 비동기 쓰기 (NFS I/O 지연 완화)
)

# 환경변수로 콘솔 이중 출력 제어
if os.environ.get("LOG_TO_STDOUT", "false").lower() == "true":
    logger.add(sys.stdout, level="DEBUG",
               format="{time:HH:mm:ss} | {level:<8} | {message}")

주요 설정 포인트

설정이유
enqueue=True비동기 쓰기NFS I/O 지연이 요청 처리를 차단하지 않도록
rotation="10 MB"파일 크기 제한단일 파일이 과도하게 커지는 것을 방지
retention="7 days"보관 기간디스크 고갈 방지 + 최근 장애 추적에 충분
compression="gz"로테이션된 파일 압축NFS 스토리지 절약

5️⃣ FastAPI 코드에서 사용

# routes/predict.py, routes/reload.py 등
from utils.logger import logger

# 예측 로그
logger.info(f"[Predict] alias={alias}, mode={mode}, client_id={client_id}")

# 핫스왑 로그
logger.info(f"[Reload] alias={alias} 모델 교체 완료: v{version}")

# 에러 로그
logger.exception("예측 실패")

6️⃣ 검증

# PVC 상태 확인
kubectl -n fastapi-dev get pvc fastapi-logs-pvc-dev

# Pod 내 로그 파일 확인
kubectl -n fastapi-dev exec $(kubectl -n fastapi-dev get po -l app=fastapi-dev -o name | head -1) \
  -- ls -la /app/logs/

# NFS 서버에서 직접 확인
ls -la /mnt/nfs_share/mlops/fastapi-logs/dev/

# 로그 내용 확인
kubectl -n fastapi-dev exec $(kubectl -n fastapi-dev get po -l app=fastapi-dev -o name | head -1) \
  -- tail -20 /app/logs/fastapi.log

7️⃣ 체크리스트

  • PV/PVC 생성 및 Bound 상태 확인 (dev/prod 각각)
  • FastAPI Deployment에 volumeMounts 설정 반영
  • fsGroup / runAsUser 설정으로 NFS 쓰기 권한 확보
  • LOG_TO_STDOUT 환경변수 dev/prod 차별 설정
  • Pod 재시작 후에도 이전 로그 파일이 유지되는지 확인

🧩 팁

  • NFS 마운트 실패 시 Pod가 ContainerCreating에서 멈춘다 — NFS 서버 접근 가능 여부를 먼저 확인
  • **Loguru enqueue=True**는 비동기 버퍼이므로, Pod가 갑자기 종료되면 마지막 몇 줄이 유실될 수 있다 — 크리티컬 이벤트는 Slack 알림으로 이중 보장
  • prod 환경에서는 LOG_TO_STDOUT=false로 설정하여 stdout 노이즈를 줄이되, Loki/Promtail 연동 시에는 stdout도 활성화 고려

설계 판단 (Why This Way?)

NFS PVC를 선택하여 Pod 라이프사이클과 독립적인 로그 보존과 ReadWriteMany 동시 쓰기를 확보했고, Loguru의 enqueue=True 비동기 쓰기로 NFS I/O 지연이 FastAPI 요청 처리를 차단하지 않도록 했습니다.


다음에 읽을 글

MLOps 운영 고도화 5단계: Airflow 안정화 & FastAPI HTTPS — TLS 보안과 스케줄러 안정화