[BACK]Return to faq16.html CVS log [TXT][DIR] Up to [local] / www / faq

File: [local] / www / faq / faq16.html (download) (as text)

Revision 1.24, Wed Apr 3 19:59:04 2024 UTC (2 months ago) by tj
Branch: MAIN
CVS Tags: HEAD
Changes since 1.23: +2 -2 lines

7.5 updates

<!doctype html>
<html lang=en id=faq>

<!-- If you make edits to any FAQ documents, please start each sentence
     on a new line, and try to keep the general formatting consistent
     with the rest of the pages -->

<title>OpenBSD FAQ: Virtualization</title>
<meta charset=utf-8>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="../openbsd.css">
<link rel="canonical" href="https://www.openbsd.org/faq/faq16.html">

<!--
Copyright (c) 2018 Solene Rapenne <solene@openbsd.org>

Permission to use, copy, modify, and distribute this documentation for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.

THE DOCUMENTATION IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS DOCUMENTATION INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS DOCUMENTATION
-->

<h2 id=OpenBSD>
<a href="../index.html">
<i>Open</i><b>BSD</b></a>
FAQ - Virtualization
<small>
<a href="index.html">[FAQ Index]</a>
</small>
</h2>
<hr>

<ul>
  <li><a href="#Introduction" >Introduction</a>
  <li><a href="#Prerequisites">Prerequisites</a>
  <li><a href="#StartVm"      >Starting a VM</a>
  <li><a href="#VMMnet"       >Networking</a>
</ul>

<hr>

<h2 id="Introduction">Introduction</h2>

OpenBSD comes with the <a href="https://man.openbsd.org/vmm">vmm(4)</a>
hypervisor and <a href="https://man.openbsd.org/vmd">vmd(8)</a> daemon.
Virtual machines can be orchestrated with the
<a href="https://man.openbsd.org/vmctl">vmctl(8)</a> control utility,
using configuration settings stored in the
<a href="https://man.openbsd.org/vm.conf">vm.conf(5)</a> file.

<p>
The following features are available:

<ul>
  <li>serial console access to the virtual machines
  <li><a href="https://man.openbsd.org/tap">tap(4)</a> interfaces
  <li>per-VM user/group ownership
  <li>privilege separation
  <li>raw, qcow2 and qcow2-derived images
  <li>dumping and restoring of guest system memory
  <li>virtual switch management
  <li>pausing and unpausing VMs
</ul>

The following features are not available at this time:

<ul>
  <li>graphics
  <li>snapshots
  <li>guest SMP support
  <li>hardware passthrough
  <li>live migration across hosts
  <li>live hardware change
</ul>

<!-- XXXrelease - update when vmm supports vga or more oses -->
Supported guest operating systems are currently limited to OpenBSD and Linux.
As there is no VGA support yet, the guest OS must support serial console.

<h2 id="Prerequisites">Prerequisites</h2>

A CPU with nested paging support is required to use
<a href="https://man.openbsd.org/vmm">vmm(4)</a>.
Support can be checked by looking at the processor feature flags: SLAT for
AMD or EPT for Intel.
In some cases, virtualization capabilities must be manually enabled in the
system's BIOS.
Be sure to run the <a href="https://man.openbsd.org/fw_update">fw_update(8)</a>
command after doing so to get the required <code>vmm-firmware</code> package.

<p>
Processor compatibility can be checked with the following command:

<pre class="cmdbox">
$ <b>dmesg | egrep '(VMX/EPT|SVM/RVI)'</b>
</pre>

Before going further, enable and start the
<a href="https://man.openbsd.org/vmd">vmd(8)</a> service.

<pre class="cmdbox">
# <b>rcctl enable vmd</b>
# <b>rcctl start vmd</b>
</pre>

<h2 id="StartVm">Starting a VM</h2>

In the following example, a VM will be created with 50GB of disk space and 1GB
of RAM.
It will boot from the <code>install75.iso</code> image file.

<pre class="cmdbox">
# <b>vmctl create -s 50G disk.qcow2</b>
vmctl: qcow2 imagefile created
# <b>vmctl start -m 1G -L -i 1 -r install75.iso -d disk.qcow2 example</b>
vmctl: started vm 1 successfully, tty /dev/ttyp8
# <b>vmctl show</b>
   ID   PID VCPUS  MAXMEM  CURMEM     TTY        OWNER NAME
    1 72118     1    1.0G   88.1M   ttyp8         root example
</pre>

To view the console of the newly created VM, attach to its serial console:

<pre class="cmdbox">
# <b>vmctl console example</b>
Connected to /dev/ttyp8 (speed 115200)
</pre>

The escape sequence <code>~.</code> is needed to leave the serial console.
See the <a href="https://man.openbsd.org/cu">cu(1)</a> man page for more info.
When using a <code>vmctl</code> serial console over SSH, the ~ (tilde)
character must be escaped to prevent
<a href="https://man.openbsd.org/ssh">ssh(1)</a> from dropping the connection.
To exit a serial console over SSH, use <code>~~.</code> instead.

<p>
The VM can be stopped using <a href="https://man.openbsd.org/vmctl">vmctl(8)</a>.

<pre class="cmdbox">
# <b>vmctl stop example</b>
stopping vm: requested to shutdown vm 1
</pre>

Virtual machines can be started with or without a
<a href="https://man.openbsd.org/vm.conf">vm.conf(5)</a> file in place.
The following <code>/etc/vm.conf</code> example would replicate the above
configuration:

<pre class="cmdbox">
vm "example" {
    memory 1G
    enable
    disk /home/user/disk.qcow2
    local interface
}
</pre>

Some configuration properties in
<a href="https://man.openbsd.org/vm.conf">vm.conf(5)</a>
can be reloaded by <a href="https://man.openbsd.org/vmd">vmd(8)</a> on the fly.
<!-- XXX specify which ones -->
Other changes, like adjusting the amount of RAM or disk space, require the VM
to be restarted.

<h2 id="VMMnet">Networking</h2>

Network access to <a href="https://man.openbsd.org/vmm">vmm(4)</a> guests
can be configured a number of different ways, four of which are detailed
in this section.

<p>
In the examples below, various IPv4 address ranges will be mentioned for
different use cases:

<ul>
  <li><b>Private Addresses</b>
      (<a href="https://tools.ietf.org/html/rfc1918">RFC1918</a>) are those
      reserved for private networks such as <code>10.0.0.0/8</code>,
      <code>172.16.0.0/12</code>, and <code>192.168.0.0/16</code> are not
      globally routable.
  <li><b>Shared Addresses</b>
      (<a href="https://tools.ietf.org/html/rfc6598">RFC6598</a>) are similar
      to private addresses in that they are not globally routable, but are
      intended to be used on equipment that can perform address translation.
      The address space is <code>100.64.0.0/10</code>.
</ul>

<h3>Option 1 - VMs only need to talk to the host and each other</h3>

For this setup, vmm uses <i>local interfaces</i>: interfaces that use
the shared address space defined above.

<p>
Using <a href="https://man.openbsd.org/vmctl">vmctl(8)</a>'s <code>-L</code>
flag creates a local interface in the guest which will receive an address
from vmd via DHCP.
This essentially creates two interfaces: one for the host and the other
for the VM.

<h3>Option 2 - NAT for the VMs</h3>

This setup builds upon the previous and allows VMs to connect outside
the host.
<a href="https://man.openbsd.org/sysctl.2#ip.forwarding">IP forwarding</a>
is required for it to work.

<p>
The following line in <code>/etc/pf.conf</code> will enable
<a href="pf/nat.html">Network Address Translation</a> and redirect DNS requests
to the specified server:

<pre class="cmdbox">
match out on egress from 100.64.0.0/10 to any nat-to (egress)
pass in proto { udp tcp } from 100.64.0.0/10 to any port domain \
	rdr-to $dns_server port domain
</pre>

Reload the pf ruleset and the VM(s) can now connect to the internet.

<h3>Option 3 - Additional control over the VM network configuration</h3>

Sometimes you may want additional control over the virtual network for your
VMs, such as being able to put certain ones on their own virtual switch.
This can be done using a <a href="https://man.openbsd.org/bridge">bridge(4)</a>
and a <a href="https://man.openbsd.org/vether">vether(4)</a> interface.

<p>
Create a <code>vether0</code> interface that will have a private IPv4 address
as defined above.
In this example, we'll use the <code>10.0.0.0/8</code> subnet.

<pre class="cmdbox">
# <b>echo 'inet 10.0.0.1 255.255.255.0' > /etc/hostname.vether0</b>
# <b>sh /etc/netstart vether0</b>
</pre>

Create the <code>bridge0</code> interface with the <code>vether0</code>
interface as a bridge port:

<pre class="cmdbox">
# <b>echo 'add vether0' > /etc/hostname.bridge0</b>
# <b>sh /etc/netstart bridge0</b>
</pre>

Ensure that NAT is set up properly if the guests on the virtual network
need access beyond the physical machine.
An adjusted NAT line in <code>/etc/pf.conf</code> might look like this:

<pre class="cmdbox">
match out on egress from vether0:network to any nat-to (egress)
</pre>

The following lines in <a href="https://man.openbsd.org/vm.conf">vm.conf(5)</a>
can be used to ensure that a virtual switch is defined:

<pre class="cmdbox">
switch "my_switch" {
    interface bridge0
}

vm "my_vm" {
    ...
    interface { switch "my_switch" }
}
</pre>

Inside the <code>my_vm</code> guest, it's now possible to assign
<code>vio0</code>
an address on the <code>10.0.0.0/24</code> network and set the default route to
<code>10.0.0.1</code>.

<p>
For convenience, you may wish to set up a
<a href="faq6.html#DHCP">DHCP server</a> on <code>vether0</code>.

<h3>Option 4 - VMs as real hosts on the same network</h3>

In this scenario, the VM interface will be attached to the same network as
the host so it can be configured as if it were physically connected to the
host network.
This option only works for Ethernet-based devices, as the IEEE 802.11 standard
prevents wireless interfaces from participating in network bridges.

<p>
Create the <code>bridge0</code> interface with the host network interface as a
bridge port.
In this example, the host network interface is <code>em0</code> - you should
substitute the interface name that you wish to connect the VM to:

<pre class="cmdbox">
# <b>echo 'add em0' > /etc/hostname.bridge0</b>
# <b>sh /etc/netstart bridge0</b>
</pre>

As done in the previous example, create or modify the
<a href="https://man.openbsd.org/vm.conf">vm.conf(5)</a> file to ensure
that a virtual switch is defined:

<pre class="cmdbox">
switch "my_switch" {
    interface bridge0
}

vm "my_vm" {
    ...
    interface { switch "my_switch" }
}
</pre>

The <code>my_vm</code> guest can now participate in the host network as if it
were physically connected.
<p>

<b>Note:</b> If the host interface (<code>em0</code> in the above example) is
also configured using DHCP,
<a href="https://man.openbsd.org/dhcpleased">dhcpleased(8)</a> running on that
interface may block DHCP requests from reaching guest VMs.
In this case, you should select a different host interface not using DHCP,
or terminate any <a href="https://man.openbsd.org/dhcpleased">dhcpleased(8)</a>
processes assigned to that interface before starting VMs, or use static IP
addresses for the VMs.