본문 바로가기
[GPUaaS]/TensorFlow

[중요3] 운영 표준 - [최종] KServer & NAS & S3 & TFJob.yaml (라벨/MIG/RWO/RWM 적용)

by METAVERSE STORY 2026. 1. 30.
반응형

 

 

좋아, 이제 “실제 운영에 쓰는 풀버전 TFJob 설계” 단계로 제대로 가보자.
아래 설명은 요약 없음, 처음부터 끝까지,
👉 왜 이렇게 해야 하는지 → 어디서 실행되는지 → 각 필드의 의미까지 전부 풀어줄게.


0️⃣ 먼저 전체 흐름부터 (이걸 머리에 그려야 YAML이 이해됨)

 
(사람/CI) kubectl apply tfjob-train-prod.yaml[TFJob Controller] ├─ Chief Pod (GPU) │ ├─ NAS: 데이터셋 + 결과 공유 │ └─ 학습 완료 시 DONE 생성 │ ├─ Worker Pod들 (GPU) │ └─ NAS: 데이터셋 읽기 전용 │ └─ Uploader Sidecar (Chief만) └─ NAS 결과 → Object Storage(S3) ↓ [Object Storage] └─ 모델 저장 ↓ [KServe] └─ S3에서 모델 로드 (NAS 접근 ❌)

👉 이 구조가 “정석”
(공공/금융/멀티테넌시 전부 이 패턴)


1️⃣ 질문 1에 대한 명확한 답부터

❓ Worker도 데이터셋 공유하려면 NAS 연동해야 해?

✅ 정답: YES, 반드시 필요

이유:

  • TF Distributed Training에서
    • Chief만 데이터 읽고 Worker에게 전달 ❌ (병목)
    • Chief + Worker 모두 동일 데이터셋 접근 ⭕

그래서 실무에서는:

  • NAS (RWX)
    • /dataset : 읽기 전용
    • /output : Chief만 쓰기

2️⃣ 스토리지 역할 분리 (이게 핵심 설계)

경로스토리지접근 주체
/dataset NAS (RWX) Chief + Worker (RO)
/output NAS (RWX) Chief (RW)
S3 Object Storage Uploader → KServe

📌 Worker는 결과 저장 안 함
📌 KServe는 NAS 접근 완전 차단


3️⃣ tfjob-train-prod.yaml 풀버전 (운영 기준)

아래 YAML은 그대로 파일로 저장해서 apply 가능한 형태야.


📄 tfjob-train-prod.yaml (FULL)

 
apiVersion: kubeflow.org/v1 kind: TFJob metadata: name: tf-mnist-train namespace: ml-train spec: runPolicy: cleanPodPolicy: None tfReplicaSpecs: ################################ # 1️⃣ Chief (학습 + 결과 관리) ################################ Chief: replicas: 1 restartPolicy: OnFailure template: spec: nodeSelector: gpu.vendor: nvidia gpu.model: A100 gpu.mem: 80gb gpu.mig: enabled gpu.mig.profile: 1g.10gb gpu.role: chief gpu.pool: train containers: # 🔹 Trainer (실제 학습) - name: trainer image: myrepo/tf-mnist-train:latest command: ["python", "train.py"] resources: requests: nvidia.com/mig-1g.10gb: 1 limits: nvidia.com/mig-1g.10gb: 1 volumeMounts: - name: dataset mountPath: /dataset readOnly: true - name: output mountPath: /output # 🔹 Uploader (결과 S3 업로드) - name: uploader image: amazon/aws-cli command: ["/bin/sh", "-c"] args: - | echo "Waiting for training completion..." while true; do if [ -f /output/DONE ]; then echo "Training done. Uploading to S3" aws s3 sync /output \ s3://tf-result-bucket/tf-mnist-train/ \ --endpoint-url $AWS_ENDPOINT_URL exit 0 fi sleep 30 done envFrom: - secretRef: name: objstore-cred resources: requests: cpu: "100m" memory: "128Mi" limits: cpu: "500m" memory: "512Mi" volumeMounts: - name: output mountPath: /output volumes: - name: dataset persistentVolumeClaim: claimName: dataset-nas-pvc - name: output persistentVolumeClaim: claimName: train-output-nas-pvc ################################ # 2️⃣ Worker (연산 전용) ################################ Worker: replicas: 4 restartPolicy: OnFailure template: spec: nodeSelector: gpu.vendor: nvidia gpu.model: A100 gpu.mem: 80gb gpu.mig: enabled gpu.mig.profile: 1g.10gb gpu.role: worker gpu.pool: train containers: - name: trainer image: myrepo/tf-mnist-train:latest command: ["python", "train.py"] resources: requests: nvidia.com/mig-1g.10gb: 1 limits: nvidia.com/mig-1g.10gb: 1 volumeMounts: - name: dataset mountPath: /dataset readOnly: true volumes: - name: dataset persistentVolumeClaim: claimName: dataset-nas-pvc

4️⃣ NAS PVC는 사전에 반드시 있어야 함

📄 dataset-nas-pvc.yaml

 
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: dataset-nas-pvc namespace: ml-train spec: accessModes: - ReadWriteMany storageClassName: ncp-nas-company-a resources: requests: storage: 2Ti

📄 train-output-nas-pvc.yaml

 
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: train-output-nas-pvc namespace: ml-train spec: accessModes: - ReadWriteMany storageClassName: ncp-nas-company-a resources: requests: storage: 1Ti
 
kubectl apply -f dataset-nas-pvc.yaml kubectl apply -f train-output-nas-pvc.yaml

5️⃣ 학습 코드에서 반드시 해야 할 것

train.py 마지막

 
model.save("/output/model") with open("/output/DONE", "w") as f: f.write("done")

📌 이 DONE 파일이 Uploader 트리거


6️⃣ 결과를 KServe에서 사용하는 방법

📄 InferenceService (Serving 전용)

 
apiVersion: serving.kserve.io/v1beta1 kind: InferenceService metadata: name: mnist namespace: ml-serving spec: predictor: tensorflow: storageUri: s3://tf-result-bucket/tf-mnist-train/model

📌 중요

  • KServe namespace에는
    • NAS PVC ❌
    • NAS StorageClass ❌
  • 오직 S3만 접근

7️⃣ 이 구조의 장점 (운영 관점)

항목이유
Worker NAS 사용 데이터 중복 제거
결과 S3 이동 Serving 분리
Uploader Sidecar 학습 코드 단순화
NAS ↔ KServe 분리 보안 사고 차단

8️⃣ 지금 이 수준이면 어디까지 왔냐면

✔ GPU MIG 운영
✔ TFJob 분산 학습
✔ NAS 공유 설계
✔ S3 승인 파이프라인
✔ KServe 보안 분리

👉 이건 “개인 실습” 수준이 아니라
회사 표준 아키텍처 문서로 써도 되는 수준
이야.

 

 

 

반응형

댓글