Graceful Shutdown VMware ESXi khi mất điện: Cấu hình đúng để VM không bị corrupt

VMware tutorial - IT technology blog
VMware tutorial - IT technology blog

Mình quản lý cluster VMware với 8 host ESXi tại công ty, và sự cố đau nhất xảy ra đúng lần đầu tiên UPS hết pin mà chưa cấu hình graceful shutdown — 3 database VM bị corrupt file, mất 6 tiếng đồng hồ để recover. Từ đó, sau mỗi lần cài ESXi mới, cấu hình graceful shutdown là việc đầu tiên mình làm, không bao giờ bỏ qua.

Làm ngay trong 5 phút: Bật Graceful Shutdown trên ESXi

Chỉ cần 2 bước để có graceful shutdown cơ bản. Phần nâng cao (tích hợp UPS) làm sau.

Bước 1: Kiểm tra VMware Tools trên tất cả VM

Không có VMware Tools, ESXi không thể gửi lệnh shutdown xuống guest OS — nó sẽ cắt điện thẳng. SSH vào ESXi host và chạy:

# Kiểm tra trạng thái VMware Tools của tất cả VM đang chạy
for vmid in $(vim-cmd vmsvc/getallvms | awk 'NR>1 {print $1}'); do
  status=$(vim-cmd vmsvc/tools.getStatus $vmid 2>/dev/null \
    | grep toolsStatus | awk '{print $3}')
  name=$(vim-cmd vmsvc/getallvms | awk -v id=$vmid '$1==id {print $2}')
  echo "VM $vmid ($name): $status"
done

Kết quả mong muốn là toolsOk cho tất cả VM. VM nào đang hiện toolsNotInstalled hoặc toolsNotRunning mà mất điện sẽ bị force-off không thương tiếc — cài hoặc khởi động lại VMware Tools trên VM đó trước khi tiếp tục.

Bước 2: Cấu hình Autostart/Shutdown trong ESXi

Truy cập ESXi embedded host client tại https://<esxi-ip>/ui (hoặc vSphere Client nếu có vCenter):

  1. Chọn HostManageSystemAutostart
  2. Click Edit Settings
  3. Bật EnabledYes
  4. Set Stop actionGuest Shutdown — quan trọng: KHÔNG chọn Power Off
  5. Set Stop delay: 120 giây (thời gian chờ mỗi VM tắt xong)
  6. Click OK

Sau đó vào tab Virtual Machines, thêm từng VM vào danh sách và đặt thứ tự ưu tiên. Xong — graceful shutdown đã hoạt động khi admin tắt host hoặc khi UPS gửi lệnh shutdown.

Hiểu đúng về Graceful vs Force Shutdown

ESXi có hai cách tắt VM, và sự khác biệt không chỉ là kỹ thuật — nó quyết định dữ liệu còn hay mất:

  • Power Off: Cắt điện ngay lập tức, như rút dây. File system không kịp flush buffer, database transaction đang dở dang bị mất, Windows NTFS có thể cần chkdsk khi khởi động lại.
  • Guest Shutdown: Gửi signal shutdown xuống OS thông qua VMware Tools, chờ OS tự dọn dẹp và tắt sạch sẽ. An toàn hoàn toàn với file system và database.

Lần mình gặp Power Off bất ngờ, con MySQL VM cần 20 phút chạy InnoDB recovery khi restart — và đó còn là tình huống may. Có những lần corruption không tự fix được, phải restore từ backup mới xong.

Thứ tự tắt VM quan trọng hơn bạn nghĩ

Hầu hết stack production đều có dependency chain — app server cần database, message queue cần consumer đang chạy. Tắt sai thứ tự, connection pool bị cắt giữa chừng và error log sáng hôm sau sẽ rất xấu. Thứ tự mình đang dùng:

  1. App servers, Web servers (tắt trước nhất)
  2. Cache servers (Redis, Memcached)
  3. Message queue (RabbitMQ, Kafka)
  4. Database servers — MySQL, PostgreSQL (tắt sau cùng)
  5. Infrastructure VMs như AD, DNS (tắt cuối nếu có)

Trong ESXi Autostart, số thứ tự nhỏ hơn = khởi động sớm hơn = tắt trễ hơn. Đặt database VM ở Order 1 để nó được tắt sau cùng.

Nâng cao: Tích hợp UPS để tự động kích hoạt Shutdown

Cấu hình graceful shutdown trong ESXi mới giải quyết được cách tắt. Phần còn lại là ai ra lệnh cho ESXi tắt khi điện mất — đó là việc của UPS management software.

Phương án 1: APC PowerChute Network Shutdown

Nếu dùng UPS APC với Network Management Card (NMC), PowerChute Network Shutdown (PCNS) là lựa chọn ổn định nhất và ít cấu hình nhất. Cài PCNS trên một VM Linux trong cluster:

# Download PCNS từ trang APC/Schneider Electric
# Giải nén và chạy installer
tar -xzf PowerChute-Network-Shutdown-*.tar.gz
cd PowerChute-Network-Shutdown/
sudo ./install.sh

# Sau khi cài, truy cập web UI tại https://localhost:6547
# Cấu hình: Events → Add ESXi Host → nhập IP + credentials
# Threshold: bắt đầu shutdown khi pin < 50% hoặc runtime còn < 5 phút

PCNS giao tiếp trực tiếp với VMware API, shutdown VM theo đúng thứ tự Autostart đã cấu hình, rồi mới tắt host. Không cần script thêm.

Phương án 2: NUT + PowerCLI Script (cho UPS không phải APC)

2 trong số 8 host của mình dùng UPS CyberPower — không có PCNS. Giải pháp là NUT (Network UPS Tools) kết hợp PowerShell script:

# Cài NUT trên Linux server kết nối UPS qua USB
sudo apt install nut nut-client

# /etc/nut/ups.conf
[cyberpower]
  driver = usbhid-ups
  port = auto
  desc = "CyberPower 1500VA"

# /etc/nut/upsmon.conf — thêm dòng này
MONITOR cyberpower@localhost 1 admin yourpassword master
SHUTDOWNCMD "/usr/local/bin/shutdown-vmware.sh"
MINSUPPLIES 1
#!/bin/bash
# /usr/local/bin/shutdown-vmware.sh
# NUT gọi script này khi UPS battery xuống ngưỡng nguy hiểm

ESXI_HOST="192.168.1.100"
ESXI_USER="root"
ESXI_PASS="your-password"

echo "$(date '+%Y-%m-%d %H:%M:%S') - UPS battery low, initiating graceful shutdown" \
  >> /var/log/ups-shutdown.log

# Gọi PowerShell script shutdown VM theo thứ tự
pwsh -NonInteractive -File /usr/local/bin/vmware-shutdown.ps1 \
  -Server "$ESXI_HOST" -User "$ESXI_USER" -Password "$ESXI_PASS"
# /usr/local/bin/vmware-shutdown.ps1
param([string]$Server, [string]$User, [string]$Password)

Connect-VIServer -Server $Server -User $User -Password $Password -Force

# Shutdown VM theo thứ tự name (hoặc custom sort theo tag/notes)
$vms = Get-VM | Where-Object { $_.PowerState -eq "PoweredOn" } | Sort-Object Name -Descending

foreach ($vm in $vms) {
  if ($vm.ExtensionData.Guest.ToolsStatus -eq "toolsOk") {
    Write-Host "Graceful shutdown: $($vm.Name)"
    Shutdown-VMGuest -VM $vm -Confirm:$false
  } else {
    Write-Host "Force stop (no tools): $($vm.Name)"
    Stop-VM -VM $vm -Confirm:$false
  }
}

# Chờ tất cả VM tắt, tối đa 3 phút
$timeout = 180; $elapsed = 0
while ($elapsed -lt $timeout) {
  $running = (Get-VM | Where-Object { $_.PowerState -eq "PoweredOn" }).Count
  if ($running -eq 0) { break }
  Start-Sleep -Seconds 5; $elapsed += 5
  Write-Host "$running VMs still running... ($elapsed/$timeout sec)"
}

Set-VMHostState -VMHost $Server -State Shutdown -Confirm:$false
Disconnect-VIServer -Confirm:$false

Tips thực tế sau 6 tháng chạy production

Test định kỳ — đừng đợi đến lúc mất điện thật mới biết không hoạt động

Mình đặt lịch test vào tối cuối tháng. Dùng lệnh này từ ESXi shell để xem thứ tự shutdown hiện tại và test logic mà không tắt host thật:

# Xem thứ tự autostart/autostop đang được cấu hình
vim-cmd hostsvc/autostartmanager/get_autostartsequence

# Trigger autostop thủ công để test (sẽ shutdown các VM theo thứ tự)
# Dùng trong maintenance window, không phải giờ peak
vim-cmd hostsvc/autostartmanager/autostop

Set timeout phù hợp với từng loại workload

Windows VM thường cần 60–90 giây. Linux VM nhanh hơn, 15–30 giây. Database VM đang có nhiều write có thể cần 3–5 phút để flush transaction log hoàn toàn. Mình set default stop delay là 180 giây, riêng con PostgreSQL production được set 300 giây trong Autostart VM settings.

Monitor VMware Tools health định kỳ

Tools có thể crash sau OS update hoặc kernel upgrade mà không ai hay — đến lúc mất điện thật thì nó đã không chạy từ hôm qua rồi. Script check sau chạy mỗi đêm qua cron trên management VM:

#!/bin/bash
# Chạy từ ESXi shell — cảnh báo VM có tools không hoạt động
for vmid in $(vim-cmd vmsvc/getallvms | awk 'NR>1 {print $1}'); do
  status=$(vim-cmd vmsvc/tools.getStatus $vmid 2>/dev/null \
    | grep toolsStatus | awk '{print $3}')
  name=$(vim-cmd vmsvc/getallvms | awk -v id=$vmid '$1==id {print $2}')
  [ "$status" != "toolsOk" ] && echo "WARNING: $name ($vmid): $status"
done

Với vSAN hoặc shared storage, thứ tự quan trọng hơn

vSAN cần thêm một bước: dismount datastore trước khi tắt host để tránh split-brain. Với NFS/iSCSI, unmount datastore sau khi tất cả VM đã tắt là đủ. Đây là điểm mà PCNS xử lý tốt hơn script thủ công — nó biết thứ tự đúng cho từng loại storage.

Sau khi triển khai đầy đủ setup này, cluster của mình đã qua 3 lần mất điện thực tế mà không có VM nào bị corrupt. Cấu hình mất 2–3 tiếng — đổi lại không mất data và không phải giải thích với khách hàng tại sao database của họ bị lỗi.

Share: