This article illustrates how to generate an Ubuntu Server 22.04 image template using Packer and just Subiquity on Proxmox.
subtlety
This new live system is based on cloud-init and uses a YAML file to fully automate the installation process. It differs in several points from the previous system.
- The syntax is much easier to understand (YAML format vs. debconf-set-selections).
- It is possible to have hybrid situations where some sections can be interactive and others can be answered automatically from the settings.
proxmox
Packer requires a user account to perform actions on the Proxmox API. The following commands will create a new user accountempacador@pve
with restricted permissions.
$ pveum useradd packer@pve$ pveum passwd packer@pveEnter the new password: ****************Retype the new password: ****************$ pveum roleadd Wrapper -privs"VM.Config.Disk VM.Config.CPU VM.Config.Memory Datastore.AllocateSpace Sys.Modify VM.Config.Options VM.Allocate VM.Audit VM.Console VM.Config.CDROM VM.Config.Network VM.PowerMgmt VM .Config.HWType VM.Monitor"$ pveum aclmod / -user packager@pve -role Packager
Information
proxmoxpveum
it is available through an SSH connection or the web shell accessible from the node parameters in the user interface.
Download Ubuntu Server 22.04 ISO fromthe image repository. At the time of writing this article, the most recent version available wasubuntu-22.04-server-live-amd64.iso
. Place the ISO inside thelocal
storage under theiso image
category.
packer
builder configuration
Packer will run a workflow to create a new template that can then be used to quickly start new virtual machines with preset settings already applied.
Technically, Packer will start a VM on Proxmox, launch the installer from the boot command with a reference to the configuration file, and convert the VM to a template at the end when the configuration is fully complete.
{ "builders": [{ "model":"next", "proxmox_url":"https://proxmox.madalynn.xyz/api2/json", "Username":"{{ user `proxmox_username` }}", "clave":"{{ usuario `proxmox_password` }}", "that":"next", "network adapters": [{ "ponte":"vmbr0"}], "nightclubs": [{ "model":"scsi", "disk_size":"20G", "storage_pool":"local-lvm", "storage_group_type":"lvm"}], "This file":"local:iso/ubuntu-22.04-live-server-amd64.iso", "dismount_en":real, "boot_wait":"5s", "memory":1024, "model name":"ubuntu-22.04", "http_directory":"http", "boot_command": [ "C", "linux /casper/vmlinuz --- autoinstall ds='nocloud-net;s=http://{{ .HTTPIP }}:{{ .HTTPPort }}/' ", "<enter><wait>", "initrd /casper/initrd<enter><wait>", "boot<enter>"], "ssh_username":"Madalyn", "ssh_password":"Madalyn", "ssh_timeout":"20m"}]}
Most of the parameters are quite simple to understand. EITHERssh_timeout
it will give the installer time to download the latest security updates during installation.
Start Packer with the following command.
$ packer build -archivo-var=secrets.json ubuntu.json
Bribe
ovar file
The parameter provides flexibility to extract secrets (such as credentials) and dynamic parameters to use the workflow for building multiple Ubuntu images. The minimum required must include the Proxmox credentials of the user created above.
{ "proxmox_username":"packager@pve", "nextmox_password":"fQk9f5Wd22aBgv"}
Packer will start an HTTP server from the contents of thehttp
directory (with thehttp_directory
parameter). This will allow Subiquity to get the cloud seed files remotely.
Notice
The Subiquity live installer uses more memory than the debian installer. Packager default value (512M
) is not enough and will lead to a weird kernel panic. Wear1G
not minimum.
---[ end Kernel panic - not syncing: No working boot found. Try passing the init= option to the kernel. See the Linux documentation /admin-guide/init.rst for guidance. ]---
The boot command tells cloud-init to start and uses thenocloud-net
data source to be able to load theuser data
mimetadata
files from a remote HTTP endpoint. the additionalautomatic installation
The parameter will force Subiquity to perform destructive actions without asking the user for confirmation.
{ ... "boot_command": [ "C", "linux /casper/vmlinuz --- autoinstall ds='nocloud-net;s=http://{{ .HTTPIP }}:{{ .HTTPPort }}/' ", "<enter><wait>", "initrd /casper/initrd<enter><wait>", "boot<enter>"], ...}
commission setup
Cloud-init will take care of everything else. However, Packer will assume provisioning is complete as soon as you can connect to the virtual machine via SSH. But at this time, the setup process will not be completed completely. The wrapper should be told to wait until the cloud initialization has completed completely.
Technically speaking, the easiest solution is to wait until the/var/lib/cloud/instance/boot-finished
the file is present. Creating this file is the last thing cloud-init does. A bash script with a simpleTime
will do the trick.
{ "Suppliers": [{ "model":"Concha", "online": [ "while [! -f /var/lib/cloud/instance/boot-finished]; echo 'Esperando cloud-init...'; dormir 1; hecho"]}
The provisioners will run directly on the virtual machine as soon as the SSH connection is available. packer standmany providers. For example, you can start an Ansible playbook or set up the Chef client in this step.
Cloud initialization
Since Subitiquy uses cloud-init, the configuration must be present in two files,user data
mimetadata
.user data
is the main configuration file that Subitiquity and cloud-init will use for provisioning.metadata
is an additional file that can hold some additional metadata in theEC2 Metadata Service Format.
Observation
ometadata
the file can be empty (and it will be for Proxmox), but it must be present, otherwise cloud-init will not start correctly.
http├── metadata└── user data
Cloud-init supports several formats for configuration files. YAML is the easiest to understand and will be used for the following snippets. Subiquity adds a new moduleautomatic installation
which houses all the configuration needed for the installation.
#cloud-configautomatic installation: ...
Notice
Unlike a classic cloud boot file, everything must be under theautomatic installation
key. The rest will be ignored.
oofficial documentationlists all available parameters that can be configured. The scope is limited compared to what was possible with the Debian installer, but Subiquity gives you the ability to use all the others.cloud seed modulesto compensate.
Observation
Under the hood, Subiquity will be able to handle some actions itself (like partitioning) and will generate a cloud boot configuration file that will run after a reboot for the rest.
All "native" cloud-init modules must be under theuser data
key. For example, to use thewrite_files
cloud starter module, the following configuration can be used.
#cloud-configautomatic installation: ... user data: write_files:-camino:/etc/crontab feliz:15* * * *ship_logs raiz add:real ...
Automatic installation settings
The automatic installation is responsible for answering all questions asked during setup (keyboard layout, additional packages, …). The scope is limited and additional workflows must be managed with cloud-init modules (see above).
#cloud-configautomatic installation: version:1 location:In us keyboard: provision:es ssh: installation server:real permitir-pw:real packages:-who-guest-agent
owho-guest-agent
The packet is required for Packer to discover the VM's IP address to make the SSH connection. This will also allow Proxmox to display the virtual machine's resources directly in the user interface.
The virtual machine will be set up in English with a French keyboard. The mapping keys correspond to the settings in/etc/default/keyboard
. veryour manual pagefor more details.
An SSH server is required for remote Packer connections. By default, it will attempt to connect using just a username and password. This requires enabling thepermitir-pw
parameter.
Bribe
Whichpermitir-pw
, the SSH server will only accept connections using certificates. The wrapper must be configured to do this usingassh_keypair_name
section.
Identity
In addition to the above parameters, Subiquity can also create a user account during provisioning with theidentity
section.
#cloud-configautomatic installation: identity: host name:ubuntu Username:medallion clave:$6$xyz$1D0kz5pThgRWqxWw6JaZy.6FdkUCSRndc/PMtDr7hMK5mSw7ysChRdlbhkX83PBbNBpqXqef3sBkqGw3Rahs..
This section is also responsible for setting the hostname. Since this VM only serves as the base for the template, this is not important and should be configured during final provisioning.
The above block will create a usermedallion
commedallion
as password.
Bribe
It is possible to generate an encrypted Unix password with the following command.
$ openssl passwd -6 -salt xyz madalynn
For more flexibility on how the account is created, you can use the cloud-init moduleusers
instead of.
#cloud-configautomatic installation: ... user data: users:-Name:medallion clave:$6$xyz$1D0kz5pThgRWqxWw6JaZy.6FdkUCSRndc/PMtDr7hMK5mSw7ysChRdlbhkX83PBbNBpqXqef3sBkqGw3Rahs.. groups: [adm, cdrom, dip, plugdev, lxd, sudo] lock password:false sudo:ALL=(ALL) NO PASSWORD:ALL Concha:/bin/bash ssh_authorized_keys:-ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJEXrziuUOCpWPvwOsGuF4K+aq1ufToGMi4ra/1omOZb
This module provides more parameters to configure: groups, binary shell, authorized SSH keys… EITHERsudo
parameter allows the use ofsudo
command without entering any password. This will be useful later to use, for example, Ansible to complete the installation from the template.
Observation
Cannot use cloud-init moduleusers
and automatic installationidentity
block at the same time. Subquity will discard theusers
module configuration yesidentity
is present.
the net
Subiquity allows the use of two preconfigured layouts,lvm
mistraight
. By default, Subiquity will uselvm
with a logical volume of 4G. The installer will not extend the partition to use the full capacity of the volume group. It is also possible to configure the size of the swap file in the file system (0
to disable).
#cloud-configautomatic installation: ... store: provision: Name:straight trocar: Size:0
Sestraight
is used, a single partition/dev/sda2
it will be created using the entire disk.
Filesystem Size Used % Usage Available Mounted Onudev 1.9G 0 1.9G 0% /desarrollotmpfs 394M 696K 393M 1% /run/dev/sda2 20G 3,6G 15G 20% /tmpfs 2.0G 0 2.0G 0% /dev/shmtmpfs 5.0M 0 5.0M 0% /execute/blocktmpfs 2.0G 0 2.0G 0% /sys/fs/cgroup
It is also possible to use a more complex configuration based oncortinaundersettings
key. This is a requirement if the virtual machine has more than one disk (preconfigured layouts will not work in this situation).
#cloud-configautomatic installation: ... store: settings:-model:disco I would go:root disk Size:larger-model:share I would go:boot partition device:root disk Size:10%-model:share I would go:root partition Size:20G-model:share I would go:data partition device:root disk Size: -1
The above setup will create three partitions on the largest drive.
- 10% for the boot partition.
- 20G for the root partition.
- The rest for the data partition.
These are the first steps to a custom design. However, it is not enough and will require more steps (format, mount, …).
Notice
If a preconfigured layout is used, the custom settings will be ignored.
GitHub
The full setup is available on GitHub atairls/madalynn-packerrepository.