Wie werden VirtualBox-Maschinen automatisch gestartet und heruntergefahren?

52

Ich muss ein Softwaresystem ausführen, das als Appliance auf einem dedizierten Computer installiert werden soll. Um Energie zu sparen, plane ich, das System stattdessen auf einer VirtualBox-VM auszuführen.

Der Host ist eine Standard-Linux-Box mit einem SysV-Init-System, der Gast ist ein stark modifiziertes Linux und ich würde es vorziehen, es nicht weiter ändern zu müssen. VirtualBox wird in der OSE-Version verwendet.

Ich habe bereits herausgefunden, wie die VM beim Booten des Hosts gestartet wird ( Bearbeiten: Dies geschieht, wie Nikhil weiter unten erwähnt, über den Befehl VBoxManager startvm), aber wie kann ich die VM ordnungsgemäß herunterfahren? Jedes Skript, das auf dem Host ausgeführt wird, muss warten, bis der Gast vollständig heruntergefahren wurde.

Kann jemand vorschlagen, wie zum Beispiel eine Servicedatei aussehen müsste, die dies tut?

jstarek
quelle
könnten Sie das Startskript zum Starten der virtuellen Maschine beim Booten geben
Anfänger

Antworten:

34

Haben Sie es mit acpipowerbuttondiesem Befehlssatz versucht ?

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

Bearbeiten Sie nach dem Lesen der Kommentare:

Sie können acpidoder andere acpi-Dienstprogramme verwenden, um es anmutig zu machen. Können Sie auch weitere Informationen darüber bereitstellen, wie Sie die Maschine im Moment herunterfahren?

Plain shutdownwürde nicht auf unfertige Jobs warten, eine Zeitverzögerung könnte zu lang sein.

Ich gehe davon aus, dass Sie keinen Fenstermanager verwenden. Probieren Sie dieses Tool aus.

Habe gerade diesen Daemon gesehen . Vielleicht finden Sie es nützlich.

Mavromatis Lozay
quelle
Vielen Dank für Ihre Antwort und willkommen bei unix.stackexchange.com! Ich befürchte jedoch, dass Ihre Antwort auch nicht mein Problem behebt: acpipowerbutton simuliert das Drücken des Netzschalters auf einem realen Computer, aber nach der Ausgabe dieses Befehls auf dem Host würde die VM erneut einige Zeit benötigen, um herunterzufahren.
Jstarek
4
Sicher. Sie müssen also eine Schleife schreiben, die prüft, ob die VM noch läuft. ACPI ist genau die gleiche Methode, die ich in meinen Skripten verwende. vboxmanage list runningvmsbis deine VM weg ist.
Nils
OK, während ich denke, dass ich mich in der Praxis mit einem Management-Wrapper begnüge, +50 für den Hinweis auf das Initskript!
Jstarek
16

Ziehen Sie die Verwendung von Vagrant in Betracht , um Virtualbox-Instanzen zu instanziieren und zu steuern, anstatt dies selbst zu codieren. Die Dokumentation ist ausgezeichnet und ich schlage vor, dass Sie es überprüfen, anstatt zu versuchen, Ihr eigenes zu rollen.

Das Entscheidende dabei ist, dass Sie eine einfache Steuerdatei erstellen und dann ausführen vagrant up, um so viele VirtualBox-Instanzen zu starten, wie Sie möchten. Sie können verwenden, vagrant sshum sich bei den Hosts anzumelden und vagrant haltden Host herunterzufahren (ohne zu beenden). vagrant destroywird die Instanzen loswerden.

Es unterstützt die Bereitstellung mit Puppet, Ansible oder Chef und ermöglicht es Ihnen, die meisten der freigelegten VBox-Konfigurationseinstellungen zu steuern.

Aaron Brown
quelle
2
Ich bin ein Fan von Landstreicher, aber in diesem Fall, wofür um alles in der Welt würdest du es wollen? Auf dem OP wird eine Appliance ausgeführt, und es wird kein eigenes System aufgebaut, sodass bei der Bereitstellung keine Lösung gefunden wird. Und warum sollten Sie aus der Appliance eine benutzerdefinierte "Box" machen, um Vagrant zu verwenden, wenn Sie dazu im Grunde genommen das System mit virtualbox erstellen müssten?
mc0e
10

Ich habe eine ähnliche Anwendung wie Sie, mit dem Unterschied, dass ich das System neu starten und einen Snapshot wiederherstellen muss.

Was Sie interessiert, ist der Headless-Modus .

Ich habe einige solcher Dienste und verwende daher folgendes Skript:

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

Wie kann ich die VM ordnungsgemäß herunterfahren?

Wenn Sie die VM ordnungsgemäß deaktivieren möchten, haben Sie je nach Anwendung zwei Möglichkeiten:

  • Emulieren Sie "Shutdown-Button" oder "Sleep-Button" und bereiten Sie die VM darauf vor (um ordnungsgemäß zu schließen)
    • VBoxManage controlvm <uuid>|<VMname> acpipowerbutton
    • VBoxManage controlvm <uuid>|<VMname> acpisleepbutton
  • Speichern Sie den VM-Status, um ihn anschließend wiederherzustellen
    • VBoxManage controlvm <uuid>|<VMname> savestate

TIPPS: Sie könnten nützlich finden:

  • VBoxManage list vms - Liste der verfügbaren VMS
  • rdesktop IP-ADDR:3389oder rdesktop-vrdp IP-ADDR:3389- wenn Sie eine grafische Benutzeroberfläche wünschen (auch aus der Ferne ), wenn Sie im Headless-Modus arbeiten:VBoxHeadless -s <uuid>|<VMname>
  • VBoxManage startvm - Beginnen Sie mit der grafischen Benutzeroberfläche für das lokale Debuggen

Zugehöriges VirtualBox-Handbuch Kapitel: Kapitel 7. Virtuelle Remote-Maschinen - Schritt für Schritt: Erstellen einer virtuellen Maschine auf einem Headless-Server

PS Wenn Sie an bereits implementierten Lösungen mit vollem Funktionsumfang interessiert sind, scheint OpenStack eine interessante Wahl zu sein.

Grzegorz Wierzowiecki
quelle
10

Informationen zur VirtualBox VM-Verwaltung finden Sie unter http://www.virtualbox.org/manual/ch08.html

Verwenden Sie den Befehl, um die VMs aufzulisten VBoxManage list vms

Verwenden Sie zum Starten der VM den Befehl VBoxManage startvm

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

Verwenden Sie zur Steuerung der VM VBoxManage controlvm

Mit dem controlvmUnterbefehl können Sie den Status einer virtuellen Maschine ändern, die gerade ausgeführt wird. Folgendes kann angegeben werden:

VBoxManage controlvm <vm> pauseSetzt eine virtuelle Maschine vorübergehend in die Warteschleife, ohne ihren Status endgültig zu ändern. Das VM-Fenster wird grau dargestellt, um anzuzeigen, dass die VM derzeit angehalten ist. (Dies entspricht der Auswahl des Elements "Pause" im Menü "Maschine" der GUI.)

Verwenden Sie VBoxManage controlvm <vm> resumediese Taste, um einen vorherigen Pausenbefehl rückgängig zu machen. (Dies entspricht der Auswahl des Elements "Fortsetzen" im Menü "Maschine" der GUI.)

VBoxManage controlvm <vm> resethat auf einer virtuellen Maschine die gleiche Auswirkung wie auf einem realen Computer auf die Schaltfläche "Zurücksetzen": Ein Kaltstart der virtuellen Maschine, der das Gastbetriebssystem sofort neu startet und erneut startet. Der Status der VM wird nicht vorab gespeichert, und es können Daten verloren gehen. (Dies entspricht der Auswahl des Elements "Zurücksetzen" im Menü "Maschine" der GUI.)

VBoxManage controlvm <vm> poweroffhat dieselbe Auswirkung auf eine virtuelle Maschine wie das Ziehen des Stromkabels an einem realen Computer. Auch hier wird der Status der VM nicht im Voraus gespeichert und es können Daten verloren gehen. (Dies entspricht der Auswahl des Elements "Schließen" im Menü "Maschine" der grafischen Benutzeroberfläche oder dem Drücken der Schaltfläche zum Schließen des Fensters und der Auswahl von "Maschine ausschalten" im Dialogfeld.)

Danach lautet der VM-Status "Ausgeschaltet".

Nikhil Mulley
quelle
Beachten Sie, dass dies auf einigen Systemen der vboxmanageFall ist (alles in Kleinbuchstaben).
Arcege
2
Vielen Dank für Ihre Antwort, aber leider, das ist mein Problem nicht ansprechen: Ich muss anmutig den Gast herunterfahren, dh Ausgabe ein „shutdown -h now“ innerhalb des Gast und Host warten , bis der Gast vollständig heruntergefahren hat. Keiner der VBoxManage controlvmUnterbefehle macht das.
Jstarek
Sie können sicherstellen, dass alle virtuellen Maschinen auf dem Host heruntergefahren sind, bevor der Host herunterfährt. Wenn Sie den Host vom Gast aus steuern müssen, verwenden Sie virtualbox.org/manual/ch08.html#vboxmanage-guestcontrol. Dies gibt Ihnen jedoch möglicherweise nicht das, wonach Sie suchen. Sie sollten ein Startskript wie ein /etc/init.d/vboxvms-serviceSkript auf dem Hostsystem schreiben , das beim Start alle VMs einschaltet und beim Stoppen alle VMs ausschaltet.
Nikhil Mulley
VBoxManage controlvm savestateist eine andere Möglichkeit (zumindest Google sagt es mir), es speichert den Status des Rechners und fährt ihn sauber herunter, aber es gibt immer noch keine Möglichkeit, den Host zum Warten zu zwingen.
Baarn,
5

Bei einem systembasierten System können Sie dies versuchen.

Schritt 1: Erstellen Sie eine Servicedatei

[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

Schritt 2: Aktivieren Sie die Servicedatei

$ sudo systemctl enable vboxvmservice@vm_name.service

Verweise

Jan Rüegg
quelle
1
Es wird bevorzugt, hier eine Antwort einzuschließen und optional Links zu detaillierteren Informationen bereitzustellen. Linkziele verschwinden ohne Vorankündigung und Ihre Antwort ist wertlos.
Anthon
Nun, das Problem ist, dass ich hier nicht wirklich die gesamte systemd-Datei in Link 1 kopieren kann, oder sollte ich das tun?
Jan Rüegg
Nun, leider ist "link rot" in diesen Fällen ein großes Problem ... Ich denke, für die Nachwelt, die folgenden zwei Zeilen fangen die Grundidee hinter Ihrem Link ein: Es wird ein Dienst erstellt, mit VBoxHeadless -s %idem VBoxManage controlvm %i savestatedie VM gestartet und gestoppt wird.
Jstarek
Versuchte dies in Debian Jessie, aber es funktionierte nicht. Erstellt Benutzer und Gruppe, setzt den Besitz aller Dateien (einschließlich / dev / vbox *). Wenn der Dienst gestartet wird, kann er die VM nicht finden, obwohl der Name richtig ist. Verwendet schließlich das normale Init-Skript.
Mivk
3

Wie wäre es, den Befehl per ssh vom Host an den Gast zu senden?

Ich bin mir nicht sicher, ob es funktioniert und ob Sie den Status der Maschine danach überprüfen oder so etwas wie einen Exit-Status erhalten können, aber es sollte mindestens sauber bleiben.

Baarn
quelle
Gute Gedanken, aber dies würde gewährleisten, dass die Gast-VM über das Netzwerk vom Host aus erreichbar ist, zumindest über den SSH-Port (22).
Nikhil Mulley
Grundsätzlich würde dies funktionieren, die Appliance ist im gesamten LAN über ihren DNS-Eintrag erreichbar. Angenommen, ich habe ein Skript geschrieben, das immer dann in die Appliance geschrieben wird, wenn der Host ausfällt. Es muss immer noch blockiert werden (Pause), bis der Gast vollständig heruntergefahren ist. Genau das ist der Punkt meiner Frage: Wie kann das Skript feststellen, wann der Gast nicht erreichbar ist, sodass der Steuerungsfluss an SysV-Init zurückgegeben und der Host weiterhin heruntergefahren werden kann?
Jstarek
1
In Ihrem Kommentar wird davon ausgegangen, dass auf dem Hostsystem und nicht auf dem Gastsystem alles reibungslos funktioniert. Was ist, wenn das Stromkabel am Host-System ausgesteckt ist? Es ist eine andere Diskussion. Ihr SysV-init auf dem Host-System wartet darauf, dass das Dienstskript die VMs stoppt, solange das Dienstskript die Logik zum ordnungsgemäßen Ausschalten der Gast-VMs versteht (Herunterfahren auf dem Remote-Host ausführen oder einfach über die vbox-Schnittstelle ausschalten) und Geben Sie dann den Erfolgs- oder Fehlerstatus an die Konsole oder an init zurück.
Nikhil Mulley
1
In Bezug auf: Wie das Skript erkennt, ob der Gast nicht erreichbar ist, versuchen Sie einfach zu überprüfen, ob die VM über die VboxManager-Oberfläche aktiviert oder deaktiviert ist und ob der Gast ssh'able ist. Überwachen Sie auch das Host-System, um sicherzustellen, dass die VM rechtzeitig über Vboxmanager und ssh'able verfügbar ist.
Nikhil Mulley
1

Meine Lösung: In diesem Shellscript ist 'root' der Aufrufer und 'theuser' der Eigentümer von 'thevm'.

Ich weiß, dass die vms beendet wurden, wenn die Ausgabe des Befehls VBoxManage list runningvmseine leere Zeichenfolge zurückgibt.

...
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
quelle
1

Vm starten:

VBoxManage startvm VMNAME --type headless

Um vm zu stoppen:

VBoxManage controlvm VMNAME savestate

Alle laufenden VMs auflisten:

VBoxManage list runningvms
RIT
quelle
0

Vielleicht hilft dies als Teil der Lösung.

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

Warum melden Sie sich nicht bei Ihrem Gast an und fahren von dort aus herunter?

Sofern Sie keinen triftigen Grund haben, sshd nicht zu installieren und wirklich über VBox auf die VM zuzugreifen, würde ich ein Skript verwenden, das nur eine ausführt ssh shutdown -h now. Um ehrlich zu sein, würde ich für jede Maschine ein Skript erstellen, das sie ordnungsgemäß herunterfährt und dabei einige Überprüfungen durchführt.

Packen Sie einfach ein /etc/init.d/shutdown_vm-Skript, das das andere Skript vom Host aufruft. Der Aufruf wird blockiert, bis er fertig ist. Dieser Prozess (wie beschrieben) fügt dem Gast eine Linux-Abhängigkeit hinzu, entfernt jedoch die VBox-Abhängigkeit auf dem Host.

Auf den Punkt gebracht: Sie müssen nicht auf VBox zugreifen, um eine Maschine herunterzufahren. Wenn Sie über eine Möglichkeit verfügen, darauf zuzugreifen (z. B. ssh), hat das Betriebssystem immer eine Möglichkeit, dies zu tun (das Einschalten ist natürlich anders).

estani
quelle
Zwei Gründe: Erstens wollte ich, wie in der ursprünglichen Frage angegeben, das stark geänderte Gastbetriebssystem nicht ändern, wenn es nicht wirklich notwendig war. Zweitens, und was noch wichtiger ist, sollte dies eine saubere Möglichkeit bieten, alle laufenden VMs automatisch herunterzufahren, wenn der Host heruntergefahren wurde.
Jstarek
@jstarek Sie müssen Ihr Gastbetriebssystem jedoch nicht ändern, wenn Sie dies nicht möchten (99,99% der Zeit haben Sie die Möglichkeit, sich anzumelden, oder ist dies eine Ausnahme). Und genau das ist die Idee, wenn der Host ausfällt, wird das richtige Skript aufgerufen, wenn die Laufzeit geändert wird, und dies meldet sich nur beim Gast an und beendet es von "innen", was Vagrant sowieso tut ... bevor er brachial wird Kraft ", das ist ...
estani