전가상화는 게스트를 "속인다". 게스트 커널은 진짜 하드웨어 위에 있다고 믿고 특권 명령을 실행하는데 하이퍼바이저가 그것을 가로채(trap) 대신 처리한다 — Windows처럼 소스를 손댈 수 없는 OS를 돌리는 이유다. 반가상화는 게스트 커널을 수정해 특권 명령 대신 하이퍼콜(hypercall)로 부탁하게 만든다.
전가상화의 성능 문제는 Intel VT-x·AMD AMD-V가 해결했다. CPU가 게스트 모드를 직접 제공해 가로채기 비용을 없앴고, 그래서 전가상화가 표준이 됐다. 반가상화는 I/O 영역(virtio)에만 남았다.
grep -E 'vmx|svm' /proc/cpuinfo # Intel=vmx, AMD=svm 플래그가 보이면 지원grep -c -E 'vmx|svm' /proc/cpuinfo # 지원 논리 코어 수(0이면 미지원 또는 BIOS 비활성)
[Type 1] [Type 2]
+------------------+ +------------------+
| VM | VM | VM | | VM | VM |
+------------------+ +------------------+
| 하이퍼바이저 | | 하이퍼바이저(앱) |
+------------------+ +------------------+
| 하드웨어 | | 호스트 OS |
+------------------+ +------------------+
| 하드웨어 |
+------------------+
Type 2가 느린 이유: 게스트의 요청이 하이퍼바이저 → 호스트 OS → 하드웨어로 한 단계를 더 거친다.
그래서 서버실은 Type 1, 내 노트북은 Type 2가 정석이다.
⚠️ 함정: KVM의 분류가 헷갈리는 지점이다. KVM은 커널 모듈이라 "호스트 OS 위"처럼 보이지만, 적재되는 순간 리눅스 커널 자체가 하이퍼바이저로 변신한다. 그래서 통상 Type 1으로 분류하며, 시험 보기도 "KVM = Type 1, VirtualBox = Type 2"가 표준이다.
virsh list # 실행 중인 도메인만virsh list --all # 정지된 것까지 전부virsh start vm1 # 시작virsh shutdown vm1 # 정상 종료(ACPI 신호 전달)virsh destroy vm1 # 강제 종료(전원 코드 뽑기) — 삭제 아님!virsh undefine vm1 # 도메인 정의 삭제(제거)virsh suspend vm1 # 일시 정지(메모리 유지)virsh resume vm1 # 정지 해제virsh dominfo vm1 # 상태·CPU·메모리 정보virsh dumpxml vm1 > vm1.xml # 설정을 XML로 내보내기 (반대: virsh define vm1.xml)virsh autostart vm1 # 호스트 부팅 시 자동 시작
⚠️ 함정: virsh destroy는 이름과 달리 가상 머신을 지우지 않는다. 전원 코드를 뽑듯 강제로 끄는 것이며, 디스크와 정의는 남아 virsh start로 다시 켤 수 있다. 등록을 지우는 명령은 virsh undefine이다.
libvirt가 존재하는 이유는 추상화다. virsh 명령은 KVM뿐 아니라 Xen·LXC에도 통하며 접속 URI만 바꾸면 된다. 도메인 XML은 /etc/libvirt/qemu/, 디스크 이미지 기본 저장소는 /var/lib/libvirt/images/다.
namespace는 시야 — 컨테이너 안에서 ps를 치면 자기 프로세스만, ip addr을 치면 자기 인터페이스만 보인다.
cgroup은 한도 — 한 컨테이너가 호스트 자원을 통째로 잡아먹지 못하게 막는다.
"컨테이너는 가벼운 가상 머신"이라는 표현은 시험에서 오답이다. 컨테이너에는 게스트 커널도 하이퍼바이저도 없다. 그래서 리눅스 호스트 위에서 Windows 컨테이너를 돌릴 수 없고, 커널 취약점이 뚫리면 격리도 함께 뚫린다.
컨테이너의 뿌리는 1979년 유닉스 chroot다. 리눅스에서 cgroup·namespace가 커널에 들어오며 기반이 갖춰졌고 LXC가 이를 묶었으며, 2013년 Docker가 이미지와 레지스트리라는 유통 개념을 얹으며 폭발적으로 퍼졌다 — 격리 기술보다 "배포 방식"이 혁신이었다.
docker pull nginx:1.25 # 레지스트리에서 이미지 내려받기(태그 지정)docker images # 로컬 이미지 목록docker run -d -p 8080:80 --name web nginx # 컨테이너 생성 + 실행docker ps # 실행 중인 컨테이너 (전부: docker ps -a)docker exec -it web /bin/bash # 실행 중인 컨테이너에서 명령 실행(셸 접속)docker logs -f web # 컨테이너 표준출력 로그(실시간)docker stop web # 정상 정지docker rm web # 컨테이너 삭제(정지 상태여야 함)docker rmi nginx # 이미지 삭제docker build -t myapp:1.0 . # Dockerfile로 이미지 빌드
옵션
의미
-d
detached, 백그라운드 실행
-it
대화형(-i 표준입력 유지 + -t 유사 터미널)
-p 호스트:컨테이너
포트 매핑(publish)
-v 호스트경로:컨테이너경로
볼륨·바인드 마운트
--name / -e KEY=VALUE / --rm
이름 지정 / 환경 변수 / 종료 시 자동 삭제
docker rm(컨테이너 삭제)과 docker rmi(이미지 삭제)를 바꿔 쓰는 문제가 있다 — i가 붙으면 image다. 또 -p 8080:80은 호스트 포트가 앞, 컨테이너 포트가 뒤이며 순서를 뒤집은 보기는 오답이다.
컨테이너가 삭제되면 쓰기 계층이 통째로 사라진다. 그래서 보존할 데이터는 볼륨으로 밖에 둔다.
-v /host/data:/var/lib/mysql처럼 호스트 디렉터리를 연결하면(바인드 마운트) 컨테이너를 지워도 데이터가 남는다.
Dockerfile은 이미지를 만드는 절차를 적은 텍스트 파일이며, 각 지시어가 이미지의 한 계층(layer)이 된다.
FROM ubuntu:22.04 # 베이스 이미지(반드시 첫 지시어)ENV APP_HOME=/app # 환경 변수WORKDIR /app # 작업 디렉터리(없으면 생성)COPY ./src /app # 호스트 파일을 이미지로 복사RUN apt-get update && apt-get install -y python3 # 빌드 시점에 실행EXPOSE 8080 # 사용할 포트를 문서화CMD ["python3", "app.py"] # 컨테이너 시작 시 실행할 기본 명령
지시어
역할
FROM
베이스 이미지 지정(항상 첫 줄)
RUN
빌드 시점에 명령 실행(결과가 이미지에 남음)
COPY / ADD
파일 복사(ADD는 URL·자동 압축 해제 지원)
WORKDIR / ENV / USER
작업 디렉터리 / 환경 변수 / 실행 사용자
EXPOSE
노출 포트 문서화(실제 개방은 -p)
CMD / ENTRYPOINT
실행 시점의 기본 명령(덮어쓰기 가능) / 고정 실행 파일
RUN과 CMD의 시점이 다르다. RUN은 docker build 중 실행되어 결과가 이미지에 굳고, CMD는 docker run 할 때 실행되며 여러 번 써도 마지막 하나만 유효하다. EXPOSE는 문서화일 뿐 외부 접근을 열지 않는다.
Podman은 RHEL 8부터 Docker를 대체하는 기본 컨테이너 엔진이다.
Docker와의 차이는 두 가지 — 데몬리스(상주 데몬 dockerd 없이 컨테이너를 직접 띄움), 루트리스(일반 사용자 권한으로 실행).
옵션은 Docker 호환이라 podman run -d -p 8080:80 nginx가 그대로 통한다. 시스템 컨테이너 계열 LXC/LXD도 알아둔다.
# 직접 쳐보기 — 가상화 지원과 격리 기능 관찰 (안전: 조회 위주)grep -c -E 'vmx|svm' /proc/cpuinfo # CPU 가상화 지원 코어 수(0이면 미지원)lsmod | grep kvm # KVM 모듈 적재 여부ls -l /dev/kvm 2>/dev/null || echo "KVM 미사용"lsns | head # 시스템의 namespace 목록ls /sys/fs/cgroup | head # cgroup 계층virsh list --all 2>/dev/null || echo "libvirt 미설치"docker ps -a 2>/dev/null || echo "Docker 미설치"
GUI 외에 VBoxManage 명령행 도구를 제공하며, VBoxManage <하위명령> <VM이름> [옵션] 구조로 일관된다.
VBoxManage list vms # 등록된 VM 목록(실행 중만: list runningvms)VBoxManage showvminfo "vm1" # VM 상세 정보VBoxManage startvm "vm1" --type headless # GUI 없이 백그라운드로 시작VBoxManage controlvm "vm1" acpipowerbutton # 정상 종료 요청(강제: poweroff)VBoxManage modifyvm "vm1" --memory 2048 # 설정 변경(메모리)VBoxManage snapshot "vm1" take "before-update" # 스냅샷 생성
함께 설치하는 Guest Additions는 게스트 안에 넣는 보조 드라이버다. 해상도 자동 조절·클립보드 공유·공유 폴더를 가능하게 한다(VMware Tools와 같은 역할).