LoginSignup
0
0

WindowsホストOSを定期再起動させているHyper-VゲストのWebサービスが「VM再起動」だけでは時々仮想ネットワークの疎通が取れないことがあったので「VM停止(電源OFF)→VM起動」も加えてみた

Posted at

1. 発生していた課題

WindowsホストOSを定期アップデート目的で「タスクスケジューラ」にて「毎週水曜日3:00にホストOS再起動(shutdown -r -t 30)」を行っていました。

「Hyper-V」の「自動開始アクション」でも「サービスが停止したときに実行されていた場合は自動的に起動する」にしているので、大抵はホストOSのWindowsアップデート後の再起動でゲストのVMもWebサービスを再開できているのですが、
時々仮想ネットワークとの疎通がとれていない事態が発生していたので、
PowerShellで「curlによるHTTPレスポンスコードが000と404の時にVM再起動(Restart-VM -Name $vm.Name -Force)」を作成し「タスクスケジューラ」にて毎日6:00~7:00の15分間隔で実行するように設定し運用していました。

修正前のPowerShellコード(クリックで表示)

# テストでは利用するアカウントを Hyper-V Administrators にも所属させておくこと #

# 監視するURLを入力 #
 $URL = "<監視したいURL>"

# レスポンスコードを取得(ただしこの構文はHTTPのみ。HTTPSは --insecure処理必要) #
 $CODE = curl.exe -o NUL -w "%{http_code}" -s $URL
 write-host $CODE
 $DATE = Get-Date -Format "yyyy/MM/dd HH:mm:ss"
 write-output "$DATE [ $URL ] CODE: $CODE`r`n" |Out-File -NoNewline -Append .\WebAccessRepair.log

# コードが000または404である時は全てのVMを再起動させる #
 if ( $CODE -eq "000" -Or $CODE -eq "404" )
 {
    foreach($vm in Get-VM | Select Name)
	{
	# VM再起動 #
	write-host $vm.Name "VM再起動"
	Restart-VM -Name $vm.Name -Force
	Start-Sleep -s 5	# 5秒待機 #
	}

しかし、この対策でも、HTTPレスポンスコードが000のままWebサービスが再開できていない事象が発生してしまいました。。
1_status000になってしまった...png
(「CODE: 000」のまま復旧しなかった。。)

2. 回避策の実施

サービス停止が発生してしまったHyper-Vゲストの状態は「停止」であったり、
またはゲストOSは起動しているが、仮想ネットワークとは疎通がとれておらず手動再起動させないとならない状態であることも発生していたので、
ホストOSの再起動のタイミングとHyper-Vサービス終了と再開が上手く合わずにこれら事象が発生していたのでしょうが、それは「VM再起動」だけでは解決できない様でした。

そこで、初回は「VM再起動」を試みるが、2回目もHTTPレスポンスコードが000または404の場合は「VM停止(電源OFF)→VM起動」を行うようにコードに追記しました。


# テストでは利用するアカウントを Hyper-V Administrators にも所属させておくこと #

# 監視するURLを入力 #
$URL = "<監視したいURL>"

# レスポンスコードを取得(ただしこの構文はHTTPのみ。HTTPSは --insecure処理必要)  #
$CODE = curl.exe -o NUL -w "%{http_code}" -s $URL
write-host $CODE
$DATE = Get-Date -Format "yyyy/MM/dd HH:mm:ss"
write-output "$DATE [ $URL ] CODE: $CODE`r`n" | Out-File -NoNewline -Append .\WebAccessRepair.log

# 初回のVM再起動または2回目のVM停止と再起動を管理するフラグ
$restartFlag = $false

# コードが000または404である時は全てのVMを再起動させる #
if ($CODE -eq "000" -Or $CODE -eq "404") {
    # 初回のVM再起動
    if (-not $restartFlag) {
        foreach ($vm in Get-VM | Select Name) {
            # VM再起動 #
            write-host $vm.Name "VM再起動"
            Restart-VM -Name $vm.Name -Force
            Start-Sleep -Seconds 5 # 5秒待機 #
        }
        $restartFlag = $true
    }
    # 2回目のVM停止とVM起動
    else {
        foreach ($vm in Get-VM | Select Name) {
            # VM停止 #
            write-host $vm.Name "VM停止(電源OFF)"
            Stop-VM -Name $vm.Name -TurnOff
            Start-Sleep -Seconds 5 # 5秒待機 #
            # VM起動 #
            write-host $vm.Name "VM起動"
            Start-VM -Name $vm.Name
            Start-Sleep -Seconds 10 # 10秒待機 #
        }
    }
}

3. 効果の確認

動作ログを見ていましたら、たまたま発生していた記録がありました。
この発生日もWebサービスはうまく再開できていたようなので気が付きませんでしたが、
対策は上手くできたと判断しました。
2_status000から復帰できている.png
(「CODE: 000」が発生しましたが、再開できて「CODE: 200」が返ってきている)

以上です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0