Virtual Machine (VM): guest OS, 스냅샷, 마이그레이션
정의
Virtual Machine (VM) 은 hypervisor 위에 실행되는 완전한 가상 컴퓨터 입니다. 가상 CPU (vCPU), 가상 메모리 (vRAM), 가상 디스크, 가상 NIC 을 갖고, 그 위에 게스트 OS 를 부팅합니다. 게스트 OS 는 자기가 물리 컴퓨터 위에 있다고 착각합니다.
VM 은 container 와 달리 자체 커널 을 실행합니다. 이것이 VM 의 강한 격리와 큰 오버헤드의 근본 이유입니다.
구성 요소
vCPU
- Hypervisor 가 물리 코어를 시분할하여 여러 vCPU 를 제공
- 게스트에게는 완전한 CPU 처럼 보임
- CPU pinning: 특정 vCPU 를 특정 물리 코어에 고정 (성능/일관성 향상)
- NUMA topology: 게스트에도 NUMA 를 노출하여 큰 워크로드가 지역성 활용
vRAM
- 게스트 물리 메모리는 hypervisor 관점에서는 그냥 메모리 풀
- EPT (Extended Page Tables) 로 게스트 물리 → 호스트 물리 이중 변환을 하드웨어가 함
- Ballooning: hypervisor 가 게스트에게 “회수 요청” 을 보내 유휴 메모리를 다시 가져옴
- KSM (Kernel Same-page Merging): 여러 게스트가 같은 페이지 (예: 같은 배포판 커널) 를 공유
가상 디스크
파일 또는 볼륨 형태:
| 포맷 | 특징 | Hypervisor |
|---|---|---|
| qcow2 | QEMU CoW, 스냅샷, thin provisioning | KVM/QEMU |
| VMDK | VMware 표준 | ESXi, Workstation |
| VHD / VHDX | Microsoft 표준 | Hyper-V |
| raw | 헤더 없이 그대로, 성능 최고 | 모든 hypervisor |
| VDI | VirtualBox 자체 포맷 | VirtualBox |
가상 NIC (vNIC)
- 에뮬레이션: e1000, rtl8139 (게스트가 물리 카드처럼 인식, 느림)
- virtio-net: 게스트가 virtio 를 알고 있어 직접 hypervisor 와 통신 (paravirtual, 훨씬 빠름)
- SR-IOV: 물리 NIC 을 나누어 게스트가 하드웨어 레벨로 접근
virtio
Rusty Russell (Linux 커널) 이 2008 년 발표한 paravirtual I/O 프레임워크. 게스트와 hypervisor 가 공유하는 링 버퍼 (vring) 로 통신.
virtio-blk,virtio-scsi: 디스크virtio-net: 네트워크virtio-balloon: 메모리 회수virtio-gpu: 그래픽virtio-fs: 파일시스템 (호스트 디렉토리 공유)
virtio 는 오늘날 KVM/QEMU 뿐 아니라 대부분의 hypervisor 가 지원하는 사실상 표준입니다.
부팅 흐름
- hypervisor 가 VM 프로세스를 시작 (QEMU 프로세스 등)
- 가상 펌웨어 실행 (SeaBIOS 또는 OVMF/UEFI)
- 부트로더 (GRUB 등) 가 커널 이미지 로드
- 게스트 커널 부팅 (수백 MB 메모리 초기화, 디바이스 검색)
- init/systemd 시작, 서비스 부트
- 최종적으로 login 프롬프트 또는 앱 실행
Full boot 은 30~60 초 걸리는 게 흔합니다. Container 가 수초 안에 뜨는 것과 대조됩니다.
Cloud-init
퍼블릭 클라우드에서 같은 이미지에서 여러 VM 을 띄우려면 인스턴스별 커스터마이징 이 필요합니다.
- 호스트네임 설정
- SSH 키 주입
- 사용자 계정 생성
- 패키지 설치
- 초기 스크립트 실행
cloud-init 이 이를 자동화합니다. 클라우드 provider 의 metadata service (예: AWS http://169.254.169.254/) 에서 정보를 읽어 부팅 시 적용. user-data 로 shell script 나 YAML (cloud-config) 를 지정할 수 있습니다.
#cloud-config
hostname: web01
users:
- name: deploy
sudo: ALL=(ALL) NOPASSWD:ALL
ssh_authorized_keys:
- ssh-ed25519 AAAA... deploy@laptop
packages:
- nginx
- postgresql-client
runcmd:
- systemctl enable --now nginx
스냅샷 (Snapshot)
특정 시점의 VM 상태 (메모리 + 디스크) 를 저장하여 나중에 그 상태로 되돌릴 수 있습니다.
종류
- 디스크 스냅샷: 파일시스템 시점 저장 (qcow2, ZFS, LVM)
- 메모리 스냅샷: RAM 을 dump (VM 이 정지되어 있어야 하거나 live 지원 필요)
- Full snapshot: 디스크 + 메모리 + 장치 상태 모두 (VMware, VirtualBox 지원)
사용처
- 업그레이드 전 백업, 실패 시 롤백
- 개발/테스트 환경 재현
- 짧은 기간 (몇 분~시간)
WARNING
프로덕션에서 스냅샷을 오래 유지하면 안 됩니다. qcow2 는 스냅샷이 쌓일수록 CoW 체인이 길어져 I/O 성능이 크게 저하됩니다. VMware 도 스냅샷 delta 파일이 커지면 문제. 스냅샷은 짧게 쓰고 지우거나 백업 파일로 export 하세요.
Live Migration
실행 중인 VM 을 거의 무중단 으로 다른 물리 서버로 옮기는 기술.
Pre-copy 방식 (표준)
- 원본 서버에서 메모리 페이지를 백그라운드로 대상 서버에 복사 시작
- VM 계속 실행 중이므로 dirty page 발생
- dirty page 만 다시 복사, 반복
- dirty rate 가 충분히 낮아지면 마지막 stop-and-copy
- VM 을 원본에서 잠깐 (수십 ms) 멈추고 남은 페이지 + CPU 상태 전송
- 대상에서 VM 재개
Post-copy 방식
- VM 을 대상으로 옮겨서 즉시 재개
- 메모리 접근 시 원본에서 page fault 로 가져옴
Post-copy 는 다운타임이 더 짧지만 원본 실패 시 VM 이 죽습니다. VMware vMotion, KVM libvirt migration, Xen 모두 지원합니다.
요구 조건
- 두 서버가 공유 스토리지 (NFS, iSCSI, Ceph) 를 봐야 함 (또는 storage migration 병행)
- CPU 모델이 호환 가능해야 함 (EVC / CPU masking 으로 완화)
- 네트워크 대역폭 (특히 대용량 VM)
VM 관리 CLI 예시 (libvirt / KVM)
# 새 VM 생성 (cloud image 사용)
virt-install \
--name web01 \
--memory 4096 --vcpus 2 \
--disk path=/var/lib/libvirt/images/web01.qcow2,size=20 \
--cdrom /iso/ubuntu-24.04-server.iso \
--network network=default \
--graphics none --console pty,target_type=serial
# 실행/정지
virsh start web01
virsh shutdown web01 # 정중한 종료
virsh destroy web01 # 강제 종료
# 스냅샷
virsh snapshot-create-as web01 pre-upgrade
virsh snapshot-list web01
virsh snapshot-revert web01 pre-upgrade
# Live migration (공유 스토리지 전제)
virsh migrate --live web01 qemu+ssh://target-host/system
# 콘솔 접속
virsh console web01
VM 이 컨테이너보다 유리한 경우
- 다른 커널 필요: Linux 위에서 Windows 실행
- 커널 수준 튜닝: 실시간 커널, 커스텀 모듈 로드
- 강한 격리 필요: 규제 산업 (금융, 의료), 멀티테넌트
- 하드웨어 에뮬레이션: 다른 CPU 아키텍처, 특수 디바이스
- 레거시 앱: 오래된 OS 그대로 유지 (Windows Server 2003 등)
VM 이 잘 안 맞는 경우
- 마이크로서비스 (수백~수천 인스턴스): 부팅/이미지 부담이 큼
- 짧은 수명 워크로드 (배치 잡): 부팅에 몇 분 걸리면 잡보다 오래 걸릴 수 있음
- 개발자 로컬 반복 (edit-restart): container 대비 반복 사이클이 느림
이런 경우 container 가 자연스러운 선택입니다.
참고
- 관련 가상화 전체
- 관련 Hypervisor
- 관련 VM vs Container 심층 비교
- 관련 Docker
- Cloud-init: https://cloudinit.readthedocs.io/
- libvirt: https://libvirt.org/
- Rusty Russell, virtio
이 글의 용어 (4개)
- [Container] Docker: image, layer, registryvirtualization
- 정의 Docker = 컨테이너 빌드 + 실행 + 배포 의 표준 도구. 2013 출시 → 컨테이너 시대 의 시작. 현재는 OCI 표준 으로 진화 ( , , 등 호환). Layere…
- 가상화 (Virtualization): 하드웨어, OS, 컨테이너 계층 전체 정리virtualization
- 정의 가상화 (Virtualization) 는 물리 자원 (CPU, RAM, 디스크, NIC) 을 소프트웨어 계층으로 감싸 여러 논리 인스턴스로 분할 하거나 하나로 통합 하는 기…
- Hypervisor: Type 1 (bare metal) vs Type 2 (hosted)virtualization
- 정의 Hypervisor (Virtual Machine Monitor, VMM) 는 여러 VM 을 한 물리 머신 위에서 실행하도록 하드웨어를 가상화하는 소프트웨어입니다. CPU …
- VM vs Container: 층 구조, 성능, 격리 완벽 비교virtualization
- 정의 VM 과 Container 는 같은 문제 (하나의 물리 서버에 여러 워크로드 격리) 를 다른 방식으로 푸는 두 접근 입니다. VM 은 하드웨어를 가상화하고, Containe…
💬 댓글