以PowerShell指令碼進行VM的Clone備份
一、緣起
1、專業的VM線上備份軟體每套都不便宜,不是以CPU計價,就是以台數計價。若以公司全部ESX主機來算,挺貴的。
2、在與主管討論後,採取折衷方案,將目前虛擬機分為兩大類。
A類備份週期比較短的,每天備份一次,服務為線上交易類為主,有類似SQL高度交易的程序。
B類備份週期較長。一周甚至一個月備份一次都可以。如Printer Server、Terminal Server之類的。
3、然後將A類虛擬機,集中於兩台伺服器上,共四顆CPU。因此備份軟體先以備份此兩台,四顆CPU為主。
4、其餘伺服器上的虛擬機,先以Clone的方式複製一份出來,由於Clone出來的虛擬機為關機狀態,因此透過網路的方式,下載到網路分享的路徑。以達到備份目的。週期以一周為主。
5、Clone雖然可以透過vCenter排程的方式進行,但是下載不行。如果可以將一連串動作,以指令排程的方式進行,就可以減輕管理員的負擔。
二、程式碼
這是PowerShell程式。
#--------- Function - dumpvm() - Clone VM ------------
Function dumpvm( $vm , $cloneName ){
$cloneFolder = $vm.Parent
$cloneSpec = New-Object VMWare.Vim.VirtualMachineCloneSpec
$cloneSpec.Location = New-Object VMWare.Vim.VirtualMachineRelocateSpec
$cloneSpec.Location.Datastore = ( Get-Datastore -VM $vm.Name | Get-View ).MoRef
$clonevm = Get-VM -Name $cloneName #嘗試取得舊的clone
if( $clonevm -eq $null ){
Write-Host $clonevm " 不存在"
}else{
# 如果有舊的clone就殺掉
Write-Host "有舊的 " $clonevm " 存在,嘗試刪除"
Remove-VM -DeleteFromDisk:$true -VM $clonevm -Confirm:$false
}
$cloneSpec.Snapshot = $vm.Snapshot.CurrentSnapshot
$cloneSpec.Location.Transform = [VMware.Vim.VirtualMachineRelocateTransformation]::sparse
#Clone VM 給備分用
$vm.CloneVM( $cloneFolder , $cloneName , $cloneSpec )
}
#--------- Function - backupvm() - Copy VM to CIFS Location ------------
Function backupvm( $vm , $cloneName , $destRootPathStr ){
#拷貝 Clone 的備分到網路路徑
$ds = Get-Datastore -VM $vm.Name -Name "Storage1"
New-PSDrive -Name myds -PSProvider vimdatastore -Root "\" -location $ds
#確認備份路徑是否存在
$destDir = New-Object System.IO.DirectoryInfo( $destRootPathStr+"\"+$cloneName )
if ( !$destDir.Exists ) {
#不存在就建立
$rootPath = New-Object System.IO.DirectoryInfo( $destRootPathStr )
#建子目錄
$rootPath.CreateSubdirectory( $cloneName )
}
$destFullPath = $destRootPathStr+"\"+$cloneName
New-PSDrive -Name dest -PSProvider Filesystem -Root $destFullPath
#拷貝 Clone 的 VM 過去
Copy-DatastoreItem myds:\$cloneName\* -Destination "dest:\"
#拷貝完畢 刪除clone
#嘗試重新取得clone
$clonevm = Get-VM -Name $cloneName
if( $clonevm -eq $null ){
Write-Host $clonevm " 不存在"
}else{
# 如果有clone就殺掉
Write-Host "拷貝完畢刪除 " $clonevm
Remove-VM -DeleteFromDisk:$true -VM $clonevm -Confirm:$false
}
}
Add-PSSnapin VMWare.VimAutomation.Core
#讀入清單
$backuplists = Import-Csv "backuplists.csv"
Write-Host $backuplists.Count
#接上VC
Connect-VIServer -Server "192.168.1.66" -User "Domain\User" -Password "password
for ($backuploop = 0; $backuploop -lt $backuplists.count ; $backuploop++) {
#要被備份的VM
$vm = Get-VM -Name $backuplists[$backuploop].VMName | Get-View
#準備要Clone到VM的名稱
$cloneName = "clone-"+$vm.Name
#備份主路徑
$destRootPathStr = $backuplists[$backuploop].backupPath
dumpvm $vm $cloneName
backupvm $vm $cloneName $destRootPathStr
}
#中斷VC連接
Disconnect-VIServer -Confirm:$false
三、程式碼流程說明
前提:有架設vCenter,因此程式碼會連入vCenter(以下簡稱VC)進行操作,故有些指令是VC獨有的。如果是ESX就應該使用New-VM的方式做,而不是用CloneVM。
1、準備一個CSV檔,程式會由CSV檔,讀入要備份的VM名稱,及要備份到的主路徑(網路共享路徑也可以)。
2、連入VC
3、根據VM名稱,取得VM。
4、定義Clone的VM名稱。( 這裡一概以 『 clone-VM原來名稱 』作為Clone產生VM的名稱 )
5、Clone VM ( 由 dumpvm函式負責 )
6、拷貝Clone完的 VM 到網路上。(由 backupvm 函式負責)
7、關閉VC連接。
dumpvm函式
1、CloneVM必須具備3個參數。
$vm.CloneVM_Task( $cloneFolder, $cloneName, $cloneSpec )
cloneName:
就是Clone完的VM名稱。這裡一概以 『 clone-VM原來名稱 』作為Clone產生VM的名稱。
cloneFolder:
必須指定Clone到哪個目的資料夾,如果我們希望放在與目前的VM相同位置底下,只要設定給這個變數為目前VM的『parent』值即可。
cloneSpec:
這是一個有趣的參數,其他雜七雜八的參數都在這。其引用的物件命名空間來自於『 Vmware.Vim.VirtualMachineCloneSpec 』。因此必須使用New-Object引用。另外還必須建立來自『 VMWare.Vim.VirtualMachineRelocateSpec 』的物件,這是為了指定 『 $cloneSpec.Location 』下面相關屬性。比如:Target host、datastore、cluster、resource pool之類。但不是全部都要設,視情況而定。在這裡我們只針對下列幾個項目設定
Datastore:
指定與來源VM相同的儲存裝置。
Transform:
VMware.Vim.VirtualMachineRelocateTransformation 只有兩個值。『 sparse 』或『 flat 』。『 sparse 』表示Thin provisioned,屬於thin disk。『 flat 』相反,建立的是thick disk。至於Thin或Thick的定義及區別,另參照VMWare相關技術文章,在此不贅述。
2、$cloneSpec.Snapshot:
一般而言,我們Clone時,大部分希望是以VM目前的狀態為主。當然也可以透過CloneVM 的API控制,使Clone的對象是之前的Snapshop。如果這地方不特別指定,就以 current state 為主。如果要更精確的話,應該在CloneVM動作之前,先進行一次Snapshop動作,然後指定該Snapshop為Clone的版本。
3、中間有一段判別式,如果有相同名稱的Clone存在的話,則刪除之,再進行Clone。
以PowerGUI觀察cloneSpec的相關屬性
$cloneSpec.Location
backupvm函式
1、兩個重點,從哪裡來,拷貝到哪裡去。
2、New-PSDrive會建立與資料存放區中任一位置 (例如網路磁碟機、本機電腦上的目錄或登錄機碼) 對應或關聯的 Windows PowerShell 磁碟機。vimdatastore 代表磁碟類型為VMWare Datastore。Filesystem本機目錄或網路磁碟機都是用這個。
3、以Copy-DatastoreItem方法,將VM資料夾拷貝到網路上備份。
四、排程執行
使用排程工具,執行內容指令如下
powershell [指令檔完整路徑]
例如:
powershell C:\Scripts\
五、後記
1、程式碼中間有一段為嘗試抓取以Clone-XXXXX為名的VM,以便偵知是否已有同名的VM存在,決定是否直接Clone或先刪除舊的Clone VM。若無抓到同名的Clone VM,會有錯誤訊息,不過測試結果並不影響後續作業,個人因此不特別處理。可以用偵錯或乾脆拿掉這段,以避免礙眼。
2、Clone + Copy的方式極為耗時,且因為拷貝出來的VM檔案,脫離VMFS格式,檔案會與原先設定硬碟大小相同,不再支持Thin格式。因次備份空間應以VM的硬碟加總大小,在多加一些迴轉空間,以避免失敗。同時因為備分時間不算短,如過公司VM挺多的時候,最好還是要分批處理,個人實作時,以一周為周期,星期五晚上開始做,每周做5-6個VM,下周換另一批。
3、這種方式並不能取代較為專業的備份軟體,因為這些軟體大多針對備份最佳化,支持壓縮、去除重複數據,且速度也較快。同時高交易服務性質的VM,仍應當交給專業備份軟體處理。這種方式可以做為另一種保險方式。