У меня есть Windows Server 2012R2 hyper-v хост. Это выполняет много VMs, включая некоторых Linux VMs.
У меня есть один Linux VM, который был occationally, но несколько регулярно отказывающий где-нибудь в ядре, приводящем к становлению VM абсолютно безразличным.
Я знаю, что hyper-v имеет средство "heartbeat", и он успешно обнаруживает VM, отказывающий как потеря heartbeat.
Однако я в замешательстве относительно того, как настроить hyper-v так, чтобы он на самом деле сделал что-либо с сигналом подтверждения работоспособности. По-видимому, однажды была опция сбросить VM, если heartbeat потерян для> 1 минута, но это было или удалено или помещено куда-нибудь, я не могу найти.
У меня только есть этот сервер, таким образом делание вещей как кластеризация или обработка отказа не действительно жизнеспособно (это - домашний сервер лаборатории).
Прежде чем любой прокомментирует, Да, я пытаюсь разыскать причину катастрофического отказа в VM, но это - неисправность, мешал.
powerhell - это ваше спасение:
$VM = Get-VMIntegrationService -VMName test-vm -Name Heartbeat
if ($VM.PrimaryStatusDescription -ne "OK")
{
write-host "VM Dead ? restarting ..."
Stop-VM test-vm -Force -TurnOff
Start-VM test-vm
}
Просто добавьте это в планировщик задач.
Если ваша ВМ не поддерживает сердцебиение, то измените это на ping ВМ вместо проверки HB.
.Мне нужно было решение для мониторинга пульса всех виртуальных машин Hyper-V и автоматического выполнения аппаратного сброса при блокировке виртуальной машины. Как вы, наверное, уже знаете. кажется, что вы можете сделать это с помощью Hyper-V, когда у вас настроен кластер, но только с одним хостом Hyper-V, что невозможно без некоторых настраиваемых сценариев.
Я нашел хороший VBS, который отслеживает сердцебиение всех систем и даже имеет настраиваемое количество повторных попыток и льготный период в последней версии . Исходный сценарий и описание можно найти здесь . Было бы неплохо запланировать это для запуска при запуске системы (не помещайте его просто в папку автозагрузки, потому что это потребует от администратора Hyper-V входа в систему до того, как скрипт запустится).
Использование: - Скопируйте сценарий VMHeartBeat.vbs в любое место по вашему выбору. - Либо дважды щелкните сценарий, либо откройте командную строку, перейдите в папку, в которую скопирован сценарий, и затем запустите cscript.exe. VMHeartBeat.vbs
Примечание. Если дважды щелкнуть мышью скрипт wscript.exe или в зависимости от того, какой движок сценариев по умолчанию будет использоваться для запуска сценарий. Когда вы используете cscript.exe,вам нужно сохранить командное окно всегда открыт.
Этот сценарий создаст файл журнала в том же месте, что и сценарий. и продолжайте добавлять к нему события успеха / неудачи. Имя файла журнала VMHeartBeatEvents.log
Вот и все. Все готово для обнаружения потери пульса виртуальной машины, а затем выполнения аппаратного сброса.
Чтобы проверить, работает ли скрипт, вы можете скачать NotMyFault.exe , а затем скопируйте его на виртуальную машину. Теперь просто беги VMHearBeat.vbs на хосте Hyper-V и откройте notmyfault.exe внутри ВМ, выберите ошибку и нажмите «Do Bug». В зависимости от того, какой тип ошибки вы выберите, ВМ может синий экран. На данный момент VMHearBeat.vbs обнаружил бы потерю сердечного ритма и выполнил бы полный сброс виртуальная машина. Вы можете проверить файл журнала, как упоминалось ранее, чтобы узнать, был ли аппаратный сброс успешным или нет.
Чтобы сохранить сценарий, я также вставил последнюю версию кода .VBS (с количеством повторов и льготным периодом) ниже.
ОБНОВЛЕНИЕ: В последней версии сценария действительно были некоторые ошибки, поэтому приведенный ниже сценарий был изменен, и я подтвердил, что он работает на Server 2012R2. \ v2
необходимо добавить в строку №20, а 10
необходимо изменить на 11
в строке №4 функции VMHardReset
.
Option Explicit
'Define Event log constants here
Const EVENT_INFO = 4
Const EVENT_ERROR = 1
Const RETRY_COUNT = 3
Const CHECK_EVERY_X_SECS = 6
Dim objSummaryInfo, objWMIService, objVMService, intValArray, objVMitems
Dim InParam, OutParam, objItem, strQuery
Dim Job, objShell
Dim colArgs, strLog, dict, compName
Set colArgs = WScript.Arguments.Named
'Get Command Line arguments in to some variables
strLog = colArgs.Item("log")
Set objShell = Wscript.CreateObject("Wscript.Shell")
Set objWMIService = GetObject("winmgmts:\\" & "." & "\root\virtualization\v2")
Set objVMService = objWMIService.ExecQuery("SELECT * FROM Msvm_VirtualSystemManagementService").ItemIndex(0)
intValArray = Array(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199)
Set dict = CreateObject("Scripting.Dictionary")
While (1)
Wscript.echo(CStr(Now()) +": Testing Loop ")
objVMItems = objVMService.GetSummaryInformation(NULL,intValArray,objSummaryInfo)
for each objItem in objSummaryInfo
compName = objItem.ElementName
if (not dict.Exists(compName)) then
dict.add compName,0
end if
If (objItem.EnabledState=2 AND (objItem.HeartBeat = 6 OR objItem.HeartBeat = 13)) Then
dict.Item(compName)=dict.Item(compName)+1
WriteLog(" **"+compName+"** missed heartbeat check; count "+CStr(dict.Item(compName)))
if (dict.Item(compName) >= RETRY_COUNT ) then
dict.Item(compName)= 0
Wscript.echo(CStr(Now()) +": Now performing a hard reset on "+compName)
VMHardReset(compName)
end if
Else
dict.Item(compName)= 0
End If
Next
Set objVMItems=Nothing
Set objItem = Nothing
Set objSummaryInfo = Nothing
Wscript.Sleep CHECK_EVERY_X_SECS * 1000
Wend
Set objWMIService = Nothing
Set objVMService = Nothing
Set InValArray = Nothing
Function VMHardReset(vmElementName)
Dim objvm, strLine
Set objvm = GetComputerSystem(vmElementName)
Set InParam = objvm.Methods_("RequestStateChange").InParameters.SpawnInstance_()
InParam.RequestedState=11
Set OutParam = objvm.ExecMethod_("RequestStateChange",InParam)
If (TrackJob(OutParam)) Then
strLine = "Virtual Machine: " & vmElementName & " has been successfully recovered from a hearbeat failure"
'Write Success Event to text log
WriteLog(strLine)
Set strLine=Nothing
'Write a Windows Event Log
objShell.LogEvent EVENT_INFO, strLine
Else
strLine = "Virtual Machine: " & vmElementName & " could not be recovered from a hearbeat failure"
'Write Failure Event to text log
WriteLog(strLine)
Set strLine=Nothing
'Write a Windows Event Log
objShell.LogEvent EVENT_ERROR, strLine
End If
Wscript.echo(CStr(Now()) +": "+strLine)
Set InParam = nothing
Set objvm = nothing
Set vmElementName = Nothing
End Function
Function GetComputerSystem(vmElementName)
strQuery = "select * from Msvm_ComputerSystem where ElementName = '" & vmElementName & "'"
set GetComputerSystem = objWMIService.ExecQuery(strQuery).ItemIndex(0)
'Set GetComputerSystem = Nothing
Set strQuery = Nothing
End Function
Function TrackJob(OutParam)
Dim Job
If (OutParam.ReturnValue = 0) Then
TrackJob=True
ElseIf (OutParam.ReturnValue <> 4096) Then
TrackJob=False
Else
Set Job = objWMIService.Get(OutParam.Job)
While (Job.JobState = 3) or (Job.JobState = 4)
Set Job = objWMIService.Get(OutParam.Job)
Wend
If (Job.JobState <> 7) Then
TrackJob=False
Else
TrackJob = True
End If
End If
Set OutParam = Nothing
Set Job = Nothing
End Function
Sub WriteLog(line)
Dim objFileStream, objFileSystem
Set objFileSystem = CreateObject("Scripting.FileSystemObject")
Set objFileStream = objFileSystem.OpenTextFile("VMHeartBeatEvents.log", 8, true, -1)
objfileStream.WriteLine CStr(Now()) +": "+line
objfileStream.Close
Set objFileSystem = Nothing
End Sub