QEMU KVM as a service
Now it is possible to start a virtual machine as a service at boot time, but you need to create it as SMF service. We assume that you have installed kvm package as:
dev0# apt install kvm
This is a meta-package which installs all required packages and the SMF service. After reboot you will see default instance of the kvm service:
dev0# svcs kvm STATE STIME FMRI disabled 18:18:16 svc:/system/kvm:default
Don't try to enable it, it will not start, anyway, it is a template only for default parameters that you don't configure. Let's create one.
First you need to add an instance of the service, type in the command line:
dev0# svccfg -s kvm add vm01
Now you need to create 3 groups of properties: hvm, net and disks:
dev0# svccfg -s kvm:vm01 addpg hvm application dev0# svccfg -s kvm:vm01 addpg net application dev0# svccfg -s kvm:vm01 addpg disk application
Now you can configure the new VM. Specify amount memory size:
dev0# svccfg -s kvm:vm01 setprop hvm/mem = astring: 1g
By default the size is set to 512m. Create a zvol for the new VM and add it to the service:
dev0# zfs create -b 4k -V 10g data/kvm/disk0 dev0# svccfg -s kvm:vm01 setprop disk/disk0 = astring: disk0 dev0# svccfg -s kvm:vm01 addpg disk0 application dev0# svccfg -s kvm:vm01 setprop disk0/zvol = astring: data/kvm/disk0
Second command specifies a "label" of the disk, in our example it is disk0, but you can choose something else. This label point to another program group which is created in next line. The latest command adds our new zvol as the disk device in the new section. By default, the model of disk is virtio.
In the real world we need a network for our VM, let's do it:
dev0# svccfg -s kvm:vm01 setprop net/net0 = astring: net0
This command adds a lablel of the network, like we did it for disks. Now configure the new section:
dev0# svccfg -s kvm:vm01 addpg net0 application dev0# svccfg -s kvm:vm01 setprop net0/name = astring: vnic0 dev0# svccfg -s kvm:vm01 setprop net0/link = astring: zsw0 dev0# svccfg -s kvm:vm01 setprop net0/ip = astring: 172.16.0.10 dev0# svccfg -s kvm:vm01 setprop net0/netmask = astring: 255.255.255.0 dev0# svccfg -s kvm:vm01 setprop net0/gateway = astring: 172.16.0.1 dev0# svccfg -s kvm:vm01 setprop net0/dns0 = astring: 10.20.30.1
- net0/link defines a VNIC for the VM
- net0/link defines the parent NIC for the vnic
- net0/ip defines an IP-address which will be assigned to the nic inside VM (as DHCP)
- net0/netmask define the netmask for the network
- net0/gateway is the default router for the network
- net0/dns0 is an IP-address of your name server
You need to refresh the data:
dev0# svccfg -s kvm:vm01 refresh
That's all, you are ready to start our new VM:
dev0# svcs kvm STATE STIME FMRI disabled 18:18:16 svc:/system/kvm:default - - svc:/system/kvm:vm01 dev0# svcadm enable kvm:vm01 dev0# svcs kvm STATE STIME FMRI disabled 18:18:16 svc:/system/kvm:default online 21:55:01 svc:/system/kvm:vm01
But wait, you may say that the VM is not installed yet, what does it boot?
Right! Don't worry, let's configure it at run-time, first you need to see the output, i.e. create a VNC server, you need to connect the control monitor and change it:
dev0# nc -U /var/run/kvm/vm01/ctl QEMU 0.14.1 monitor - type 'help' for more information (qemu)
At start time the service creates a working directory to store there some control files such as a socket, pid-file, console, vnc socket. These files used to control the VM, let's use it too!
First, let's configure our vnc:
(qemu) info vnc info vnc (qemu) change vnc ::5900 change vnc ::5900 (qemu) info vnc info vnc Server: address: :::5900 auth: none Client: none (qemu)
By default we use a UNIX socket for VNC server but here we changed it and assign port 5900, second query shows us that the VM is now configured as a vnc server.
Now we need a boot device, let's add a removable cd-rom to boot:
(qemu) info block info block virtio0: type=hd removable=0 file=/dev/zvol/rdsk/data/kvm/disk0 ro=0 drv=raw encrypted=0 ide1-cd0: type=cdrom removable=1 locked=0 [not inserted] floppy0: type=floppy removable=1 locked=0 [not inserted] sd0: type=floppy removable=1 locked=0 [not inserted] (qemu) change ide1-cd0 /export/home/denis/ISO/FreeBSD-11.2-RELEASE-amd64-disc1.iso change ide1-cd0 /export/home/denis/ISO/FreeBSD-11.2-RELEASE-amd64-disc1.iso (qemu) info block info block virtio0: type=hd removable=0 file=/dev/zvol/rdsk/data/kvm/disk0 ro=0 drv=raw encrypted=0 ide1-cd0: type=cdrom removable=1 locked=0 file=/export/home/denis/ISO/FreeBSD-11.2-RELEASE-amd64-disc1.iso ro=0 drv=raw encrypted=0 floppy0: type=floppy removable=1 locked=0 [not inserted] sd0: type=floppy removable=1 locked=0 [not inserted] (qemu)
Unfortunately, to boot the system you need to reset it:
(qemu) system_reset system_reset (qemu)
In some time you will see the booted system:
Bingo! It works!
Boot options example:
dev0# svccfg -s kvm:vm01 addpg boot application dev0# svccfg -s kvm:vm01 setprop boot/order = astring: cd dev0# svccfg -s kvm:vm01 setprop boot/once = astring: d dev0# svccfg -s kvm:vm01 setprop boot/menu = astring: on
Serial properties example:
dev0# svccfg -s kvm:vm01 addpg serial application dev0# svccfg -s kvm:vm01 setprop serial/type = astring: telnet dev0# svccfg -s kvm:vm01 setprop serial/mode = astring: server dev0# svccfg -s kvm:vm01 setprop serial/option = astring: nowait dev0# svccfg -s kvm:vm01 setprop serial/bind = astring: localhost:4444
By default we create a UNIX socket for the serial console (/var/run/kvm/vm01/console). You may use nc -U to connect it (like for control socket).
VNC
For a security reason we use a UNIX socket for the VNC server too. At any time you can change it as shown above but the better way is to use noVNC project to connect it. To do it you need a web socket proxy:
dev0# apt install -y novnc websockify
And start it:
dev0# websockify --web=/usr/share/novnc/ 6080 --unix-target=/var/run/kvm/vm01/vnc -D
The proxy will redirect all queries from the port 6080 to the specified UNIX socket. Also you can read about it here: How To use noVNC on DilOS
APPENDIX
HVM configurable properties:
- hvm/cpu - emulating cpu type (qemu64 by default)
- hvm/smp - number of cpus (1)
- hvm/cores - number of processor cores (1)
- hvm/threads - number of processor threads (1)
- hvm/sockets - number of processor sockets (1)
- hvm/mem - amount memory size for the VM (512M)
- hvm/vga - type of the video device (std)
Network configurable properties:
- netX/name - name of VNIC
- netX/link - parent interface for the vnic
- netX/model - emulating model of the nic (virtio)
- netX/mac - ethernet address of the nic, it it generated value if you did not specify it
- netX/vlan - VLAN id if the parent interface is a trunk
You don't need to create a VNIC manually using dladm, also you don't need to create a vnd device. The service will do it for you automatically. Also the will be removed when you disable the service for your VM. You may not specify the name of VNIC, the service does it for you too. A new vnic will be named kvmX (where X is a unused number, if you already have lot of such interfaces). Cool, isn't it?
Disk configurable properties:
- diskX/zvol - name of zvol which will be used as storage device for the VM
- diskX/model - emulating model of the interface (virtio)
- diskX/serial - serial no of the device (yes, we can specify it too!)
Boot options:
- boot/order - devices order to boot the VM
- boot/once - used to boot the VM only once (at first boot)
- boot/menu - used to choose boot device at boot time (on/off)
Serial console properties:
- serial/type - type of the connection (unix/tcp/udp/telnet)
- serial/mode - mode of the connection (should be server or leave it empty)
- serial/option - comma separated options of the connection (nowait,nodelay)
- serial/path - UNIX socket full path (/var/run/kvm/vm01/console)
- serial/bind - use this address:port pair where server is listen connections (empty by default)
- serial/target - use this address:port pair to send all console data to this point (for tcp client type, for example)