/static/codemoomoo2.png

10. Virtualization (VirtualBox, QEMU)

Virtualization คือเทคโนโลยีที่สร้างชั้นนามธรรม (Abstraction Layer) ระหว่างฮาร์ดแวร์ทางกายภาพและระบบปฏิบัติการ เพื่อรันหลาย OS บนเครื่องเดียวกันได้พร้อมกัน บทความนี้ครอบคลุมตั้งแต่แนวคิดพื้นฐาน, ประเภทของ Hypervisor, การใช้งาน VirtualBox และ QEMU ไปจนถึง libvirt, Virtual Networking ขั้นสูง และ Infrastructure as Code


10.1 แนวคิดของ Virtualization (Virtualization Concepts)

Virtualization คือกระบวนการสร้างเครื่องเสมือน (Virtual Machine: VM) ที่จำลองทรัพยากรฮาร์ดแวร์ทางกายภาพ เช่น CPU, RAM, Disk, Network ให้ระบบปฏิบัติการ Guest มองเห็นเหมือนเครื่องคอมพิวเตอร์จริง โดยมี Hypervisor หรือ Virtual Machine Monitor (VMM) ทำหน้าที่จัดการและจัดสรรทรัพยากรระหว่าง VM แต่ละตัว

10.1.1 Virtualization คืออะไร และประโยชน์ (Consolidation, Isolation, Portability)

Virtualization คือเทคโนโลยีที่ทำให้สามารถรันหลายระบบปฏิบัติการ (Operating System) บนฮาร์ดแวร์ชุดเดียวได้อย่างอิสระต่อกัน โดยอาศัยซอฟต์แวร์ที่เรียกว่า Hypervisor เป็นตัวกลางในการจัดสรรทรัพยากร CPU, RAM, Storage และ Network ระหว่าง VM แต่ละตัว

ประโยชน์หลักของ Virtualization มีดังนี้

flowchart TB
    subgraph Physical["Physical Hardware (ฮาร์ดแวร์จริง)"]
        CPU[CPU
หน่วยประมวลผล] RAM[RAM
หน่วยความจำ] DISK[Disk
หน่วยเก็บข้อมูล] NIC[NIC
การ์ดเครือข่าย] end subgraph Hyper["Hypervisor Layer (ชั้น Hypervisor)"] VMM[VMM / Hypervisor
ตัวจัดการเครื่องเสมือน] end subgraph VMs["Virtual Machines (เครื่องเสมือน)"] VM1[VM1: Linux Server
Web Server] VM2[VM2: Windows
Database] VM3[VM3: BSD
Firewall] end Physical --> Hyper Hyper --> VMs

10.1.2 Type 1 Hypervisor (Bare-metal): ESXi, Xen, Hyper-V, KVM, Proxmox VE

Type 1 Hypervisor หรือ Bare-metal Hypervisor คือ Hypervisor ที่ติดตั้งโดยตรงบนฮาร์ดแวร์ทางกายภาพ โดยไม่ต้องมี Host OS รองรับ ทำให้มีประสิทธิภาพสูงและ Overhead ต่ำ เหมาะสำหรับ Production Server และ Data Center

ตัวอย่าง Type 1 Hypervisor ที่นิยมใช้

10.1.3 Type 2 Hypervisor (Hosted): VirtualBox, VMware Workstation/Fusion, Parallels

Type 2 Hypervisor หรือ Hosted Hypervisor คือ Hypervisor ที่ติดตั้งเป็นโปรแกรมบน Host OS เช่น Windows, macOS, Linux ใช้งานง่าย เหมาะสำหรับ Desktop, การพัฒนาซอฟต์แวร์, และการเรียนการสอน แต่มี Overhead สูงกว่า Type 1 เพราะต้องผ่านชั้น Host OS

ตัวอย่าง Type 2 Hypervisor

คุณสมบัติ Type 1 (Bare-metal) Type 2 (Hosted)
ตำแหน่งติดตั้ง บน Hardware โดยตรง บน Host OS
Overhead ต่ำ สูงกว่า
ประสิทธิภาพ สูง ปานกลาง
ความซับซ้อนในการติดตั้ง สูง ง่าย
Use Case Production, Data Center Desktop, Development
ตัวอย่าง ESXi, KVM, Hyper-V, Xen VirtualBox, VMware Workstation

10.1.4 Full Virtualization vs Paravirtualization vs Hardware-assisted (Intel VT-x, AMD-V, VT-d, IOMMU)

ประเภทของ Virtualization Technique

  1. Full Virtualization (การจำลองสมบูรณ์): Guest OS ไม่ต้องรู้ว่าตัวเองทำงานอยู่บน VM โดย Hypervisor จะจำลอง Hardware ทั้งหมดผ่าน Binary Translation หรือ Trap-and-Emulate ทำให้ Guest OS ดั้งเดิมรันได้โดยไม่ต้องแก้ไข แต่มี Overhead สูง
  2. Paravirtualization (การจำลองบางส่วน): Guest OS รับรู้ว่าทำงานอยู่บน VM และมีการแก้ไข Kernel ให้เรียก Hypercall แทน Privileged Instruction ทำให้ประสิทธิภาพดีกว่า Full Virtualization แต่ต้องดัดแปลง Guest OS เช่น Xen PV
  3. Hardware-assisted Virtualization: ใช้คำสั่งพิเศษใน CPU เช่น Intel VT-x หรือ AMD-V ที่ช่วยให้ Hypervisor ทำงานในโหมดพิเศษ (Root Mode) และ Guest ทำงานใน Non-root Mode ทำให้ประสิทธิภาพใกล้เคียง Native

เทคโนโลยี Hardware Support

สมการเปรียบเทียบ Performance Overhead

PVM = PNative × ( 1 Ohyp )

โดยที่:

10.1.5 Container vs VM (เทียบ overhead, isolation, boot time)

Container และ Virtual Machine เป็นเทคโนโลยี Isolation ที่แตกต่างกันในระดับความลึกและกลไก

คุณสมบัติ Virtual Machine Container
ระดับการแยก (Isolation Level) Hardware-level Process-level
ขนาด Image GB (1-100+) MB (10-500)
เวลา Boot นาที (1-5 นาที) วินาที (1-5 วินาที)
OS Kernel แต่ละ VM มี Kernel ของตัวเอง ใช้ Kernel ของ Host ร่วมกัน
Resource Overhead สูง ต่ำมาก
Security Isolation แข็งแรงกว่า อ่อนกว่า (อาศัย Namespace, cgroups)
Use Case ต่าง OS, Workload หนัก, Legacy App Microservices, CI/CD, Cloud-native
ตัวอย่าง VirtualBox, VMware, KVM Docker, Podman, LXC
flowchart LR
    subgraph VMArch["VM Architecture"]
        VMHW[Hardware]
        VMHV[Hypervisor]
        VMG1[Guest OS 1
+ Bins/Libs
+ App] VMG2[Guest OS 2
+ Bins/Libs
+ App] VMHW --> VMHV VMHV --> VMG1 VMHV --> VMG2 end subgraph CTArch["Container Architecture"] CTHW[Hardware] CTOS[Host OS Kernel] CTRT[Container Runtime
เช่น containerd] CT1[Container 1
Bins/Libs + App] CT2[Container 2
Bins/Libs + App] CT3[Container 3
Bins/Libs + App] CTHW --> CTOS CTOS --> CTRT CTRT --> CT1 CTRT --> CT2 CTRT --> CT3 end

10.2 พื้นฐาน Virtual Machine (Virtual Machine Fundamentals)

ในส่วนนี้จะกล่าวถึงองค์ประกอบพื้นฐานของ Virtual Machine ตั้งแต่ทรัพยากรเสมือน, รูปแบบไฟล์ Disk Image, Snapshot และ Clone ไปจนถึงการเพิ่มประสิทธิภาพด้วย Guest Tools

10.2.1 Virtual CPU, RAM, Disk, Network, Display

ทรัพยากรหลักของ VM ที่ Hypervisor จำลองให้กับ Guest OS

สมการคำนวณ CPU Overcommit Ratio

R = vCPUi CPUphysical

โดยที่:

10.2.2 Disk Image Format: VDI, VMDK, QCOW2, RAW, VHD

รูปแบบไฟล์ Virtual Disk ที่นิยมใช้ในปัจจุบัน

Format เจ้าของ คุณสมบัติเด่น นามสกุล
VDI (VirtualBox Disk Image) Oracle Native ของ VirtualBox, รองรับ Snapshot .vdi
VMDK (Virtual Machine Disk) VMware มาตรฐานเปิด, รองรับโดย VMware/VirtualBox .vmdk
QCOW2 (QEMU Copy-on-Write v2) QEMU Snapshot, Compression, Encryption, Sparse .qcow2
RAW - ประสิทธิภาพสูงสุด, ไม่มี Feature เพิ่มเติม .raw, .img
VHD/VHDX Microsoft ใช้ใน Hyper-V, Azure .vhd, .vhdx

ตัวอย่างคำสั่งจัดการ Disk Image ด้วย qemu-img

# สร้าง qcow2 image ขนาด 20GB (sparse - ใช้พื้นที่เท่าที่ต้องการ)
qemu-img create -f qcow2 ubuntu.qcow2 20G

# แปลง raw เป็น qcow2
qemu-img convert -f raw -O qcow2 disk.img disk.qcow2

# แสดงข้อมูลของ image
qemu-img info ubuntu.qcow2

# ขยายขนาด disk เพิ่มอีก 10GB
qemu-img resize ubuntu.qcow2 +10G

# สร้าง snapshot
qemu-img snapshot -c snap1 ubuntu.qcow2

# แสดงรายการ snapshot
qemu-img snapshot -l ubuntu.qcow2

# ย้อนกลับ snapshot
qemu-img snapshot -a snap1 ubuntu.qcow2

10.2.3 Snapshot vs Clone (Linked Clone, Full Clone)

Snapshot คือการบันทึกสถานะของ VM ณ เวลาใดเวลาหนึ่ง รวมทั้ง Disk, RAM (optional), CPU State สามารถย้อนกลับ (Revert) ได้ทุกเมื่อ ใช้กลไก Copy-on-Write (CoW) เพื่อประหยัดพื้นที่

Clone คือการคัดลอก VM เพื่อสร้าง VM ใหม่ที่เหมือนกัน มี 2 แบบ

  1. Full Clone: คัดลอกข้อมูลทั้งหมด VM ใหม่เป็นอิสระจากต้นฉบับ ใช้พื้นที่มาก แต่ Performance เต็มที่
  2. Linked Clone: สร้าง Differential Disk ที่ชี้กลับไปยัง Base Disk ของ VM ต้นฉบับ ใช้พื้นที่น้อย เร็ว แต่ลบ Base ไม่ได้
flowchart TD
    Base[Base VM
ต้นฉบับ 20GB] Snap1[Snapshot 1
Delta 200MB] Snap2[Snapshot 2
Delta 500MB] Current[Current State] Linked[Linked Clone
Delta 100MB] Full[Full Clone
Copy 20GB] Base --> Snap1 Snap1 --> Snap2 Snap2 --> Current Base -.อ้างอิง.-> Linked Base ==คัดลอก==> Full

10.2.4 Thin vs Thick Provisioning

Thin Provisioning (Sparse): จัดสรรพื้นที่จริงเท่าที่ใช้งาน หากสร้าง Disk 100GB แต่ใช้ 5GB ก็จะกินพื้นที่ Host เพียง 5GB ทำให้ใช้ Storage มีประสิทธิภาพ แต่อาจทำ Overcommit จนเต็ม

Thick Provisioning: จองพื้นที่เต็มขนาดตั้งแต่ตอนสร้าง มี 2 แบบ

# สร้าง thin-provisioned qcow2 disk 100GB (จะใช้พื้นที่จริงเท่าที่ต้องการ)
qemu-img create -f qcow2 thin_disk.qcow2 100G

# สร้าง thick-provisioned raw disk 10GB (จองพื้นที่เต็ม)
qemu-img create -f raw -o preallocation=full thick_disk.raw 10G

# ตรวจสอบขนาดจริงด้วย du และ ls
du -h thin_disk.qcow2     # แสดงขนาดที่ใช้จริง (อาจเพียง 200KB)
ls -lh thin_disk.qcow2    # แสดงขนาดที่กำหนด (100GB)

10.2.5 Guest Additions / VMware Tools / SPICE Agent

Guest Tools คือซอฟต์แวร์เสริมที่ติดตั้งบน Guest OS เพื่อเพิ่มประสิทธิภาพและฟีเจอร์การใช้งานร่วมกับ Host

ฟีเจอร์ที่ Guest Tools มอบให้

Hypervisor Guest Tools ที่ใช้
VirtualBox VirtualBox Guest Additions
VMware VMware Tools / open-vm-tools
QEMU/KVM qemu-guest-agent + SPICE Agent
Hyper-V Hyper-V Integration Services
Parallels Parallels Tools
# ติดตั้ง VirtualBox Guest Additions บน Ubuntu Guest
sudo apt update
sudo apt install -y build-essential dkms linux-headers-$(uname -r)
# จากนั้น mount ISO Guest Additions จากเมนู Devices > Insert Guest Additions CD image
sudo mount /dev/cdrom /mnt
sudo /mnt/VBoxLinuxAdditions.run

# ติดตั้ง qemu-guest-agent บน Ubuntu Guest (สำหรับ QEMU/KVM)
sudo apt install -y qemu-guest-agent spice-vdagent
sudo systemctl enable --now qemu-guest-agent
sudo systemctl enable --now spice-vdagent

10.3 VirtualBox

Oracle VirtualBox เป็น Type 2 Hypervisor แบบ Open Source ที่ได้รับความนิยมสูงในงาน Desktop Virtualization, การเรียนการสอน, และการทดสอบซอฟต์แวร์ รองรับ Host หลายแพลตฟอร์ม (Windows, macOS, Linux, Solaris) และ Guest OS หลากหลาย

10.3.1 การติดตั้ง VirtualBox และ Extension Pack

การติดตั้ง VirtualBox บนระบบปฏิบัติการต่าง ๆ

# Ubuntu/Debian
sudo apt update
sudo apt install -y virtualbox virtualbox-ext-pack

# Fedora/RHEL (ผ่าน Oracle Repository)
sudo dnf install -y https://download.virtualbox.org/virtualbox/7.0.20/VirtualBox-7.0-7.0.20_163906_fedora39-1.x86_64.rpm

# Arch Linux
sudo pacman -S virtualbox virtualbox-host-modules-arch virtualbox-guest-iso

# โหลด Kernel Module
sudo modprobe vboxdrv

# เพิ่ม user เข้า group vboxusers (สำหรับการใช้ USB Passthrough)
sudo usermod -aG vboxusers $USER

# ตรวจสอบ version
VBoxManage --version

Extension Pack เป็น Plugin เสริมที่ให้ฟีเจอร์เพิ่มเติม เช่น

หมายเหตุ: Extension Pack มี License แบบ PUEL (Personal Use and Evaluation License) สำหรับการใช้ส่วนตัวและประเมินผลฟรี แต่ใช้เชิงพาณิชย์ต้องซื้อ License

10.3.2 การสร้าง VM ใหม่ (Wizard)

ขั้นตอนการสร้าง VM ผ่าน VirtualBox GUI

  1. คลิก New หรือกด Ctrl+N
  2. ตั้งชื่อ VM และเลือก Type (Linux, Windows, BSD, ฯลฯ) และ Version
  3. กำหนด Memory Size (RAM) - แนะนำ 2GB สำหรับ Linux, 4GB ขึ้นไปสำหรับ Windows
  4. สร้าง Virtual Hard Disk - เลือก VDI Format, Dynamically Allocated, ขนาด 20-50GB
  5. ปรับแต่ง Settings: CPU, Network, Storage, Display ก่อนเริ่มใช้งาน
  6. คลิก Start และเลือก ISO เพื่อ Boot ติดตั้ง OS

10.3.3 การตั้งค่า Hardware: CPU, Memory, Video, Storage Controller

การตั้งค่าฮาร์ดแวร์เสมือนใน VirtualBox

10.3.4 Network Mode: NAT, NAT Network, Bridged, Host-only, Internal Network

VirtualBox รองรับโหมดเครือข่าย 6 แบบหลัก ๆ ที่ใช้กันบ่อย

Mode Outbound Inbound VM-to-VM Host-to-VM VM-to-Host
NAT ❌ (ต้อง Port Forward)
NAT Network ❌ (ต้อง Port Forward)
Bridged
Host-only
Internal
Generic Driver ขึ้นกับ Driver ขึ้นกับ Driver ขึ้นกับ Driver ขึ้นกับ Driver ขึ้นกับ Driver
flowchart LR
    Internet[Internet
เครือข่ายภายนอก] Router[Physical Router] Host[Host Machine] NAT[VirtualBox NAT
10.0.2.0/24] Bridge[Bridged
Direct Access] HostOnly[Host-only
192.168.56.0/24] VM1[VM1: NAT Mode
10.0.2.15] VM2[VM2: Bridged
192.168.1.50] VM3[VM3: Host-only
192.168.56.10] Internet --- Router Router --- Host Host --- NAT Host --- Bridge Host --- HostOnly NAT --- VM1 Bridge --- VM2 HostOnly --- VM3

10.3.5 Shared Folder, Shared Clipboard, Drag & Drop

Shared Folder ช่วยให้ Guest เข้าถึง Folder ของ Host ได้

# บน Host - กำหนด Shared Folder ผ่าน VBoxManage
VBoxManage sharedfolder add "MyVM" --name "shared" --hostpath "/home/user/shared" --automount

# บน Linux Guest - mount แบบ manual
sudo mount -t vboxsf shared /mnt/shared

# หรือเพิ่มใน /etc/fstab สำหรับ auto-mount
shared /mnt/shared vboxsf defaults,uid=1000,gid=1000 0 0

การเปิด Shared Clipboard และ Drag and Drop ทำได้ผ่านเมนู Devices > Shared Clipboard / Drag and Drop > Bidirectional

10.3.6 Guest Additions

Guest Additions เป็นชุด Driver และเครื่องมือที่ติดตั้งบน Guest OS เพื่อเพิ่มประสิทธิภาพและฟีเจอร์การใช้งาน

# ติดตั้ง Guest Additions บน Ubuntu Guest
# 1. เลือก Devices > Insert Guest Additions CD image จากเมนู VirtualBox
# 2. รันคำสั่งต่อไปนี้บน Guest

sudo apt update
sudo apt install -y build-essential dkms linux-headers-$(uname -r)

sudo mkdir -p /mnt/cdrom
sudo mount /dev/cdrom /mnt/cdrom
cd /mnt/cdrom
sudo ./VBoxLinuxAdditions.run

# Reboot เพื่อใช้งาน
sudo reboot

# ตรวจสอบหลัง reboot
lsmod | grep vbox
# ควรเห็น: vboxsf, vboxvideo, vboxguest

10.3.7 Snapshot Management

# สร้าง Snapshot
VBoxManage snapshot "MyVM" take "before-update" --description "ก่อนติดตั้ง update"

# แสดงรายการ Snapshot
VBoxManage snapshot "MyVM" list

# ย้อนกลับไป Snapshot
VBoxManage controlvm "MyVM" poweroff
VBoxManage snapshot "MyVM" restore "before-update"

# ลบ Snapshot (Merge เข้า parent)
VBoxManage snapshot "MyVM" delete "before-update"

10.3.8 Import / Export OVA / OVF

OVA (Open Virtualization Appliance) และ OVF (Open Virtualization Format) เป็นมาตรฐานเปิดสำหรับ Package VM ให้พกพาข้าม Hypervisor ได้

# Export VM เป็นไฟล์ OVA
VBoxManage export "MyVM" -o MyVM.ova \
    --vsys 0 \
    --product "My Application" \
    --producturl "https://example.com" \
    --vendor "MyCompany" \
    --version "1.0"

# Import จากไฟล์ OVA
VBoxManage import MyVM.ova --vsys 0 --vmname "ImportedVM"

# Import พร้อมปรับ CPU และ Memory
VBoxManage import MyVM.ova \
    --vsys 0 \
    --vmname "NewVM" \
    --cpus 4 \
    --memory 4096

10.3.9 VBoxManage Command-line

VBoxManage เป็น CLI Tool ที่ทรงพลังสำหรับจัดการ VirtualBox โดยไม่ต้องใช้ GUI

#!/bin/bash
# สคริปต์ตัวอย่าง: สร้าง VM Ubuntu Server แบบ headless

VM_NAME="ubuntu-server"
ISO_PATH="$HOME/iso/ubuntu-22.04-live-server-amd64.iso"
DISK_SIZE=20000  # 20GB (หน่วย MB)
RAM_SIZE=2048    # 2GB
CPU_COUNT=2

# 1. สร้าง VM
VBoxManage createvm --name "$VM_NAME" --ostype "Ubuntu_64" --register

# 2. ตั้งค่า Memory และ CPU
VBoxManage modifyvm "$VM_NAME" \
    --memory $RAM_SIZE \
    --cpus $CPU_COUNT \
    --vram 16 \
    --graphicscontroller vmsvga \
    --boot1 dvd --boot2 disk \
    --nic1 nat \
    --audio none

# 3. สร้างและเชื่อม Hard Disk
VM_DIR=$(VBoxManage showvminfo "$VM_NAME" --machinereadable | grep CfgFile | cut -d'"' -f2 | xargs dirname)
VBoxManage createhd --filename "$VM_DIR/$VM_NAME.vdi" --size $DISK_SIZE
VBoxManage storagectl "$VM_NAME" --name "SATA" --add sata --controller IntelAhci
VBoxManage storageattach "$VM_NAME" --storagectl "SATA" --port 0 --device 0 --type hdd --medium "$VM_DIR/$VM_NAME.vdi"

# 4. แนบ ISO สำหรับติดตั้ง
VBoxManage storagectl "$VM_NAME" --name "IDE" --add ide --controller PIIX4
VBoxManage storageattach "$VM_NAME" --storagectl "IDE" --port 0 --device 0 --type dvddrive --medium "$ISO_PATH"

# 5. Forward Port SSH
VBoxManage modifyvm "$VM_NAME" --natpf1 "ssh,tcp,,2222,,22"

# 6. Boot แบบ headless
VBoxManage startvm "$VM_NAME" --type headless

echo "✅ VM $VM_NAME เริ่มทำงานแล้ว"
echo "📡 SSH: ssh -p 2222 user@localhost"

10.4 QEMU (Quick EMUlator)

QEMU เป็น Open Source Machine Emulator และ Virtualizer ที่ทรงพลังที่สุดตัวหนึ่ง รองรับสถาปัตยกรรม CPU หลากหลาย (x86, ARM, RISC-V, PowerPC, MIPS, SPARC) สามารถทำงานทั้งแบบ Pure Emulation (ช้าแต่ Cross-architecture) และร่วมกับ KVM เพื่อทำ Hardware-assisted Virtualization บน Linux

10.4.1 ประวัติและสถาปัตยกรรม

QEMU ถูกสร้างโดย Fabrice Bellard ในปี 2003 (ผู้สร้าง FFmpeg, TCC) เพื่อเป็น Generic Machine Emulator แบบ Open Source

flowchart TB
    subgraph Era1["ค.ศ. 2003-2007: Pure Emulation Era"]
        E1[QEMU 0.x
Bellard เริ่มต้น] E2[TCG
Tiny Code Generator] E3[KQEMU
Kernel Accelerator] end subgraph Era2["ค.ศ. 2007-2012: KVM Integration"] K1[KVM 2007
Avi Kivity] K2[QEMU + KVM
Hardware Acceleration] K3[libvirt 2008
Management Layer] end subgraph Era3["ค.ศ. 2012-2020: Modern Features"] M1[virtio paravirt] M2[Live Migration] M3[SPICE Display] M4[QMP Protocol] end subgraph Era4["ค.ศ. 2020-ปัจจุบัน: Cloud Native"] N1[microvm
Firecracker] N2[Confidential VM
SEV/TDX] N3[ARM64 Native] N4[RISC-V Support] end Era1 --> Era2 --> Era3 --> Era4

10.4.2 Emulation vs Virtualization mode

QEMU ทำงานได้สองโหมดหลัก

  1. Full System Emulation (qemu-system-*): จำลอง CPU และฮาร์ดแวร์ทั้งระบบ ใช้ TCG (Tiny Code Generator) แปลคำสั่ง Guest เป็น Host แบบ Just-in-Time สามารถรัน OS ของ Architecture ที่ต่างกันได้ เช่น รัน ARM Linux บน x86 Host
  2. User Mode Emulation (qemu-*): รันโปรแกรมของ Architecture อื่นบน Linux Host เช่น รัน ARM Binary บน x86 Linux โดยใช้ Linux Kernel ของ Host ใช้ใน QEMU User Mode + binfmt_misc เพื่อรัน Container Multi-arch

10.4.3 QEMU + KVM (Hardware Acceleration on Linux)

เมื่อ Host เป็น Linux + CPU มี VT-x/AMD-V การใช้ KVM ร่วมกับ QEMU จะทำให้ประสิทธิภาพใกล้เคียง Native

# ตรวจสอบว่า CPU รองรับ Virtualization
egrep -c '(vmx|svm)' /proc/cpuinfo
# ถ้าผลลัพธ์ > 0 แสดงว่ารองรับ

# ตรวจสอบว่า KVM Module โหลดอยู่
lsmod | grep kvm
# ควรเห็น: kvm_intel หรือ kvm_amd

# ถ้ายังไม่โหลด
sudo modprobe kvm
sudo modprobe kvm_intel   # หรือ kvm_amd

# ติดตั้ง QEMU + KVM
# Ubuntu/Debian
sudo apt install -y qemu-system-x86 qemu-utils qemu-kvm

# Fedora/RHEL
sudo dnf install -y qemu-kvm qemu-img

# Arch
sudo pacman -S qemu-full

# เพิ่ม user เข้า group kvm
sudo usermod -aG kvm,libvirt $USER

# ตรวจสอบ KVM device
ls -la /dev/kvm
# ควรเห็น: crw-rw---- 1 root kvm

10.4.4 qemu-img: create, convert, resize, snapshot

# สร้าง qcow2 disk ขนาด 20GB พร้อม encryption
qemu-img create -f qcow2 -o encrypt.format=luks,encrypt.key-secret=sec0 \
    --object secret,id=sec0,data=mypassword \
    encrypted.qcow2 20G

# แปลง vmdk → qcow2 (ใช้กับ VM ที่ migrate จาก VMware)
qemu-img convert -p -f vmdk -O qcow2 source.vmdk target.qcow2
# -p คือ progress bar

# Compress qcow2 ให้เล็กลง
qemu-img convert -O qcow2 -c original.qcow2 compressed.qcow2

# ตรวจสอบ Integrity ของ Image
qemu-img check ubuntu.qcow2

# Rebase qcow2 (เปลี่ยน backing file)
qemu-img rebase -b new_base.qcow2 child.qcow2

# วัด actual disk usage
qemu-img info --backing-chain disk.qcow2

10.4.5 qemu-system-x86_64 options: -m, -smp, -drive, -netdev, -boot, -display, -enable-kvm

Option หลักของ qemu-system-x86_64

10.4.6 การสร้างและ boot VM จาก ISO

#!/bin/bash
# ตัวอย่างการติดตั้ง Ubuntu Server บน QEMU/KVM

VM_NAME="ubuntu-test"
ISO="ubuntu-22.04-live-server-amd64.iso"
DISK="${VM_NAME}.qcow2"
DISK_SIZE="20G"
RAM="4G"
CPUS="4"

# 1. สร้าง qcow2 disk
qemu-img create -f qcow2 "$DISK" "$DISK_SIZE"

# 2. Boot จาก ISO เพื่อติดตั้ง
qemu-system-x86_64 \
    -name "$VM_NAME" \
    -enable-kvm \
    -cpu host \
    -smp "$CPUS" \
    -m "$RAM" \
    -drive file="$DISK",format=qcow2,if=virtio \
    -cdrom "$ISO" \
    -boot order=d \
    -netdev user,id=net0,hostfwd=tcp::2222-:22 \
    -device virtio-net-pci,netdev=net0 \
    -vga virtio \
    -display gtk,gl=on \
    -usb -device usb-tablet

# 3. หลังติดตั้งเสร็จ Boot จาก disk แทน
qemu-system-x86_64 \
    -name "$VM_NAME" \
    -enable-kvm \
    -cpu host \
    -smp "$CPUS" \
    -m "$RAM" \
    -drive file="$DISK",format=qcow2,if=virtio \
    -boot order=c \
    -netdev user,id=net0,hostfwd=tcp::2222-:22 \
    -device virtio-net-pci,netdev=net0 \
    -vga virtio \
    -display gtk,gl=on

echo "📡 SSH เข้า VM: ssh -p 2222 user@localhost"

10.4.7 การเข้าถึง Console: SDL, GTK, VNC, SPICE

โหมดแสดงผลของ QEMU

Display คุณสมบัติ Use Case
none ไม่มีจอภาพ (Headless) Server, CI/CD
sdl SDL Window Local Desktop
gtk GTK Window พร้อมเมนู Linux Desktop
vnc เข้าผ่าน VNC Protocol Remote Access
spice SPICE Protocol ประสิทธิภาพดีกว่า VNC Remote Desktop
curses Text Terminal SSH Session
# Headless mode + VNC
qemu-system-x86_64 \
    -enable-kvm -m 2G -smp 2 \
    -drive file=disk.qcow2,if=virtio \
    -display none \
    -vnc :1 \
    -daemonize
# เชื่อมต่อด้วย: vncviewer localhost:5901

# SPICE mode พร้อม USB redirection
qemu-system-x86_64 \
    -enable-kvm -m 4G -smp 4 \
    -drive file=disk.qcow2,if=virtio \
    -spice port=5930,disable-ticketing=on \
    -device virtio-serial-pci \
    -device virtserialport,chardev=spicechannel0,name=com.redhat.spice.0 \
    -chardev spicevmc,id=spicechannel0,name=vdagent
# เชื่อมต่อด้วย: remote-viewer spice://localhost:5930

10.4.8 Serial Console

Serial Console ทำให้สามารถเข้าถึง VM ผ่าน Text Terminal ได้ เหมาะสำหรับ Server, การ Debug, และ Headless

# QEMU + Serial Console
qemu-system-x86_64 \
    -enable-kvm -m 2G -smp 2 \
    -drive file=disk.qcow2,if=virtio \
    -nographic \
    -serial mon:stdio \
    -append "console=ttyS0,115200n8 root=/dev/vda1"

# ภายใน Linux Guest ต้องตั้งค่า Kernel Boot Parameter
# แก้ไข /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="console=tty1 console=ttyS0,115200n8"
GRUB_TERMINAL="serial console"
GRUB_SERIAL_COMMAND="serial --unit=0 --speed=115200"

# จากนั้น
sudo update-grub  # Debian/Ubuntu
# หรือ
sudo grub2-mkconfig -o /boot/grub2/grub.cfg  # RHEL/Fedora

# Enable getty บน serial port
sudo systemctl enable serial-getty@ttyS0.service
sudo systemctl start serial-getty@ttyS0.service

หมายเหตุ: ในโหมด -nographic กด Ctrl+A จากนั้น X เพื่อออกจาก QEMU, Ctrl+A C เพื่อเข้า QEMU Monitor


10.5 libvirt และ virt-manager

libvirt คือ Toolkit และ API มาตรฐานสำหรับจัดการ Virtualization ที่รองรับ Hypervisor หลายตัว (KVM/QEMU, Xen, LXC, VirtualBox, VMware ESXi, Hyper-V) โดยใช้ Domain XML เป็นตัวกำหนดค่า VM และมี virt-manager เป็น GUI Tool ที่ทำให้การจัดการง่ายขึ้น

10.5.1 libvirtd และ virsh (Command-line)

libvirtd คือ Daemon ที่ทำงานเบื้องหลัง รับคำสั่งผ่าน Unix Socket หรือ TCP/TLS และสั่งงาน Hypervisor ที่อยู่ใต้

# ติดตั้ง libvirt + KVM stack
# Ubuntu/Debian
sudo apt install -y qemu-kvm libvirt-daemon-system libvirt-clients \
    bridge-utils virt-manager virtinst libosinfo-bin

# Fedora/RHEL
sudo dnf install -y @virtualization

# Arch
sudo pacman -S qemu-full libvirt virt-manager dnsmasq bridge-utils

# Enable และ Start service
sudo systemctl enable --now libvirtd

# เพิ่ม user เข้า group
sudo usermod -aG libvirt,kvm $USER
newgrp libvirt

# ตรวจสอบสถานะ
virsh list --all
virsh nodeinfo
virsh capabilities | head -50

คำสั่ง virsh ที่ใช้บ่อย

# จัดการ Domain (VM)
virsh list                            # แสดง VM ที่กำลังรัน
virsh list --all                      # แสดงทั้งหมด
virsh start <vm>                      # เริ่ม VM
virsh shutdown <vm>                   # ปิดแบบ graceful
virsh destroy <vm>                    # บังคับปิด
virsh reboot <vm>                     # รีบูต
virsh undefine <vm> --remove-all-storage  # ลบ VM พร้อม disk

# ดูข้อมูล
virsh dominfo <vm>                    # ข้อมูลทั่วไป
virsh dumpxml <vm>                    # ดู XML
virsh edit <vm>                       # แก้ไข XML
virsh console <vm>                    # เข้า Serial Console (Ctrl+] เพื่อออก)

# Snapshot
virsh snapshot-create-as <vm> snap1 "Description"
virsh snapshot-list <vm>
virsh snapshot-revert <vm> snap1
virsh snapshot-delete <vm> snap1

# Resource
virsh setmem <vm> 4G --config         # ตั้ง memory
virsh setvcpus <vm> 4 --config        # ตั้ง vCPU
virsh autostart <vm>                  # เปิด autostart

10.5.2 virt-manager (GUI)

virt-manager เป็น GTK GUI สำหรับจัดการ VM ผ่าน libvirt มีฟีเจอร์

10.5.3 virt-install

virt-install เป็น CLI ที่ใช้สร้าง VM ใหม่ผ่าน libvirt อย่างรวดเร็ว

# สร้าง Ubuntu Server VM แบบอัตโนมัติด้วย Cloud-init
virt-install \
    --name ubuntu-22 \
    --memory 4096 \
    --vcpus 2 \
    --disk path=/var/lib/libvirt/images/ubuntu-22.qcow2,size=20,bus=virtio \
    --os-variant ubuntu22.04 \
    --network network=default,model=virtio \
    --graphics spice \
    --cdrom /var/lib/libvirt/iso/ubuntu-22.04-live-server-amd64.iso \
    --noautoconsole

# สร้าง VM แบบ PXE Boot
virt-install \
    --name pxe-vm \
    --memory 2048 --vcpus 2 \
    --disk size=10 \
    --network network=default,model=virtio \
    --pxe \
    --os-variant generic

# Import VM จาก qcow2 ที่มีอยู่
virt-install \
    --name imported-vm \
    --memory 2048 --vcpus 2 \
    --disk path=/path/to/existing.qcow2 \
    --import \
    --os-variant ubuntu22.04 \
    --network network=default

10.5.4 Domain XML

Domain XML คือไฟล์ XML ที่อธิบายโครงสร้าง VM ทั้งหมด

<!-- ตัวอย่าง Domain XML แบบเรียบง่าย -->
<domain type='kvm'>
  <name>my-server</name>
  <uuid>4dea22b3-1d52-d8f3-2516-782e98ab3fa0</uuid>
  <memory unit='KiB'>4194304</memory>          <!-- 4 GB -->
  <currentMemory unit='KiB'>4194304</currentMemory>
  <vcpu placement='static'>2</vcpu>
  <os>
    <type arch='x86_64' machine='pc-q35-7.2'>hvm</type>
    <boot dev='hd'/>
    <boot dev='cdrom'/>
  </os>
  <features>
    <acpi/>
    <apic/>
    <vmport state='off'/>
  </features>
  <cpu mode='host-passthrough' check='none' migratable='on'/>
  <clock offset='utc'>
    <timer name='rtc' tickpolicy='catchup'/>
    <timer name='pit' tickpolicy='delay'/>
    <timer name='hpet' present='no'/>
  </clock>
  <devices>
    <emulator>/usr/bin/qemu-system-x86_64</emulator>
    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2' discard='unmap'/>
      <source file='/var/lib/libvirt/images/my-server.qcow2'/>
      <target dev='vda' bus='virtio'/>
    </disk>
    <interface type='network'>
      <source network='default'/>
      <model type='virtio'/>
    </interface>
    <serial type='pty'>
      <target type='isa-serial' port='0'/>
    </serial>
    <console type='pty'>
      <target type='serial' port='0'/>
    </console>
    <graphics type='spice' autoport='yes'>
      <listen type='address'/>
      <image compression='off'/>
    </graphics>
    <video>
      <model type='virtio' heads='1' primary='yes'/>
    </video>
  </devices>
</domain>

10.5.5 Storage Pool (dir, lvm, nfs, gluster, rbd) และ Volume

Storage Pool คือแหล่งเก็บ Virtual Disk ของ VM โดย libvirt รองรับหลายประเภท

Pool Type คำอธิบาย Use Case
dir Directory บน filesystem Default, ทดสอบ
fs Mount filesystem แยก Storage
logical LVM Volume Group Performance
disk Physical Disk Direct Access
iscsi iSCSI Target SAN
netfs NFS, GlusterFS Shared Storage
rbd Ceph RBD Cloud Storage
zfs ZFS ZFS Features
# สร้าง Storage Pool แบบ dir
virsh pool-define-as mypool dir - - - - "/var/lib/libvirt/images/mypool"
virsh pool-build mypool
virsh pool-start mypool
virsh pool-autostart mypool

# สร้าง Volume ใน Pool
virsh vol-create-as mypool myvm.qcow2 20G --format qcow2

# แสดงรายการ Volume
virsh vol-list mypool

# ลบ Volume
virsh vol-delete --pool mypool myvm.qcow2

# ดูข้อมูล Pool
virsh pool-info mypool

10.5.6 Virtual Network: NAT, Routed, Bridge, Isolated

<!-- ตัวอย่าง NAT Network (default) -->
<network>
  <name>default</name>
  <forward mode='nat'>
    <nat>
      <port start='1024' end='65535'/>
    </nat>
  </forward>
  <bridge name='virbr0' stp='on' delay='0'/>
  <ip address='192.168.122.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.122.2' end='192.168.122.254'/>
    </dhcp>
  </ip>
</network>

<!-- ตัวอย่าง Isolated Network -->
<network>
  <name>isolated</name>
  <bridge name='virbr1' stp='on' delay='0'/>
  <ip address='10.10.10.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='10.10.10.100' end='10.10.10.200'/>
    </dhcp>
  </ip>
</network>
# สร้าง Network
virsh net-define isolated.xml
virsh net-start isolated
virsh net-autostart isolated

# แสดงรายการ Network
virsh net-list --all

# DHCP Lease ปัจจุบัน
virsh net-dhcp-leases default

10.5.7 Autostart, Persistent vs Transient

# เปิด Autostart
virsh autostart my-vm

# ปิด Autostart
virsh autostart --disable my-vm

# สร้าง Transient VM
virsh create my-vm.xml

# Define Persistent VM
virsh define my-vm.xml

10.6 Virtual Networking ขั้นสูง (Advanced Virtual Networking)

ระบบเครือข่ายเสมือน (Virtual Networking) เป็นหัวใจของ Virtualization โดยเฉพาะในงาน Lab, Cloud, และ NFV (Network Function Virtualization) ในส่วนนี้จะกล่าวถึงเทคโนโลยีระดับ Linux Kernel จนถึง Hardware Passthrough

Linux Bridge คือ Software Switch ที่ทำงานในระดับ Layer 2 ใน Linux Kernel ใช้เชื่อม VM, Container, และ Physical Interface เข้าด้วยกัน

# สร้าง bridge ใหม่ด้วย ip command (modern)
sudo ip link add name br0 type bridge
sudo ip link set br0 up

# กำหนด IP ให้ bridge
sudo ip addr add 192.168.100.1/24 dev br0

# เพิ่ม physical interface เข้า bridge
sudo ip link set eth0 master br0

# แสดงโครงสร้าง bridge
sudo bridge link show
ip link show master br0

# ลบ interface ออกจาก bridge
sudo ip link set eth0 nomaster

# ลบ bridge
sudo ip link set br0 down
sudo ip link delete br0 type bridge

# ตรวจสอบ MAC table
sudo bridge fdb show br br0

# brctl (legacy แต่ยังพบบ่อย)
sudo brctl show
sudo brctl addbr br0
sudo brctl addif br0 eth0

10.6.2 TAP/TUN Interface

# สร้าง TAP interface สำหรับ VM
sudo ip tuntap add mode tap user $USER name tap0
sudo ip link set tap0 master br0
sudo ip link set tap0 up

# ใช้ TAP กับ QEMU
qemu-system-x86_64 \
    -enable-kvm -m 2G \
    -drive file=disk.qcow2,if=virtio \
    -netdev tap,id=net0,ifname=tap0,script=no,downscript=no \
    -device virtio-net-pci,netdev=net0,mac=52:54:00:12:34:56

# ลบ TAP
sudo ip link delete tap0

10.6.3 Open vSwitch เบื้องต้น

Open vSwitch (OVS) คือ Software-Defined Switch ที่รองรับฟีเจอร์ขั้นสูงเช่น OpenFlow, VLAN, VXLAN, GRE Tunnel เหมาะกับ Cloud และ Network Virtualization

# ติดตั้ง Open vSwitch
sudo apt install -y openvswitch-switch

# สร้าง bridge แบบ OVS
sudo ovs-vsctl add-br ovs-br0

# เพิ่ม port
sudo ovs-vsctl add-port ovs-br0 eth1

# กำหนด VLAN tag ให้ port
sudo ovs-vsctl set port eth1 tag=100

# แสดงโครงสร้าง
sudo ovs-vsctl show

# สร้าง VXLAN Tunnel
sudo ovs-vsctl add-port ovs-br0 vxlan0 \
    -- set interface vxlan0 type=vxlan \
    options:remote_ip=10.0.0.2 options:key=42

10.6.4 VLAN ใน VM

VLAN (Virtual LAN) ใช้แบ่งเครือข่าย Layer 2 ออกเป็นหลายส่วนบน Physical Switch เดียวกัน โดยใช้ Tag (IEEE 802.1Q)

# สร้าง VLAN sub-interface บน Linux
sudo ip link add link eth0 name eth0.100 type vlan id 100
sudo ip addr add 192.168.100.1/24 dev eth0.100
sudo ip link set eth0.100 up

# Bridge สำหรับ VLAN
sudo ip link add name br-vlan100 type bridge
sudo ip link set eth0.100 master br-vlan100
sudo ip link set br-vlan100 up

# ใน Domain XML ของ libvirt
# <interface type='bridge'>
#   <source bridge='br-vlan100'/>
#   <model type='virtio'/>
# </interface>

10.6.5 PCI Passthrough / SR-IOV / GPU Passthrough

PCI Passthrough คือการให้ VM เข้าถึงอุปกรณ์ PCI โดยตรง เช่น GPU, Network Card, NVMe ได้ Performance ใกล้เคียง Native ต้องการ IOMMU (VT-d/AMD-Vi)

ขั้นตอนการเปิด IOMMU และ Passthrough

  1. เปิด IOMMU ใน BIOS/UEFI
  2. แก้ Kernel Parameter
  3. Bind อุปกรณ์เข้า vfio-pci
  4. กำหนดใน Domain XML
# 1. ตรวจสอบ CPU รองรับ IOMMU
sudo dmesg | grep -E "DMAR|IOMMU"

# 2. เปิด IOMMU ใน Kernel (Intel)
# แก้ /etc/default/grub เพิ่มใน GRUB_CMDLINE_LINUX_DEFAULT
# intel_iommu=on iommu=pt
# (AMD: amd_iommu=on iommu=pt)

sudo update-grub
sudo reboot

# 3. ตรวจสอบ IOMMU Group
for d in /sys/kernel/iommu_groups/*/devices/*; do
    n=${d#*/iommu_groups/*}; n=${n%%/*}
    printf 'IOMMU Group %s ' "$n"
    lspci -nns "${d##*/}"
done | sort -k3 -n

# 4. หา Vendor:Device ID ของ GPU ที่ต้อง passthrough
lspci -nn | grep -i nvidia
# ตัวอย่าง: 01:00.0 VGA compatible controller [0300]: NVIDIA [10de:1c03]

# 5. Bind เข้า vfio-pci
echo "options vfio-pci ids=10de:1c03,10de:10f1" | \
    sudo tee /etc/modprobe.d/vfio.conf

echo "vfio_pci" | sudo tee -a /etc/modules
sudo update-initramfs -u
sudo reboot

# 6. เพิ่มใน Domain XML
# <hostdev mode='subsystem' type='pci' managed='yes'>
#   <source>
#     <address domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
#   </source>
# </hostdev>

SR-IOV (Single Root I/O Virtualization) ทำให้ NIC หรือ GPU เดียวแบ่งออกเป็น Virtual Function (VF) หลายตัว ส่ง Passthrough ให้ VM แต่ละตัวได้

# เปิด VF บน NIC
echo 4 | sudo tee /sys/class/net/eth0/device/sriov_numvfs

# ดู VF ที่สร้าง
lspci | grep "Virtual Function"
ip link show eth0

10.7 Automation และ Infrastructure as Code

การจัดการ VM ด้วยมือทำให้เกิด Configuration Drift และยากต่อการสร้างซ้ำ Infrastructure as Code (IaC) เป็นแนวทางที่กำหนดโครงสร้าง Infrastructure ในรูปแบบ Code/Declarative File ทำให้สามารถ Version Control, Review, และ Reproduce ได้

10.7.1 Vagrant (Box, Vagrantfile) กับ VirtualBox / libvirt

Vagrant คือเครื่องมือสร้างและจัดการ VM Environment สำหรับนักพัฒนา รองรับหลาย Provider (VirtualBox, libvirt, VMware, Docker)

# Vagrantfile - ตัวอย่าง multi-VM development environment
Vagrant.configure("2") do |config|
  # Web Server
  config.vm.define "web" do |web|
    web.vm.box = "ubuntu/jammy64"
    web.vm.hostname = "web.local"
    web.vm.network "private_network", ip: "192.168.56.10"
    web.vm.network "forwarded_port", guest: 80, host: 8080
    web.vm.provider "virtualbox" do |vb|
      vb.memory = "1024"
      vb.cpus = 2
      vb.name = "web-server"
    end
    web.vm.provision "shell", inline: <<-SHELL
      apt-get update
      apt-get install -y nginx
      systemctl enable --now nginx
    SHELL
  end

  # Database Server
  config.vm.define "db" do |db|
    db.vm.box = "ubuntu/jammy64"
    db.vm.hostname = "db.local"
    db.vm.network "private_network", ip: "192.168.56.20"
    db.vm.provider "virtualbox" do |vb|
      vb.memory = "2048"
      vb.cpus = 2
    end
    db.vm.provision "shell", inline: <<-SHELL
      apt-get update
      apt-get install -y postgresql
      systemctl enable --now postgresql
    SHELL
  end
end
# คำสั่ง Vagrant
vagrant up                  # สร้างและ boot VM ทั้งหมด
vagrant up web              # boot เฉพาะ web
vagrant ssh web             # SSH เข้า VM
vagrant halt                # ปิด VM
vagrant destroy -f          # ลบ VM
vagrant reload --provision  # restart และ run provision ใหม่
vagrant status              # แสดงสถานะ
vagrant box list            # แสดง Box ที่ดาวน์โหลดแล้ว

10.7.2 Packer สำหรับสร้าง Image

HashiCorp Packer ใช้สร้าง Machine Image (Golden Image) แบบอัตโนมัติจาก ISO รองรับการ Build หลาย Platform พร้อมกัน

# ubuntu.pkr.hcl
packer {
  required_plugins {
    qemu = {
      version = ">= 1.0.9"
      source  = "github.com/hashicorp/qemu"
    }
  }
}

source "qemu" "ubuntu" {
  iso_url          = "https://releases.ubuntu.com/22.04/ubuntu-22.04.4-live-server-amd64.iso"
  iso_checksum     = "sha256:45f873de9f8cb637345d6e66a583762730bbea30277ef7b32c9c3bd6700a32b2"
  output_directory = "output-qemu"
  shutdown_command = "echo 'ubuntu' | sudo -S shutdown -P now"
  disk_size        = "20G"
  format           = "qcow2"
  accelerator      = "kvm"
  http_directory   = "http"
  ssh_username     = "ubuntu"
  ssh_password     = "ubuntu"
  ssh_timeout      = "30m"
  vm_name          = "ubuntu-22.04"
  net_device       = "virtio-net"
  disk_interface   = "virtio"
  boot_wait        = "5s"
  boot_command = [
    "c<wait>",
    "linux /casper/vmlinuz autoinstall ds=nocloud-net;s=http://{{.HTTPIP}}:{{.HTTPPort}}/ ---<enter>",
    "initrd /casper/initrd<enter>",
    "boot<enter>"
  ]
}

build {
  sources = ["source.qemu.ubuntu"]

  provisioner "shell" {
    inline = [
      "sudo apt-get update",
      "sudo apt-get install -y nginx docker.io",
      "sudo systemctl enable nginx docker"
    ]
  }
}
# ติดตั้ง Packer
curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
sudo apt update && sudo apt install -y packer

# Build image
packer init ubuntu.pkr.hcl
packer validate ubuntu.pkr.hcl
packer build ubuntu.pkr.hcl

10.7.3 Cloud-init สำหรับ guest configuration

cloud-init เป็นเครื่องมือมาตรฐานสำหรับ Configure VM ตอน First Boot ใช้กันแพร่หลายใน Cloud Provider

# user-data.yaml
#cloud-config
hostname: my-server
fqdn: my-server.example.com
manage_etc_hosts: true

users:
  - name: admin
    sudo: ALL=(ALL) NOPASSWD:ALL
    shell: /bin/bash
    ssh_authorized_keys:
      - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... admin@laptop

package_update: true
package_upgrade: true
packages:
  - nginx
  - docker.io
  - git
  - vim
  - htop

write_files:
  - path: /etc/nginx/sites-available/default
    content: |
      server {
        listen 80 default_server;
        root /var/www/html;
        index index.html;
      }

runcmd:
  - systemctl enable --now nginx
  - systemctl enable --now docker
  - usermod -aG docker admin

timezone: Asia/Bangkok
# meta-data.yaml
instance-id: my-server-001
local-hostname: my-server
# สร้าง cloud-init seed ISO
cloud-localds seed.iso user-data.yaml meta-data.yaml

# Boot VM พร้อม cloud-init
qemu-system-x86_64 \
    -enable-kvm -m 2G -smp 2 \
    -drive file=ubuntu-cloud.qcow2,if=virtio \
    -drive file=seed.iso,if=virtio,format=raw \
    -netdev user,id=net0,hostfwd=tcp::2222-:22 \
    -device virtio-net-pci,netdev=net0 \
    -nographic

10.7.4 Terraform + libvirt provider

Terraform เป็น IaC Tool ที่ใช้ Declarative Language ในการกำหนด Infrastructure

# main.tf
terraform {
  required_providers {
    libvirt = {
      source  = "dmacvicar/libvirt"
      version = "0.7.6"
    }
  }
}

provider "libvirt" {
  uri = "qemu:///system"
}

resource "libvirt_pool" "vm_pool" {
  name = "tf_pool"
  type = "dir"
  target {
    path = "/var/lib/libvirt/images/tf_pool"
  }
}

resource "libvirt_volume" "ubuntu_base" {
  name   = "ubuntu-22.04-base"
  pool   = libvirt_pool.vm_pool.name
  source = "https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img"
  format = "qcow2"
}

resource "libvirt_volume" "vm_disk" {
  count          = 3
  name           = "vm-${count.index}.qcow2"
  pool           = libvirt_pool.vm_pool.name
  base_volume_id = libvirt_volume.ubuntu_base.id
  size           = 21474836480  # 20 GB
}

resource "libvirt_cloudinit_disk" "init" {
  count          = 3
  name           = "init-${count.index}.iso"
  pool           = libvirt_pool.vm_pool.name
  user_data      = templatefile("${path.module}/user-data.yaml", {
    hostname = "vm-${count.index}"
  })
  meta_data      = "instance-id: vm-${count.index}\nlocal-hostname: vm-${count.index}\n"
}

resource "libvirt_domain" "vm" {
  count  = 3
  name   = "vm-${count.index}"
  memory = 2048
  vcpu   = 2
  
  cloudinit = libvirt_cloudinit_disk.init[count.index].id
  
  network_interface {
    network_name   = "default"
    wait_for_lease = true
  }
  
  disk {
    volume_id = libvirt_volume.vm_disk[count.index].id
  }
  
  console {
    type        = "pty"
    target_type = "serial"
    target_port = "0"
  }
  
  graphics {
    type        = "spice"
    listen_type = "address"
    autoport    = true
  }
}

output "vm_ips" {
  value = {
    for idx, vm in libvirt_domain.vm :
    vm.name => vm.network_interface[0].addresses[0]
  }
}
# คำสั่ง Terraform
terraform init      # ดาวน์โหลด provider
terraform plan      # ตรวจสอบสิ่งที่จะเปลี่ยน
terraform apply     # สร้าง infrastructure
terraform destroy   # ลบทั้งหมด
terraform show      # แสดง state ปัจจุบัน

10.7.5 Ansible สำหรับ provisioning VM

Ansible เป็น Configuration Management Tool ที่ใช้ YAML กำหนดค่า ไม่ต้องติดตั้ง Agent (Agentless ผ่าน SSH)

# inventory.ini
[webservers]
web1 ansible_host=192.168.122.10
web2 ansible_host=192.168.122.11

[dbservers]
db1 ansible_host=192.168.122.20

[all:vars]
ansible_user=ubuntu
ansible_ssh_private_key_file=~/.ssh/id_ed25519
# playbook.yml
---
- name: ตั้งค่า Web Servers
  hosts: webservers
  become: yes
  
  tasks:
    - name: อัพเดท package cache
      apt:
        update_cache: yes
        cache_valid_time: 3600
    
    - name: ติดตั้ง nginx และ git
      apt:
        name:
          - nginx
          - git
          - curl
        state: present
    
    - name: คัดลอก nginx config
      template:
        src: nginx.conf.j2
        dest: /etc/nginx/sites-available/default
      notify: restart nginx
    
    - name: เปิดใช้งาน nginx service
      systemd:
        name: nginx
        enabled: yes
        state: started
    
    - name: เปิด firewall ports
      ufw:
        rule: allow
        port: '{{ item }}'
        proto: tcp
      loop:
        - 80
        - 443
  
  handlers:
    - name: restart nginx
      systemd:
        name: nginx
        state: restarted

- name: ตั้งค่า Database Servers
  hosts: dbservers
  become: yes
  
  tasks:
    - name: ติดตั้ง PostgreSQL
      apt:
        name: postgresql
        state: present
        update_cache: yes
    
    - name: เปิดใช้งาน PostgreSQL
      systemd:
        name: postgresql
        enabled: yes
        state: started
# คำสั่ง Ansible
ansible -i inventory.ini all -m ping              # test connection
ansible-playbook -i inventory.ini playbook.yml    # run playbook
ansible-playbook -i inventory.ini playbook.yml --check  # dry run
ansible-playbook -i inventory.ini playbook.yml --limit web1  # เฉพาะ host

10.8 Nested Virtualization

Nested Virtualization คือการรัน Hypervisor ภายใน VM ทำให้ VM ตัวลูก (L2) สามารถใช้ Hardware-assisted Virtualization ได้ มีประโยชน์สำหรับ Lab, Training, CI/CD ที่ต้องการ Test Hypervisor

10.8.1 การเปิดใช้งาน (KVM nested, VirtualBox nested)

flowchart TB
    L0[L0: Physical Host
Bare Metal + Linux + KVM] L1[L1: Outer VM
Linux + KVM ภายใน VM] L2A[L2: Inner VM A
Windows] L2B[L2: Inner VM B
Linux] L0 --> L1 L1 --> L2A L1 --> L2B
# === KVM Nested Virtualization ===

# 1. ตรวจสอบว่า nested เปิดอยู่หรือไม่
cat /sys/module/kvm_intel/parameters/nested
# ถ้าได้ "Y" หรือ "1" คือเปิด

# 2. เปิด nested (Intel)
sudo modprobe -r kvm_intel
sudo modprobe kvm_intel nested=1

# ตั้งให้ถาวร
echo "options kvm_intel nested=1" | \
    sudo tee /etc/modprobe.d/kvm-nested.conf

# AMD
echo "options kvm_amd nested=1" | \
    sudo tee /etc/modprobe.d/kvm-nested.conf

# 3. ใน Domain XML ของ VM ที่จะเป็น L1 ต้องใช้ cpu mode='host-passthrough'
# <cpu mode='host-passthrough'/>

# === VirtualBox Nested Virtualization ===
VBoxManage modifyvm "MyVM" --nested-hw-virt on

10.8.2 ข้อจำกัดด้านประสิทธิภาพ

Performance Penalty ของ Nested Virtualization

PL2 = PNative × ( 1 OL1 ) × ( 1 OL2 )

โดยที่:

โดยรวม L2 VM อาจมีประสิทธิภาพเพียง 50-70% ของ Native ขึ้นกับ Workload

10.8.3 Use Case: Lab, CI/CD, Kubernetes Testing

กรณีใช้งานที่เหมาะกับ Nested Virtualization


10.9 การเปรียบเทียบกับ Hypervisor อื่น (Hypervisor Comparison)

10.9.1 Proxmox VE (KVM + LXC + Web UI)

Proxmox Virtual Environment เป็น Open Source Distribution ที่รวม KVM, LXC, ZFS, Ceph, และ Web UI สำหรับใช้งาน Type 1 Hypervisor บน Bare-metal

คุณสมบัติเด่น

10.9.2 VMware ESXi / vSphere

VMware ESXi เป็น Type 1 Hypervisor เชิงพาณิชย์อันดับหนึ่ง พร้อม vSphere เป็น Management Platform

ฟีเจอร์ Enterprise

10.9.3 Microsoft Hyper-V

Hyper-V เป็น Type 1 Hypervisor ที่ฝังอยู่ใน Windows Server และ Windows 10/11 Pro/Enterprise

10.9.4 Xen / XCP-ng

Xen Project เป็น Open Source Hypervisor ที่เก่าแก่ ยังคงใช้ใน AWS EC2 และ Citrix Hypervisor

XCP-ng เป็น Distribution ที่พัฒนาต่อจาก Citrix Hypervisor พร้อม Xen Orchestra เป็น Web UI

10.9.5 oVirt / Red Hat Virtualization

oVirt เป็น Open Source Virtualization Management Platform ที่ใช้ KVM โดย Red Hat Virtualization (RHV) เป็น Enterprise Version (กำลังจะ End-of-life)

10.9.6 การเลือกใช้ตาม Use Case (Home Lab, SMB, Enterprise)

Use Case Hypervisor แนะนำ เหตุผล
Desktop / นักพัฒนา VirtualBox, QEMU ฟรี, ติดตั้งง่าย, GUI ดี
Home Lab Proxmox VE, ESXi Free ฟีเจอร์ครบ, Web UI
SMB Server Proxmox VE, Hyper-V, ESXi Essentials ราคาถูก, รองรับ SMB workload
Enterprise Data Center VMware vSphere, Hyper-V ฟีเจอร์ Enterprise, Support
Cloud Provider KVM, Xen Open Source, ปรับแต่งได้
HPC / GPU Workload KVM + PCI Passthrough ประสิทธิภาพสูงสุด
Container Workload Podman, Docker, K8s Lightweight, Cloud-native
Cross-Architecture QEMU (TCG mode) จำลอง CPU ต่าง Architecture

สมการประเมิน Total Cost of Ownership (TCO)

TCO = Clicense + Chardware + Coperation + Ctraining Sconsolidation

โดยที่:


สรุปท้ายบท

Virtualization เป็นเทคโนโลยีพื้นฐานที่ขับเคลื่อนทั้ง Cloud Computing, DevOps, และ Modern Infrastructure ในบทนี้ได้ครอบคลุมตั้งแต่แนวคิดพื้นฐาน, ประเภทของ Hypervisor (Type 1/2), การใช้งาน VirtualBox และ QEMU/KVM ในเชิงลึก, การจัดการผ่าน libvirt และ virt-manager, Virtual Networking ขั้นสูงรวมถึง PCI Passthrough/SR-IOV, การทำ Infrastructure as Code ด้วย Vagrant/Packer/Terraform/Ansible/cloud-init, Nested Virtualization และการเปรียบเทียบกับ Hypervisor อื่น ๆ

การเลือก Hypervisor ที่เหมาะสมขึ้นกับ Use Case, งบประมาณ, และ Skill ของทีม โดย VirtualBox เหมาะกับนักพัฒนาและการเรียนการสอน, QEMU + KVM + libvirt เหมาะกับ Linux Server และ Cloud, Proxmox VE เหมาะกับ Home Lab และ SMB, ส่วน VMware vSphere/Hyper-V เหมาะกับ Enterprise ที่ต้องการ Support และฟีเจอร์ขั้นสูง

ในยุคปัจจุบัน เส้นแบ่งระหว่าง VM และ Container เริ่มเลือนลาง โดยมีเทคโนโลยีลูกผสมเช่น Firecracker microVM, Kata Containers, gVisor ที่นำข้อดีของทั้งสองมาผสมผสาน เพื่อรองรับ Workload Cloud-native ที่ต้องการทั้ง Performance และ Security