On Hetzner#
Qemu guests on MaaS from Hetzner AX42, using vfio-passthru for one of the two NVMe SSDs on the host. Simultaneous Multithreading (SMT) disabled and six cores pinned for the guest machine, two left for Linux and the GitHub runner.
Hostname naming convention for the guest:
xnvme-ci-hetzner-bookworm-amd64-XX
Runner naming convention:
xnvme-ci-hetzner-bookworm-amd64-XX-runner-YY
Installation of the bare-metal instances are done via the rescue system, which you enable with the Hetzner Robot Console. To assist with the setup, scripts are provided making this less of an effort.
System Properties#
With the following hardware properties:
CPU |
Memory |
Motherboard |
NVMe Devices |
---|---|---|---|
AMD Ryzen 7 PRO 8700GE |
2x 32GB M324R4GA3BB0-CQKOD |
AsRockRack B665D4U-1L |
|
And the following system software setup and configuration:
One NVMe SSD has Debian Bookworm installed
System packages needed for CI, qemu, etc.
Docker Community Edition installed
GitHub Runner unpacked, but not not registered
BDF:
0000:01:00.0
The
vfio-pci
Kernel module is loaded at bootSecond NVMe SSD is bound to
vfio-pci
at boot usingdevbind
scriptBDF:
0000:02:00.0
Members of the
kvm
group can usevfio
A
ghr
user is available for the GitHub Runner to execute asghr
is a member ofkvm
, thus, can run qemu withkvm
and vfio-passthrughr
hasmemlock unlimited
and can thus launch qemu guest with a lot of memory
To install a system have a look at the following section and for details, then look at the scripts and config files referred to there.
System bootstrap#
Via the Hetzner Robot console:
Make sure you have a sensible firewall-template applied
Activate the rescue system
Power reset the system
Once it is booted, log into the rescue system for the bare-metal machine, and run the following to fetch the scripts and config files:
# Grab the scripts and files
curl -L https://github.com/xnvme/xnvme/archive/refs/heads/next.tar.gz \
| tar --strip-components=5 -xz xnvme-next/docs/contributing/ci/runners
# Run the install-script (replace XX with the id of the system e.g. 01)
cd hetzner-setup
./hetzner_setup.sh XX
reboot
Note
Replace XX
with the numerically unique identifier of the system. This
will be utilized to construct the hostname using the naming convention
described above.
Warning
The ssh-key utilized via the rescue system is added to authorized_keys
.
Since it is not possible to SSH into the box as root
with
login/password, then only the owner of the key will be able to login.
The system will reboot after the above commands execute without error. The
contents of the hetzner-setup
folder are copied into the system and will be
available after reboot.
Post-Install#
Once the system is up, SSH into it as root
and run:
# Run post-install tasks (user configuration, system setup, etc.)
cd hetzner-setup
./postinstall.sh
# Set password for the 'ghr' user
passwd ghr
After this, complete the following tasks:
Retrieve the Windows guest image
Set up the GitHub Runner
Reboot the system
Details are provided in the following sections. When running those commands,
then start by switching to the ghr
user:
su - ghr
Then set the following variables:
export HSB_USERNAME=<LOOK_IN_HETZNER_CONSOLE>
export TOKEN=<LOOK_IN_GITHUB_SETTINGS>
export URL=https://github.com/xnvme/xnvme
Note
You find the TOKEN in the GitHub web interface when adding a new runner
under Settings / Runners / New self-hosted runner
.
Windows Guest Image#
Unlike the other guests, the Windows image cannot be distributed. Therefore,
you must manually retrieve it from the private Hetzner Storage Box. The
postinstall.sh
script has already prepared everything needed to launch
a Windows guest, including UEFI, OVMF, and TPM support.
Download the image using the command below, replacing your username with your
Storage Box <USERNAME>
:
# Download the Windows image from Hetzner Storage Box
wget \
--http-user ${HSB_USERNAME} \
--ask-password \
--directory-prefix /home/ghr/system_imaging/disk/ \
https://${HSB_USERNAME}.your-storagebox.de/win11.qcow2
Once the image is in place, the system is ready to receive jobs from GitHub. The next section explains how to install the runner.
Note
The Windows guest image is 64 GB in size. Downloading it takes approximately 10 minutes.
Runner Registration#
Then run:
cd ~/actions-runner
./config.sh --unattended \
--url ${URL} \
--token ${TOKEN} \
--no-default-labels \
--labels self-hosted,linux,amd64,maas \
--replace \
--name ${HOSTNAME}-runner-01
Note
Currently, there is a 1:1:1
relationship between Host:Runner:Guest
.
If this changes, adjust the runner name accordingly in the command above.
Install the runner with permission to use vfio-pci
:
# Install the service
sudo ./svc.sh install ghr
sudo sed -i '/^\[Service\]/a LimitMEMLOCK=infinity' /etc/systemd/system/actions.runner.*.service
sudo systemctl daemon-reload
sudo ./svc.sh status
Do not start the service at this point, to avoid it getting a CI job. Instead,
reboot
the system to ensure that it boots and services start as expected.