← 이야기 목록
생산성·AI

🔌 패스스루는 무엇을 넘길지가 아니라, 무엇이 남아야 하는지의 문제였습니다

GPU와 디스크를 가상머신에 넘기려다 하드웨어에 막혔습니다. IOMMU 그룹, 부팅 디스크와 얽힌 드라이버, 그리고 개별 패스스루가 대가로 가져가는 것까지 실제 구성 기준으로 정리했습니다.

2026년 8월 10일

가상화로 서버를 합치기로 했으면 다음 단계는 정해져 있습니다. 하드웨어를 게스트에 넘기는 일이죠. GPU는 AI 가상머신으로, 하드디스크는 나스 가상머신으로. 그림으로 그릴 땐 간단했는데, 실제로는 하드웨어가 몇 번 거절했습니다. 그 과정에서 질문 자체를 바꿔야 한다는 걸 알았어요. (왜 이런 구조를 택했는지는 나스와 AI 서버를 한 대에 합쳤습니다에 정리해 뒀습니다.)

질문의 방향이 반대였습니다

처음엔 “무엇을 넘길까”를 고민했습니다. GPU 넘기고, 하드 넘기고, 나머지는 호스트가 쓰고. 그런데 실제로 막히는 지점은 전부 반대편에 있었어요. 넘기려는 장치가 문제가 아니라, 호스트에 반드시 남아야 하는 것과 얽혀 있는지가 문제였습니다.

호스트에 남아야 하는 대표적인 게 부팅 디스크입니다. 이게 어디에 물려 있느냐가 나머지 선택지를 전부 결정했어요. 그래서 패스스루 계획은 넘길 목록을 적는 게 아니라, 남아야 할 것부터 표시하고 시작하는 게 맞았습니다.

IOMMU 그룹은 협상 대상이 아닙니다

장치를 게스트에 넘기려면 먼저 IOMMU를 켜야 합니다. 여기서 첫 함정이 있었어요. 많은 문서가 부트로더 설정 파일을 고치라고 하는데, ZFS 루트로 설치한 최근 버전은 다른 부트로더를 씁니다. 엉뚱한 파일을 고치고 재부팅해봐야 아무 일도 일어나지 않아요.

nano /etc/kernel/cmdline
# 커널 파라미터에 intel_iommu=on iommu=pt 추가

proxmox-boot-tool refresh
reboot

켜고 나면 장치들이 어떤 그룹으로 묶여 있는지 확인합니다.

for d in /sys/kernel/iommu_groups/*/devices/*; do
  n=${d#*/iommu_groups/}; n=${n%%/*}
  printf 'Group %s: ' "$n"; lspci -nns "${d##*/}"
done | sort -V

여기서 알아야 할 규칙이 하나 있습니다. 넘기려는 장치가 다른 장치와 같은 그룹에 있으면, 그 장치들도 함께 넘어갑니다. 골라서 뺄 수 없어요. 그래서 부팅 디스크가 같은 그룹에 들어 있으면 그 순간 통째 패스스루는 불가능해집니다.

이건 설정으로 우회할 수 있는 종류의 제약이 아닙니다. 메인보드가 장치들을 어떻게 묶어놨느냐의 문제라서요. 그룹이 나눠져 있지 않으면 그 하드웨어로는 안 되는 겁니다. 다행히 GPU는 깨끗하게 분리돼 있어 바로 넘어갔습니다.

부팅 디스크가 같은 컨트롤러에 물린 순간

문제는 하드디스크 쪽이었습니다. 구성이 이랬어요.

메인보드 SATA        SSD 2개(부팅) + HDD 4개
SATA 확장 카드       HDD 4개

확장 카드는 부팅과 무관하니 통째로 넘기면 됩니다. 그런데 안 넘어갔어요.

원인은 드라이버였습니다. 흔히 쓰는 방식은 장치 종류를 지정해 가상화용 드라이버에 붙이는 건데, 이 방식은 같은 종류의 다른 장치까지 함께 잡아버립니다. 확장 카드도 SATA 컨트롤러고 부팅 SSD가 물린 메인보드 포트도 SATA 컨트롤러예요. 호스트는 부팅해야 하니 기본 드라이버가 살아 있어야 하고, 그 드라이버가 카드를 먼저 채가는 상황이 됐습니다.

해결은 종류가 아니라 장치 하나만 콕 집는 것이었습니다.

apt install driverctl
driverctl set-override 0000:02:00.0 vfio-pci
driverctl list-overrides

주소로 지정하니 그 카드만 넘어갔습니다. 종류로 거는 방식이 편해 보이지만, 부팅에 쓰이는 장치와 종류가 겹치는 순간 쓸 수 없다는 걸 여기서 배웠어요.

메인보드에 물린 하드 4개는 통째로 넘길 방법이 없었습니다. 부팅 SSD와 같은 컨트롤러에 있으니까요. 그래서 디스크를 하나씩 개별로 넘겼습니다.

qm set 100 --sata1 /dev/disk/by-id/ata-XXXXXXXX

결국 카드는 통째로, 보드 쪽 하드는 개별로 넘기는 혼합 구성이 됐습니다. 처음 계획과는 다르지만, 부팅 디스크의 위치를 생각하면 이게 유일한 답이었어요.

개별 패스스루는 이름을 잃는 거래입니다

개별 방식은 유연합니다. 아무 디스크나 골라서 넘길 수 있어요. 대신 잃는 게 있었습니다.

게스트가 디스크의 모델명과 시리얼을 보지 못합니다. 나스 안에서 하드 4개가 전부 똑같은 이름으로 뜹니다. 처음엔 별 문제 아니라고 생각했는데, 나중에 상태 확인 화면을 만들면서 발목을 잡았어요. 호스트가 보는 디스크와 게스트가 보는 디스크를 짝지어야 하는데, 한쪽에 이름이 없으니 무엇이 무엇인지 알 수가 없었습니다.

디스크에 문제가 생겼을 때 어느 물리 디스크인지 특정하지 못하면 곤란해집니다. 그래서 넘기기 전에 포트 번호와 시리얼을 따로 적어뒀어야 했어요. 지금은 그 대응표를 손으로 관리하고 있습니다.

세 가지 방식, 무엇을 얻고 무엇을 잃는가

방식얻는 것잃는 것쓰는 곳
컨트롤러 통째게스트가 디스크 정보를 그대로 봄. 상태 점검도 가능부팅 디스크가 섞이면 불가확장 카드
디스크 개별아무 디스크나 넘길 수 있음모델명과 시리얼이 안 보임보드 SATA
장치 공유여러 컨테이너가 나눠 씀가상머신에는 못 씀내장 그래픽

세 번째 방식은 성격이 좀 다릅니다. 넘기는 게 아니라 나눠 쓰는 거라서요. 내장 그래픽을 이렇게 여러 컨테이너에 물려두면 영상 트랜스코딩 같은 걸 동시에 처리할 수 있습니다. 다만 가상머신에는 이 방식을 쓸 수 없어요.

정리

패스스루에서 실제로 결정권을 가진 건 넘기려는 장치가 아니라 호스트에 남아야 하는 것이었습니다. 부팅 디스크가 어느 컨트롤러에 물려 있느냐가 나머지를 전부 정했어요.

그래서 순서를 이렇게 잡는 게 맞았습니다. 먼저 호스트에 남아야 할 것을 표시하고, IOMMU 그룹을 확인해 무엇이 함께 묶여 있는지 보고, 그다음에 남은 선택지 중에서 고르는 것. 이 순서로 보면 안 되는 조합은 처음부터 안 된다는 게 보입니다.

그리고 개별 패스스루처럼 유연해 보이는 방법에는 대개 대가가 있습니다. 무엇을 잃는지 알고 고르면 나중에 덜 당황해요. 저는 모르고 골랐다가 반년쯤 지나서 청구서를 받았습니다.

다른 이야기 보기 홀로라도 도구 →