안동민 개발노트

본문 시작

가상화의 개념

하이퍼바이저 유형과 전가상화·반가상화·하드웨어 지원 가상화가 CPU·메모리·I/O를 격리하는 방식을 이해합니다.

클라우드 서비스에서 서버를 생성하면 몇 분 안에 사용할 수 있습니다.

VM 상품을 선택했다면 하나의 물리 서버 위에 여러 가상 서버가 동작할 수 있습니다. 클라우드에는 물리 서버를 전용으로 제공하는 베어메탈 상품도 있습니다.

이것을 가능하게 하는 기술이 가상화(Virtualization)입니다.

가상화는 현대 클라우드 인프라의 기반이며, OS 과목의 거의 모든 개념이 여기서 다시 등장합니다.


가상화란 무엇인가

가상화는 물리적 하드웨어 위에 소프트웨어로 가상의 하드웨어를 만드는 기술입니다.

하나의 물리 서버에서 여러 운영체제를 독립적으로 실행할 수 있습니다.

왜 가상화가 필요한가

자원 효율: 서버 한 대가 CPU의 10%만 사용하고 있다면 나머지 90%가 낭비됩니다.

가상화로 여러 서비스를 통합하면 유휴 자원을 활용할 수 있습니다. 실제 활용률은 부하와 자원 배분에 따라 달라집니다.

격리(Isolation): 서비스 A의 크래시가 서비스 B에 영향을 주지 않아야 합니다.

각 VM은 독립된 게스트 OS를 가져 게스트 내부 실패를 격리합니다. 다만 호스트·하이퍼바이저 장애나 공유 자원 부족은 여러 VM에 영향을 줄 수 있습니다.

유연성: 물리 서버를 구매하고 설치하는 데 수 주가 걸리지만, VM은 수 분 내에 생성하고 삭제할 수 있습니다.

이식성: CPU·가상 장치·이미지 형식과 설정이 호환되는 호스트에서는 VM 이미지를 옮겨 실행 환경을 재사용할 수 있습니다.

개발 환경과 프로덕션 환경의 차이를 줄입니다.


하이퍼바이저

하이퍼바이저(Hypervisor)는 가상 머신을 생성하고 관리하는 소프트웨어입니다.

VMM(Virtual Machine Monitor)이라고도 합니다.

Type 1 (베어메탈, Native)

하드웨어 위에 직접 설치됩니다.

호스트 OS가 없거나 최소한입니다.

하이퍼바이저 자체가 하드웨어를 직접 제어합니다.

  • VMware ESXi: 엔터프라이즈 환경에서 널리 사용되는 베어메탈 하이퍼바이저
  • Microsoft Hyper-V: Windows Server에 내장
  • Xen: 초기 클라우드 인프라와 여러 가상화 환경에서 널리 사용
  • KVM: Linux 커널에 통합된 하이퍼바이저. 여러 클라우드와 서버 가상화 환경에서 사용

성능이 우수하여 데이터센터와 클라우드에서 사용됩니다.

Type 2 (호스트형, Hosted)

일반 OS(Windows, macOS, Linux) 위에 애플리케이션처럼 설치됩니다.

  • VirtualBox: 여러 호스트 OS를 지원
  • VMware Workstation/Fusion: 데스크톱용 호스트형 가상화 제품
  • Parallels Desktop: macOS 전용

개발 환경이나 테스트 용도로 사용됩니다.

호스트 OS와 장치 처리 경로에서 추가 비용이 생길 수 있지만, Type 구분만으로 실제 성능 순위를 정할 수는 없습니다.

KVM — 경계가 모호한 하이퍼바이저

KVM(Kernel-based Virtual Machine)은 Linux 커널의 모듈입니다.

Linux를 부팅하면 일반 OS처럼 보이지만, KVM 모듈을 로드하면 커널이 CPU의 가상화 확장을 사용해 VM 실행을 직접 관리합니다.

그래서 단순히 Type 1/Type 2 중 하나로만 외우기보다, Linux 커널이 하이퍼바이저 역할을 하고 QEMU 같은 사용자 공간 도구가 장치 에뮬레이션과 관리 기능을 보탠다고 이해하는 편이 정확합니다.

kvm_check.py
import subprocess

def check_virtualization():
    """시스템의 가상화 지원 확인"""
    # CPU 가상화 지원 확인
    with open("/proc/cpuinfo") as f:
        cpuinfo = f.read()

    if "vmx" in cpuinfo:
        print("Intel VT-x 지원")
    elif "svm" in cpuinfo:
        print("AMD-V 지원")
    else:
        print("현재 /proc/cpuinfo에서 vmx/svm 플래그를 찾지 못함")

    # KVM 모듈 로드 확인
    result = subprocess.run(["lsmod"], capture_output=True, text=True)
    if "kvm" in result.stdout:
        print("KVM 모듈 로드됨")
    else:
        print("KVM 모듈 미로드")

    # 현재 가상환경에서 실행 중인지 확인
    result = subprocess.run(
        ["systemd-detect-virt"], capture_output=True, text=True
    )
    virt = result.stdout.strip()
    if virt == "none":
        print("이 도구가 인식하는 가상 환경을 감지하지 못함")
    else:
        print(f"가상 환경에서 실행 중: {virt}")

이 코드는 함수를 정의하며 직접 호출하지는 않습니다. 플래그 노출, 로드된 모듈, 가상 환경 감지는 서로 다른 확인입니다. 명령 실패와 내장 KVM 여부는 따로 확인해야 합니다.


전가상화와 반가상화

전가상화(Full Virtualization): 게스트 OS가 자신이 가상 환경에서 돌고 있다는 사실을 몰라도 실행될 수 있습니다.

게스트 OS를 수정할 필요가 없다는 것이 핵심입니다.

과거에는 특권 명령을 소프트웨어로 변환하는 Binary Translation이 중요했지만, 현대 시스템에서는 VT-x/AMD-V 같은 하드웨어 지원으로 많은 트랩과 전환을 CPU가 직접 처리합니다.

반가상화(Paravirtualization): 게스트 OS 또는 게스트 드라이버가 가상 환경을 인지하고, 실제 장치를 흉내 낸 느린 경로 대신 하이퍼바이저가 제공하는 최적화된 인터페이스를 사용합니다.

초기 Xen처럼 커널 수정이 필요한 방식도 있었지만, 현대에는 VirtIO처럼 게스트 드라이버를 통해 실용적으로 적용되는 경우가 많습니다.

VirtIO — 반가상화의 실용적 해결

완전한 하드웨어 에뮬레이션(e1000 NIC, IDE 디스크)은 호환성은 좋지만 I/O 경로가 길어질 수 있습니다.

VirtIO는 게스트와 호스트 사이에 최적화된 가상 장치 인터페이스를 제공합니다.

게스트에 VirtIO 드라이버를 설치하면, 네트워크와 디스크 I/O에서 에뮬레이션 장치보다 훨씬 낮은 오버헤드를 기대할 수 있습니다.

  • 네트워크: e1000 같은 에뮬레이션 NIC 대신 virtio-net을 사용할 수 있습니다.
  • 디스크: IDE/SATA 에뮬레이션 대신 virtio-blk 또는 virtio-scsi를 사용할 수 있습니다.

VirtIO 드라이버는 virtqueue를 통해 요청을 전달하고 백엔드가 처리합니다. 실제 이점은 백엔드와 워크로드에도 달려 있습니다.


하드웨어 지원 가상화

현대 CPU는 가상화를 하드웨어로 지원합니다.

Intel의 VT-x(2005~)와 AMD의 AMD-V(2006~)가 대표적입니다.

하드웨어 가상화 지원이 있으면 CPU는 하이퍼바이저와 게스트를 분리해서 실행할 수 있는 모드를 제공합니다.

하이퍼바이저는 더 높은 제어 권한에서, 게스트 OS는 격리된 VM 실행 모드에서 동작합니다.

하이퍼바이저가 가로채도록 설정한 동작이나 특정 이벤트에서 CPU가 VM Exit를 일으킵니다.

이 덕분에 예전처럼 모든 특권 명령을 소프트웨어로 번역할 필요가 크게 줄었습니다.

KVM에서 실행과 제어가 나뉘는 지점

게스트 실행, 커널에서 처리한 exit, 사용자 공간 반환을 구별합니다.

KVM에서 실행과 제어가 나뉘는 지점
단계처리 주체다음 동작
게스트 실행CPU가 게스트 코드를 실행하고 주소를 변환설정된 가로채기 조건이나 이벤트에서 VM Exit 발생
커널의 exit 처리KVM이 exit 원인에 맞게 처리커널에서 처리하면 게스트를 재개할 수 있음
사용자 공간 처리필요한 경우 KVM_RUN이 VMM에 반환VMM이 I/O 등을 처리하고 KVM_RUN으로 다시 진입
게스트 실행
처리 주체: CPU가 게스트 코드를 실행하고 주소를 변환
다음 동작: 설정된 가로채기 조건이나 이벤트에서 VM Exit 발생
커널의 exit 처리
처리 주체: KVM이 exit 원인에 맞게 처리
다음 동작: 커널에서 처리하면 게스트를 재개할 수 있음
사용자 공간 처리
처리 주체: 필요한 경우 KVM_RUN이 VMM에 반환
다음 동작: VMM이 I/O 등을 처리하고 KVM_RUN으로 다시 진입

일반 메모리 접근마다 VMM으로 돌아오지는 않습니다. 하드웨어 exit 횟수와 KVM_RUN의 사용자 공간 반환 횟수도 같은 지표가 아닙니다.

  • CPU의 VT-x / AMD-V: 게스트 실행 모드와 제어 전환을 지원합니다.
  • 메모리의 EPT / NPT: 게스트 물리 주소에서 호스트 물리 주소로의 추가 변환을 하드웨어가 처리합니다.
  • I/O의 VT-d / IOMMU: DMA 주소 변환과 격리를 제공합니다.
  • SR-IOV: 지원하는 장치가 여러 가상 기능(VF)을 노출하도록 합니다.

EPT(Extended Page Tables): 게스트 가상 → 게스트 물리 → 호스트 물리의 2단계 주소 변환을 하드웨어가 처리합니다.

이전에는 섀도 페이지 테이블을 소프트웨어로 관리해야 했고, 이것은 오버헤드가 컸습니다.

VT-d / IOMMU는 장치의 DMA 주소 변환과 접근 격리를 제공하며, VFIO 같은 소프트웨어와 함께 장치 직접 할당을 뒷받침합니다. GPU 패스스루의 성능도 장치·드라이버·메모리 및 I/O 구성에 따라 확인해야 합니다.

hardware_virt_check.sh
# Intel VT-x 지원 확인
grep -c vmx /proc/cpuinfo   # 0이면 현재 환경에 vmx 플래그가 노출되지 않음

# AMD-V 지원 확인
grep -c svm /proc/cpuinfo

# IOMMU 활성화 확인
dmesg | grep -i iommu

# kvm_intel 모듈의 EPT 사용 옵션 확인 (해당 모듈이 있을 때)
cat /sys/module/kvm_intel/parameters/ept  # Y이면 옵션 활성

AWS EC2의 Nitro System처럼 현대 클라우드는 네트워크와 스토리지 I/O의 많은 부분을 전용 하드웨어나 별도 제어 평면으로 오프로드합니다.

그래서 최신 VM은 예전 가상화보다 훨씬 낮은 오버헤드를 보이지만, 실제 성능 차이는 워크로드, 인스턴스 유형, I/O 경로에 따라 달라집니다.

다음 절에서는 가상화보다 가벼운 격리 기술인 컨테이너를 다루겠습니다.