VMが再起動しない
ある日のこと,ESXiをメンテナンスモードにしてシャットダウンしてみた.
「よし,メンテ完了!じゃあ作業再開だ!」と意気揚々とVMを操作するも,なぜかVMが動かない.
「あれ?このVM自動起動設定いれてたよね?」と思ったら,原因はESXiがまだメンテナンスモードのままだったこと.
まぁ,そりゃそうだよね,とモードを解除してリトライ.……が,それでもVMは立ち上がらない.
「え,なんで?再起動くらい普通にしてくれてもいいじゃん……」とちょっと困惑.
軽くググってみたけど,これといった解決策は見つからず.
ならば,自分で解決策を作るしかない!ということで,今回の冒険が始まりました.
解決作
自動起動設定されたVMだけを,再起動したかったのでESXiから再起動設定されたVMの識別できないかぁ?と思って調べたところ
#ESXiの再起動設定されたVM名置き場
hostsvc/autostartmanager/get_autostart
という場所に再起動されたVMのリストが格納されていた.
ここから,VMのIDが取得できることに気づいたので後は簡単
適当にpythonでメンテナンスモードを解除するプログラムと,自動起動設定されたVMを起動するプログラムを作って,ESXiの再起動時にメンテナンスモード→自動起動設定されたVMを起動するようにすれば,ESXi起動時にメンテナンスモードも解除されてVMが自動起動されました.
# メンテナンスモードを解除する関数
def exit_maintenance_mode(hostname, username, password):
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
while True:
try:
client.connect(hostname, username=username, password=password)
stdin, stdout, stderr = client.exec_command('vim-cmd hostsvc/maintenance_mode_exit')
output = stdout.read().decode().strip()
error = stderr.read().decode().strip()
# メンテナンスモード解除の結果をチェック
if "vim-cmd" not in output and not error:
print(f"メンテナンスモードの解除に成功しました: {hostname}")
break # 成功したらループを抜ける
print(f"Output: {output}")
print(f"Error: {error}")
except Exception as e:
print(f"接続失敗({hostname})。再試行します。Error: {e}")
finally:
client.close()
time.sleep(60) # 再試行まで待機する
# 自動起動設定されたVMを起動する関数
def start_autostart_vms(hostname, username, password):
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
client.connect(hostname, username=username, password=password)
stdin, stdout, stderr = client.exec_command('vim-cmd hostsvc/autostartmanager/get_autostart')
output = stdout.read().decode().strip()
error = stderr.read().decode().strip()
if error:
print(f"Error: {error}")
return
auto_start_vms = []
for line in output.split("\n"):
if "vim.VirtualMachine:" in line:
vm_id = line.split("'")[1].split(":")[1]
auto_start_vms.append(vm_id)
for vm_id in auto_start_vms:
print(f"Starting VM: {vm_id}")
client.exec_command(f'vim-cmd vmsvc/power.on {vm_id}')
except Exception as e:
print(f"Error: {e}")
finally:
client.close()
終わりに
実はこれ,もうちょっと課金してvCenter Serverを導入すれば解決していた問題だったかもしれない.
というわけでESXiとセットでvCenter Serverもいかがでしょうか?