Как автоматически запускать и выключать машины VirtualBox?


52

Мне нужно запустить систему программного обеспечения, которая предназначена для установки в качестве устройства на выделенном компьютере. Чтобы сэкономить энергию, я планирую запустить систему на виртуальной машине VirtualBox.

Хост - это стандартная Linux-система с системой SysV-Init, гостем является сильно модифицированный Linux, и я бы предпочел не менять его дальше. VirtualBox используется в версии OSE.

Я уже разобрался, как запустить виртуальную машину при загрузке хоста ( Edit: это делается, как Никхил упоминал ниже, с помощью команды VBoxManager startvm), но как я могу корректно завершить работу VM? Любой скрипт, работающий на хосте, должен будет ждать, пока гость полностью не отключится.

Кто-нибудь может подсказать, как, например, должен выглядеть сервисный файл, делающий это?


не могли бы вы дать сценарий запуска для запуска виртуальной машины во время загрузки
— Beginner

Ответы:


34

Вы пробовали acpipowerbuttonиз этого набора команд?

VBoxManage controlvm        <uuid>|<name>
                            pause|resume|reset|poweroff|savestate|
                            acpipowerbutton|acpisleepbutton|

Редактировать после прочтения комментариев:

Вы можете использовать acpidили другие утилиты acpi, чтобы сделать его изящным. Кроме того, можете ли вы предоставить больше информации о том, как вы выключаете машину в данный момент?

Равнина shutdownне будет ждать незавершенных работ, задержка может быть слишком большой.

Я предполагаю, что вы не используете оконный менеджер, поэтому попробуйте этот инструмент.

Просто видел этого демона . Вы можете найти это полезным.


Спасибо за ваш ответ и добро пожаловать на unix.stackexchange.com! Тем не менее, я боюсь, что ваш ответ также не решает мою проблему: acpipowerbutton имитирует нажатие кнопки питания на реальной машине, но после выполнения этой команды на хосте виртуальной машине, опять же, потребуется некоторое время для выключения.
— Jstarek

4
Конечно. Таким образом, вы должны написать цикл, который проверяет, работает ли виртуальная машина. ACPI - точно такой же метод, который я использую в своих сценариях для этого. vboxmanage list runningvmsпока ваша ВМ не исчезнет.
— Нильс

Хорошо, хотя я думаю, что на практике я соглашусь на упаковку управления, +50 к вам за указание на начальный текст!
— Jstarek

16

Вместо того, чтобы кодировать это самостоятельно, рассмотрите возможность использования Vagrant , который создан для создания экземпляров и управления экземплярами виртуальных ящиков. Документация отличная, и я предлагаю вам проверить ее, а не пытаться накатить свою.

Суть в том, что вы создаете простой управляющий файл, а затем запускаете vagrant upдля запуска столько экземпляров VirtualBox, сколько хотите. Вы можете использовать vagrant sshдля входа в хосты и vagrant haltвыключить хост (без завершения). vagrant destroyизбавится от экземпляров.

Он поддерживает инициализацию с помощью Puppet, Ansible или Chef и позволяет вам контролировать большинство выставленных настроек конфигурации VBox.


2
Я фанат бродяги, но в таком случае, зачем тебе это? OP запускает устройство, а не создает свою собственную систему, поэтому подготовка полностью пропускает суть. И зачем идти и делать из устройства нестандартную «коробку», просто чтобы использовать vagrant, когда вы в основном проходите процесс сборки системы с виртуальной коробкой для этого?
— mc0e

10

У меня есть такое же приложение, как у вас, с одним отличием: мне нужно перезагрузить систему и восстановиться из снимка.

То, что вас интересует, это безголовый режим .

У меня есть несколько таких служб, поэтому я использую следующий скрипт:

VBox_StopRestoreStart.sh

#!/bin/bash
if [ -z "$1" ]; then
        echo "Usage: $0 VMNAME_or_UUID"
        exit 1
fi
set -x
VBoxManage controlvm  "$1" poweroff  #enforce turnoff
VBoxManage snapshot   "$1" restorecurrent   #retore state
VBoxManage showvminfo "$1" | grep State   #display state to ensure
VBoxHeadless -s       "$1"  #run in headless mode in background

как я могу изящно выключить ВМ?

Если вы хотите отключить виртуальную машину, у вас есть два варианта, в зависимости от вашего приложения:

  • Эмулируйте «кнопку выключения» или «спящую кнопку» и подготовьте виртуальную машину, чтобы она отреагировала на нее (изящно закрылась)
    • VBoxManage controlvm <uuid>|<VMname> acpipowerbutton
    • VBoxManage controlvm <uuid>|<VMname> acpisleepbutton
  • Сохранить состояние ВМ, чтобы потом восстановить
    • VBoxManage controlvm <uuid>|<VMname> savestate

СОВЕТЫ: ​​Вы можете найти полезное:

  • VBoxManage list vms - список доступных vms
  • rdesktop IP-ADDR:3389или rdesktop-vrdp IP-ADDR:3389- когда вам нужен графический интерфейс (даже удаленно ), когда вы работаете в автономном режиме:VBoxHeadless -s <uuid>|<VMname>
  • VBoxManage startvm - начать с графического интерфейса для локальной отладки

Соответствующая глава руководства VirtualBox: Глава 7. Удаленные виртуальные машины. Шаг за шагом: создание виртуальной машины на автономном сервере

PS Если вы заинтересованы в полнофункциональных уже реализованных решениях, OpenStack кажется интересным выбором.


10

Изучите документацию по управлению виртуальными машинами VirtualBox по адресу http://www.virtualbox.org/manual/ch08.html.

Для вывода списка виртуальных машин используйте команду VBoxManage list vms

Для запуска ВМ используйте команду VBoxManage startvm

http://www.virtualbox.org/manual/ch08.html#vboxmanage-controlvm

Для управления ВМ используйте VBoxManage controlvm

controlvmСубкоманда позволяет изменить состояние виртуальной машины , которая в настоящее время работает. Можно указать следующее:

VBoxManage controlvm <vm> pauseвременно приостанавливает работу виртуальной машины, не изменяя ее состояние навсегда. Окно виртуальной машины будет окрашено в серый цвет, чтобы указать, что виртуальная машина в данный момент приостановлена. (Это эквивалентно выбору пункта «Пауза» в меню «Машина» GUI.)

Используйте VBoxManage controlvm <vm> resumeдля отмены предыдущей команды паузы. (Это эквивалентно выбору пункта «Возобновить» в меню «Машина» GUI.)

VBoxManage controlvm <vm> resetна виртуальной машине действует так же, как нажатие кнопки «Сброс» на реальном компьютере: холодная перезагрузка виртуальной машины, которая немедленно перезапустит и снова загрузит гостевую операционную систему. Состояние виртуальной машины не сохраняется заранее, и данные могут быть потеряны. (Это эквивалентно выбору пункта «Сброс» в меню «Машина» GUI.)

VBoxManage controlvm <vm> poweroffдействует на виртуальную машину так же, как и на кабель питания на реальном компьютере. Опять же, состояние виртуальной машины не сохраняется заранее, и данные могут быть потеряны. (Это эквивалентно выбору пункта «Закрыть» в меню «Машина» графического интерфейса или нажатию кнопки закрытия окна, а затем выбору «Выключить машину» в диалоговом окне.)

После этого состояние виртуальной машины будет отключено.


Обратите внимание, что в некоторых системах это так vboxmanage(все в нижнем регистре).
— Arcege

2
Спасибо за ваш ответ, но, к сожалению, это не решает мою проблему: мне нужно изящно завершить работу гостя, т. Е. Выполнить «shutdown -h now» внутри гостевой системы и попросить хост подождать, пока гость полностью не выключится. Ни одна из VBoxManage controlvmподкоманд не делает этого.
— Jstarek

Вы можете убедиться, что, перепроверив все vms, не работают на хосте, прежде чем хост выйдет из строя. Если вам нужно управлять хостом изнутри гостя, то virtualbox.org/manual/ch08.html#vboxmanage-guestcontrol, но это может не дать вам того, что вы ищете. Вы должны написать скрипт запуска, такой как /etc/init.d/vboxvms-serviceскрипт, на хост-системе, который при запуске включит все vms и после остановки заставит все vms выключиться.
— Nikhil Mulley

VBoxManage controlvm savestateЭто еще одна возможность (по крайней мере, Google говорит мне), она сохраняет состояние компьютеров и корректно завершает работу, но по-прежнему не может заставить хост ждать.
— Баарн

5

Для системной системы вы можете попробовать это.

Шаг № 1: создать сервисный файл

[Unit]
Description=VBox Virtual Machine %i Service
Requires=systemd-modules-load.service
After=systemd-modules-load.service

[Service]
User=user
Group=vboxusers
ExecStart=/usr/bin/VBoxHeadless -s %i
ExecStop=/usr/bin/VBoxManage controlvm %i savestate

[Install]
WantedBy=multi-user.target

Шаг № 2: Включить служебный файл

$ sudo systemctl enable vboxvmservice@vm_name.service

Рекомендации


1
Здесь желательно включить ответ и при необходимости предоставить ссылки на более подробную информацию. Цели ссылок исчезают без уведомления, что делает ваш ответ бесполезным.
— Антон

Ну, проблема в том, что я не могу скопировать весь файл systemd в ссылке 1 здесь, или я должен это сделать?
— Ян Рюегг

Что ж, к сожалению, «гниение ссылок» в этих случаях является огромной проблемой ... Я думаю, что для потомков следующие две строки улавливают основную идею вашей ссылки: она создает сервис, который использует VBoxHeadless -s %iдля запуска и VBoxManage controlvm %i savestateостановки виртуальной машины.
— Jstarek

Попробовал это в Debian Jessie, но это не сработало. Создал пользователя и группу, установил владение всеми файлами (включая / dev / vbox *). Но когда служба запускается, она не может найти виртуальную машину, даже если имя верное. Будет использовать обычный скрипт инициализации в конце концов.
— MIVK

3

Как насчет отправки команды через ssh с хоста на гостя?

Я не уверен, что это работает, и если вы можете проверить состояние машины после этого или получить что-то вроде состояния выхода, но это должно быть чистым по крайней мере.


Хорошая мысль, но это гарантирует, что гостевая виртуальная машина будет доступна через сеть с хоста, по крайней мере, через порт ssh (22).
— Nikhil Mulley

По сути, это будет работать, устройство может быть доступно во всей локальной сети через его DNS-запись. Однако предположим, что я написал сценарий, который ssh'd в устройстве всякий раз, когда хост отключается - ему все равно придется блокировать (пауза), пока гость не отключится полностью. Именно в этом и заключается мой вопрос: как сценарий может узнать, когда гость отключен, чтобы он мог вернуть поток управления обратно в SysV-Init, и хост мог продолжать отключаться?
— Jstarek

1
Ваш комментарий предполагает, что все будет работать гладко на хост-системе, а не на гостевой системе. Что, если кабель питания подключен к хост-системе? Это другое обсуждение. Ваш SysV-init в хост-системе будет ждать, пока сценарий службы остановит виртуальные машины, если сценарий службы понимает логику правильного отключения гостевых виртуальных машин (отключение на удаленном хосте или просто отключение через интерфейс vbox) и затем yield возвращает статус успеха или ошибки обратно на консоль или в init.
— Nikhil Mulley

1
Относительно того, как скрипт знает, когда гость выключен, попробуйте просто проверить, включен или выключен виртуальный компьютер из интерфейса VboxManager и гость ли ssh'able. Кроме того, поместите некоторый мониторинг в хост-систему, который будет выполнять проверку доступности виртуальной машины из Vboxmanager и ее ssh'able на своевременной основе.
— Nikhil Mulley

1

Мое решение: в этом сценарии оболочки «root» является инициатором, а «theuser» является владельцем «thevm»

Я знаю, что vms закончился, когда выходные данные команды VBoxManage list runningvmsвозвращают пустую строку.

...
start(){
    su -c "VBoxHeadless --startvm thevm" -s /bin/bash theuser &
    # maybe another vbox command
}

stop(){
    su -c "VBoxManage controlvm thevm acpipowerbutton" -s /bin/bash theuser
    # maybe another vbox command
    while [ "`su -c 'VBoxManage list runningvms' -s /bin/bash theuser`" != "" ]
    do
        echo waiting for VMs to shutdown
        sleep 3
    done
}
...

1

Для запуска vm:

VBoxManage startvm VMNAME --type headless

Чтобы остановить ВМ:

VBoxManage controlvm VMNAME savestate

Список всех запущенных виртуальных машин:

VBoxManage list runningvms

0

Может быть, это поможет как часть решения.

VBoxManage list runningvms | tr -s '\" {' '%{' | cut -d '%' -f3  | while read uuid; do
   VBoxManage controlvm $uuid savestate; 
done

0

Почему бы вам не войти в свой гость и не отключиться оттуда?

Если у вас нет веской причины не устанавливать sshd и не получать доступ к виртуальной машине через VBox, я бы выбрал скрипт, который просто выдает ssh shutdown -h now. Если честно, я бы создал скрипт для каждой машины, который правильно выключит его и проведет некоторые проверки на нем.

Просто упакуйте /etc/init.d/shutdown_vm скрипт, который вызывает другой с хоста, вызов будет блокирован, пока не будет готов. Этот процесс (как описано) добавляет зависимость linux на гостя, но удаляет зависимость VBox на хосте.

Сокращение к погоне: вам не нужен доступ к VBox для выключения компьютера, если у вас есть какие-то средства доступа к нему (например, ssh), то ОС всегда будет иметь для этого какие-то средства (включение, разумеется, другое)


Две причины: во-первых, как было указано в исходном вопросе, я не хотел менять сильно модифицированные гостевые ОС, если в этом не было необходимости. Во-вторых, и что более важно, это было предназначено для обеспечения чистого способа автоматического выключения всех работающих виртуальных машин, если хост был выключен.
— Jstarek

@jstarek Но вам не нужно изменять гостевую ОС, если вы этого не хотите (99,99% времени у вас есть какие-то средства для входа или это исключение). И именно в этом и заключается идея: если хост выйдет из строя, при изменении времени выполнения будет вызван соответствующий скрипт, который просто регистрирует гостя и закрывает его из «изнутри», что в любом случае делает vagrant ... перед тем, как перейти к "грубому" сила "это ...
— estani
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.