Vấn đề thực tế: Cluster HA “chạy ngon” nhưng vẫn có downtime
Hồi năm ngoái, cụm vSphere của mình có 4 ESXi host, chạy khoảng 60 VM production. Một buổi sáng, một host bị lỗi nguồn — chết hoàn toàn. HA restart các VM sang host còn lại, nhưng 8 VM không thể khởi động được. Log báo “Insufficient resources to satisfy HA failover level for cluster”.
Thực ra cluster HA đang làm đúng việc của nó — từ chối bật VM vì Admission Control đang “giữ chỗ” tài nguyên cho failover. Nhưng ngưỡng cấu hình quá cao so với thực tế, tạo ra nghịch lý: nhìn trực quan cluster vẫn còn tài nguyên, VM vẫn bị block không cho chạy.
Chưa hết. DRS đang để ở mức aggressive — cứ vài phút lại vMotion VM lung tung, storage I/O tăng vọt. Mấy cái database VM chịu thiệt nhất, latency spike lên rõ rệt mỗi lần bị di chuyển.
Phân tích nguyên nhân: Hai cơ chế bị hiểu nhầm
Admission Control và bẫy Slot Policy mặc định
Admission Control hoạt động theo logic đơn giản: trước khi cho phép bật thêm VM, nó kiểm tra — nếu một host chết ngay lúc này, cluster có đủ CPU và RAM để restart toàn bộ VM không? Nếu không đủ → block. Hợp lý. Vấn đề nằm ở cách tính “đủ”.
Có 3 chế độ tính toán:
- Cluster resource percentage: Giữ lại X% tổng CPU và RAM của toàn cluster
- Slot policy (Legacy): Chia tài nguyên thành các “slot” đều nhau, giữ lại N slot trống
- Dedicated failover hosts: Chỉ định 1–2 host luôn standby, không chạy VM thường
Vấn đề của mình nằm ở Slot Policy mặc định. Slot size được tính dựa trên VM có reservation cao nhất trong cluster — một con SQL Server reserve 32 GB RAM. Kết quả: mỗi slot = 32 GB RAM. Với 60 VM, số slot cần giữ lại trở thành con số khổng lồ, chiếm gần hết tài nguyên “dự phòng” ngay cả khi cluster vẫn còn nhiều RAM trống thực tế.
DRS aggressive mode: vMotion liên tục không phải lúc nào cũng tốt
DRS (Distributed Resource Scheduler) tự động cân bằng tải bằng vMotion, với Migration Threshold từ 1 (Conservative) đến 5 (Aggressive). Ở mức 4–5, DRS vMotion VM ngay khi imbalance nhỏ — đôi khi vMotion xong lại vMotion ngược lại vài phút sau. Database VM không có vMotion-aware workload sẽ bị latency spike mỗi lần bị di chuyển.
Các cách giải quyết Admission Control
Phương án 1: Cluster resource percentage (phù hợp nhất cho đa số)
Chuyển sang tính theo phần trăm tổng tài nguyên. Công thức đơn giản: nếu cluster có N host và cần chịu được 1 host chết, giữ lại 1/N × 100% tài nguyên. Với 4 host: giữ 25% CPU và 25% RAM.
# Kết nối vCenter
Connect-VIServer -Server vcenter.lab.local -User [email protected]
$cluster = Get-Cluster -Name "Production-Cluster"
# Xem cấu hình Admission Control hiện tại
$cluster.ExtensionData.Configuration.DasConfig.AdmissionControlPolicy
# Cập nhật sang Percentage-based: 25% CPU, 25% RAM
$spec = New-Object VMware.Vim.ClusterConfigSpecEx
$spec.dasConfig = New-Object VMware.Vim.ClusterDasConfigInfo
$spec.dasConfig.admissionControlPolicy = New-Object VMware.Vim.ClusterFailoverResourcesAdmissionControlPolicy
$spec.dasConfig.admissionControlPolicy.cpuFailoverResourcesPercent = 25
$spec.dasConfig.admissionControlPolicy.memoryFailoverResourcesPercent = 25
$spec.dasConfig.admissionControlPolicy.autoComputePercentages = $false
$cluster.ExtensionData.ReconfigureComputeResource($spec, $true)
Write-Host "Admission Control cập nhật: 25% CPU, 25% RAM"
Phương án 2: Dedicated failover host (nếu có host dư)
Không cần tính toán, cấu hình đơn giản nhất — chỉ định hẳn 1 host không chạy VM thường, chỉ dùng khi failover. Nhược điểm rõ ràng: lãng phí tài nguyên nếu host đó ngồi không 99% thời gian.
$failoverHost = Get-VMHost -Name "esxi-04.lab.local"
$spec = New-Object VMware.Vim.ClusterConfigSpecEx
$spec.dasConfig = New-Object VMware.Vim.ClusterDasConfigInfo
$spec.dasConfig.admissionControlPolicy = New-Object VMware.Vim.ClusterFailoverHostAdmissionControlPolicy
$spec.dasConfig.admissionControlPolicy.failoverHosts = @($failoverHost.ExtensionData.MoRef)
$cluster.ExtensionData.ReconfigureComputeResource($spec, $true)
Phương án 3: Tắt Admission Control — không khuyến nghị
Một số team tắt hoàn toàn để “linh hoạt” hơn. Nhưng khi failover thật xảy ra, cluster có thể không đủ tài nguyên restart VM — VM sẽ chết vĩnh viễn thay vì được restart sang host khác. Rủi ro không đáng.
Tối ưu DRS Migration Threshold
Sau khi thử lần lượt từng mức trong vài tuần trên production:
- Level 1–2: Gần như không vMotion gì, imbalance kéo dài. Một host chạy 80% trong khi host khác 30%.
- Level 3: VMware chỉ vMotion khi imbalance rõ rệt (>12% difference). Phù hợp hầu hết workload.
- Level 4–5: vMotion liên tục, storage I/O cao, DB VM bị ảnh hưởng.
Level 3 là điểm cân bằng tốt nhất. Quan trọng hơn, nên set VM Override cho các database VM để chúng không bị DRS tự ý di chuyển:
# Set DRS Manual cho VM nhạy cảm với latency
$vm = Get-VM -Name "sql-server-01"
$clusterSpec = New-Object VMware.Vim.ClusterConfigSpecEx
$vmOverride = New-Object VMware.Vim.ClusterDrsVmConfigSpec
$vmOverride.operation = [VMware.Vim.ArrayUpdateOperation]::add
$vmOverride.info = New-Object VMware.Vim.ClusterDrsVmConfig
$vmOverride.info.key = $vm.ExtensionData.MoRef
$vmOverride.info.enabled = $true
$vmOverride.info.behavior = [VMware.Vim.DrsBehavior]::manual
$clusterSpec.drsVmConfigSpec = @($vmOverride)
$cluster.ExtensionData.ReconfigureComputeResource($clusterSpec, $true)
Write-Host "$($vm.Name): DRS đặt Manual — sẽ không tự vMotion"
Cách tốt nhất: Kết hợp cả hai và monitor định kỳ
Config cuối cùng sau 6 tháng chạy ổn định:
- Admission Control: Percentage-based, 25% CPU + 25% RAM
- DRS Level: 3 (Balanced)
- Database VM: DRS Manual override
Script health-check chạy hàng ngày để phát hiện sớm nếu có host bắt đầu overload:
# health-check-cluster.ps1
Connect-VIServer -Server vcenter.lab.local -User [email protected] -Password $env:VCENTER_PASS
$cluster = Get-Cluster -Name "Production-Cluster"
$hosts = Get-VMHost -Location $cluster
Write-Host "=== Cluster Health Check ===" -ForegroundColor Cyan
Write-Host "HA: $($cluster.HAEnabled) | DRS: $($cluster.DrsEnabled)"
foreach ($vmhost in $hosts) {
$cpuPct = [math]::Round(($vmhost.CpuUsageMhz / $vmhost.CpuTotalMhz) * 100, 1)
$memPct = [math]::Round(($vmhost.MemoryUsageMB / $vmhost.MemoryTotalMB) * 100, 1)
$warn = if ($cpuPct -gt 80 -or $memPct -gt 85) { "[WARN]" } else { "[OK] " }
Write-Host "$warn $($vmhost.Name) | CPU: $cpuPct% | RAM: $memPct%"
}
# Kiểm tra VM bị tắt HA restart
$dasConfigs = $cluster.ExtensionData.Configuration.DasVmConfig
$disabledCount = ($dasConfigs | Where-Object { $_.DasSettings.RestartPriority -eq 'disabled' }).Count
Write-Host "`nVM với HA restart disabled: $disabledCount"
So sánh nhanh với Proxmox HA
Dùng Proxmox cho lab cá nhân sau đó, cái đập vào mắt ngay: không có Admission Control, không có DRS. Tạo HA Group, thêm VM vào, xong. Đơn giản hơn hẳn — phù hợp lab hoặc SMB nhỏ không cần kiểm soát chi tiết.
VMware hơn ở chỗ có thể pin VM vào specific host, đặt reservation và limit, rồi để DRS tự tối ưu trong khuôn khổ đó. Nhưng Proxmox thắng ở visibility — HA log rõ hơn, debug dễ hơn khi VM fail to restart. Mò trong vSphere Event log thì… không phải trải nghiệm vui.
Tóm lại chỉ cần hai thay đổi: đừng để Admission Control ở Slot Policy mặc định khi cluster có VM với reservation cao — chuyển sang Percentage-based với ngưỡng 1/N × 100%. Và set DRS Level 3 kèm Manual override cho workload nhạy cảm với latency. Hai cái này tránh được khá nhiều incident không đáng có.
