Session note on CAPMOX v0.9.1 against the 2-node PVE cluster, the plan and its execution log. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
4.4 KiB
4.4 KiB
Session: CAPMOX against a two-node PVE cluster
Date: 2026-09-29 23:11 CEST
Question
pv1-1 became the PVE cluster homelab, and a second node pv1-2 joined it. Does the CAPI/CAPMOX
configuration need changes to work against the cluster?
What was checked
- PVE API (read-only GETs with the
capmox@pve!capitoken, 2026-09-29):/cluster/status,/nodes,/storage,/nodes/<n>/network,/nodes/<n>/storage,/cluster/resources,/access/acl. - CAPMOX v0.9.1 source (Go proxy zip): scheduler, clone path, template lookup,
templates/cluster-template.yaml. - PVE
qemu-serverPVE/API2/Qemu.pm(HEAD, not pinned to a PVE release): the clone target check.
Findings
PVE state:
| Item | pv1-1 | pv1-2 |
|---|---|---|
| IP | 192.168.0.8 | 192.168.0.10 |
| CPU / RAM | 16 / 29.2 GiB | 12 / 40.9 GiB |
vmbr0 VLAN-aware |
yes | no |
local-lvm |
local LVM-thin | local LVM-thin (not shared) |
| Templates | 101 ubuntu-2404-kube-v1.35.9, 9000, 9001 |
none |
- Storage definitions (
local,local-lvm,proxy-seeds) are cluster-wide without anodesrestriction, but none of them is shared. - The
capmox@pveACLs (/,/storage,/sdn/zones/localnetwork) are cluster-wide, so they coverpv1-2as well. There are no SDN zones.
CAPMOX v0.9.1:
- Node choice. If the ProxmoxMachine has its own
allowedNodes, that list replaces the ProxmoxCluster's (internal/service/scheduler/vmscheduler.go:52-62).- The scheduler balances by how many machines of this cluster are already on each node
(
status.nodeLocations), and only picks a node where the requested memory fits (vmscheduler.go:75-119). memoryAdjustmentis applied per node, against that node's own total memory.- With empty
allowedNodesthe scheduler isn't called and the VM clones on the source node (internal/service/vmservice/vm.go:477).
- The scheduler balances by how many machines of this cluster are already on each node
(
- Clone.
targetgoes to the PVE clone call as-is (pkg/proxmox/goproxmox/api_client.go:84-95).- PVE refuses a cross-node clone when any source disk is on non-shared storage:
can't clone VM to node '<target>' (VM uses local storage). - Setting
full: trueorstoragedoes not change that. - v0.9.1 has no
localStorageoption.
- PVE refuses a cross-node clone when any source disk is on non-shared storage:
templateSelectorsearches the whole PVE cluster and needs exactly one match (api_client.go:149-212). "One template per node with the same tags" fails withfound 2 VM templates.- API URL and credentials. Everything goes through one API URL; nothing in the credentials
names a node.
- Cross-node requests should be forwarded by PVE (standard PVE behaviour, not checked in code).
192.168.0.8ispv1-1, so a downpv1-1also means no API for CAPMOX.
- Bridge.
bridge/vlanare written intonetXwithout any check (vm.go:338).
Conclusion:
- Nothing has to change for the current setup to keep working.
lab1pinsallowedNodes: [pv1-1]andsourceNode: pv1-1, which is decision #7. - Using
pv1-2requires two things:- Make
vmbr0onpv1-2VLAN-aware and trunk VLAN 4 on its switch port. - Either put a template copy on
pv1-2, or add shared storage.
- Make
- With a template copy per node:
- Workers get one ProxmoxMachineTemplate and one MachineDeployment per PVE node, each with
sourceNode,templateID(the node's own VMID) andallowedNodes: [<node>]. For cluster-autoscaler that is one node group per PVE node. - KubeadmControlPlane takes a single infrastructureRef, so the control plane stays on one node.
- Workers get one ProxmoxMachineTemplate and one MachineDeployment per PVE node, each with
Open questions
- How to get the template onto
pv1-2: a second image-builder run (PROXMOX_NODE=pv1-2), orqm clone+qm migrate/ vzdump-restore? The image-builder run is reproducible; the copy is faster. - Is shared storage (NFS) worth adding instead? It gives one MachineDeployment spread over both nodes, and the control plane can use both nodes too.
- Behaviour when a cross-node clone fails: the scheduler may keep picking the same node. This is inferred from the code, not tested.
Follow-ups
- The owner chose: no shared storage for now; copy template 101 to
pv1-2as 9101; keeplab1-workersand addlab1-workers-pv1-2. Plan: 2026-09-29-2315-pv1-2-workers. It covers the bridge fix, the template copy, the second MD, the CA limits and a decision row superseding #7. - Update the "Lab facts" in CLAUDE.md/AGENTS.md: PVE cluster
homelab,pv1-2at 192.168.0.10.