All checks were successful
Podman DDNS Image / build-and-push-ddns (push) Successful in 54s
353 lines
11 KiB
Markdown
353 lines
11 KiB
Markdown
# Virsh
|
|
|
|
Virtual Machine Management
|
|
|
|
- [Virsh](#virsh)
|
|
- [Before you Begin](#before-you-begin)
|
|
- [Connecting to External Servers via SSH](#connecting-to-external-servers-via-ssh)
|
|
- [Configuring Aliases](#configuring-aliases)
|
|
- [One-off Connections](#one-off-connections)
|
|
- [Useful Virsh Commands](#useful-virsh-commands)
|
|
- [Virsh Networking](#virsh-networking)
|
|
- [Create a Virtual Network](#create-a-virtual-network)
|
|
- [Attach a New Virtual Network](#attach-a-new-virtual-network)
|
|
- [Detach a Virtual Network](#detach-a-virtual-network)
|
|
- [Destroy a Virtual Network](#destroy-a-virtual-network)
|
|
- [Set a Static IP](#set-a-static-ip)
|
|
- [Creating VMs](#creating-vms)
|
|
- [Create VM with No Graphics and use an Existing QCOW2 Disk](#create-vm-with-no-graphics-and-use-an-existing-qcow2-disk)
|
|
- [Create a Cloud Init Compatible VM](#create-a-cloud-init-compatible-vm)
|
|
- [Create VM with Graphics using an ISO Installation Disk](#create-vm-with-graphics-using-an-iso-installation-disk)
|
|
- [Create VM using Host Device as Disk](#create-vm-using-host-device-as-disk)
|
|
- [Snapshots](#snapshots)
|
|
- [Virt Builder](#virt-builder)
|
|
|
|
## Before you Begin
|
|
|
|
1. Add yourself to the `qemu` and `libvirt` groups: `usermod -aG libvirt,qemu ducoterra`
|
|
2. Change the images ownership to qemu: `chown -R qemu:qemu /var/lib/libvirt/images`
|
|
3. Change the iso ownership to qemu: `chown -R qemu:qemu /var/lib/libvirt/iso`
|
|
4. Allow group write access to images: `chmod 770 /var/lib/libvirt/images`
|
|
5. Allow group write access to iso: `chmod 770 /var/lib/libvirt/iso`
|
|
6. Tell virsh to connect to your root system rather than your user: `export LIBVIRT_DEFAULT_URI='qemu:///system'`
|
|
7. Export your editor so virsh knows what to use: `export EDITOR=vim`
|
|
|
|
## Connecting to External Servers via SSH
|
|
|
|
<https://libvirt.org/uri.html#ssh-transport>
|
|
|
|
### Configuring Aliases
|
|
|
|
1. Edit `~/.config/libvirt/libvirt.conf`
|
|
2. Add your aliases
|
|
|
|
```bash
|
|
uri_aliases = [
|
|
"3dserver=qemu+ssh://3dserver/system",
|
|
]
|
|
```
|
|
|
|
3. Export the alias: `export LIBVIRT_DEFAULT_URI=3dserver`
|
|
|
|
### One-off Connections
|
|
|
|
```bash
|
|
export LIBVIRT_DEFAULT_URI='qemu+ssh://user@server/system'
|
|
```
|
|
|
|
## Useful Virsh Commands
|
|
|
|
```bash
|
|
# Show node info
|
|
virsh nodeinfo
|
|
|
|
# List OS variants
|
|
osinfo-query os
|
|
|
|
# List all current machines
|
|
virsh list --all
|
|
|
|
# Connect to console VM
|
|
virsh console fedora42-test
|
|
|
|
# Connect to graphical VM
|
|
virt-viewer --wait fedora42-test
|
|
|
|
# Get leased IP Addresses for the default network
|
|
virsh net-dhcp-leases default
|
|
|
|
# Reboot a VM
|
|
virsh reboot <domain>
|
|
|
|
# Shutdown a VM
|
|
virsh shutdown <domain>
|
|
|
|
# Force shutdown a VM
|
|
virsh destroy <domain>
|
|
|
|
# Remove a VM
|
|
virsh undefine --nvram <domain>
|
|
|
|
# Remove a VM including storage
|
|
virsh undefine <domain> --nvram --remove-all-storage
|
|
```
|
|
|
|
## Virsh Networking
|
|
|
|
### Create a Virtual Network
|
|
|
|
Creating a new network will require an XML configuration file. To see the
|
|
default network's configuration, use
|
|
|
|
```bash
|
|
virsh net-dumpxml default > virbr0.xml
|
|
```
|
|
|
|
To create a dual-stack network, use the following. (Note, I generated a unique
|
|
local ipv6 address [here](https://www.unique-local-ipv6.com/)).
|
|
|
|
```xml
|
|
<network>
|
|
<name>dual-stack</name>
|
|
<forward mode="nat"/>
|
|
<domain name="dual-stack"/>
|
|
<ip address="192.168.100.1" netmask="255.255.255.0">
|
|
<dhcp>
|
|
<range start="192.168.100.2" end="192.168.100.254"/>
|
|
</dhcp>
|
|
</ip>
|
|
<ip family="ipv6" address="fd4d:58e7:17f6:1::1" prefix="64"/>
|
|
</network>
|
|
```
|
|
|
|
I've already defined this network in `active/software_virsh/dual-stack-dhcp.xml`. Install it with
|
|
|
|
```bash
|
|
# Define and autostart the network
|
|
virsh net-define active/software_virsh/dual-stack-dhcp.xml
|
|
virsh net-start dual-stack-dhcp
|
|
virsh net-autostart dual-stack-dhcp
|
|
|
|
# List networks to ensure it created
|
|
virsh net-list --all
|
|
|
|
# Get the UUID of the created network
|
|
virsh net-uuid dual-stack-dhcp
|
|
```
|
|
|
|
### Attach a New Virtual Network
|
|
|
|
```bash
|
|
export VM_NAME=my_vm
|
|
virsh attach-interface \
|
|
--type bridge \
|
|
--source virbr1 \
|
|
--model virtio \
|
|
--config \
|
|
--live \
|
|
--domain ${VM_NAME}
|
|
```
|
|
|
|
### Detach a Virtual Network
|
|
|
|
```bash
|
|
# List mac addresses of connected interfaces'
|
|
export VM_NAME=my_vm
|
|
virsh domiflist --domain $VM_NAME
|
|
virsh detach-interface --domain k0s-worker0 --type bridge --mac "52:54:00:f6:b9:83" --live
|
|
```
|
|
|
|
### Destroy a Virtual Network
|
|
|
|
```bash
|
|
export NETWORK_NAME=mynetwork
|
|
virsh net-undefine --network $NETWORK_NAME
|
|
virsh net-destroy --network $NETWORK_NAME
|
|
```
|
|
|
|
### Set a Static IP
|
|
|
|
To set a static IP, run `virsh net-edit default` and add the following between `<dhcp>` and `</dhcp>`
|
|
|
|
```bash
|
|
# Add a host
|
|
virsh net-update default add-last ip-dhcp-host \
|
|
'<host mac="52:54:00:6f:78:f3" ip="192.168.122.222"/>' \
|
|
--live --config --parent-index 0
|
|
|
|
# Modify a host
|
|
virsh net-update default modify ip-dhcp-host \
|
|
'<host mac="52:54:00:6f:78:f3" ip="192.168.122.222"/>' \
|
|
--live --config --parent-index 0
|
|
|
|
# Delete a host
|
|
virsh net-update default delete ip-dhcp-host \
|
|
'<host mac="52:54:00:6f:78:f3" ip="192.168.122.222"/>' \
|
|
--live --config --parent-index 0
|
|
```
|
|
|
|
## Creating VMs
|
|
|
|
If you have [an osbuild
|
|
image](/active/software_osbuild/image_builder.md#installing) you can run the
|
|
following to generate a qcow2 disk image. Then you can [create a VM with an
|
|
existing qcow2
|
|
disk](#create-vm-with-no-graphics-and-use-an-existing-qcow2-disk) and skip the
|
|
installation process altogether.
|
|
|
|
```bash
|
|
sudo systemctl start osbuild-composer.socket
|
|
composer-cli compose list
|
|
export IMAGE_UUID=
|
|
export VM_DISK_PATH=/var/lib/libvirt/images/fedora43-test.qcow2
|
|
composer-cli compose image --filename ${VM_DISK_PATH} ${IMAGE_UUID}
|
|
```
|
|
|
|
### Create VM with No Graphics and use an Existing QCOW2 Disk
|
|
|
|
```bash
|
|
# Start the default network if it isn't already
|
|
virsh net-start --network default
|
|
|
|
export VM_NAME="fedora43-test"
|
|
export VM_DISK_PATH=/var/lib/libvirt/images/fedora43-test.qcow2
|
|
|
|
# OPTIONAL: export your qcow2 disk now if using osbuild
|
|
export IMAGE_UUID=
|
|
composer-cli compose image --filename ${VM_DISK_PATH} ${IMAGE_UUID}
|
|
|
|
# Install
|
|
# `--location /path/to/image.iso` supplies a disk installer. (Remove `--import`)
|
|
# `--import` skips the installation process.
|
|
# `--graphics spice --video qxl,model.ram=131072,model.vram=131072,model.vgamem=131072 --channel spicevmc` installs graphics
|
|
# `--console pty,target.type=virtio` adds a console connection
|
|
# For any command, use `virt-install --arg=?` to see all available options
|
|
virt-install \
|
|
--name "${VM_NAME}" \
|
|
--boot uefi,firmware.feature0.name=secure-boot,firmware.feature0.enabled=no \
|
|
--cpu host-passthrough --vcpus sockets=1,cores=8,threads=2 \
|
|
--ram=8192 \
|
|
--os-variant=fedora41 \
|
|
--network bridge:virbr0 \
|
|
--graphics none \
|
|
--console pty,target.type=virtio \
|
|
--import --disk "path=${VM_DISK_PATH},bus=virtio"
|
|
```
|
|
|
|
#### Create a Cloud Init Compatible VM
|
|
|
|
<https://cloudinit.readthedocs.io/en/latest/reference/examples.html>
|
|
|
|
```bash
|
|
# Fedora
|
|
# https://fedoraproject.org/cloud/download
|
|
export VM_NAME="cloud-init-test-fedora"
|
|
export VM_DISK_PATH=/var/lib/libvirt/images/Fedora-Cloud-Base-Generic-43-1.6.x86_64.qcow2
|
|
|
|
# Rocky
|
|
# https://rockylinux.org/download
|
|
export VM_NAME="cloud-init-test-rocky"
|
|
export VM_DISK_PATH=/var/lib/libvirt/images/Rocky-10-GenericCloud-Base.latest.x86_64.qcow2
|
|
|
|
# Ubuntu
|
|
# https://cloud-images.ubuntu.com/noble/current/
|
|
export VM_NAME="cloud-init-test-ubuntu"
|
|
export VM_DISK_PATH=/var/lib/libvirt/images/noble-server-cloudimg-amd64.img
|
|
|
|
# Debian
|
|
# https://cloud.debian.org/images/cloud/trixie/20251117-2299/
|
|
export VM_NAME="cloud-init-test-debian"
|
|
export VM_DISK_PATH=/var/lib/libvirt/images/debian-13-generic-amd64-20251117-2299.qcow2
|
|
|
|
# Set --cloud-init disable=no to allow cloud-init to run again after first boot
|
|
virt-install \
|
|
--name "${VM_NAME}" \
|
|
--boot uefi,firmware.feature0.name=secure-boot,firmware.feature0.enabled=no \
|
|
--cpu host-passthrough --vcpus sockets=1,cores=8,threads=2 \
|
|
--ram=8192 \
|
|
--os-variant=fedora41 \
|
|
--network bridge:virbr0 \
|
|
--graphics none \
|
|
--import --disk "path=${VM_DISK_PATH},bus=virtio" \
|
|
--cloud-init disable=yes,user-data="active/software_virsh/cloud-init/user-data,meta-data=active/software_virsh/cloud-init/meta-data"
|
|
```
|
|
|
|
### Create VM with Graphics using an ISO Installation Disk
|
|
|
|
```bash
|
|
# `--cdrom /path/to/image.iso` supplies a disk installer. (Remove `--import`)
|
|
# `--import` skips the installation process.
|
|
# `--graphics spice --video qxl --channel spicevmc` installs graphics
|
|
# `--console pty,target.type=virtio` adds a console connection
|
|
# For any command, use `virt-install --arg=?` to see all available options
|
|
export VM_NAME="fedora43-kinoite-test"
|
|
export VM_ISO_PATH=/var/lib/libvirt/iso/fedora43.iso
|
|
export VM_DISK_PATH=/var/lib/libvirt/images/fedora43.qcow2
|
|
virt-install \
|
|
--name "${VM_NAME}" \
|
|
--boot uefi,firmware.feature0.name=secure-boot,firmware.feature0.enabled=no \
|
|
--cpu host-passthrough --vcpus sockets=1,cores=8,threads=2 \
|
|
--ram=8192 \
|
|
--os-variant=fedora41 \
|
|
--network bridge:virbr0 \
|
|
--graphics spice --video virtio --channel spicevmc \
|
|
--cdrom ${VM_ISO_PATH} \
|
|
--disk "path=${VM_DISK_PATH},size=64,bus=virtio,format=qcow2"
|
|
```
|
|
|
|
### Create VM using Host Device as Disk
|
|
|
|
```bash
|
|
# `--cdrom /path/to/image.iso` supplies a disk installer. (Remove `--import`)
|
|
# `--import` skips the installation process.
|
|
# `--graphics spice --video qxl --channel spicevmc` installs graphics
|
|
# `--console pty,target.type=virtio` adds a console connection
|
|
# `--hostdev 0x1234:0x5678` adds a block storage device
|
|
# For any command, use `virt-install --arg=?` to see all available options
|
|
export VM_NAME="usb-linux"
|
|
virt-install \
|
|
--name "${VM_NAME}" \
|
|
--boot uefi,firmware.feature0.name=secure-boot,firmware.feature0.enabled=no \
|
|
--import \
|
|
--cpu host-passthrough --vcpus sockets=1,cores=8,threads=2 \
|
|
--ram=8192 \
|
|
--os-variant=fedora41 \
|
|
--network bridge:virbr0 \
|
|
--graphics spice --video qxl --channel spicevmc \
|
|
--hostdev 0x13fe:0x6500,boot.order=1 \
|
|
--disk none
|
|
```
|
|
|
|
## Snapshots
|
|
|
|
See [qemu qcow2 snapshots](/active/software_qemu/qemu.md#qcow2-snapshots)
|
|
|
|
## Virt Builder
|
|
|
|
<https://docs.fedoraproject.org/en-US/fedora-server/virtualization/vm-install-diskimg-virtbuilder/#_minimal_effort_customization>
|
|
|
|
You can use virt-builder to build vm images
|
|
|
|
```bash
|
|
export VM_NAME=fedora42-vb
|
|
export VM_DISK_PATH=/var/lib/libvirt/images/fedora42-vb.qcow2
|
|
|
|
# Build the image
|
|
virt-builder fedora-42 \
|
|
--format qcow2 --output ${VM_DISK_PATH} \
|
|
--root-password locked:disabled \
|
|
--hostname ${VM_NAME} \
|
|
--selinux-relabel \
|
|
--firstboot-command 'useradd -m -G wheel -p "" ducoterra ; chage -d 0 ducoterra'
|
|
|
|
# Run the built image
|
|
virt-install \
|
|
--name "${VM_NAME}" \
|
|
--cpu host-passthrough --vcpus sockets=1,cores=8,threads=2 \
|
|
--ram=8192 \
|
|
--os-variant=fedora41 \
|
|
--network bridge:virbr0 \
|
|
--graphics none \
|
|
--console pty,target.type=virtio \
|
|
--import --disk "path=${VM_DISK_PATH},bus=virtio"
|
|
``` |