Skip to content

Instantly share code, notes, and snippets.

@itzg
Last active December 30, 2023 01:46
Show Gist options
  • Star 24 You must be signed in to star a gist
  • Fork 9 You must be signed in to fork a gist
  • Save itzg/2577205f2036f787a2bd876ae458e18e to your computer and use it in GitHub Desktop.
Save itzg/2577205f2036f787a2bd876ae458e18e to your computer and use it in GitHub Desktop.
Configuring a libvirt domain with a static IP address via cloud-init local datasource

Here is how to create a cloud-init disk image and OS disk image suitable for configuring into a libvirt domain file.

In my case I am naming my domain (a.k.a. virtual machine or VM) xenial with a static IP address of 192.168.0.101. The filenames "network-config" and "user-data" files are arbitrary, so they can be named with a prefix for the domain, etc.

First, get the cloud image and convert into QCOW2 format:

qemu-img convert -O qcow2 xenial-server-cloudimg-amd64-disk1.img xenial-server-cloudimg-amd64-disk1.qcow2

and extend the image size, which will become the root volume:

qemu-img resize xenial-server-cloudimg-amd64-disk1.qcow2 +8G

QCOW is a copy-on-write, differential image structure, so create an image relative to the base distribution image:

qemu-img create -f qcow2 -b xenial-server-cloudimg-amd64-disk1.qcow2 xenial.qcow2

Create the cloud-init datasource (DS) image:

cloud-localds -N network-config.yml xenial-user-data.img user-data.yml

Place all of those images in /var/lib/libvirt/images and create the domain:

virsh create domain.xml

Now you can attach to the console of the domain and log in with the pass configured in user-data:

virsh console xenial
<domain type='kvm'>
<name>xenial</name>
<memory>1048576</memory>
<os>
<type>hvm</type>
<boot dev="hd" />
</os>
<features>
<acpi/>
</features>
<vcpu>1</vcpu>
<devices>
<interface type='bridge'>
<source bridge='br0'/>
<model type='virtio'/>
</interface>
<disk type='file' device='disk'>
<driver type='qcow2' cache='none'/>
<source file='/var/lib/libvirt/images/xenial.qcow2'/>
<target dev='vda' bus='virtio'/>
</disk>
<disk type='file' device='disk'>
<source file='/var/lib/libvirt/images/xenial-user-data.img'/>
<target dev='vdb' bus='virtio'/>
</disk>
<console type="pty">
<target type="serial" port="1"/>
</console>
</devices>
</domain>
# This section needs to go into the /etc/network/interfaces on the
# host machine. This section replaces what you would have had for eno1
# or whatever your primary physical ethernet device is named.
auto br0
iface br0 inet static
address 192.168.0.100/24
gateway 192.168.0.1
dns-nameservers x.x.x.x x.x.x.x
bridge_ports eno1
bridge_maxwait 0
version: 1
config:
- type: nameserver
address:
- x.x.x.x
- x.x.x.x
- type: physical
name: ens2
subnets:
- control: auto
type: static
address: 192.168.0.101/24
gateway: 192.168.0.1
#cloud-config
password: passw0rd
chpasswd:
expire: false
ssh_pwauth: no
ssh_authorized_keys:
- ssh-rsa ...yours goes here...
@luther7
Copy link

luther7 commented Mar 15, 2018

Thank you very much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment