alpine-cloud-init
alpine-cloud-init copied to clipboard
How to build a minimal cloud-init image for Proxmox
Table of contents: [toc]
Preamble
The following procedure describes how to create a small bootable cloud-init template with Alpine Linux for creating virtual machines on a Proxmox VE server/cluster.
The official Cloud Images are currently (Sept. 2022) only available for AWS, this shows how to make a NoCloud cloud-init image suitable for Proxmox VE.
References
Alpine Linux
Proxmox VE
Create cloud-init image
Create base Image
- Download "VIRTUAL" ISO to shared ISO storage on PVE cluster (Target: cephfs).
- Create the virtual machine (VM):
- Use high number identify it later when it is a template (e.g. 9000)
- No installation CD/DVD (will be applied later)
- 1 GB system drive on shared VM drive which can be grown later (Target: osd).
- 1024 MiB RAM with 512 MiB minimum
- All cores (4)
- Configure VM:
- Remove default "IDE 2" DVD/CDROM
- Add uploaded ISO as DVD/CDROM - SCSI 2
- Disable NET Boot
- Install Alpine Linux in the VM:
- Follow the normal installation instructions
- Add default user "alpine", another default user can be created using cloud-init if required.
- Reboot
- Create a snaphot, really.
Copy keys to VM for root ssh access with a password
Using the Proxmox Console to make configurtion as root easier, the default configuration disables password access for root.
In the VM:
# Enable password root login for sshd
vi /etc/ssh/sshd_config
# Add
PermitRootLogin yes
# Restart SSH daemon
service sshd restart
On the PC with the keys to be copied:
# Copy ssh ids from current PC to VM with ssh-copy-ids
ssh-copy-ids root@vm-name
In the VM:
# disable root login for sshd
vi /etc/ssh/sshd_config
# Remove
PermitRootLogin yes
# Restart SSH daemon
service sshd restart
Configure VM
Connect to VM ssh root@vm-name
Prepare operating system
# Enable all repositories (test is required for kubernetes executables)
vi /etc/apk/repositories
# Update & upgrade system
apk upgrade --no-cache --available
# Install required packages
apk --no-cache --cache-max-age 30 add \
cloud-init \
util-linux \
chrony \
openssh-server-pam \
doas \
sudo \
e2fsprogs \
e2fsprogs-extra \
dosfstools \
gettext \
lsblk \
parted \
tzdata
# Update the kernel options
sed -Ei \
-e "s|^[# ]*(default_kernel_opts)=.*|\1=\"console=ttyS0,115200n8 cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory\"|" \
-e "s|^[# ]*(serial_port)=.*|\1=ttyS0|" \
-e "s|^[# ]*(modules)=.*|\1=sd-mod,usb-storage,ext4|" \
-e "s|^[# ]*(default)=.*|\1=virt|" \
-e "s|^[# ]*(timeout)=.*|\1=1|" \
"/etc/update-extlinux.conf"
/sbin/extlinux --install /boot
/sbin/update-extlinux --warn-only
# Disable getty for physical ttys, enable getty for serial ttyS0.
sed -Ei -e '/^tty[0-9]/s/^/#/' -e '/^#ttyS0:/s/^#//' "/etc/inittab"
. . .
# configure sudo and doas
# --- no password required ---
echo '%wheel ALL=(ALL) NOPASSWD: ALL' > "/etc/sudoers.d/wheel"
echo 'permit nopass :wheel' > "/etc/doas.d/wheel.conf"
# --- with required user password ---
echo '%wheel ALL=(ALL) ALL' > "/etc/sudoers.d/wheel"
echo 'permit persist :wheel' > "/etc/doas.d/wheel.conf"
# explicitly lock the root account
/bin/sh -c "/bin/echo 'root:*' | /usr/sbin/chpasswd -e"
/usr/bin/passwd -l root
# Update services
rc-update add chronyd default
Configure cloud-init
Now cloud-init itself needs to be configured.
Configure VM
The cloud-init package was installed previously with the other prerequisites.
A mixture of information from Proxmox VE and alpine linux sources
# Setup cloud-init defaults
setup-cloud-init
# Set Proxmox options as Datasources
echo 'datasource_list: [ NoCloud, ConfigDrive ]' > "/etc/cloud/cloud.cfg.d/99_pve.cfg"
# Shut down the VM and do **NOT** restart it
poweroff
Configure Proxmox
In a shell on the proxmox server (not the VM), here 9000 is the VM ID number.
Add virtual CDROM for cloud-init configuration (cloud-init reads configuration from mounted drive)
qm set 9000 --ide2 local-lvm:cloudinit
Set boot device:
qm set 9000 --boot c --bootdisk scsi0
Enable serial device:
qm set 9000 --serial0 socket --vga serial0
So, everything is set to test it. It would be possible to convert this to a template right now but it is better to be safe than sorry.
Testing the container before converting it to a template
Either in the Proxmox UI or terminal:
qm clone 9000 1024 --name AlpineTest
In the Cloud-Init options for VM 1024, try settting "User", "Password" and "SSH public key" BEFORE starting the VM for the first time. Remeber to press the Regenerate Image button to update the CDROM containing the Cloud-Init configuration.
Start AlpineTest and you should now have a VM with the configured information.
Convert VM image to a Proxmox template
Either in the Proxmox UI or terminal (you will have to remove any snapshots beforehand):
qm template 9000
Create VM from template
Don't forget to switch Mode: to Full Clone!
Here are a few optional changes where 1024 is the VM ID number of the clone:
Resize drive (BEFORE starting!)
Increase the size of the drive BEFORE starting the clone, cloud-init will automatically expand the root parttition to match the new size.
In a shell on the proxmox server (not the VM) add 5G to the image's drive capacity:
qm resize 1024 scsi0 +5G
Increase RAM
Enable guest agent support in Proxmox VM (1024) -> Hardware -> Memory
Install QEMU Guest Agent
VM
sudo apk add qemu-guest-agent
Proxmox
Enable guest agent support in Proxmox VM (1024) -> Options -> QEMU Guest Agent
Install a different shell
The default shell in Alpine Linux is /bin/ash, you can install another shell, e.g. bash (bourne again shell).
Install bash and bash-completion:
sudo apk add bash bash-completion
Change the user's shell in /etc/passwd using chsh:
chsh -s /bin/bash
Reconnect . . . .
Credits
Inspired to try out cloud-init after watching Perfect Proxmox Template with Cloud Image and Cloud Init by TechnoTim.