반응형
좋아, 이제 “실제 운영에 쓰는 풀버전 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 보안 분리
👉 이건 “개인 실습” 수준이 아니라
회사 표준 아키텍처 문서로 써도 되는 수준이야.
반응형
'[GPUaaS] > TensorFlow' 카테고리의 다른 글
| [중요2] 운영 표준 - [최종] Train.py & TFJob.yaml (라벨/MIG/RWO 적용) (0) | 2026.01.30 |
|---|---|
| [중요2] 운영 표준 - TFJob.yaml (라벨/MIG/RWO/S3 적용) (0) | 2026.01.28 |
| [중요2] 운영 표준 - ☸️ Kubernetes + TensorFlow 구동 원리 (0) | 2026.01.28 |
| [중요2] 운영 표준 - GPU 노드 라벨 세트 (0) | 2026.01.28 |
| [GPU 타입] 운영 무중단 - 라벨 NodePool 등록 (1) | 2026.01.27 |
| [GPU 타입] 신규 라벨 NodePool 등록 (라벨 + Taint + Affinity 세트) (0) | 2026.01.26 |
| [GPU] Node Affinity + GPU 타입 분리 (A100 / H100) (0) | 2026.01.26 |
| [GPU] requests = limits가 좋은 이유 (0) | 2026.01.26 |
댓글