본문 바로가기

카테고리 없음

[AEWS 4기] EKS 스터디 9주차 (AI/ML 워크로드 EKS )


AI/ML 워크로드에서 GPU 인프라를 어떻게 컨테이너와 Kubernetes 환경으로 가져올 수 있는지, 그리고 베어메탈  환경이나 클라우드가 아닌 환경에선 어떻게 사용하는지 등을 이전 경험을 살려 공유하고 싶어서 작성함

들어가며

우리 생활 반경에 점점 AI 인프라와 AI 모델이 차지 하는 범위가 점점 커지면서 GPU는 AI/ML 인프라의 핵심 리소스가 됐다.

과거에는 베어메탈 서버에 GPU 드라이버, CUDA, cuDNN, 프레임워크를 직접 설치해서 사용하는 방식이 일반적이었다. 하지만 이 방식은 환경 구성, 재현성, 리소스 활용률, 확장성 측면에서 여러 문제가 있었다.

컨테이너와 Kubernetes는 이런 문제를 꽤 많이 완화해준다. 다만 GPU는 CPU나 메모리처럼 단순하게 쪼개서 쓰기 어려운 특성이 있기 때문에, GPU 리소스를 컨테이너 환경에서 잘 사용하려면 기본 개념과 할당 방식을 이해해야 한다.

기존 AI/ML 인프라의 문제점

전통적인 GPU 서버 운영 방식은 베어메탈 서버에 필요한 드라이버와 라이브러리를 직접 설치하는 형태였다. 단일 사용자나 작은 규모의 실험에서는 괜찮아 보이지만, 조직 단위로 여러 모델과 여러 팀이 GPU를 함께 사용하기 시작하면 관리 난이도가 급격히 올라간다.

주요 문제는 다음과 같다.

문제 설명
환경 구성 복잡성 CUDA, cuDNN, NVIDIA Driver, TensorFlow, PyTorch 사이의 버전 호환성을 직접 맞춰야 한다.
재현성 부족 같은 실험 환경을 다른 서버나 다른 사용자 환경에서 그대로 재현하기 어렵다.
리소스 비효율 고가의 GPU가 특정 사용자나 프로젝트에 묶여 유휴 상태로 남기 쉽다.
확장성 제한 GPU 서버를 늘릴 때마다 동일한 환경 구성 작업을 반복해야 한다.

쉽게 말하면 GPU 자체도 비싸지만, GPU를 잘 쓰기 위한 운영 비용도 만만치 않다.

컨테이너가 가져온 장점

컨테이너는 애플리케이션 실행 환경을 이미지로 패키징한다. 덕분에 ML 프레임워크, Python 패키지, 사용자 공간 라이브러리를 이미지 안에 포함할 수 있고, 같은 이미지를 여러 환경에서 동일하게 실행할 수 있다.

컨테이너 격리의 기반에는 Linux 커널 기능인 cgroupsnamespaces가 있다.

기능 역할
cgroups CPU, 메모리, 디스크 I/O, 네트워크 같은 리소스 사용량을 제한하고 제어한다.
namespaces 프로세스가 볼 수 있는 PID, 네트워크, 마운트, 사용자 영역 등을 격리한다.

이 구조 덕분에 컨테이너는 여러 워크로드를 같은 호스트에서 실행하면서도 각자의 실행 환경을 분리할 수 있다. AI/ML 관점에서는 실험 환경을 이미지로 고정하고, Kubernetes 위에서 필요한 만큼 배포하거나 스케일링할 수 있다는 점이 특히 중요하다.

그래도 GPU는 까다롭다

컨테이너가 많은 문제를 해결해주지만 GPU에는 별도의 난점이 있다. GPU는 단순한 파일이나 프로세스 리소스가 아니라 물리 장치, 커널 드라이버, 사용자 공간 라이브러리, 장치 파일이 함께 맞물려 동작한다.

대표적인 한계는 다음과 같다.

한계 설명
물리적 분할 어려움 초기 GPU는 CPU 코어처럼 여러 컨테이너에 자연스럽게 나눠 할당하기 어려웠다.
드라이버 스택 복잡성 GPU 접근에는 NVIDIA Driver, CUDA, 사용자 공간 라이브러리 등 여러 계층이 필요하다.
장치 파일 접근 제어 컨테이너가 /dev/nvidia* 같은 장치 파일에 안전하게 접근하도록 관리해야 한다.

최근에는 NVIDIA A100 같은 GPU에서 MIG 기능이 등장하면서 하드웨어 수준의 분할이 가능해졌다. 하지만 모든 GPU가 MIG를 지원하는 것은 아니고, 운영 방식도 일반 컨테이너 리소스와는 다르게 접근해야 한다.

Kubernetes에서 단일 GPU 할당

Kubernetes에서 GPU를 사용하려면 보통 노드에 NVIDIA Driver와 NVIDIA Device Plugin이 필요하다.

#GPU 노드에서 먼저 GPU가 보이는지 확인합니다.


lspci | grep -i nvidia

#Kubernetes 노드 상태도 확인합니다.
kubectl get nodes -o wide


#Pod Security Admission을 쓰는 클러스터라면 GPU Operator namespace를 privileged로 열어야 합니다.
kubectl create namespace gpu-operator

kubectl label --overwrite namespace gpu-operator \
  pod-security.kubernetes.io/enforce=privileged

 

2. 권장 방식: GPU Operator로 설치

이 방식은 NVIDIA가 현재 권장하는 Kubernetes GPU 구성 방식입니다. Driver를 노드에 직접 설치하지 않고 GPU Operator가 Driver 컨테이너로 설치하게 둘 수 있습니다.

하지만,, 우리가 AWS를 쓰는경우  “GPU Operator가 Driver를 컨테이너로 설치하는 과정”을 제대로 보려면 EKS GPU Optimized AMI를 쓰면 안 됩니다. 그 AMI에는 이미 NVIDIA Driver와 Container Toolkit이 들어있어서, GPU Operator 설치 시 driver.enabled=false, toolkit.enabled=false로 꺼야 합니다.

 

실습 목적이 “Driver 없는 노드에 GPU Operator가 Driver DaemonSet으로 설치하는 과정 보기”라면 구성은 이렇게 가는 게 맞습니다.

권장 실습 구성

  • EKS Cluster
  • GPU EC2: g4dn.xlarge 또는 g5.xlarge
  • Node Group: self-managed node group
  • AMI: Ubuntu EKS AMI 또는 GPU Driver가 없는 일반 EKS-compatible AMI
  • GPU Operator: driver.enabled=true, toolkit.enabled=true

NVIDIA도 EKS에서 GPU Operator를 쓰는 방식을 설명하면서, 기본 EKS GPU AMI 방식은 Driver/Runtime이 이미 들어있고, GPU Operator 방식은 Operator가 Driver 컨테이너, Device Plugin, Toolkit, MIG Manager 등을 관리한다고 설명합니다.

 

3. Pod를 배포할때 GPU를 사용하려면? 

apiVersion: v1
kind: Pod
metadata:
  name: gpu-workload
spec:
  containers:
    - name: trainer
      image: nvidia/cuda:12.4.1-base-ubuntu22.04
      resources:
        limits:
          nvidia.com/gpu: 1

이 방식에서는 Pod 하나가 GPU 1개를 전용으로 사용한다. 성능은 거의 네이티브에 가깝지만, 해당 GPU를 다른 Pod와 유연하게 공유하기 어렵다.

이런 방식을 Passthrough 방식이라고 부른다.

GPU Passthrough 방식

GPU Passthrough는 호스트에 장착된 물리 GPU를 하나의 VM 또는 컨테이너에 직접 할당하는 방식이다. VMware 환경에서도 특정 VM에 GPU를 직접 연결하고, 그 위에서 Kubernetes 워크로드가 GPU를 사용하는 구성이 가능하다.

장점은 명확하다. GPU를 거의 직접 사용하는 구조라 성능 손실이 적고, 특정 GPU 기능을 활용하기 쉽다. 반면 GPU가 특정 VM이나 Pod에 전용으로 묶이기 때문에 멀티 사용자 환경에서는 자원 낭비가 발생할 수 있다.

 

 

즉, AWS 같은 퍼블릭 클라우드에서는 사용자가 직접 GPU Passthrough를 구성하지 않는다.

대신 g4dn, g5, p4d, p5 같은 GPU 인스턴스 타입을 선택하면 클라우드 제공자가 GPU 접근 경로를 미리 구성해 제공한다.

 

Kubernetes 관점에서는 해당 노드에 NVIDIA Driver, Container Toolkit, Device Plugin 또는 GPU Operator를 설치해 GPU를 nvidia.com/gpu 리소스로 노출하고 Pod가 이를 요청해 사용한다.

 

구분 내용
장점 네이티브에 가까운 성능, 드라이버 레벨 제어, Tensor Core 같은 기능 활용
단점 GPU 공유 어려움, 유휴 시간에도 리소스 점유, 멀티테넌트 환경 비효율

GPU 공유 방식

GPU 공유 방식에서 자주 비교되는 개념이 MIG와 vGPU다. 둘 다 하나의 물리 GPU를 여러 사용자나 워크로드가 사용하도록 만든다는 점은 비슷하지만, 동작 방식은 꽤 다르다.

항목 MIG vGPU
개념 GPU를 하드웨어 수준에서 여러 인스턴스로 분할 GPU를 소프트웨어 기반으로 시간 분할해 가상화
지원 GPU Ampere 아키텍처 이상, 예: A100 대부분의 NVIDIA GPU에서 지원 가능
격리 수준 메모리, 캐시, SM 등 하드웨어 격리 메모리는 논리적으로 분리, 연산은 time-sharing
성능 예측 가능성 높음 다른 VM 부하에 따라 변동 가능
오버헤드 낮음 context switching 등으로 상대적으로 높음
동적 변경 MIG 인스턴스 재구성 가능 VM 생성 시 설정한 vGPU 리소스가 고정되는 경우가 많음
적합한 워크로드 AI 추론, MLOps, 멀티테넌트 모델 호스팅 VDI, 개발 테스트, 일반 GPU VM 환경
라이선스 MIG 자체는 별도 라이선스 불필요 vGPU 소프트웨어 라이선스 필요

정리하면 MIG는 성능 예측 가능성과 격리가 중요한 AI/ML 워크로드에 잘 맞고, vGPU는 여러 VM이 유연하게 GPU를 나눠 써야 하는 환경에 더 잘 맞는다.

마무리

AI/ML 인프라에서 GPU를 잘 운영하려면 단순히 GPU 서버를 많이 두는 것만으로는 부족하다. 드라이버와 라이브러리 호환성, 실험 환경 재현성, GPU 리소스 공유 방식, Kubernetes 스케줄링 구조를 함께 고려해야 한다.

컨테이너와 Kubernetes는 ML 워크로드 운영의 복잡도를 줄여주지만, GPU는 여전히 별도의 이해가 필요한 리소스다. 단일 GPU 전용 할당, Passthrough, MIG, vGPU 같은 방식을 구분해두면 EKS나 온프레미스 Kubernetes 환경에서 GPU 워크로드를 설계할 때 훨씬 명확하게 판단할 수 있다.