LabHub
배우기 러닝패스 코스

Virtualisation with QEMU/KVM

How to Read a QEMU Command Line

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

한 줄 요약

QEMU 커맨드라인은 가상 하드웨어의 부품 목록이다. 플래그 하나하나가 게스트가 보게 될 장치를 정한다.

Concept map: 가상 하드웨어의 부품 목록 · format= 를 명시 · -netdev 와 -device 의 분리 · 호스트 쪽 백엔드

왜 이게 필요했나

실무에서는 대부분 libvirt 나 클라우드 콘솔을 쓴다. 그런데 문제가 생기면 결국 그 아래의 QEMU 커맨드라인을 읽어야 한다. libvirt 의 XML 도 결국 이 커맨드라인으로 변환되고, ps aux | grep qemu 로 실제 실행 인자를 확인하는 것이 진단의 첫걸음이다.

어떻게 동작하나

최소한의 VM 은 이렇게 생겼다.

qemu-system-x86_64 \
  -accel tcg \
  -m 512 \
  -smp 2 \
  -drive file=/root/vm/vm01.qcow2,if=virtio,format=qcow2 \
  -netdev user,id=n0,hostfwd=tcp::12222-:22 \
  -device virtio-net-pci,netdev=n0 \
  -nographic \
  -serial mon:stdio

각 플래그의 의미.

플래그 의미 실무 포인트
-accel kvm / tcg 가속기 선택 -accel help 로 쓸 수 있는 것 확인
-m 512 메모리(MB) 단위 생략 시 MB
-smp 2 vCPU 개수 -smp 2,sockets=1,cores=2 로 토폴로지 지정 가능
-drive ...,if=virtio 디스크 + 인터페이스 format= 를 명시해야 안전
-netdev / -device 백엔드 / 프론트엔드 둘은 항상 쌍이다
-nographic 그래픽 없음 서버 환경 기본
-serial mon:stdio 시리얼을 stdio 로, 모니터 겸용 Ctrl-a c 로 전환
-monitor unix:<경로>,server,nowait 모니터를 유닉스 소켓으로 자동화에 적합

-netdev-device 의 분리가 처음엔 헷갈린다. -netdev호스트 쪽 백엔드(패킷이 어디로 가는가), -device게스트가 보는 NIC(어떤 카드로 보이는가)다. 둘을 id= 로 연결한다.

네트워크 모드

모드 특징 언제
user (SLIRP) 유저 공간 NAT. 특권 불필요 개발/테스트. 이 실습 환경의 유일한 선택
tap 커널 TAP 장치 프로덕션. 특권 필요
bridge TAP 을 브리지에 연결 VM 간 통신, 외부 노출
vhost-net 링 처리를 커널에서 고성능

user 모드는 게스트가 밖으로 나가는 것은 되지만 밖에서 게스트로 들어오는 것은 안 된다. 그래서 hostfwd 로 포트를 뚫는다.

-netdev user,id=n0,hostfwd=tcp::12222-:22

호스트의 12222 로 들어온 TCP 를 게스트의 22 로 보낸다. 이 리슨 소켓은 QEMU 가 시작하는 즉시 열린다 — 게스트가 아직 부팅 중이어도 ss -ltn 에 보인다. 게스트가 안 떴으면 연결이 거부될 뿐이다.

모니터

QEMU 모니터는 실행 중인 VM 에게 말을 거는 콘솔이다.

-monitor unix:/root/vm/mon.sock,server,nowait
echo 'info status' | nc -U /root/vm/mon.sock
echo 'info block'  | nc -U /root/vm/mon.sock

info status(실행/정지), info block(디스크), info network, system_powerdown(ACPI 종료 요청), savevm/loadvm(실행 중 스냅샷) 같은 명령이 있다. 자동화에서는 소켓으로 붙이는 것이 표준이다.

콘솔

-nographic-serial 조합으로 시리얼 콘솔을 쓴다. 게스트 커널에 console=ttyS0 을 넘겨야 커널 메시지가 시리얼로 나온다. 로그를 파일로 남기려면 -serial file:/root/vm/console.log 를 쓴다.

부팅 초기에 보이는 것들의 순서를 알아 두면 어디까지 진행됐는지 알 수 있다.

  1. SeaBIOS (version ...) — 펌웨어가 떴다
  2. Booting from Hard Disk... — 부트로더로 넘어갔다
  3. Linux version ... — 커널이 시작됐다
  4. 로그인 프롬프트 — 유저 공간까지 왔다

1번은 QEMU 가 시작되자마자 나온다. TCG 라서 3번까지 오래 걸려도, 1~2번이 보이면 디스크와 부트로더는 정상이라는 뜻이다.

현장에서 만나는 모습

ps aux | grep qemu 로 실제 인자 확인. libvirt 의 XML 과 실제 실행 인자가 다른 경우가 있다(캐시된 도메인 정의, 핫플러그된 장치). 진짜는 프로세스 커맨드라인에 있다.

format= 을 생략해 생기는 문제. QEMU 가 파일 내용을 보고 포맷을 추측하는데, 게스트가 디스크 첫 부분에 qcow2 헤더처럼 보이는 데이터를 쓰면 다음 부팅에서 오인할 수 있다. 항상 명시한다.

다음 실습에서 할 것

/opt/vm/ 의 이미지를 백킹으로 오버레이를 만들고, 실행 스크립트를 정확한 플래그로 작성하고, 실제로 띄워 시리얼 로그 · 모니터 응답 · hostfwd 리슨 소켓 세 가지를 확인한다.