En este artículo voy a cubrir las tareas de administración básica de un host de máquinas virtuales VirtualBox sin entorno gráfico, desde la creación de máquinas virtuales, hasta la configuración de VNC, creación de discos y encendido/apagado de máquinas virtuales, totalmente desde línea de comandos.
En artículos anteriores expliqué cómo instalar VirtualBox en GNU/Linux y en FreeBSD. Ahora voy a explica cómo gestionar un hipervisor VirtualBox sin entorno gráfico completamente desde línea de comandos, utilizando como base un host FreeBSD. Mi idea es montar un servidor de máquinas virtuales (comúnmente denominado simplemente como "host") FreeBSD sin entorno gráfico (headless, sin cabeza), utilizando VirtualBox como tecnología de virtualización, y gestionarlo completamente desde línea de comandos (tal como haría con virsh).
Spoiler alert: es perfectamente posible.
Como plataforma de pruebas utilizo mi propia workstastion FreeBSD la cual posee algunas máquinas virtuales creadas previamente desde la interfaz gráfica:
emi@hal9000:~ % ll VirtualBox\ VMs/ total 12 drwxr-xr-x 3 emi wheel 512 Jun 9 2015 W2008/ drwxr-xr-x 3 emi wheel 512 Feb 17 13:19 alpine/ drwxr-xr-x 4 emi wheel 512 Aug 18 2015 kali/
Mi plan es crear, instalar y poner en funcionamiento una máquina virtual GNU/Linux (Devuan, más precisamente), accediendo al display de la máquina virtual de forma remota mediante VNC, como lo hace QEMU, sin recurrir en ningún momento a la interfaz gráfica (como si efectivamente se tratase de una instalación de VirtualBox sin entorno gráfico).
En el artículo Cómo mapear un disco físico o partición a un guest VirtualBox había introducido la herramienta de gestión VBoxManage
, la interfaz de control de VirtualBox de línea de comandos que permite realizar todas las operaciones y funciones provistas por la interfaz gráfica, más muchas otras características avanzadas.
La cantidad de subcomandos de la herramienta VBoxManage es abrumadora, aunque se puede acudir a la ayuda simplemente ejecutando:
VBoxManage
Creación de una máquina virtual
El subcomando "createvm" se utiliza para definir (en jerga libvirt) nuevas máquinas virtuales:
emi@hal9000:~ % VBoxManage createvm Usage: VBoxManage createvm --name <name> [--groups <group>, ...] [--ostype <ostype>] [--register] [--basefolder <path>] [--uuid <uuid>]
Es posible listar el tipo de sistemas operativos disponibles ejecutando VBoxManage list ostypes
. La lista es inmensa. Para el caso se puede utilizar el tipo genérico "Linux_64", pues se desea instalar una distribución derivada de Debian de 64 bits:
emi@hal9000:~/VirtualBox VMs % VBoxManage createvm --name "Devuan" --ostype Linux_64 --register Virtual machine 'Devuan' is created and registered. UUID: dd25c9d9-a2a9-45fc-9cab-f0c52d27a7f8 Settings file: '/home/emi/VirtualBox VMs/Devuan/Devuan.vbox'
Al crear la máquina virtual, VirtualBox crea automáticamente un nuevo subdirectorio dentro del directorio "VirtualBox VMs" en del $HOME
del usuario actual:
emi@hal9000:~ % ll VirtualBox\ VMs/ total 16 drwx------ 2 emi wheel 512 Mar 8 08:53 Devuan/ drwxr-xr-x 3 emi wheel 512 Jun 9 2015 W2008/ drwxr-xr-x 3 emi wheel 512 Feb 17 13:19 alpine/ drwxr-xr-x 4 emi wheel 512 Aug 18 2015 kali/
Este directorio contiene la definición de la máquina virtual:
emi@hal9000:~ % ll VirtualBox\ VMs/Devuan/ total 8 -rw------- 1 emi wheel 5976 Mar 8 08:53 Devuan.vbox
Editar la configuración de una máquina virtual
Luego de crear la máquina virtual se necesitará configurar su hardware (opciones, cantidad de memoria, dispositivos de red, discos, etc.), para ello se recurre al subcomando "modifyvm":
emi@hal9000:~ % VBoxManage modifyvm Usage: VBoxManage modifyvm <uuid|vmname> [--name <name>] [--groups <group>, ...] [--description <desc>] [--ostype <ostype>] [--iconfile <filename>] [--memory <memorysize in MB>] [--pagefusion on|off] [--vram <vramsize in MB>] [--acpi on|off] [--pciattach 03:04.0] [--pciattach 03:04.0@02:01.0] [--pcidetach 03:04.0] [--ioapic on|off] [--hpet on|off] [--triplefaultreset on|off] [--hwvirtex on|off] [--nestedpaging on|off] [--largepages on|off] [--vtxvpid on|off] [--vtxux on|off] [--pae on|off] [--longmode on|off] [--synthcpu on|off] [--cpuidset <leaf> <eax> <ebx> <ecx> <edx>] [--cpuidremove <leaf>] [--cpuidremoveall] [--hardwareuuid <uuid>] [--cpus <number>] [--cpuhotplug on|off] [--plugcpu <id>] [--unplugcpu <id>] [--cpuexecutioncap <1-100>] [--rtcuseutc on|off] [--graphicscontroller none|vboxvga|vmsvga] [--monitorcount <number>] [--accelerate3d on|off] [--accelerate2dvideo on|off] [--firmware bios|efi|efi32|efi64] [--chipset ich9|piix3] [--bioslogofadein on|off] [--bioslogofadeout on|off] [--bioslogodisplaytime <msec>] [--bioslogoimagepath <imagepath>] [--biosbootmenu disabled|menuonly|messageandmenu] [--biossystemtimeoffset <msec>] [--biospxedebug on|off] [--boot<1-4> none|floppy|dvd|disk|net>] [--nic<1-N> none|null|nat|bridged|intnet|hostonly| generic|natnetwork] [--nictype<1-N> Am79C970A|Am79C973| 82540EM|82543GC|82545EM| virtio] [--cableconnected<1-N> on|off] [--nictrace<1-N> on|off] [--nictracefile<1-N> <filename>] [--nicproperty<1-N> name=[value]] [--nicspeed<1-N> <kbps>] [--nicbootprio<1-N> <priority>] [--nicpromisc<1-N> deny|allow-vms|allow-all] [--nicbandwidthgroup<1-N> none|<name>] [--bridgeadapter<1-N> none|<devicename>] [--hostonlyadapter<1-N> none|<devicename>] [--intnet<1-N> <network name>] [--nat-network<1-N> <network name>] [--nicgenericdrv<1-N> <driver> [--natnet<1-N> <network>|default] [--natsettings<1-N> [<mtu>],[<socksnd>], [<sockrcv>],[<tcpsnd>], [<tcprcv>]] [--natpf<1-N> [<rulename>],tcp|udp,[<hostip>], <hostport>,[<guestip>],<guestport>] [--natpf<1-N> delete <rulename>] [--nattftpprefix<1-N> <prefix>] [--nattftpfile<1-N> <file>] [--nattftpserver<1-N> <ip>] [--natbindip<1-N> <ip> [--natdnspassdomain<1-N> on|off] [--natdnsproxy<1-N> on|off] [--natdnshostresolver<1-N> on|off] [--nataliasmode<1-N> default|[log],[proxyonly], [sameports]] [--macaddress<1-N> auto|<mac>] [--mouse ps2|usb|usbtablet|usbmultitouch] [--keyboard ps2|usb [--uart<1-N> off|<I/O base> <IRQ>] [--uartmode<1-N> disconnected| server <pipe>| client <pipe>| file <file>| <devicename>] [--guestmemoryballoon <balloonsize in MB>] [--audio none|null|oss] [--audiocontroller ac97|hda|sb16] [--clipboard disabled|hosttoguest|guesttohost| bidirectional] [--draganddrop disabled|hosttoguest [--vrde on|off] [--vrdeextpack default|<name> [--vrdeproperty <name=[value]>] [--vrdeport <hostport>] [--vrdeaddress <hostip>] [--vrdeauthtype null|external|guest] [--vrdeauthlibrary default|<name> [--vrdemulticon on|off] [--vrdereusecon on|off] [--vrdevideochannel on|off] [--vrdevideochannelquality <percent>] [--usb on|off] [--usbehci on|off] [--snapshotfolder default|<path>] [--teleporter on|off] [--teleporterport <port>] [--teleporteraddress <address|empty> [--teleporterpassword <password>] [--teleporterpasswordfile <file>|stdin] [--tracing-enabled on|off] [--tracing-config <config-string>] [--tracing-allow-vm-access on|off] [--usbcardreader on|off] [--autostart-enabled on|off] [--autostart-delay <seconds>] [--defaultfrontend default|<name>]
Lo primero necesario es definir la cantidad de memoria RAM que tendrá la máquina virtual, agregar al menos una interfaz de red, y configurar las opciones de boot:
emi@hal9000:~ % VBoxManage modifyvm "Devuan" --memory 512 --acpi on --boot1 dvd --nic1 nat
Con eso se han asignado 512 megabytes de memoria RAM, se habilitó el soporte para ACPI, se especificó la unidad de DVDROM como primer y único dispositivo desde donde inciar el sistema, y se agregó una interfaz de red conectada a la red NAT.
Luego es probable que se desee agregar un disco, por ejemplo de 2 gigabytes. Para ello, primero es necesario crearlo:
emi@hal9000:~ % VBoxManage createhd --filename VirtualBox\ VMs/Devuan/Devuan.vdi --size 2000 0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100% Disk image created. UUID: c056423f-3b8f-4a40-a36e-3b3d22860f1e
Y luego asignarlo a la nueva máquina virtual utilizando el subcomando "storageattach":
emi@hal9000:~ % VBoxManage storageattach Usage: VBoxManage storageattach <uuid|vmname> --storagectl <name> [--port <number>] [--device <number>] [--type dvddrive|hdd|fdd] [--medium none|emptydrive|additions| <uuid|filename>|host:<drive>|iscsi] [--mtype normal|writethrough|immutable|shareable| readonly|multiattach] [--comment <text>] [--setuuid <uuid>] [--setparentuuid <uuid>] [--passthrough on|off] [--tempeject on|off] [--nonrotational on|off] [--discard on|off] [--bandwidthgroup <name>] [--forceunmount] [--server <name>|<ip>] [--target <target>] [--tport <port>] [--lun <lun>] [--encodedlun <lun>] [--username <username>] [--password <password>] [--initiator <initiator>] [--intnet]
Tal como se observa en la ayuda, se debe contar con un controlador IDE/SATA/SCSI para agregar el disco. Por ejemplo, para crear un controlador IDE, ejecutar:
emi@hal9000:~ % VBoxManage storagectl Devuan --name "IDE Controller" --add ide --controller PIIX4
(Ejecutar VBoxManage storagectl
para obtener el listado completo de parámetros y opciones.)
En este punto la máquina virtual cuenta ya con un controlador IDE al cual se le conectará el disco rígido en uno de sus ports. Es como si se estuviese ensamblando una máquina pieza por pieza (como hacíamos antes de la era de la virtualización cuando comprábamos hardware nuevo).
Agregar el disco como dispositivo 0 del puerto 0 (primary master), especificando la ruta al archivo vdi:
emi@hal9000:~ % VBoxManage storageattach Devuan --storagectl "IDE Controller" --port 0 --device 0 --type hdd --medium /home/emi/VirtualBox\ VMs/Devuan/Devuan.vdi
Y además agregar un DVDROM como dispositivo 1 del port 0 (primary slave) que contenga la imagen de instalación de Devuan:
emi@hal9000:~ % VBoxManage storageattach Devuan --storagectl "IDE Controller" --port 0 --device 1 --type dvddrive --medium /home/emi/Downloads/devuan-jessie-netboot-amd64-alpha2.iso
Configurar el display VNC para acceso remoto
Para poder acceder al display de una máquina virtual desde un host remoto (que cuente con interfaz gráfica y un cliente VNC) será necesario contar con el pack de extensión VNC:
emi@hal9000:~ % VBoxManage list extpacks Extension Packs: 1 Pack no. 0: VNC Version: 4.3.36_OSE Revision: 105129 Edition: Description: VNC plugin module VRDE Module: VBoxVNC Usable: true Why unusable:
Para ello, se debe haber compilado VirtualBox en FreeBSD con soporte para VNC:

Habilitar el acceso remoto al display de una máquina virtual debe ser una configuración temporal, por ejemplo para instalar el sistema operativo o diagnosticar errores. Luego esta opción debe estar desactivada, ya que se accederá al sistema guest directamente a través de la red tanto en sistemas GNU/Linux (SSH) como Windows (RDP).
Se debe elegir un puerto donde aceptar conexiones entrantes y opcionalmente una dirección IP y contraseña:
emi@hal9000:~ % VBoxManage setproperty vrdeextpack VNC emi@hal9000:~ % VBoxManage modifyvm Devuan --vrde on emi@hal9000:~ % VBoxManage modifyvm Devuan --vrdeauthtype null emi@hal9000:~ % VBoxManage modifyvm Devuan --vrdeaddress 127.0.0.1 emi@hal9000:~ % VBoxManage modifyvm Devuan --vrdeport 6666 emi@hal9000:~ % VBoxManage modifyvm Devuan --vrdeproperty VNCPassword=123456
Si se requiere una contraseña más fuerte, utilizar "12345678" o "abc123".
Tener en cuenta que esta contraseña queda visible en la línea de comandos del proceso VBoxHeadless
en el host. Por ejemplo es posible obtenerla desde la salida de ps
.
Se observa que con esta configuración sólo aceptará conexiones desde localhost
(--vrdeaddress 127.0.0.1
). Para eliminar esta restricción, descartar la configuración --vrdeaddress
y filtrar las conexiones entrantes hacia el puerto 6666
por IP de origen en el firewall del host.
Lógicamente se debe escoger un puerto diferente para cada máquina virtual.
Listar la configuración de una máquina virtual
Al finalizar la configuración de la máquina virtual, es posible obtener un listado de su configuración de hardware y opciones ejecutando VBoxManage showvminfo
:
emi@hal9000:~ % VBoxManage showvminfo Devuan Name: Devuan Groups: / Guest OS: Other Linux (64-bit) UUID: dd25c9d9-a2a9-45fc-9cab-f0c52d27a7f8 Config file: /home/emi/VirtualBox VMs/Devuan/Devuan.vbox Snapshot folder: /home/emi/VirtualBox VMs/Devuan/Snapshots Log folder: /home/emi/VirtualBox VMs/Devuan/Logs Hardware UUID: dd25c9d9-a2a9-45fc-9cab-f0c52d27a7f8 Memory size: 512MB Page Fusion: off VRAM size: 8MB CPU exec cap: 100% HPET: off Chipset: piix3 Firmware: BIOS Number of CPUs: 1 PAE: on Long Mode: off Synthetic CPU: off CPUID overrides: None Boot menu mode: message and menu Boot Device (1): DVD Boot Device (2): DVD Boot Device (3): HardDisk Boot Device (4): Not Assigned ACPI: on IOAPIC: off Time offset: 0ms RTC: local time Hardw. virt.ext: on Nested Paging: on Large Pages: on VT-x VPID: on VT-x unr. exec.: on State: powered off (since 2016-03-08T12:43:43.000000000) Monitor count: 1 3D Acceleration: off 2D Video Acceleration: off Teleporter Enabled: off Teleporter Port: 0 Teleporter Address: Teleporter Password: Tracing Enabled: off Allow Tracing to Access VM: off Tracing Configuration: Autostart Enabled: off Autostart Delay: 0 Default Frontend: Storage Controller Name (0): IDE Controller Storage Controller Type (0): PIIX4 Storage Controller Instance Number (0): 0 Storage Controller Max Port Count (0): 2 Storage Controller Port Count (0): 2 Storage Controller Bootable (0): on IDE Controller (0, 0): /home/emi/VirtualBox VMs/Devuan/Devuan.vdi (UUID: c056423f-3b8f-4a40-a36e-3b3d22860f1e) IDE Controller (0, 1): /home/emi/Downloads/devuan-jessie-netboot-amd64-alpha2.iso (UUID: 7d1ecc35-b62b-479b-808c-06692696bd76) NIC 1: MAC: 080027F084AC, Attachment: NAT, Cable connected: on, Trace: off (file: none), Type: Am79C973, Reported speed: 0 Mbps, Boot priority: 0, Promisc Policy: deny, Bandwidth group: none NIC 1 Settings: MTU: 0, Socket (send: 64, receive: 64), TCP Window (send:64, receive: 64) NIC 2: disabled NIC 3: disabled NIC 4: disabled NIC 5: disabled NIC 6: disabled NIC 7: disabled NIC 8: disabled Pointing Device: PS/2 Mouse Keyboard Device: PS/2 Keyboard UART 1: disabled UART 2: disabled LPT 1: disabled LPT 2: disabled Audio: disabled Clipboard Mode: disabled Drag'n'drop Mode: disabled VRDE: enabled (Address 0.0.0.0, Ports 3389, MultiConn: off, ReuseSingleConn: off, Authentication type: null) Video redirection: disabled VRDE property: TCP/Ports = "6666" VRDE property: TCP/Address = "127.0.0.1" USB: disabled EHCI: disabled USB Device Filters: <none> Available remote USB devices: <none> Currently Attached USB Devices: <none> Bandwidth groups: <none> Shared folders: <none> VRDE Connection: not active Clients so far: 0 Video capturing: not active Capture screens: 0 Capture file: /home/emi/VirtualBox VMs/Devuan/Devuan.webm Capture dimensions: 1024x768 Capture rate: 512 kbps Capture FPS: 25 Guest: Configured memory balloon size: 0 MB
Esta información es la misma que obtiene al ingresar desde la interfaz gráfica de VirtualBox:

(En realidad es mucha más información que la que ofrece la interfaz gráfica.)
Listar máquinas virtuales
Para listar las máquinas virtuales disponibles y en ejecución, utilizar list vms
y list runningvms
:
emi@hal9000:~ % VBoxManage list vms "alpine" {6c5c2365-e9e6-4ae9-b225-c44f93ca1ce9} "Devuan" {dd25c9d9-a2a9-45fc-9cab-f0c52d27a7f8} emi@hal9000:~ % VBoxManage list runningvms emi@hal9000:~ %
Iniciar una máquina virtual headless
El subcomando "startvm" se utiliza para iniciar máquinas virtuales. Aunque si el host no posee entorno gráfico, se debe especificar adicionalmente la opción --type headless
:
emi@hal9000:~ % VBoxManage startvm Devuan --type headless Waiting for VM "Devuan" to power on... VM "Devuan" has been successfully started. emi@hal9000:~ % VBoxManage list runningvms "Devuan" {dd25c9d9-a2a9-45fc-9cab-f0c52d27a7f8}
De esta forma se inicia la máquina virtual en segundo plano, sin necesidad de contar con un entorno gráfico en el host.
Acceso al display de una máquina virtual
De acuerdo a la configuración de display VNC será posible acceder al display de la máquina virtual desde un sistema remoto que cuente con un cliente VNC (mi favorito es KRDC)

Long mode
En caso de utilizar máquinas virtuales de 64 bits, puede suceder que el sistema operativo guest no detecte adecuadamente la arquitectura amd64/x86-64. En tal caso, habilitar el long mode en la configuración de procesador de la máquina virtual:
emi@hal9000:~ % VBoxManage modifyvm Devuan --longmode on
Apagar una máquina virtual
Al finalizar la instalación se reinicia el sistema. Pero será necesario apagar la máquina virtual para remover la imagen ISO del DVDROM y cambiar el orden de boot para que inicie desde el disco rígido.
Se debe utilizar el subcomando "controlvm":
emi@hal9000:~ % VBoxManage controlvm Devuan poweroff 0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
Tener en cuenta que poweroff no es un apagado del sistema operativo guest, sino que simula una interrupción en el suministro de energía (similar a virsh destroy
).
Modificar el orden de booteo
Algunos parámetros de configuración de los subcomandos de VBoxManage
aceptan subíndices. Por ejemplo, el orden de booteo se establece de acuerdo al subíndice del parámetro boot<i>
:
emi@hal9000:~ % VBoxManage modifyvm "Devuan" --boot1 dvd --boot2 disk
Detach de un medio removible
VBoxManage no tiene un comando "detach", por ende, para quitar un medio removible (CD/DVD), simplemente se debe asignar "none" en el dispositivo en cuestión:
emi@hal9000:~ % VBoxManage storageattach Devuan --storagectl "IDE Controller" --port 0 --device 1 --type dvddrive --medium none
Networking en modo "host-only"
El modo host-only implementa una red privada en donde todas las máquinas virtuales pueden comunicarse entre sí y el host. Este modo de red permite implementar una red cerrada útil para asegurar comunicaciones entre guests que no deben ser visibles desde el exterior (por ejemplo el acceso a un servidor de bases de datos desde un servidor Web). También es útil para conectarse a una máquina virtual desde el host (por ejemplo, para tareas de backup y monitoreo).
Este modo requiere que el host cuente con una interfaz de red virtual.
emi@hal9000:~ % VBoxManage list hostonlyifs emi@hal9000:~ %
Inicialmente el host no posee una interfaz host-only, por lo que deberá crearse:
emi@hal9000:~ % VBoxManage hostonlyif create 0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100% Interface 'vboxnet0' was successfully created
Los nombres de las interfaces host-only se generan de forma automática y están conformados por la palabra "vboxnet" junto con un subíndice:
emi@hal9000:~ % VBoxManage list hostonlyifs Name: vboxnet0 GUID: 786f6276-656e-4074-8000-0a0027000000 DHCP: Disabled IPAddress: 192.168.56.1 NetworkMask: 255.255.255.0 IPV6Address: IPV6NetworkMaskPrefixLength: 0 HardwareAddress: 0a:00:27:00:00:00 MediumType: Ethernet Status: Down VBoxNetworkName: HostInterfaceNetworking-vboxnet0
A través de esta interfaz, el host ofrecerá direcciones IP de forma dinámica (DHCP) a las máquinas virtuales conectadas a esta red. Es posible tener múltiples interfaces (y por ende rede) en modo host-only.
Al crear la interfaz, esta debe ser visible desde el host:
emi@hal9000:~ % ifconfig vboxnet0 vboxnet0: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500 ether 0a:00:27:00:00:00 nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL> media: Ethernet autoselect status: active
Luego de crearla, es necesario configurar su dirección IP y verificar desde el host:
emi@hal9000:~ % VBoxManage hostonlyif ipconfig vboxnet0 --ip 192.168.56.1 emi@hal9000:~ % ifconfig vboxnet0 vboxnet0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500 ether 0a:00:27:00:00:00 inet 192.168.56.1 netmask 0xffffff00 broadcast 192.168.56.255 nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL> media: Ethernet autoselect status: active
Para agregar una interfaz en modo host-only a una máquina virtual, ejecutar el siguiente comando:
emi@hal9000:~ % VBoxManage modifyvm Devuan --nic2 hostonly
Notar el cambio de subíndice en el parámetro "nic".
Iniciar la máquina virtual y verificar el acceso a la red host-only:
emi@hal9000:~ % VBoxManage startvm Devuan --type headless Waiting for VM "Devuan" to power on... VM "Devuan" has been successfully started. emi@hal9000:~ % VBoxManage list runningvms "Devuan" {dd25c9d9-a2a9-45fc-9cab-f0c52d27a7f8}
emi@hal9000:~ % ping -c 1 192.168.56.101 PING 192.168.56.101 (192.168.56.101): 56 data bytes 64 bytes from 192.168.56.101: icmp_seq=0 ttl=64 time=0.220 ms --- 192.168.56.101 ping statistics --- 1 packets transmitted, 1 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 0.220/0.220/0.220/0.000 ms
Enjoy!
Oracle VM VirtualBox User Manual - Remote virtual machines
Oracle VM VirtualBox User Manual - VBoxManage
Oracle VM VirtualBox User Manual - Virtual networking