[VirtualBox]VirtualBox虛擬機開啟web服務並且設置虛擬機隨宿主系統開機

參考網址:個人圖書館

VirtualBox虛擬機開啟web服務並且設置虛擬機隨宿主系統開機自啟動

本文是無廢話篇,不是virtualbox的安裝入門篇,如何安裝請參考官方文檔。本文中的宿主系統爲CentOS 7或Arch Linux, 其他系統大同小異。需要注意的是,如果你的系統是Arch Linux,那麼還需要安裝virtualbox-ext-oracle這個軟件包,但是在官方源中是沒有這個包的,它在AUR源中,因此要先安裝yay工具,然後再通過yay -S virtualbox-ext-oracle來安裝,可能你還需要安裝這個包的可選依賴包rdesktop。

一、配置virtualbox的web服務
1、編輯/etc/default/virtualbox文件

這個文件是virtualbox的web服務和自動啟動服務的主配置文件,默認情況下是沒有的,請自行創建,文件內容如下:
VBOXWEB_USER="vbox"
VBOXWEB_TIMEOUT=10
VBOXWEB_LOGFILE="/var/log/vboxwebservice.log"
VBOXWEB_HOST="宿主機的IP地址"

請指定ipv4地址,ipv6沒試過,大概率是不行的。。。以上配置在Arch Linux系統下是不需要的,Arch Linux將上述配置都寫在了systemd腳本中了,這個後面再詳細介紹。

2、接著創建web服務的日誌文件,並修改文件屬主:
touch /var/log/vboxwebservice.log
chown vbox:vboxusers /var/log/vboxwebservice.log
如果系統中沒有vbox用戶和vboxusers用戶組,請自行創建,並將vbox用戶加入到vboxusers組中,具體如何操作自行查閱useradd、groupadd以及usermod、groupmod等命令的用法。

3、重啟virtualbox webservice:
CentOS7:systemctl restart vboxweb-service
ArchLinux:systemctl restart vboxweb.service

如果發現此服務之前並沒有生效,可以先運行systemctl enable vboxweb-service使之生效。

驗證它是否正確地運行並處於偵聽狀態:
ps -aef | grep vboxweb

如果發現沒有正確啟動,可以查看/var/log/vboxwebservice.log日誌文件,可能會看到一些錯誤信息,根據相關錯誤信息再想辦法一一解決,我在配置過程中沒有出現錯誤,還是很順利的。

4、配置web服務有什麼用?
配置了web服務之後,就可以在宿主機上安裝配置web管理界面了,就不用遠程登錄宿主機來啟動、管理虛擬機了。最有名的web管理端要數phpVirtualBox了,這需要在宿主機上安裝web服務器、php環境,這不是本文的重點,關於PHP環境安裝配置的文章多如牛毛,這裏就不講了,至於phpVirtualBox可以上virtualbox官方網站去尋找下載地址。

二、配置virtualbox虛擬機隨宿主系統啟動而自啟

1、設置自啟所需的環境變量:

再次編輯/etc/default/virtualbox這個文件,在末尾加上如下配置項:
VBOXAUTOSTART_DB="/var/lib/virtualbox-autostart"

VBOXAUTOSTART_CONFIG="/etc/default/vb-autostart-perms"

上面一項是指定virtualbox自啟動的數據庫目錄;
下面一項指定自啟動的配置文件,主要是配置授權信息。

2、編輯/etc/default/vb-autostart-perms文件:
vim /etc/default/vb-autostart-perms
添加以下內容:

default_policy = deny
vbox= {
allow = true

}

注意:vbox用戶必須實際存在,並且已經加入了vboxusers組,如果你想手動操作虛擬機請一定用這個用戶來操作!

3、修改/var/lib/virtualbox-autostart目錄的屬主和權限:
如果沒有/var/lib/virtualbox-autostart目錄,則創建之。
mkdir /var/lib/virtualbox-autostart
chgrp vboxusers /var/lib/virtualbox-autostart
# chmod 1775 /var/lib/virtualbox-autostart

4、配置virtualbox的dbpath屬性:
這一步很關鍵,我們可以先看一下virtualbox都配置了哪些系統屬性:
vboxmanage list systemproperties
輸出很長,仔細找,可以發現Autostart database path配置項,默認情況下應該是空值。下面就來指定一下這個屬性:
vboxmanage setproperty autostartdbpath /var/lib/virtualbox-autostart
此時再查一下該項屬性,已經不是空值了:
vboxmanage list systemproperties|grep Autostart

Autostart database path:        /var/lib/virtualbox-autostart

5、你想讓哪一個虛擬系統自動啟動?
假如我們安裝配置了很多個虛擬系統,比如有windows10、CentOS7、ArchLinux等,但是只希望ArchLinux隨宿主系統一起自動啟動,那就指定一下,修改ArchLinux虛擬系統的自啟屬性:
vboxmanage modifyvm ArchLinux –autostart-enabled on –autostop-type acpishutdown
不能光管自動啟動,還要管自動停止,–autostop-type指定自動停止的方式,acpishutdown表示正常關機模式。
查看一下/var/lib/virtualbox-autostart目錄下是否有文件生成:
ls /var/lib/virtualbox-autostart
此時可以看到有兩個文件已經生成,如下所示:
vbox.start  vbox.stop

如果第4步沒有做,則第5步不會生成這兩個文件;如果4、5兩步有任一步沒有做,那麼在重啟vboxautostart-service服務時會出現“找不到*.stop文件”的錯誤,服務啟動失敗。

6、重啟vboxautostart-service服務:

CentOS 7:systemctl restart vboxautostart-service
ArchLinux:Arch Linux系統在安裝virtualbox時並沒有自動創建自啓動的vboxautostart腳本,也沒有創建systemd的啓動控制腳本,更關鍵的是沒有/usr/lib/virtualbox/VBoxAutostart這個二進制可執行文件,我估計這是Arch Linux官方團隊在將virtualbox納入軟件倉庫時忽視了這部分功能所致。如果想和CentOS 7一樣在系統啓動時自動啓動虛擬機,則還需要額外做一些工作,前提條件是得先有安裝配置好virtualbox的CentOS 7以上的系統:
(1)將CentOS系統/usr/lib/virtualbox目錄下的VBoxAutostart和vboxautostart-service.sh文件復制到Arch Linux系統的相同目錄下,具體怎麼復制就不說了,各顯神通吧。然後修改VBoxAutostart的屬性,賦予可執行屬性:
chmod +x /usr/lib/virtualbox/VBoxAutostart
/usr/lib/virtualbox/vboxautostart-service.sh的具體內容如下:
#!/bin/sh
# $Id: vboxautostart-service.sh 127855 2019-01-01 01:45:53Z bird $
## @file
# VirtualBox autostart service init script.
#
#
# Copyright (C) 2012-2019 Oracle Corporation
#
# This file is part of VirtualBox Open Source Edition (OSE), as
# available from http://www.virtualbox.org. This file is free software;
# you can redistribute it and/or modify it under the terms of the GNU
# General Public License (GPL) as published by the Free Software
# Foundation, in version 2 as it comes in the "COPYING" file of the
# VirtualBox OSE distribution. VirtualBox OSE is distributed in the
# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
#

# chkconfig: 345 35 65
# description: VirtualBox autostart service
#
### BEGIN INIT INFO
# Provides:       vboxautostart-service
# Required-Start: vboxdrv
# Required-Stop:  vboxdrv
# Default-Start:  2 3 4 5
# Default-Stop:   0 1 6
# Description:    VirtualBox autostart service
### END INIT INFO

PATH=$PATH:/bin:/sbin:/usr/sbin
SCRIPTNAME=vboxautostart-service.sh

[ -f /etc/debian_release -a -f /lib/lsb/init-functions ] || NOLSB=yes
[ -f /etc/vbox/vbox.cfg ] && . /etc/vbox/vbox.cfg

if [ -n “$INSTALL_DIR” ]; then
    binary="$INSTALL_DIR/VBoxAutostart"
else
    binary="/usr/lib/virtualbox/VBoxAutostart"
fi

# silently exit if the package was uninstalled but not purged,
# applies to Debian packages only (but shouldn't hurt elsewhere)
[ ! -f /etc/debian_release -o -x $binary ] || exit 0

[ -r /etc/default/virtualbox ] && . /etc/default/virtualbox

# Preamble for Gentoo
if [ “`which $0`” = “/sbin/rc” ]; then
    shift
fi

begin_msg()
{
    test -n "${2}" && echo "${SCRIPTNAME}: ${1}."
    logger -t "${SCRIPTNAME}" "${1}."
}

succ_msg()
{
    logger -t "${SCRIPTNAME}" "${1}."
}

fail_msg()
{
    echo "${SCRIPTNAME}: failed: ${1}." >&2
    logger -t "${SCRIPTNAME}" "failed: ${1}."
}

start_daemon() {
    usr="$1"
    shift
    su – $usr -c "$*"
}

if which start-stop-daemon >/dev/null 2>&1; then
    start_daemon() {
        usr="$1"
        shift
        bin="$1"
        shift
        start-stop-daemon –chuid $usr –start –exec $bin — $@
    }
fi

vboxdrvrunning() {
    lsmod | grep -q "vboxdrv[^_-]"
}

start() {
    [ -z “$VBOXAUTOSTART_DB” ] && exit 0
    [ -z “$VBOXAUTOSTART_CONFIG” ] && exit 0
    begin_msg "Starting VirtualBox VMs configured for autostart" console;
    vboxdrvrunning || {
        fail_msg "VirtualBox kernel module not loaded!"
        exit 0
    }
    PARAMS="–background –start –config $VBOXAUTOSTART_CONFIG"

    # prevent inheriting this setting to VBoxSVC
    unset VBOX_RELEASE_LOG_DEST

    for user in `ls $VBOXAUTOSTART_DB/*.start`
    do
        start_daemon `basename $user | sed -ne "s/\(.*\).start/\1/p"` $binary $PARAMS > /dev/null 2>&1
    done

    return $RETVAL
}

stop() {
    [ -z “$VBOXAUTOSTART_DB” ] && exit 0
    [ -z “$VBOXAUTOSTART_CONFIG” ] && exit 0

    PARAMS="–stop –config $VBOXAUTOSTART_CONFIG"

    # prevent inheriting this setting to VBoxSVC
    unset VBOX_RELEASE_LOG_DEST

    for user in `ls $VBOXAUTOSTART_DB/*.stop`
    do
        start_daemon `basename $user | sed -ne "s/\(.*\).stop/\1/p"` $binary $PARAMS > /dev/null 2>&1
    done

    return $RETVAL
}

case "$1" in
start)
    start
    ;;
stop)
    stop
    ;;
*)
    echo "Usage: $0 {start|stop}"
    exit 1
esac

exit $RETVAL

然後在/usr/sbin目錄下創建一個軟鏈接指向它:
ln -s /usr/lib/virtualbox/vboxautostart-service.sh /usr/sbin/rcvboxautostart

以上兩個步驟是借鑑CentOS 7的做法,創建sh腳本文件是必須的,而rcvboxautostart軟鏈接文件並不是必須的,經過仔細查看以上sh腳本,發現這是gentoo系統需要用到的,隨手創建一下也不費啥事。
接下來查看一下/usr/bin目錄下是否有VBox這個文件以及指向它的軟鏈接文件:
ls -l /usr/bin/{VB*,vb*}
-rwxr-xr-x 1 root root  4677  1月 15 06:33 /usr/bin/VBox
lrwxrwxrwx 1 root root     4  1月 15 06:33 /usr/bin/vboxballoonctrl -> VBox
lrwxrwxrwx 1 root root     4  1月 15 06:33 /usr/bin/VBoxBalloonCtrl -> VBox
lrwxrwxrwx 1 root root     4  1月 15 06:33 /usr/bin/vboxheadless -> VBox
lrwxrwxrwx 1 root root     4  1月 15 06:33 /usr/bin/VBoxHeadless -> VBox
lrwxrwxrwx 1 root root     4  1月 15 06:33 /usr/bin/vboxmanage -> VBox
lrwxrwxrwx 1 root root     4  1月 15 06:33 /usr/bin/VBoxManage -> VBox
-rwxr-xr-x 1 root root  1179  1月 15 06:33 /usr/bin/vboxreload
lrwxrwxrwx 1 root root     4  1月 15 06:33 /usr/bin/vboxsdl -> VBox
lrwxrwxrwx 1 root root     4  1月 15 06:33 /usr/bin/VBoxSDL -> VBox
-rwxr-xr-x 1 root root 14184  1月 15 06:33 /usr/bin/VBoxTunctl
lrwxrwxrwx 1 root root     4  1月 15 06:33 /usr/bin/vboxwebsrv -> VBox

正常情況下會出現以上的輸出結果,我們可以看到有很多VBox或vbox開頭的文件都指向了VBox,意思是都是VBox的鏈接文件,但是卻唯獨沒有與自動啓動有並的軟鏈接文件,那我們就自己創建一個:
ln -s /usr/bin/VBox /usr/bin/vboxautostart
接下來創建systemd啓動腳本,還是從CentOS 7中復制而來:
vim /usr/lib/systemd/system/vboxautostart-service.service
[Unit]
SourcePath=/usr/lib/virtualbox/vboxautostart-service.sh
Description=
Before=runlevel2.target runlevel3.target runlevel4.target runlevel5.target shutdown.target
After=vboxdrv.service    //這一句原則上應該屏蔽掉,因爲在Arch Linux系統中並沒有這個服務,所以我第一時間屏蔽了,也沒有測試保留它會有什麼問題。這項的意思是在啓動此腳本之前vboxdrv.service服務要先啓動好。
Conflicts=shutdown.target
[Service]
Type=forking
Restart=no
TimeoutSec=5min
IgnoreSIGPIPE=no
KillMode=process
GuessMainPID=no
RemainAfterExit=yes
ExecStart=/usr/lib/virtualbox/vboxautostart-service.sh start
ExecStop=/usr/lib/virtualbox/vboxautostart-service.sh stop

[Install]
WantedBy=multi-user.target

保存退出。啓用vboxauostart.service服務:
啓用:systemctl enable vboxautostart
啓動:systemctl start vboxautostart

不出啥意外情況,稍等片刻虛擬系統ArchLinux應該就啟動好了,此時用RDP客戶端軟件連接即可看到ArchLinux確實已經成功啟動,此時的vrdeport端口是默認的3389,如果此端口已經被宿主機所佔用,則會出現錯誤,需要換一個空閒的端口,不過這种情況一般出現在宿主機是windows系統比較多,Linux系統一般不會佔用這個端口,下面就來說說如何修改指定端口號:

明確指定VRDP的幾個關鍵參數:

vboxmanage modifyvm "ArchLinux" –vrde on –vrdeport 3390
將vrdeport改爲了3390,再來看看虛擬機的設置狀態:
vboxmanage showvminfo "ArchLinux"
端口衝突的問題解決。

至此virtualbox的Web服務和自啟動服務全部配置完成,今後再也不用遠程登錄宿主機來啟動virtualbox的GUI界面來配置、啟停虛擬機了。

7、安裝RemoteBox來遠程管理virtualbox:

第一步:
CentOS 7的官方庫中都沒有RemoteBox,需要上官網下載:http://remotebox.knobgoblin.org.uk/?page=downloads
選擇最新的Linux版,注意看看對應的virtualbox版本,下載好後解壓到/opt目錄下:
tar -xjf xxxxx.tar.bz2
將解壓後的文件夾移到/opt目錄,將該目錄下的remotebox文件屬性修改爲可執行:
chmod +x remotebox
此時還不能正常運行,還要安裝三個包:perl、perl-soap、perl-gtk2(CentOS 7中用yum搜索一下具體的包名再安裝即可),而Arch Linux官方庫中雖然沒有remotebox,但是在AUR庫中有,用yay可以很方便地安裝:
yay -S remotebox perl perl-soap-lite perl-gtk2-ex-formfactory
運行remotebox
出現remotebox的GUI界面,點擊connect,填入virtualbox宿主機的ip地址(端口號默認18083,如果vboxweb服務配置中沒有指定端口號則使用的就是默認值)、用戶名和密碼(即登錄linux系統的用戶和密碼)即可連接管理virtualbox虛擬機了,前提條件是該虛擬機已經開啓了RDP服務(是虛擬機配置中開啓RDP服務,而不是虛擬機系統中開啓)。

第二步:
如果運行virtualbox的不是root,而是普通用戶,比如vbox,會出現一個問題:remotebox連接上virtualbox之後,會發現看不到任何虛擬系統,造成這個問題的原因就是virtualbox創建的虛擬系統在/home/vbox目錄下,而remotebox連接vboxweb服務時是根據啓動vboxweb的用戶來確定上哪讀取虛擬系統配置,而vboxweb服務默認是以root用戶啓動的,因此remotebox就會上/root目錄下尋找,那當然就找不到嘍。因此我們需要修改vboxweb服務的啓動腳本:
vim /usr/lib/systemd/system/vboxweb.service
[Unit]
Description=VirtualBox Web Service
After=network.target

[Service]
Type=forking
User=vbox               //添加User和Group配置
Group=vboxusers    //User和Group必須配置在ExecStart之前,否則此腳本無法正確啓動
PIDFile=/tmp/vboxweb.pid    //將原值/run/vboxweb.pid修改爲此值,原因是/run目錄普通用戶沒有寫入權限
ExecStart=/usr/bin/vboxwebsrv –pidfile /tmp/vboxweb.pid –host 0.0.0.0 –background    //啓動vboxweb服務,指定pid文件位置、virtualbox主機ip,0.0.0.0表示服務綁定主機所有IP,–background表示後臺運行

[Install]
WantedBy=multi-user.target

保存退出。重載systemctl單元:
systemctl daemon-reload
重啓:systemctl restart vboxweb
此時vboxweb服務就是以vbox用戶運行了,再用remotebox連接vboxweb服務,這回就能正常看到虛擬系統了。

本篇發表於 Linux系統, 軟體使用。將永久鏈結加入書籤。