대규모 온프레미스 멀티 클러스터 환경(Kubernetes v1.34+)에서 FinOps 파이프라인을 안정적으로 무인 자동화하기 위해 컨테이너 이미지 빌드부터 엔터프라이즈급 크론잡(CronJob) 매니페스트 구축까지의 전 과정 가이드입니다.
대용량 데이터를 다루고 폐쇄망(Air-Gapped) 환경의 특성을 감안하여, ① 순차 실행 쉘 스크립트, ② 타임존 고정형 Dockerfile, ③ K8s 표준 보안 및 PVC가 적용된 CronJob YAML로 나누어 구성했습니다.
run_pipeline.sh)컨테이너가 기동되었을 때 데이터 징수(step1)부터 엑셀 빌드(step6)까지 예외 처리(Error Handling)를 하며 순차 실행해 주는 엔트리포인트 스크립트입니다. 중간에 특정 단계가 실패하면 즉시 종료(set -e)되어 무의미한 연산 낭비를 막습니다.
#!/bin/bash
# run_pipeline.sh
set -e # 스크립트 실행 도중 에러(Exit Code != 0) 발생 시 즉시 중단
echo "=== [KST 시간 기준 데일리 FinOps 배치 가동] ==="
date
# 1. Prometheus/Thanos 원천 데이터 증분 징수 (전날 00시부터 현재까지 정각 정렬 수집)
echo "▶️ [1/4] step1_prom_fetch.py 실행 중..."
python step1_prom_fetch.py --days 1 --step 1m
# 2. 데이터 병합, KST 날짜 분리 및 워크로드 기술 도메인 정규식 필터링
echo "▶️ [2/4] step2_pipeline.py 실행 중..."
python step2_pipeline.py
# 3. 노드 효율 분포도, 시계열 누적 추이, 2차원 패턴 매트릭스 히트맵 드로잉
echo "▶️ [3/4] step3_analytics.py 실행 중..."
python step3_analytics.py
# 4. 동적 상위 30% 연산, OOM 장애 추적 및 규격 위반 팟 추출 통합 마스터 엑셀 빌드
echo "▶️ [4/4] step6_excel_builder.py 실행 중..."
python step6_excel_builder.py
echo "🎉 === [FinOps 배치 완료] 최종 마스터 산출물이 안전하게 생성되었습니다. ==="
ls -lh ./data/output/
Dockerfile 작성컨테이너 내부 타임존을 Asia/Seoul로 강제 고정하여 크론 스케줄러와 파이썬 런타임의 시간대를 일치시킵니다. 폐쇄망 환경을 감안하여 패키지 캐시 최적화 및 비루트(Non-Root) 보안 계정을 적용했습니다.
# Dockerfile
FROM python:3.11-slim
# 1. 컨테이너 내부 환경변수 및 대한민국 표준시(KST) 인프라 고정
ENV TZ=Asia/Seoul
ENV PYTHONUNBUFFERED=1
WORKDIR /app
# 2. 시스템 의존성 패키지 및 타임존 데이터 인스턴스 설치
RUN apt-get update && apt-get install -y --no-install-recommends \
tzdata \
&& ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# 3. 파이프라인 필수 파이썬 의존성 패키지 설치
# TIP: 폐쇄망 환경인 경우 사내 내장 사설 레포지토리 주소를 명시하세요.
# 예: --index-url http://nexus.internal.zone/repository/pypi/simple --trusted-host nexus.internal.zone
RUN pip install --no-cache-dir --upgrade pip && \
pip install --no-cache-dir \
pandas \
pyarrow \
requests \
openpyxl \
matplotlib \
seaborn
# 4. 프로젝트 소스 코드 및 가동용 쉘 복사
COPY config.py .
COPY step1_prom_fetch.py .
COPY step2_pipeline.py .
COPY step3_analytics.py .
COPY step6_excel_builder.py .
COPY run_pipeline.sh .
# 5. 실행 권한 부여 및 보안을 위한 비루트(Non-Root) 계정 운영 고도화
RUN chmod +x run_pipeline.sh && \
chown -R 1000:1000 /app
USER 1000
ENTRYPOINT ["/bin/bash", "./run_pipeline.sh"]
사내 파일 빌드 및 푸시 가이드 (터미널 가동):
docker build -t registry.internal.zone/finops/infrastructure-analyzer:v1.0.0 . docker push registry.internal.zone/finops/infrastructure-analyzer:v1.0.0
cronjob.yaml)쿠버네티스 v1.27+ 부터 정식 지원되는 spec.timeZone 표준 필드를 활용하여 매일 새벽 2시(KST 정각)에 작동하도록 설정했습니다. 또한 컨테이너가 종료(Ephemeral)되더라도 산출물인 엑셀과 차트가 유실되지 않도록 사내 스토리지 볼륨(PersistentVolumeClaim)을 마운트합니다.
# finops-cronjob.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
name: finops-daily-analyzer
namespace: infrastructure-system # 플랫폼 관리 전용 권한 영역 분리
labels:
app.kubernetes.io/component: finops-pipeline
spec:
# 💡 [핵심] K8s 네이티브 타임존 제어 기능을 활성화하여 KST 기준 새벽 2시 정각 가동
timeZone: "Asia/Seoul"
schedule: "0 2 * * *"
concurrencyPolicy: Forbid # 이전 배치가 안 끝나면 다음 배치 중복 실행 차단 (Thanos 과부하 방지)
successfulJobsHistoryLimit: 3 # 성공한 파드 로그 보관 개수
failedJobsHistoryLimit: 5 # 실패한 파드 로그 디버깅용 보관 개수
jobTemplate:
spec:
template:
spec:
# 🛡️ 포드 레벨 보안 컨텍스트 강화
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
containers:
- name: analyzer
image: registry.internal.zone/finops/infrastructure-analyzer:v1.0.0
imagePullPolicy: IfNotPresent
# 🌐 환경변수를 통한 동적 타노스 주소 및 노드 타겟팅 인프라 토글 제어
env:
- name: THANOS_QUERY_URL
value: "http://thanos-query.internal.zone:9090"
- name: NODE_PREFIX_PATTERN
value: "name1wk\\d+" # config 원부를 오버라이드할 노드 필터 패턴 정규식
# 📊 대규모 파이썬 데이터 연산을 위한 안정적인 자원 할당 사양 (Burstable QoS)
resources:
requests:
cpu: "2"
memory: "4Gi"
limits:
cpu: "4"
memory: "8Gi"
# 💾 파일 유실 방지를 위한 마스터 산출물 디렉토리 데이터 볼륨 매핑
volumeMounts:
- name: finops-storage
mountPath: /app/data
restartPolicy: OnFailure # 실패 시에만 파드 재시작 규칙 적용
# 영구 저장소 볼륨 정의 (사내 CephFS, NFS 등 공유 볼륨 PVC 연동)
volumes:
- name: finops-storage
persistentVolumeClaim:
claimName: finops-report-pvc
data/raw/, data/merged/, data/output/ 구조를 사용하므로, 위의 YAML 설정처럼 /app/data 위치에 PVC 볼륨을 통째로 얹어주면 컨테이너가 뜨고 지는 과정과 관계없이 과거 수집된 Parquet 청크 데이터 파일들이 유실되지 않고 증분 유지(⏭️ [SKIP] 기능 활성화)됩니다.run_pipeline.sh 하단에 사내 메신저(웹훅 API)나 메일 서버 발송 명령어(curl -X POST ...)를 추가해 주시면, 매일 아침 출근 전에 전날 클러스터의 OOM 장애 목록과 최적화 결과 엑셀 주소가 담긴 FinOps 모닝 브리핑 리포트를 팀원들과 공유할 수 있어 운영 주도권을 완벽하게 가져가실 수 있습니다.