Jak automatycznie uruchamiać i wyłączać maszyny VirtualBox?

52

Muszę uruchomić system oprogramowania, który ma zostać zainstalowany jako urządzenie na dedykowanej maszynie. W celu oszczędzania energii planuję uruchomić system na maszynie wirtualnej VirtualBox.

Host jest standardowym systemem Linux z systemem SysV-Init, gość jest silnie zmodyfikowanym Linuksem i wolałbym nie zmieniać go dalej. VirtualBox jest używany w wersji OSE.

Już wymyśliłem, jak uruchomić maszynę wirtualną podczas rozruchu hosta ( edycja: jest to zrobione, jak wspomniano poniżej przez Nikhil, za pomocą polecenia VBoxManager startvm), ale jak mogę z wdziękiem zamknąć maszynę wirtualną? Każdy skrypt działający na hoście musiałby poczekać, aż gość całkowicie się zamknie.

Czy ktoś może zasugerować, jak na przykład musiałby wyglądać plik usługi, który to robi?

jstarek
źródło
czy możesz podać skrypt startowy, aby uruchomić maszynę wirtualną podczas rozruchu
Początkujący

Odpowiedzi:

34

Czy próbowałeś acpipowerbuttonz tego zestawu poleceń?

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

Edytuj po przeczytaniu komentarzy:

Możesz użyć acpidlub innych narzędzi acpi, aby uczynić go wdzięcznym. Czy możesz również podać więcej informacji o tym, jak w tej chwili wyłączyć maszynę?

Zwykły shutdownnie czekałby na niedokończone prace, opóźnienie może być zbyt długie.

Zakładam, że nie używasz menedżera okien, więc wypróbuj to narzędzie.

Właśnie widziałem tego demona . Może ci się przydać.

Mavromatis Lozay
źródło
Dziękujemy za odpowiedź i witamy na unix.stackexchange.com! Jednak obawiam się, że twoja odpowiedź również nie rozwiązuje mojego problemu: acpipowerbutton symuluje naciśnięcie przycisku zasilania na prawdziwej maszynie, ale po wydaniu tego polecenia na hoście maszyna wirtualna znów potrzebuje czasu, aby się zamknąć.
jstarek
4
Pewnie. Musisz więc napisać pętlę, która sprawdza, czy maszyna wirtualna nadal działa. ACPI to dokładnie ta sama metoda, której używam w moich skryptach. vboxmanage list runningvmsaż do zniknięcia maszyny wirtualnej.
Nils,
OK, choć myślę, że w praktyce zadowolę się pakietem do zarządzania, +50 za wskazanie initscript!
jstarek
16

Zamiast samemu to kodować, zastanów się nad użyciem Vagrant , który jest stworzony do tworzenia instancji i kontrolowania instancji virtualbox. Dokumentacja jest doskonała i sugeruję, abyś to sprawdził, zamiast próbować tworzyć własne.

Krótko mówiąc, należy utworzyć prosty plik kontrolny, a następnie uruchomić, vagrant upaby uruchomić tyle instancji VirtualBox, ile chcesz. Możesz użyć vagrant sshdo zalogowania się na hostach i vagrant haltzamknięcia hosta (bez zakończenia). vagrant destroypozbędę się instancji.

Obsługuje aprowizację za pomocą lalek, Ansible lub Chef i pozwala kontrolować większość widocznych ustawień konfiguracji VBox.

Aaron Brown
źródło
2
Jestem fanem włóczęgów, ale w takim razie, po co byś tego chciał? OP uruchamia urządzenie, a nie buduje własny system, więc obsługa administracyjna całkowicie pomija sens. I po co tworzyć niestandardowe „pudełko” z urządzenia, aby użyć włóczęgi, kiedy po prostu przechodzisz przez proces budowania systemu za pomocą Virtualbox, aby to zrobić?
mc0e
10

Mam podobną aplikację jak ty, z jedną różnicą: muszę zrestartować system i odzyskać z migawki.

Interesuje Cię tryb bezgłowy .

Mam kilka takich usług, więc używam następującego skryptu:

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

jak mogę z wdziękiem zamknąć maszynę wirtualną?

JEŚLI chcesz z wdziękiem wyłączyć maszynę wirtualną, masz dwie opcje, w zależności od aplikacji:

  • Emuluj „przycisk wyłączania” lub „przycisk uśpienia” i przygotuj maszynę wirtualną do zareagowania na nią (aby zamknąć się z wdziękiem)
    • VBoxManage controlvm <uuid>|<VMname> acpipowerbutton
    • VBoxManage controlvm <uuid>|<VMname> acpisleepbutton
  • Zapisz stan maszyny wirtualnej, aby później ją przywrócić
    • VBoxManage controlvm <uuid>|<VMname> savestate

WSKAZÓWKI: Może się przydać:

  • VBoxManage list vms - lista dostępnych vms
  • rdesktop IP-ADDR:3389lub rdesktop-vrdp IP-ADDR:3389- jeśli chcesz mieć GUI (nawet zdalnie ), gdy pracujesz w trybie bezgłowym:VBoxHeadless -s <uuid>|<VMname>
  • VBoxManage startvm - zacznij od GUI do lokalnego debugowania

Powiązany rozdział instrukcji VirtualBox: Rozdział 7. Zdalne maszyny wirtualne - Krok po kroku: tworzenie maszyny wirtualnej na serwerze bezgłowym

PS Jeśli jesteś zainteresowany w pełni funkcjonalnymi już zaimplementowanymi rozwiązaniami, OpenStack wydaje się interesującym wyborem.

Grzegorz Wierzowiecki
źródło
10

Patrz dokumentacja zarządzania VM VirtualBox na http://www.virtualbox.org/manual/ch08.html

Aby wyświetlić listę maszyn wirtualnych, użyj polecenia VBoxManage list vms

Aby uruchomić maszynę wirtualną, użyj polecenia VBoxManage startvm

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

Do kontrolowania maszyny wirtualnej użyj VBoxManage controlvm

controlvmKomenda pozwala na zmianę stanu maszyny wirtualnej, która jest aktualnie uruchomiony. Można określić następujące elementy:

VBoxManage controlvm <vm> pausetymczasowo wstrzymuje maszynę wirtualną, nie zmieniając jej stanu na dobre. Okno maszyny wirtualnej zostanie pomalowane na szaro, aby wskazać, że maszyna wirtualna jest obecnie wstrzymana. (Jest to równoważne wybraniu pozycji „Pauza” w menu „Maszyna” GUI.)

Użyj, VBoxManage controlvm <vm> resumeaby cofnąć poprzednie polecenie pauzy. (Jest to równoważne wybraniu pozycji „Wznów” w menu „Maszyna” interfejsu GUI.)

VBoxManage controlvm <vm> resetma taki sam wpływ na maszynę wirtualną jak naciśnięcie przycisku „Reset” na prawdziwym komputerze: zimny restart maszyny wirtualnej, który uruchomi się ponownie i natychmiast uruchomi system operacyjny gościa. Stan maszyny wirtualnej nie jest wcześniej zapisywany i dane mogą zostać utracone. (Jest to równoważne wybraniu pozycji „Resetuj” w menu „Maszyna” interfejsu GUI.)

VBoxManage controlvm <vm> poweroffma taki sam wpływ na maszynę wirtualną jak ciągnięcie kabla zasilającego na prawdziwym komputerze. Ponownie stan maszyny wirtualnej nie jest wcześniej zapisywany i dane mogą zostać utracone. (Jest to równoważne wybraniu pozycji „Zamknij” w menu „Maszyna” interfejsu GUI lub naciśnięciu przycisku zamknięcia okna, a następnie wybraniu opcji „Wyłącz maszynę” w oknie dialogowym.)

Następnie stan maszyny Wirtualnej zostanie „Wyłączony”.

Nikhil Mulley
źródło
Pamiętaj, że w niektórych systemach jest to vboxmanage(wszystkie małe litery).
Arcege
2
Dziękuję za odpowiedź, ale niestety to nie rozwiązuje mojego problemu: muszę z wdziękiem zamknąć gościa, tj. Wydać polecenie „zamknij -h teraz” wewnątrz gościa i niech gospodarz zaczeka, aż gość całkowicie się zamknie. Żadna z VBoxManage controlvmkomend tego nie robi.
jstarek
Możesz upewnić się, że sprawdzając ponownie wszystkie vms są wyłączone na hoście, zanim host przestanie działać. Jeśli chcesz kontrolować hosta z poziomu gościa, wtedy virtualbox.org/manual/ch08.html#vboxmanage-guestcontrol, ale to może nie dać ci tego, czego szukasz. Powinieneś napisać skrypt startowy, taki jak /etc/init.d/vboxvms-serviceskrypt na systemie hosta, który po uruchomieniu spowoduje włączenie wszystkich vms, a po zatrzymaniu spowoduje wyłączenie wszystkich vms.
Nikhil Mulley,
VBoxManage controlvm savestateto kolejna możliwość (przynajmniej Google mówi), zapisuje status maszyn i wyłącza je czysto, ale wciąż nie ma sposobu, aby zmusić hosta do czekania.
Baarn
5

W przypadku systemu opartego na systemie można spróbować tego.

Krok # 1: Utwórz plik usługi

[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

Krok # 2: Włącz plik usługi

$ sudo systemctl enable vboxvmservice@vm_name.service

Bibliografia

Jan Rüegg
źródło
1
Preferowane jest podanie tutaj odpowiedzi i opcjonalnie podanie linków do bardziej szczegółowych informacji. Łącza docelowe znikają bez uprzedzenia, przez co twoja odpowiedź jest bezwartościowa.
Anthon
Problem polega na tym, że nie mogę tak naprawdę skopiować całego pliku systemowego w linku 1 tutaj, czy powinienem to zrobić?
Jan Rüegg,
Cóż, niestety „zgnilizna linków” jest ogromnym problemem w tych przypadkach ... Myślę, że dla potomności następujące dwie linie wychwytują podstawową ideę twojego linku: tworzy usługę, która używa VBoxHeadless -s %ido uruchamiania i VBoxManage controlvm %i savestatezatrzymywania maszyny wirtualnej.
jstarek
Próbowałem tego w Debian Jessie, ale to nie działało. Utworzono użytkownika i grupę, ustawiono własność wszystkich plików (w tym / dev / vbox *). Ale gdy usługa się uruchomi, nie może znaleźć maszyny wirtualnej, nawet jeśli nazwa jest prawidłowa. W końcu użyje normalnego skryptu inicjującego.
mivk,
3

Co powiesz na wysłanie polecenia przez ssh z hosta do gościa?

Nie jestem pewien, czy to działa i czy możesz później sprawdzić stan maszyny lub uzyskać status wyjścia, ale przynajmniej powinien zostać wyczyszczony.

Baarn
źródło
Dobrze pomyślane, ale gwarantuje to, że do wirtualnej maszyny-gościa będzie można dotrzeć przez sieć z hosta, przynajmniej do portu ssh (22).
Nikhil Mulley,
Zasadniczo to zadziałałoby, urządzenie można uzyskać w całej sieci LAN za pośrednictwem wpisu DNS. Załóżmy jednak, że napisałem skrypt, który ssh zapisywał się do urządzenia za każdym razem, gdy host przestanie działać - nadal musiałby blokować (wstrzymywać), dopóki gość nie zostanie całkowicie zamknięty. Właśnie o to chodzi w moim pytaniu: skąd skrypt może wiedzieć, kiedy gość jest wyłączony, aby mógł przywrócić kontrolę nad SysV-Init, a host może nadal się wyłączać?
jstarek
1
Twój komentarz zakłada, że ​​wszystko będzie działać płynnie na systemie hosta, a nie na systemie gościa. Co się stanie, jeśli kabel zasilający zostanie podłączony do systemu hosta? To inna dyskusja. Twoja SysV-init na systemie hosta będzie czekać na skrypt serwisowy, aby zatrzymać maszyny wirtualne, o ile skrypt usług rozumie logikę, aby odpowiednio wyłączyć maszyny wirtualne gościa (zamknij program na zdalnym hoście lub po prostu wyłącz za pośrednictwem interfejsu vbox) i następnie zwróć status powodzenia lub niepowodzenia z powrotem do konsoli lub init.
Nikhil Mulley,
1
Odnośnie: skąd skrypt wie, kiedy gość nie działa, spróbuj po prostu sprawdzić, czy vm jest włączony czy wyłączony z interfejsu VboxManager i czy gość jest ssh'able. Ponadto umieść monitorowanie w systemie hosta, który będzie sprawdzał, czy maszyna wirtualna jest dostępna od Vboxmanager i jej ssh'able na czas.
Nikhil Mulley,
1

Moje rozwiązanie: w tym skoroszycie „root” jest wywoływaczem, a „użytkownik” jest właścicielem „thevm”

Wiem, że vms zakończyło się, gdy wynik polecenia VBoxManage list runningvmszwraca pusty ciąg.

...
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
}
...
Jorge Sanchez
źródło
1

Aby uruchomić vm:

VBoxManage startvm VMNAME --type headless

Aby zatrzymać vm:

VBoxManage controlvm VMNAME savestate

Wyświetl listę wszystkich uruchomionych maszyn wirtualnych:

VBoxManage list runningvms
RIT
źródło
0

Może to pomoże w ramach rozwiązania.

VBoxManage list runningvms | tr -s '\" {' '%{' | cut -d '%' -f3  | while read uuid; do
   VBoxManage controlvm $uuid savestate; 
done
użytkownik58380
źródło
0

Dlaczego nie zalogujesz się do swojego gościa i nie zamkniesz go stamtąd?

Jeśli nie masz dobrego powodu, aby nie instalować sshd i uzyskiwać dostępu do maszyny wirtualnej za pośrednictwem VBox, wybrałbym skrypt, który po prostu wydaje polecenie ssh shutdown -h now. Szczerze mówiąc, stworzę skrypt dla każdej maszyny, która poprawnie go wyłączy i wykona kilka kontroli podczas pracy.

Wystarczy spakować skrypt /etc/init.d/shutdown_vm, który wywołuje drugi z hosta, połączenie zostanie zablokowane, dopóki nie będzie gotowe. Ten proces (zgodnie z opisem) dodaje zależność linuksową u gościa, ale usuwa zależność VBox na hoście.

Przejdźmy do sedna: nie musisz uzyskiwać dostępu do VBox, aby zamknąć maszynę, jeśli masz jakieś środki dostępu do niej (tj. Ssh), wtedy system operacyjny zawsze będzie miał na to jakieś środki (włączenie, jest oczywiście inne)

estani
źródło
Dwa powody: Po pierwsze, jak stwierdzono w pierwotnym pytaniu, nie chciałem zmieniać mocno zmodyfikowanego systemu operacyjnego gościa, jeśli nie jest to naprawdę konieczne. Po drugie i, co ważniejsze, miało to zapewnić czysty sposób automatycznego zamykania wszystkich działających maszyn wirtualnych, jeśli host został zamknięty.
jstarek
@jstarek Ale nie musisz modyfikować systemu operacyjnego gościa, jeśli nie chcesz (99,99% czasu masz na to środki, aby się zalogować lub jest to wyjątek). I właśnie o to chodzi, jeśli host ulegnie awarii, odpowiedni skrypt zostanie wywołany przy zmianie środowiska uruchomieniowego, a to po prostu loguje się do gościa i wyłącza go z „wnętrza”, co w każdym razie robi włóczęga… zanim przejdzie „brutalnie” force "czyli ...
estani