23.06.15
DEVOTEE를 활성화 시키면
지금 작성한 커뮤니티 글에 대해 1개의 댓글을 달아줍니다.
버튼을 누르면 글 수정 시 ChatGPT가 작성한 댓글이 수정됩니다.
| 컨텐츠 유형 | 제목 | 저장일 | 삭제 |
|---|
본인인증 로그인에 실패하였습니다.
회원이 아니시거나 본인인증 등록이
완료되지 않은 사용자입니다.
쿠버네티스(Kubernetes)는 컨테이너 기반의 클라우드 네이티브 아키텍처를 대표하는 플랫폼으로, 경량성과 확장성 측면에서 전통적인 가상머신(VM)보다 뛰어납니다.
그러나 모든 워크로드가 컨테이너로 대체 가능한 것은 아닙니다.
예를 들어,
GUI 환경이 필요한 응용 프로그램,
GPU를 직접 제어해야 하는 그래픽 또는 AI 응용 시스템,
기존 VM 기반의 운영 체계를 그대로 유지해야 하는 레거시 서비스의 경우에는,
컨테이너보다는 VM 환경이 더 적합합니다.
하지만 기존 KVM 기반의 가상화 환경에서는 쿠버네티스 클러스터 리소스와 VM 리소스를 분리 관리해야 하는 단점이 있었습니다.
이때 등장한 것이 바로 KubeVirt입니다.
KubeVirt는 쿠버네티스 상에서 VM을 쿠버네티스 리소스로 관리할 수 있게 해주는 가상화 오케스트레이터입니다.
즉, 쿠버네티스 노드 위에 VM을 생성하더라도, 해당 노드의 나머지 리소스(CPU, 메모리, GPU 등)는 여전히 클러스터 내 다른 Pod가 사용할 수 있습니다.
이 덕분에 컨테이너와 VM을 동일한 인프라 위에서 통합적으로 운영할 수 있는 유연한 환경을 구축할 수 있습니다.
이번 글에서는 이러한 KubeVirt 환경에서 GPU 가속 VM을 만들기 위한 첫 번째 단계로, GPU Passthrough 및 Kubevirt 설치 과정을 다룹니다.
핵심 포인트는 다음 세 가지입니다.
GPU Passthrough 설정 — vfio-pci 드라이버를 이용해 NVIDIA GPU를 호스트에서 분리하고, 가상머신이 직접 접근할 수 있도록 매핑
KubeVirt 및 관련 컴포넌트 설치 — virt-handler, virt-controller, virt-launcher, virtctl, CDI 등 VM 운영에 필요한 패키지 구성
CPU 전용 할당 설정 — VM의 안정적인 GPU 처리 성능을 확보하기 위해 dedicatedCpuPlacement: true, isolateEmulatorThread: true 옵션을 활성화하고, 이를 위한 Kubernetes CPUManagerPolicy를 static 모드로 설정
본 구성은 L40S GPU 4장이 장착된 4-GPU 서버에 Ubuntu 22.04 OS를 설치하였고,
Kubernetes와 KubeVirt를 이용해 GPU Passthrough가 가능한 가상머신 환경을 설정하는 과정을 다룹니다.
이번 단계를 진행하면 GPU를 VM에 연결하기 위해 필요한 시스템 레벨 설정과 KubeVirt 초기 세팅을 할 수 있어,
이후 단계에서 GUI 기반의 GPU VM을 띄우는 환경을 준비할 수 있습니다.
GPU를 vfio-pci로 바인딩하기 전에 현재 NVIDIA 드라이버를 사용하는 모든 프로세스를 종료하는 단계입니다.
pci 그래픽 카드 정보 확인
lspci -nnk -d 10de:
4e:00.0 3D controller [0302]: NVIDIA Corporation AD102GL [L40S] [10de:26b9] (rev a1)
Subsystem: NVIDIA Corporation Device [10de:1851]
Kernel driver in use: nvidia
Kernel modules: nouveau
62:00.0 3D controller [0302]: NVIDIA Corporation AD102GL [L40S] [10de:26b9] (rev a1)
Subsystem: NVIDIA Corporation Device [10de:1851]
Kernel driver in use: nvidia
Kernel modules: nouveau
c9:00.0 3D controller [0302]: NVIDIA Corporation AD102GL [L40S] [10de:26b9] (rev a1)
Subsystem: NVIDIA Corporation Device [10de:1851]
Kernel driver in use: nvidia
Kernel modules: nouveau
de:00.0 3D controller [0302]: NVIDIA Corporation AD102GL [L40S] [10de:26b9] (rev a1)
Subsystem: NVIDIA Corporation Device [10de:1851]
Kernel driver in use: nvidia
Kernel modules: nouveaunvidia 드라이버 사용하는 process 확인 후 종료시키기
nvidia-smi
Thu Apr 10 22:37:23 2025
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 550.120 Driver Version: 550.120 CUDA Version: 12.4 |
|-----------------------------------------+------------------------+----------------------+
...
+-----------------------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=========================================================================================|
| 0 N/A N/A 114716 G /usr/lib/xorg/Xorg 84MiB |
| 0 N/A N/A 114934 G /usr/bin/gnome-shell 167MiB |
| 0 N/A N/A 1325425 C+G /app/kit/kit 4271MiB |
| 0 N/A N/A 3747596 G ...irefox/6738/usr/lib/firefox/firefox 143MiB |
+-----------------------------------------------------------------------------------------+nvidia-smi 결과에서 Process가 나오지 않을 때 까지 현재 running 중인 프로세스 종료
GPU를 물리적으로 VM에 직결(Passthrough)하기 위해 vfio-pci 드라이버를 설정하고 기존 NVIDIA 드라이버를 언로드하는 과정입니다.
# 커널 파라미터 수정
sudo vi /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash intel_iommu=on iommu=pt video=efifb:off"
GRUB_CMDLINE_LINUX="systemd.unit=multi-user.target"
# GRUB 반영
sudo update-grub
sudo update-initramfs -u
# 기존 NVIDIA/Nouveau 드라이버 언로드
sudo rmmod nvidia_drm 2>/dev/null
sudo rmmod nvidia_modeset 2>/dev/null
sudo rmmod nvidia_uvm 2>/dev/null
sudo rmmod nvidia 2>/dev/null
sudo rmmod nouveau 2>/dev/null
# VFIO 모듈 로드
sudo modprobe vfio
sudo modprobe vfio-pci
sudo modprobe vfio_iommu_type1
# NVIDIA 및 nouveau 드라이버 블랙리스트 추가
echo -e "blacklist nouveau\nblacklist nvidia\nblacklist nvidia_drm\nblacklist nvidia_modeset\nblacklist nvidia_uvm" | sudo tee /etc/modprobe.d/blacklist-nvidia.conf
# vfio-pci 모듈 자동 로드 설정
echo "vfio-pci" | sudo tee -a /etc/modules
# 재부팅
sudo reboot
# pci 그래픽 카드 정보 재확인
lspci -nnk -d 10de:
4e:00.0 3D controller [0302]: NVIDIA Corporation AD102GL [L40S] [10de:26b9] (rev a1)
Subsystem: NVIDIA Corporation Device [10de:1851]
Kernel driver in use: vfio-pci
Kernel modules: nouveau
62:00.0 3D controller [0302]: NVIDIA Corporation AD102GL [L40S] [10de:26b9] (rev a1)
Subsystem: NVIDIA Corporation Device [10de:1851]
Kernel driver in use: vfio-pci
Kernel modules: nouveau
c9:00.0 3D controller [0302]: NVIDIA Corporation AD102GL [L40S] [10de:26b9] (rev a1)
Subsystem: NVIDIA Corporation Device [10de:1851]
Kernel driver in use: vfio-pci
Kernel modules: nouveau
de:00.0 3D controller [0302]: NVIDIA Corporation AD102GL [L40S] [10de:26b9] (rev a1)
Subsystem: NVIDIA Corporation Device [10de:1851]
Kernel driver in use: vfio-pci
Kernel modules: nouveau
# kernel driver in use: vfio-pci 상태면 완료.
# 아직 vfio-pci 사용 중이라는 메세지가 없다면 아래 명령어 진행
# VFIO 드라이버에 GPU PCI ID 등록
echo 10de 26b9 | sudo tee /sys/bus/pci/drivers/vfio-pci/new_id
# GPU 1
echo 0000:4e:00.0 | sudo tee /sys/bus/pci/devices/0000:4e:00.0/driver/unbind
echo 0000:4e:00.0 | sudo tee /sys/bus/pci/drivers/vfio-pci/bind
# GPU 2
echo 0000:62:00.0 | sudo tee /sys/bus/pci/devices/0000:62:00.0/driver/unbind
echo 0000:62:00.0 | sudo tee /sys/bus/pci/drivers/vfio-pci/bind
# GPU 3
echo 0000:c9:00.0 | sudo tee /sys/bus/pci/devices/0000:c9:00.0/driver/unbind
echo 0000:c9:00.0 | sudo tee /sys/bus/pci/drivers/vfio-pci/bind
# GPU 4
echo 0000:de:00.0 | sudo tee /sys/bus/pci/devices/0000:de:00.0/driver/unbind
echo 0000:de:00.0 | sudo tee /sys/bus/pci/drivers/vfio-pci/bind
# vfio-pci bind 확인
ls -l /sys/bus/pci/drivers/vfio-pci/Kubernetes 상에서 VM을 실행할 수 있도록 해주는 KubeVirt 컴포넌트를 설치하는 단계입니다.
# 버전 확인
curl https://storage.googleapis.com/kubevirt-prow/release/kubevirt/kubevirt/stable.txt # v1.6.0
export VERSION=$(curl https://storage.googleapis.com/kubevirt-prow/release/kubevirt/kubevirt/stable.txt)
# kubevirt-operator 설치
k apply -f https://github.com/kubevirt/kubevirt/releases/download/$VERSION/kubevirt-operator.yaml
# kubevirt-cr 설치
k apply -f https://github.com/kubevirt/kubevirt/releases/download/$VERSION/kubevirt-cr.yaml
# 잘 설치되었는지 확인
k describe kubevirt.kubevirt.io -n kubevirt
kubectl get events -n kubevirt --sort-by=.lastTimestamp
k get -n kubevirt allKubeVirt의 VM을 관리하기 위한 CLI 도구인 virtctl을 설치하는 단계입니다.
# virtctl 설치
curl -L -o virtctl https://github.com/kubevirt/kubevirt/releases/download/$VERSION/virtctl-$VERSION-linux-amd64
sudo chmod +x virtctl
sudo cp virtctl /usr/bin
# virtctl 잘 설치되었는지 확인
virtctl version
# Client Version: version.Info{GitVersion:"v1.4.0", GitCommit:"9b9b3d4e7b681af96ca1b6b6a5cea75e2f05ce5b", GitTreeState:"clean", BuildDate:"2024-11-13T08:23:36Z", GoVersion:"go1.22.8 X:nocoverageredesign", Compiler:"gc", Platform:"darwin/amd64"}
# Server Version: version.Info{GitVersion:"v1.4.0", GitCommit:"9b9b3d4e7b681af96ca1b6b6a5cea75e2f05ce5b", GitTreeState:"clean", BuildDate:"2024-11-13T09:51:17Z", GoVersion:"go1.22.8 X:nocoverageredesign", Compiler:"gc", Platform:"linux/amd64"}VM 디스크 이미지 업로드 및 관리 기능을 제공하는 Containerized Data Importer(CDI)를 설치하는 단계입니다.
# cdi-operator 설치
k apply -f https://github.com/kubevirt/containerized-data-importer/releases/download/v1.61.2/cdi-operator.yaml
# cdi-cr 설치
k apply -f https://github.com/kubevirt/containerized-data-importer/releases/download/v1.61.2/cdi-cr.yamlNVIDIA GPU를 Kubernetes에서 자동으로 인식하고 관리할 수 있도록 GPU Operator를 설치하는 과정입니다.
# gpu operator helm 저장소 추가
helm repo add nvidia https://nvidia.github.io/gpu-operator
helm repo update
helm search repo nvidia/gpu-operator --versions
# gpu operator 설치
helm install --wait --generate-name \
-n gpu-operator --create-namespace \
nvidia/gpu-operator \
--version=v24.9.2 \
--set sandboxWorkloads.enabled=true # Kuvebirt를 위해서 반드시 필요한 설정
# 노드에 vm-passthrough 설정
kubectl label node dtp --overwrite nvidia.com/gpu.workload.config=vm-passthroughGPU Passthrough를 위해 KubeVirt 설정(CR)을 수정하고, 특정 GPU 리소스를 KubeVirt에서 인식하도록 구성하는 단계입니다.
apiVersion: kubevirt.io/v1
kind: KubeVirt
metadata:
name: kubevirt
namespace: kubevirt
spec:
certificateRotateStrategy: {}
configuration:
permittedHostDevices:
pciHostDevices:
- pciVendorSelector: "10DE:26b9" # lspci -nnk -d 10de: 명령어로 조회 후 입력
resourceName: nvidia.com/AD102GL_L40S
externalResourceProvider: true
developerConfiguration:
featureGates:
- CPUManager # CPU manager 설정 관련 feature gate
- DisableNodeLabeller # cpu manager false로 다시 돌아가지 못하게 제어
customizeComponents: {}
imagePullPolicy: IfNotPresent
workloadUpdateStrategy: {}k apply -f kubevirt-cr.yamlVM에서 전용 CPU 코어를 할당받아 안정적인 성능을 확보하기 위해 Kubernetes의 CPU Manager 정책을 static으로 설정하는 과정입니다.
# cpu_manager_state 확인
sudo cat /var/lib/kubelet/cpu_manager_state
{"policyName":"none","defaultCpuSet":"","checksum":1353318690}
# kubelet config 수정
vim /var/lib/kubelet/config.yaml
# 아래 내용 추가하고 저장 (key가 동일한 것이 있으면 삭제하고 추가)
...
cpuCFSQuotaPeriod: 100ms
cpuManagerPolicy: static # none 값을 static으로 변경한다.
...
kubeReserved:
cpu: 500m # 파일의 가장 마지막에 kubeReserved 옵션을 추가
# Node drain 설정
kubectl drain dtp --ignore-daemonsets --delete-emptydir-data
# kubelet 중지
sudo systemctl stop kubelet
# cpu_manager_state 삭제
sudo rm -f /var/lib/kubelet/cpu_manager_state
# kubelet 재시작
sudo systemctl restart kubelet
# Node drain 설정 제거
kubectl uncordon dtp
# cpuManagerPolicy 적용여부 확인
kubectl get --raw "/api/v1/nodes/dtp/proxy/configz" | jq .kubeletconfig.cpuManagerPolicy # "static"으로 나오면 성공
# virt-handler 재시작
kubectl -n kubevirt rollout restart daemonset virt-handler
# cpumanager=true 설정 (최초 1회 실행)
kubectl label node dtp cpumanager=true --overwrite
# 일정 시간 (10분 이상) 이후에도 여전히 true로 유지중인지 확인
kubectl get nodes --show-labels | grep 'cpumanager=true'이번 글에서는 KubeVirt 환경에서 GPU VM을 구현하기 위한 첫 단계로,
GPU Passthrough 설정과 KubeVirt 설치 과정을 살펴보았습니다.
GPU Passthrough를 통해 VM이 물리 GPU를 직접 제어하도록 만들고,
vfio-pci 바인딩 과정을 통해 안정적인 하드웨어 접근을 확보하였습니다.
또한 CPU 전용 할당(dedicated CPU placement) 설정을 통해 GPU 연산 시 CPU 스케줄링 충돌을 최소화하는 방법도 다루었습니다.
다음 글에서는 이렇게 준비된 환경 위에서 실제 GPU VM을 생성하고,
VM 내부에서 GPU가 올바르게 인식되는지 확인하는 과정까지 다루겠습니다.
이를 통해 쿠버네티스 기반의 GPU 가상화 환경을 구성하는 방법을 단계적으로 정리해보겠습니다.
DEVOTEE를 활성화 시키면
지금 작성한 댓글에 AI가 댓글을 달아줍니다.