Skip to content

perf: faster provisioning and lower resource use - #8

Merged
masterjanic merged 19 commits into
mainfrom
perf-provisioning
Oct 11, 2026
Merged

masterjanic merged 19 commits into
mainfrom
perf-provisioning

Conversation

@masterjanic

@masterjanic masterjanic commented Oct 11, 2026 •

Copy link
Copy Markdown
Member

What and why

Faster creates and less host memory and disk use; one commit per change.

  • Clones get their identity from a first-boot hook before networking (no reboot); base images are baked once (no GRUB wait, no first-boot pveupdate, Ceph packages for Ceph clusters).
  • SSH handshake deadline and 1s polling; ZFS pools, API logins, Ceph managers and OSDs in parallel; no fsync while provisioning.
  • Package cache on the host (proxmox.aptCache) for upgrade, Ceph install and bakes.
  • Live snapshots (snapshot save --live) and cluster templates in the GitHub Action.
  • Free page reporting, detect-zeroes, autotrim, Ceph memory caps, KSM check in doctor.
  • Fixes: lost node certificates, a replaced cluster CA and pveproxy serving an outdated certificate after joins (also on main), joins sent before the first node accepts them, rejected tickets after a join, unvalidated proxmox.domain.
Create, 3 nodes, 4 GiB Before After
Golden, ZFS 93s 49s
Golden, Ceph 3m03s 1m30s

How it was tested

  • go test -race ./..., golangci-lint, shellcheck; each commit builds and passes tests.
  • On a KVM host: golden ZFS and Ceph creates (with base image builds), a 1-node golden create, a 3-node installer create, live snapshot save and restore. Certificates, machine-ids and host keys checked per node.
  • Not verified: proxmox.upgrade and Ceph without --golden (the test host's connection to deb.debian.org drops downloads), the action's template input on a GitHub runner.

QEMU's port forward accepts connections while the guest still boots and
retries towards the guest only every 12s, so a probe without a handshake
deadline could stall until then.
Nodes boot without the 5s GRUB menu. During create, rpool has sync=disabled
and dpkg skips its syncs; the last step restores both so ready clusters keep
real fsync semantics for fault injection. rpool gets autotrim.
API logins, managers and OSDs run on all nodes at once; monitors and MDS
daemons stay sequential. OSD memory target and MDS cache are capped for small
nodes unless already set.
A virtio balloon with free page reporting at a fixed PCI slot, and
detect-zeroes=unmap on the disks.
Right after a join a node can reject a fresh ticket for a moment. Clients
are now safe for concurrent use, and their idle connections time out.
The domain ends up in shell scripts on the nodes.
Logs in to the joining nodes in parallel, then before each join waits until
the first node is quorate with the expected votes and /etc/pve is writable;
the API reports quorum earlier. A join refused for lack of quorum is retried.
A joining node finishes its setup before the cluster file system has synced
to it. Its key and certificate can be lost, or it writes a new cluster CA,
and a failed join leaves pvedaemon and pveproxy rejecting logins. After the
joins every node gets a new certificate from the current CA where needed.
vm.Spec.Files become QEMU fw_cfg files; BootOnce runs an installed node until
it powers off and returns its serial console.
The installer fetches the hook from the host and the node runs it once,
before networking: it skips the pveupdate of a first boot and removes the
GRUB menu wait. It also applies an identity or a bake script passed as guest
files, used by golden images. A ceph.sources that does not point at the
enterprise repository is no longer disabled.
Clones get host name, SSH host keys, machine-id, password and keys from the
first-boot hook before networking, so personalization needs no reboot. Base
images are booted once to bake them (GRUB, pveupdate, and for Ceph clusters
the Ceph packages) and power off before Proxmox VE services start. Base
images from before the hook are still personalized over SSH.
A caching HTTP proxy, reached by the nodes as 10.0.2.2, serves the upgrade,
Ceph install and base image bake. It only stores .deb files of the Debian and
Proxmox repositories; apt runs retry once with no-cache so a broken package
is fetched again. Configurable with proxmox.aptCache (default true).
snapshot save --live (MCP: live) pauses all nodes and saves their disks and
memory through QMP snapshot-save. Restoring one starts every node paused from
it, resumes them together, sets their clocks and waits for quorum.
With template: true the first run saves a live snapshot of the new cluster
in the actions cache; later runs on the same QEMU and CPU model resume it.
After a join, pveproxy can keep serving a certificate that /etc/pve no
longer holds, so logins pinned to the stored certificate fail.
@masterjanic
masterjanic merged commit 076717d into main Oct 11, 2026
15 checks passed
@masterjanic
masterjanic deleted the perf-provisioning branch October 11, 2026 19:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant