Module 06 Private Cloud 5 labs

Virtualization: VMware, Hyper-V, Proxmox

Private cloud bắt đầu từ ảo hóa: nắm vững compute, storage, network ảo hóa, VM template, snapshot & rollback, virtual network design và capacity planning — nền tảng vận hành on-prem cloud.

Công cụ thực hành Hyper-V Manager, PowerShell, Proxmox CLI (qm/pvesh), VMware vSphere CLI
Nền tảng Windows Server (Hyper-V), Proxmox VE, VMware ESXi / vSphere
Thời điểm phát hành 23/05/2026
Ngày biên soạn 23/05/2026
Người biên soạn Trần Văn Hòa — Microsoft Certified Trainer (MCT)

Mục tiêu học tập

1. Lý thuyết cốt lõi

1.1. Hypervisor — nền tảng của ảo hóa

Hypervisor là lớp phần mềm tạo và quản lý Virtual Machine (VM) bằng cách phân vùng tài nguyên vật lý (CPU, RAM, I/O). Type-1 (bare-metal): chạy trực tiếp trên hardware — VMware ESXi, Microsoft Hyper-V (kernel), Proxmox VE (KVM-based). Type-2 (hosted): chạy trên OS — VMware Workstation, VirtualBox. Trong môi trường production, Type-1 luôn được ưu tiên vì độ trễ thấp hơn và bảo mật tốt hơn.

Tiêu chíVMware ESXi / vSphereHyper-V (WS 2022)Proxmox VE 8
LicenseCommercial (vSphere Foundation+)Included in Windows ServerOpen-source (Debian + KVM)
VM tối đa/host1024 (vSphere 8)1024 (WS 2022)Không giới hạn cứng
Live MigrationvMotionLive MigrationOnline Migration (KVM)
StorageVMFS, vSAN, NFSVHDX, CSV, SMB3LVM, ZFS, Ceph, NFS
GUIvSphere Client (web)Hyper-V Manager / WACProxmox Web UI
CLIesxcli, govc, PowerCLIPowerShell Hyper-V moduleqm, pvesh, pvenode

1.2. VM Template — chuẩn hóa provisioning

Template là VM đã được sysprep/cloud-init, tắt nguồn và chuyển thành golden image. Khi clone từ template, hypervisor tạo VM mới có cấu hình chuẩn (OS, agent, hardening) mà không cần cài đặt lại. Best practice: đặt tên template theo convention tpl-{os}-{role}-{yyyymm} (vd: tpl-ubuntu2204-webserver-202601), lưu trên datastore riêng, cập nhật định kỳ.

1.3. Snapshot & Rollback

Snapshot lưu trạng thái VM (disk delta, memory, config) tại một thời điểm. Không phải backup — snapshot delta tăng trưởng theo thời gian, làm chậm I/O. Nguyên tắc: chỉ giữ snapshot ≤72h trước patch/upgrade, rollback ngay nếu có lỗi, xóa snapshot sau khi xác nhận OK. Trên Proxmox dùng qm snapshot; Hyper-V dùng Checkpoint-VM; VMware dùng New-Snapshot (PowerCLI) hoặc vim-cmd.

1.4. Virtual Network — VLAN, vSwitch, Trunk

Mỗi hypervisor có virtual switch (vSwitch) để kết nối VM với nhau và với physical network. VLAN tagging cho phép multi-tenant trên cùng physical NIC: VM được gán VLAN ID, vSwitch forward traffic đúng segment. Trên Hyper-V dùng Set-VMNetworkAdapterVlan; Proxmox dùng Linux Bridge hoặc OVS với VLAN tag trong GUI. Trunk port trên physical switch cho phép nhiều VLAN đi qua một uplink.

1.5. Capacity Planning

Capacity planning ảo hóa đo 3 chiều: CPU overcommit ratio (thông thường ≤4:1 vCPU:pCPU), RAM balloon/swap (RAM ảo > RAM vật lý gây swapping), Storage IOPS (thin provisioning tăng risk overallocation). Công cụ: Proxmox pvesh get /nodes/{node}/status; PowerShell Get-VM | Measure-Object kết hợp Get-Counter; vSphere Performance Charts + vROps.

2. Thực hành (Labs)

LAB-026

Tạo VM template

Proxmox CLI · Hyper-V · PowerShell

🎯 Mục tiêu: Tạo một VM template chuẩn hóa trên Proxmox VE (hoặc Hyper-V) để dùng lại cho mọi lần provisioning mà không cài đặt lại OS.

🧰 Công cụ / nền tảng: Proxmox VE 8 (SSH/CLI), hoặc Windows Server 2022 với Hyper-V role + PowerShell 5.1+.

📦 Chuẩn bị: Có host Proxmox hoặc Hyper-V; file ISO Ubuntu 22.04 Server hoặc Windows Server 2022 eval; quyền admin trên hypervisor.

▶️ Các bước — Proxmox VE (CLI qua SSH):

# 1. Tải cloud image Ubuntu 22.04 (cloud-init ready)
ssh root@<proxmox-host>
cd /var/lib/vz/template/iso
wget https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img

# 2. Tạo VM với ID 9000 (dùng làm template)
qm create 9000 --name tpl-ubuntu2204-base-202601 \
  --memory 2048 --cores 2 --net0 virtio,bridge=vmbr0 \
  --serial0 socket --vga serial0

# 3. Import disk từ cloud image vào storage "local-lvm"
qm importdisk 9000 jammy-server-cloudimg-amd64.img local-lvm

# 4. Gắn disk vừa import và thiết lập boot
qm set 9000 --scsihw virtio-scsi-pci --scsi0 local-lvm:vm-9000-disk-0
qm set 9000 --ide2 local-lvm:cloudinit --boot c --bootdisk scsi0

# 5. Cấu hình cloud-init (SSH key, user)
qm set 9000 --ciuser ubuntu --sshkeys ~/.ssh/id_rsa.pub
qm set 9000 --ipconfig0 ip=dhcp

# 6. Chuyển VM thành template (KHÔNG THỂ hoàn tác)
qm template 9000

# Xác nhận
qm list | grep 9000

▶️ Các bước — Hyper-V (PowerShell):

# Chạy PowerShell với quyền Administrator
# 1. Tạo VHDX từ ISO (sau khi cài OS thủ công, sysprep)
# Giả sử đã có file VHDX đã sysprep tại C:\Templates\ws2022-base.vhdx

# 2. Tạo VM "template" (không start)
New-VM -Name "tpl-ws2022-base-202601" `
       -MemoryStartupBytes 2GB `
       -Generation 2 `
       -VHDPath "C:\Templates\ws2022-base.vhdx" `
       -SwitchName "InternalSwitch"

# 3. Tắt auto-start và đặt note
Set-VM -Name "tpl-ws2022-base-202601" -AutomaticStartAction Nothing
Set-VM -Name "tpl-ws2022-base-202601" -Notes "Template: Windows Server 2022 Eval, sysprep 2026-01"

# 4. Export template ra thư mục dùng chung
Export-VM -Name "tpl-ws2022-base-202601" -Path "C:\VM-Templates\"
Get-VM -Name "tpl-ws2022-base-202601" | Select Name, State, Notes

✅ Kết quả mong đợi: Proxmox: qm list hiển thị VM 9000 với dấu hiệu template (T); Hyper-V: Get-VM trả về State=Off, Notes đúng. Clone từ template tạo VM mới trong <30 giây.

🧹 Cleanup: Template giữ lại để dùng cho LAB-027. Nếu muốn xóa: Proxmox qm destroy 9000; Hyper-V Remove-VM -Name "tpl-ws2022-base-202601" -Force.

LAB-027

Tạo VM bằng CLI/PowerShell

PowerShell · Proxmox CLI · Windows Terminal

🎯 Mục tiêu: Tạo VM mới từ template bằng CLI — không dùng GUI — để có thể tích hợp vào script/pipeline tự động hóa.

🧰 Công cụ / nền tảng: Proxmox VE: SSH + qm CLI; Hyper-V: PowerShell module Hyper-V; Windows Terminal.

📦 Chuẩn bị: Template từ LAB-026 đã sẵn sàng; PowerShell 5.1+ hoặc pwsh 7+.

▶️ Các bước — Proxmox VE (clone từ template):

# Clone full từ template 9000 → VM mới ID 101
qm clone 9000 101 --name vm-web01 --full --storage local-lvm

# Resize disk lên 20GB
qm resize 101 scsi0 20G

# Thiết lập cloud-init cho VM mới (IP tĩnh)
qm set 101 --ipconfig0 ip=192.168.100.101/24,gw=192.168.100.1
qm set 101 --nameserver 8.8.8.8

# Khởi động VM
qm start 101

# Theo dõi console
qm terminal 101   # Ctrl+O để thoát

# Kiểm tra trạng thái
qm status 101
# Output mong đợi: status: running

▶️ Các bước — Hyper-V (PowerShell):

# 1. Copy VHDX từ template
$templateVHDX = "C:\VM-Templates\tpl-ws2022-base-202601\Virtual Hard Disks\ws2022-base.vhdx"
$newVHDX      = "C:\VMs\vm-web01\vm-web01.vhdx"
New-Item -ItemType Directory -Path "C:\VMs\vm-web01" -Force
Copy-Item $templateVHDX $newVHDX

# 2. Tạo VM mới từ VHDX đã copy
New-VM -Name "vm-web01" `
       -MemoryStartupBytes 2GB `
       -Generation 2 `
       -VHDPath $newVHDX `
       -SwitchName "InternalSwitch"

# 3. Cấu hình thêm: CPU, Dynamic Memory
Set-VM -Name "vm-web01" -ProcessorCount 2
Set-VMMemory -VMName "vm-web01" -DynamicMemoryEnabled $true `
             -MinimumBytes 512MB -MaximumBytes 4GB

# 4. Khởi động VM
Start-VM -Name "vm-web01"
Get-VM -Name "vm-web01" | Select Name, State, CPUUsage, MemoryAssigned

# 5. Kết nối console (GUI)
vmconnect localhost "vm-web01"

✅ Kết quả mong đợi: VM ở trạng thái Running; Proxmox: qm guest exec 101 -- hostname trả về hostname đúng; Hyper-V: Get-VM "vm-web01" State = Running, MemoryAssigned > 0.

🧹 Cleanup: qm stop 101 && qm destroy 101 (Proxmox) hoặc Stop-VM "vm-web01" -Force; Remove-VM "vm-web01" -Force (Hyper-V).

LAB-028

Snapshot và Rollback

Proxmox CLI · PowerShell · Hyper-V

🎯 Mục tiêu: Tạo snapshot trước khi thay đổi cấu hình VM, mô phỏng lỗi, rollback về trạng thái trước và xác nhận hệ thống phục hồi đúng.

🧰 Công cụ / nền tảng: Proxmox VE: qm snapshot; Hyper-V: Checkpoint-VM / Restore-VMCheckpoint; VMware (tùy chọn): vmrun hoặc PowerCLI.

📦 Chuẩn bị: VM 101 (Proxmox) hoặc vm-web01 (Hyper-V) đang chạy từ LAB-027; quyền admin hypervisor.

▶️ Các bước — Proxmox VE:

# 1. Tạo snapshot trước khi cài nginx
qm snapshot 101 snap-before-nginx --description "Before nginx install" --vmstate

# Xác nhận snapshot tồn tại
qm listsnapshot 101

# 2. Vào VM và cài nginx (mô phỏng thay đổi)
qm guest exec 101 -- bash -c "apt-get update -y && apt-get install -y nginx"
qm guest exec 101 -- systemctl status nginx

# 3. Mô phỏng lỗi (xóa file config quan trọng)
qm guest exec 101 -- bash -c "rm -rf /etc/nginx/nginx.conf"
qm guest exec 101 -- bash -c "nginx -t"
# Output: nginx: [emerg] open() "/etc/nginx/nginx.conf" failed

# 4. Rollback về snapshot
qm rollback 101 snap-before-nginx

# 5. Khởi động lại VM và kiểm tra
qm start 101
qm guest exec 101 -- bash -c "test -f /etc/nginx/nginx.conf && echo 'RESTORED' || echo 'MISSING'"
# Output mong đợi: MISSING (nginx chưa được cài — đã rollback đúng)

# 6. Xóa snapshot sau khi xác nhận
qm delsnapshot 101 snap-before-nginx
qm listsnapshot 101   # Không còn snapshot

▶️ Các bước — Hyper-V (PowerShell):

# 1. Tạo checkpoint (snapshot)
Checkpoint-VM -Name "vm-web01" -SnapshotName "snap-before-change"

# Xem danh sách checkpoint
Get-VMCheckpoint -VMName "vm-web01" | Select Name, CreationTime

# 2. Mô phỏng thay đổi (trong VM, xóa file test)
#    Thực hiện thao tác trong console VM...

# 3. Rollback về checkpoint
$cp = Get-VMCheckpoint -VMName "vm-web01" -Name "snap-before-change"
Restore-VMCheckpoint -VMCheckpoint $cp

# 4. Khởi động lại VM
Start-VM -Name "vm-web01"
Get-VM -Name "vm-web01" | Select Name, State

# 5. Xóa checkpoint sau khi xác nhận OK
Remove-VMCheckpoint -VMName "vm-web01" -Name "snap-before-change"

✅ Kết quả mong đợi: Sau rollback, VM trở về đúng trạng thái trước khi thay đổi; dung lượng delta file giải phóng sau khi xóa snapshot; thời gian rollback <60 giây cho VM 20GB.

🧹 Cleanup: Xóa tất cả snapshot/checkpoint thừa; stop VM nếu không cần tiếp: qm stop 101 hoặc Stop-VM "vm-web01".

LAB-029

Thiết kế Virtual Network

Proxmox CLI · PowerShell · Hyper-V Manager

🎯 Mục tiêu: Tạo virtual switch và phân VLAN để cô lập traffic giữa hai nhóm VM (Production VLAN 10 và Development VLAN 20) trên cùng một host vật lý.

🧰 Công cụ / nền tảng: Proxmox VE: Linux Bridge + VLAN tagging qua file cấu hình /etc/network/interfaces; Hyper-V: New-VMSwitch, Set-VMNetworkAdapterVlan.

📦 Chuẩn bị: Ít nhất 2 VM đang tắt; quyền root/admin trên hypervisor.

▶️ Các bước — Proxmox VE:

# 1. Xem cấu hình network hiện tại
cat /etc/network/interfaces

# 2. Thêm Linux Bridge với VLAN-aware (edit qua pvesh hoặc trực tiếp)
# Thêm vào /etc/network/interfaces:
# auto vmbr1
# iface vmbr1 inet manual
#     bridge-ports none
#     bridge-stp off
#     bridge-fd 0
#     bridge-vlan-aware yes
#     bridge-vids 2-4094

# Áp dụng cấu hình mạng (không cần reboot)
ifreload -a

# 3. Gán VM 101 vào VLAN 10 (Production)
qm set 101 --net0 virtio,bridge=vmbr1,tag=10

# 4. Tạo VM 102 (dev) và gán VLAN 20
qm clone 9000 102 --name vm-dev01 --full --storage local-lvm
qm set 102 --net0 virtio,bridge=vmbr1,tag=20
qm set 102 --ipconfig0 ip=192.168.20.102/24,gw=192.168.20.1

# 5. Kiểm tra cấu hình
qm config 101 | grep net
qm config 102 | grep net

# Xác minh VLAN isolation: VM101 không ping được VM102
qm guest exec 101 -- ping -c 3 192.168.20.102
# Output mong đợi: 100% packet loss (cô lập thành công)

▶️ Các bước — Hyper-V (PowerShell):

# 1. Tạo External Virtual Switch (kết nối physical NIC)
New-VMSwitch -Name "vSwitch-Trunk" -NetAdapterName "Ethernet0" -AllowManagementOS $true

# 2. Tạo Internal Switch cho lab cô lập
New-VMSwitch -Name "vSwitch-Internal" -SwitchType Internal

# 3. Gán VM vào switch
Add-VMNetworkAdapter -VMName "vm-web01" -SwitchName "vSwitch-Internal"
Add-VMNetworkAdapter -VMName "vm-dev01" -SwitchName "vSwitch-Internal"

# 4. Đặt VLAN tag: vm-web01 → VLAN 10 (Production)
Set-VMNetworkAdapterVlan -VMName "vm-web01" -Access -VlanId 10

# 5. Đặt VLAN tag: vm-dev01 → VLAN 20 (Development)
Set-VMNetworkAdapterVlan -VMName "vm-dev01" -Access -VlanId 20

# 6. Xác nhận
Get-VMNetworkAdapterVlan -VMName "vm-web01"
Get-VMNetworkAdapterVlan -VMName "vm-dev01"
# Output: OperationMode=Access, AccessVlanId=10/20

Get-VMSwitch | Select Name, SwitchType | Format-Table

✅ Kết quả mong đợi: VM trong VLAN 10 không thể ping VM trong VLAN 20; mỗi VLAN có dải IP riêng; Get-VMNetworkAdapterVlan hoặc qm config hiển thị VLAN ID đúng.

🧹 Cleanup: Remove-VMSwitch "vSwitch-Internal" -Force hoặc xóa bridge trên Proxmox và revert /etc/network/interfaces.

LAB-030

Tạo Capacity Report

PowerShell · Proxmox pvesh · CLI

🎯 Mục tiêu: Thu thập chỉ số CPU, RAM, Storage của tất cả VM trên host, xuất báo cáo CSV, xác định VM nào đang lãng phí tài nguyên (overprovisioned) hoặc có nguy cơ thiếu.

🧰 Công cụ / nền tảng: Hyper-V: PowerShell Get-VM, Get-Counter; Proxmox: pvesh REST API, qm list.

📦 Chuẩn bị: Ít nhất 2-3 VM đang chạy; PowerShell hoặc SSH vào Proxmox host.

▶️ Các bước — Hyper-V (PowerShell):

# 1. Lấy danh sách VM và tài nguyên cấp phát
$vms = Get-VM | Select-Object Name, State, ProcessorCount,
    @{N='MemoryGB_Assigned';E={[math]::Round($_.MemoryAssigned/1GB,2)}},
    @{N='MemoryGB_Max';E={[math]::Round($_.MemoryMaximum/1GB,2)}},
    Uptime

$vms | Format-Table -AutoSize

# 2. Lấy CPU usage realtime (lấy mẫu 10 lần, 1 giây/lần)
$cpuCounters = Get-Counter '\Hyper-V Hypervisor Virtual Processor(*)\% Total Run Time' `
                -SampleInterval 1 -MaxSamples 10

$cpuCounters.CounterSamples | Where-Object { $_.InstanceName -ne '_total' } |
    Group-Object InstanceName | ForEach-Object {
        [PSCustomObject]@{
            VM        = $_.Name
            AvgCPU_Pct = [math]::Round(($_.Group.CookedValue | Measure-Object -Average).Average,2)
        }
    } | Sort-Object AvgCPU_Pct -Descending | Format-Table

# 3. Lấy dung lượng VHD
Get-VM | Get-VMHardDiskDrive | ForEach-Object {
    $vhd = Get-VHD $_.Path
    [PSCustomObject]@{
        VM            = $_.VMName
        Path          = $_.Path
        SizeGB_Max    = [math]::Round($vhd.Size/1GB,2)
        SizeGB_Used   = [math]::Round($vhd.FileSize/1GB,2)
        Type          = $vhd.VHDType
    }
} | Format-Table -AutoSize

# 4. Xuất báo cáo CSV
$report = Get-VM | Select-Object Name, State, ProcessorCount,
    @{N='MemGB';E={[math]::Round($_.MemoryAssigned/1GB,2)}},
    @{N='UptimeHours';E={[math]::Round($_.Uptime.TotalHours,1)}}

$report | Export-Csv -Path "C:\Reports\capacity-report-$(Get-Date -Format 'yyyyMMdd').csv" `
           -NoTypeInformation -Encoding UTF8
Write-Host "Report saved to C:\Reports\"

▶️ Các bước — Proxmox VE (SSH):

# 1. Xem tất cả VM và trạng thái
qm list
# VMID NAME         STATUS    MEM(MB)  BOOTDISK(GB)  PID

# 2. Lấy thông số node (host)
pvesh get /nodes/$(hostname)/status --output-format json | \
  python3 -c "import sys,json; d=json.load(sys.stdin); \
  print(f\"CPU: {d['cpu']*100:.1f}%  RAM: {d['memory']['used']//1024//1024}MB/{d['memory']['total']//1024//1024}MB  \
  Storage rootfs: {d['rootfs']['used']//1024//1024//1024}GB/{d['rootfs']['total']//1024//1024//1024}GB\")"

# 3. Lấy thông số từng VM
for vmid in $(qm list | awk 'NR>1 {print $1}'); do
  echo "=== VM $vmid ==="
  pvesh get /nodes/$(hostname)/qemu/$vmid/status/current \
    --output-format json | python3 -c "
import sys,json
d=json.load(sys.stdin)
print(f\"  Name: {d.get('name','?')}  Status: {d['status']}  CPU: {d.get('cpu',0)*100:.1f}%  RAM: {d.get('mem',0)//1024//1024}MB/{d.get('maxmem',0)//1024//1024}MB\")
"
done

# 4. Xuất CSV đơn giản
echo "VMID,Name,Status,MaxMem_MB,MaxCores" > /tmp/capacity-report.csv
qm list | awk 'NR>1 {print $1}' | while read vmid; do
  conf=$(qm config $vmid)
  name=$(echo "$conf" | grep ^name | awk '{print $2}')
  mem=$(echo "$conf"  | grep ^memory | awk '{print $2}')
  cores=$(echo "$conf" | grep ^cores | awk '{print $2}')
  status=$(qm status $vmid | awk '{print $2}')
  echo "$vmid,$name,$status,$mem,$cores"
done >> /tmp/capacity-report.csv
cat /tmp/capacity-report.csv

✅ Kết quả mong đợi: File CSV có đầy đủ thông tin mỗi VM (Name, State, CPU cores, RAM MB, Disk GB); phát hiện được ít nhất 1 VM có CPU usage <5% hoặc RAM assigned >2x RAM thực dùng (overprovisioned candidate).

🧹 Cleanup: Giữ file CSV làm baseline. Xóa nếu cần: Remove-Item "C:\Reports\capacity-report-*.csv" hoặc rm /tmp/capacity-report.csv.

3. Tình huống doanh nghiệp thực tế

Bối cảnh

Một công ty sản xuất vừa có 3 server vật lý chạy Windows Server 2022 với Hyper-V, tổng 48 core / 256 GB RAM. Đội IT phải provisioning 20 VM mới cho hệ thống ERP và muốn đảm bảo không có VM nào "ăn" hết RAM của VM quan trọng.

Giải pháp thực tế

  • Template chuẩn: Tạo 2 template (Windows Server 2022 + Ubuntu 22.04 LTS), sysprep sẵn, cài agent monitoring, hardening baseline CIS Level 1.
  • Phân VLAN: VLAN 10 — ERP Production; VLAN 20 — ERP Staging; VLAN 30 — Management. Cô lập hoàn toàn bằng Hyper-V VLAN tagging, không cần physical switch thêm.
  • Snapshot policy: Tự động snapshot trước mỗi patch Tuesday (Task Scheduler + PowerShell), xóa sau 72h xác nhận OK. Không để snapshot tích lũy >7 ngày.
  • Capacity report: Script PowerShell chạy hàng tuần, gửi email CSV qua Send-MailMessage. Alert khi host RAM usage >85%.
  • Kết quả: Thời gian provisioning VM mới từ 2 giờ (cài manual) xuống 8 phút (clone từ template); zero downtime nhờ snapshot rollback trong patch tháng đầu tiên.

📚 Nguồn tham khảo

Module 05: Bash, PowerShell & Python Automation Module 07: Private Cloud Architecture
Zalo