This explores how cloud-init works in Proxmox. You will be working in your normal groups.
Your existing VM was configured using cloud-init; we can now look at how the data was passed to it.
Get a console on the VM you created earlier,
groupXY-web. If necessary, start it.
Login (username is “ubuntu”, password is whatever you set when creating the VM), and get a root shell:
sudo -s
so that the prompt ends with a hash (#), like this:
root@group12-web:/home/ubuntu#
Let’s look at how Proxmox was able to pass your login credentials and network configuration to the VM when it started.
It does this by creating a small virtual CD-ROM image which is attached to the VM. Most VM images these days include the “cloud-init” tool which runs at first boot, reads this data, and configures the VM accordingly.
Still inside your VM, type the following:
mount -r /dev/cdrom /mnt
ls /mnt
(Flag -r means “read-only”)
You chould see some files: meta-data,
network-config, user-data,
vendor-data. Look at the contents of the two most important
ones:
cat /mnt/network-config
cat /mnt/user-data
In the user-data file, look for these settings:
hostname: groupXY-web
fqdn: groupXY-web
These are how the VM has learned its hostname. Also:
password: $5$.....etc....
chpasswd:
expire: False
provides the (hashed) password, and tells it not to expire.
The cloud-init online documentation gives you more information about what these settings mean.
Reading metadata from a disk image is what cloud-init calls the “nocloud” data source. In a public cloud, the metadata is usually provided via some other mechanism - in the case of AWS it’s a webserver on the local IP address 169.254.169.254.
Log files created by cloud-init while it ran are available at
/var/log/cloud-init-output.logand/var/log/cloud-init.log
Unmount the CD:
umount /mnt
When cloud-init ran on first VM boot, it wrote out the data it used.
So you can also find what data was used to boot this VM even with the CD
unmounted. Look at the files in the directory
/var/lib/cloud/instance:
cd /var/lib/cloud/instance
ls
cat user-data.txt
cat network-config.json
You can also see the cloud-init data that Proxmox had prepared, before starting the VM.
Get a shell on the Proxmox node in your cluster (nodeXY)
where your VM is running. That is:
>_ ShellNow run these commands, where <VMID> is the
numeric ID of your groupXY-web virtual machine:
qm cloudinit dump <VMID> user
qm cloudinit dump <VMID> network
You should see the YAML-format cloud-init data which Proxmox used to build the ISO (virtual CD-ROM). Any changes you make in the GUI to the cloud-init settings should be reflected here.
(The following is for reference only)
Only a handful of settings for cloud-init are provided in the Proxmox GUI. Any further customisation has to be done at the command line.
You can provide customised user-data or network-data for any VM, before you boot it for the first time, by putting it in a file and telling Proxmox to use that file (don’t do it now, since your VM has already booted):
### DON'T DO THIS NOW: FOR REFERENCE ONLY
### Put your user-data config in /var/lib/vz/snippets/vm123-user-data.yml
# qm set 123 --cicustom "user=local:snippets/vm123-user-data.yml"
It’s also possible to set your own user-data on the VM template that you clone from, so that all the child VMs inherit these settings. But if you do that, it completely replaces the automatically-generated user-data which Proxmox supplies for each child VM. In particular, your VM won’t learn its hostname.
The solution is to pass vendor-data, which is normally
empty, and is merged with user-data.
This exercise is done cluster-wide: just ONE user logs into nodeX1 while everyone else in the same cluster watches
Get a shell on nodeX1 in your cluster.
Using a text editor like nano or vi, create
a file called /var/lib/vz/snippets/init-web.yml, for
example:
nano /var/lib/vz/snippets/init-web.yml
Insert the following text (all three lines exactly like this):
#cloud-config
packages:
- apache2
Save it and exit. If using nano: ctrl-X, Y (for yes), Enter to accept filename.
Now back at the nodeX1 shell, enter this command:
qm set 9001 --cicustom "vendor=local:snippets/init-web.yml"
This tells your template to use the vendor-data file you created.
Now in the GUI, under nodeX1 find your template 9001 and clone it:
Wait a few seconds for the clone to take place. The clone should be created on node X1. It will take a few seconds to appear in the GUI.
Click on your new VM “testweb” in the first column, then “Cloud-Init” in the second column.
Click on “Console” in the second column, and “Start Now”. Watch it boot.
Login to the VM as username “ubuntu” and the password you set, then
use sudo -s to get a root shell.
You should find that the apache2 webserver has been installed automatically:
dpkg-query -l apache2
If this comes back with “no packages found matching apache2”, then it may still be in the process of installing. Type:
cloud-init status --wait
which should return status: done when cloud-init has
finished. Then try the dpkg-query command again.
If it’s still not working, check that the vendor-data has been picked up and is correct:
cat /var/lib/cloud/instance/vendor-data.txt
cat /var/lib/cloud/instance/vendor-cloud-config.txt
NOTE: if both the vendor-data and user-data supply the same
configuration key (such as packages or
runcmd), these may or may not be merged in a way that you
expect. See the documentation
for details.
Shutdown this VM when finished.