데보션앱 소개페이지 바로가기
로그인 선택

신고하기

CLOSE
신고사유 (대표 사유 1개)
상세내용 (선택)
0/200
  • 신고한 게시글은 더 이상 보이지 않습니다.
  • 이용약관과 운영정책에 따라 신고사유에 해당하는지 검토 후 조치됩니다.
  • 허위 신고인 경우, 신고자의 서비스 이용이 제한될 수 있으니 유의하시어 신중하게 신고해 주세요.
(이 회원이 작성한 모든 댓글과 커뮤니티 게시물이 보이지 않고, 알림도 오지 않습니다.)

미리보기

커뮤니티

      1,234

      badge 23.06.15

      글 등록

      카테고리를 선택해주세요.

      DEVOTEE를 활성화 시키면
      지금 작성한 커뮤니티 글에 대해 1개의 댓글을 달아줍니다.

      버튼을 누르면 글 수정 시 ChatGPT가 작성한 댓글이 수정됩니다.

      임시저장함에 저장되었습니다. 저장일시 : 2022.5.17 14:29:08

      임시저장함

      제목을 선택하시면 이어서 작성이 가능하며,
      최대 20건까지 저장합니다.
      컨텐츠 유형, 제목, 저장일시, 삭제로 이뤄진 임시저장 목록
      컨텐츠 유형 제목 저장일 삭제

      데보션 블로그 게재 요청

      CLOSE
      • *
      • *

      본인인증

      효율적인 데보션 서비스 이용 및
      고객님의 소중한 개인정보보호를 위해
      본인인증을 진행해주세요. 본인인증 미 진행 시 로그인이 제한됩니다.
      본인인증 실패

      본인인증 로그인에 실패하였습니다.
      회원이 아니시거나 본인인증 등록이
      완료되지 않은 사용자입니다.

      회원정보 연결

      KubeVirt로 구현하는 GPU VM (1) - GPU Passthrough 및 Kubevirt 설치

      dragonpipe 25.11.20
      2,371 8 1
      DEVOTEE 요약
      쿠버네티스 환경에서 VM 리소스를 효과적으로 관리하기 위해 등장한 KubeVirt를 활용해 GPU Passthrough 및 VM 설정 과정을 설명합니다. GPU Passthrough 설정을 통해 VM이 물리 GPU를 직접 제어하도록 구성하고, vfio-pci 드라이버를 적용해 안정적인 하드웨어 접근을 구현합니다. 또한 CPU 전용 할당 설정을 통해 GPU 작업 중 CPU 스케줄링 충돌을 최소화하며, 이를 기반으로 쿠버네티스에서 GPU VM을 생성하고 관리하는 환경을 구축할 수 있습니다.
      DEVOTEE 추천 블로그

      시작하는 글

      쿠버네티스(Kubernetes)는 컨테이너 기반의 클라우드 네이티브 아키텍처를 대표하는 플랫폼으로, 경량성과 확장성 측면에서 전통적인 가상머신(VM)보다 뛰어납니다.

      그러나 모든 워크로드가 컨테이너로 대체 가능한 것은 아닙니다.

      예를 들어,

      • GUI 환경이 필요한 응용 프로그램,

      • GPU를 직접 제어해야 하는 그래픽 또는 AI 응용 시스템,

      • 기존 VM 기반의 운영 체계를 그대로 유지해야 하는 레거시 서비스의 경우에는,

      컨테이너보다는 VM 환경이 더 적합합니다.

      하지만 기존 KVM 기반의 가상화 환경에서는 쿠버네티스 클러스터 리소스와 VM 리소스를 분리 관리해야 하는 단점이 있었습니다.

      이때 등장한 것이 바로 KubeVirt입니다.

      KubeVirt는 쿠버네티스 상에서 VM을 쿠버네티스 리소스로 관리할 수 있게 해주는 가상화 오케스트레이터입니다.

      즉, 쿠버네티스 노드 위에 VM을 생성하더라도, 해당 노드의 나머지 리소스(CPU, 메모리, GPU 등)는 여전히 클러스터 내 다른 Pod가 사용할 수 있습니다.

      이 덕분에 컨테이너와 VM을 동일한 인프라 위에서 통합적으로 운영할 수 있는 유연한 환경을 구축할 수 있습니다.


      이번 글에서는 이러한 KubeVirt 환경에서 GPU 가속 VM을 만들기 위한 첫 번째 단계로, GPU Passthrough 및 Kubevirt 설치 과정을 다룹니다.

      핵심 포인트는 다음 세 가지입니다.

      1. GPU Passthrough 설정 — vfio-pci 드라이버를 이용해 NVIDIA GPU를 호스트에서 분리하고, 가상머신이 직접 접근할 수 있도록 매핑

      2. KubeVirt 및 관련 컴포넌트 설치 — virt-handler, virt-controller, virt-launcher, virtctl, CDI 등 VM 운영에 필요한 패키지 구성

      3. 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을 띄우는 환경을 준비할 수 있습니다.


      그래픽 카드 Unbind를 위한 기존 프로세스 종료

      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: nouveau

      nvidia 드라이버 사용하는 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 중인 프로세스 종료


      vfio-pci 설정 (GPU Passthrough 설정)

      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/


      Kubevirt 설치

      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 all


      Virtctl 설치

      KubeVirt의 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"}


      CDI 설치

      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.yaml


      GPU Operator 설치

      NVIDIA 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-passthrough


      Kubevirt CR 수정

      GPU 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.yaml


      CPU Manager 설정

      VM에서 전용 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 가상화 환경을 구성하는 방법을 단계적으로 정리해보겠습니다.

      댓글 0

      DEVOTEE를 활성화 시키면
      지금 작성한 댓글에 AI가 댓글을 달아줍니다.

      dragonpipe 님의 최신 블로그

      더보기

      DEVOTEE 추천 블로그

      동영상 기고하기