Agents
Install the NodeRings agent cluster on your own hardware and connect it to the control plane
The agent is the bridge between NodeRings and your Proxmox fleet. It is a small, self-contained k3s Kubernetes cluster you run on a VM you control. NodeRings peers with it over an encrypted channel and sends VM orders as Kubernetes Custom Resources. It never touches your hypervisor directly.
This page is not complete yet. Some sections are still being expanded.
You keep ownership of everything. The agent runs in your network, reads your Proxmox credentials from your cluster, and only ever acts on VMs named NR-{uuid}. NodeRings cannot read your hypervisor token. See How it works for the security model.
Manage agents at /infrastructure/agents.
What runs inside the agent
The installer turns a plain Ubuntu VM into a peered Kubernetes cluster running the open-source NodeRings agent stack.
k3s + Calico
Lightweight Kubernetes with the Calico CNI as the cluster foundation.
Liqo
Peers your cluster to NodeRings over a Kubernetes-native WireGuard tunnel.
proxmox-operator
Reconciles ProxmoxVM / VNCRequest Custom Resources against the Proxmox API.
prometheus-pve-exporter
Scrapes Proxmox metrics locally to feed preflight and capacity checks.
Grafana Alloy
Forwards selected node and NR- VM metrics to NodeRings observability.
vnc-gateway
Relays browser VNC console sessions to Proxmox without exposing it publicly.
The full stack is open source, review it at github.com/noderings/operator before you deploy.
Namespaces created
On the agent cluster, Helm runtime namespaces and Liqo / offload namespaces are different:
| Namespace | Holds |
|---|---|
proxmox-system / virtfusion-system / solusvm-system | Operator Deployment, credentials Secrets, Alloy / exporter (Helm install) |
proxmox-system-hooks / virtfusion-system-hooks / solusvm-system-hooks | Hook script Jobs and optional noderings-hook-secrets ({helm-namespace}-hooks) |
operator (remote name; mothership uses {agent_uuid}-operator) | VM / VNC Custom Resources reflected via Liqo |
vnc-gateway (and related offload names) | VNC relay for browser console sessions |
Discover the hooks namespace with kubectl get ns | grep hooks on the agent. See Provider secrets.
Metrics forwarded to NodeRings
Grafana Alloy scrapes the local pve-exporter every 30s (/pve?target=<host:8006>&cluster=1&node=1), applies relabel rules, and forwards the result to NodeRings. Each sample gets an instance label matching your platform endpoint_url host (for example 192.168.1.100:8006).
Filter logic is defined in the operator Alloy config.
VM filter: Per-guest series are forwarded only when the name label starts with NR- (NodeRings-managed VMs). All other guests (templates, lab VMs, etc.) are dropped and never sent to NodeRings.
Forwarded series
| Metric | Scope | NodeRings use |
|---|---|---|
pve_up | Cluster, all nodes, all storage pools | Platform online preflight; node health UI |
pve_up | VMs/CTs with name=~"NR-.*" | VM power state (1 = running, 0 = stopped) |
pve_cluster_info | Cluster | Cluster metadata |
pve_node_info | Nodes | Node inventory in dashboards |
pve_version_info | Cluster | Proxmox version |
pve_guest_info | VMs/CTs with name=~"NR-.*" | Capacity joins; live validation |
pve_storage_info, pve_storage_shared | Storage pools | Storage capacity / headroom |
pve_memory_size_bytes, pve_memory_usage_bytes | Nodes (all) | Node RAM capacity and usage |
pve_memory_size_bytes, pve_memory_usage_bytes | VMs/CTs with name=~"NR-.*" | Per-VM RAM; sold-capacity views |
pve_cpu_usage_limit, pve_cpu_usage_ratio | Nodes (all) | Node CPU capacity and utilization |
pve_cpu_usage_limit, pve_cpu_usage_ratio | VMs/CTs with name=~"NR-.*" | Per-VM CPU; plan capacity checks |
pve_disk_size_bytes, pve_disk_usage_bytes | Nodes and storage pools (all) | Disk capacity on nodes and stores |
pve_disk_size_bytes, pve_disk_usage_bytes | VMs/CTs with name=~"NR-.*" | Per-VM disk; sold storage |
pve_uptime_seconds | Nodes (all) | Node uptime |
pve_uptime_seconds | VMs/CTs with name=~"NR-.*" | Guest uptime |
pve_network_transmit_bytes, pve_network_receive_bytes | VMs/CTs with name=~"NR-.*" | Bandwidth charts; billing (bandwidth-egress-gb / ingress) |
pve_network_transmit_bytes_total, pve_network_receive_bytes_total | VMs/CTs with name=~"NR-.*" | Same (counter form) |
pve_disk_write_bytes, pve_disk_read_bytes | VMs/CTs with name=~"NR-.*" | Guest disk I/O |
pve_disk_written_bytes_total, pve_disk_read_bytes_total | VMs/CTs with name=~"NR-.*" | Same (counter form) |
non_nr_pve_memory_size_bytes | Per node | Overallocation: RAM used by non-NR guests |
non_nr_pve_cpu_usage_limit | Per node | Overallocation: vCPUs used by non-NR guests |
non_nr_pve_disk_size_bytes, non_nr_pve_disk_usage_bytes | Per node | Overallocation: disk used by non-NR guests |
pve_not_backed_up_* | Cluster / guests | Backup coverage |
pve_subscription_* | Nodes | Subscription status |
pve_replication_* | VMs (when present) | Replication job status |
Dropped by Alloy (not forwarded)
| What | Rule |
|---|---|
| Non-NR VM/CT metrics | name missing or does not start with NR-: applies to pve_up, pve_guest_info, CPU/memory/disk/network/uptime series listed above |
pve_ha_state, pve_lock_state | All qemu/* and lxc/* series dropped |
| Everything else on the scrape that does not match the forwarded rows above | Not sent to NodeRings |
Requirements
The installer supports Ubuntu only today. Prefer a clean VM dedicated to the agent. Running it on the Proxmox host itself is possible, but not recommended.
| Resource | Minimum |
|---|---|
| OS | Ubuntu 22.04 or newer |
| CPU | 2 vCPU |
| RAM | 4 GB |
| Disk | 10 GB free on / |
| Public IP | A reachable public IPv4 for the peering tunnel |
| Hypervisor API | Proxmox: URL + scoped API token (Get started (Proxmox)). VirtFusion: control origin + Global API token (Get started (VirtFusion)). SolusVM 2: management-node origin + Admin API token (Get started (SolusVM 2)) |
Connectivity
| Direction | What it needs |
|---|---|
| Outbound HTTPS | NodeRings API, get.k3s.io, GitHub (Calico + liqoctl), and your DNS resolver |
| Peering tunnel | A WireGuard (UDP) tunnel to the NodeRings gateway, established from your side |
These local ports must be free on the agent VM (k3s and Calico use them): 6443/tcp, 10250/tcp, 8472/udp.
The WireGuard gateway service port is assigned by NodeRings when you create the agent. It is sequential and unique per agent, not the same for every install. After creation, find yours on the agent detail page as Gateway Service Port. If you restrict outbound UDP from the agent VM, allow traffic to the NodeRings gateway on that port.
Install the agent
Prefer the nr CLI for new agents (creates the record and installs the stack in one flow). Use the dashboard when you want a guided create + copy-paste install command. Full docs: CLI · CLI & automation.
The nr CLI runs the end-to-end flow with system pre-checks and resumable installs. From Create agent in the console you can also copy a personalized command without creating the agent first.
Service account token
Create a service account in Access Control → Service Accounts, then on the agent VM:
export NR_API_TOKEN='<service-account-token>'
echo $NR_API_TOKENDo not run nr auth login on the agent VM.
Register the cluster
Copy the command from Create agent in the console (it includes --org-id), or:
nr cluster register \
--name "Frankfurt production" \
--agent-ip <public-ipv4> \
--gateway-region AMS01 \
--org-id <org-uuid>This creates the agent record, then installs k3s, Calico, Liqo, and peers the cluster, all in one command.
Resume if interrupted
nr cluster register --resume --org-id <org-uuid>The CLI checkpoints each phase, so a flaky network won't force you to start over.
The CLI is ideal for repeatable, scripted onboarding across many hosts. See the CLI tutorial and CI how-to.
Create the agent
Open /infrastructure/agents → Create agent → Create in console and fill in:
- Name and optional description (for example
Frankfurt production) - Agent public IP: the public IPv4 of the VM you'll install on
- Gateway region: the NodeRings peering gateway closest to you (control-plane enum, e.g. AMS01)
Generate the install command
Open the agent Provisioning tab. NodeRings returns an nr cluster register command that embeds your agent ID and a short-lived install token.
The install token expires in 1 hour. If it lapses, just generate a new command, nothing else is lost.
Run it on your agent VM
SSH into your Ubuntu VM and paste the command. The installer runs unattended and:
- Installs prerequisites (
ca-certificates,curl,jq,tar) - Installs k3s (Traefik and flannel disabled)
- Installs the Calico CNI
- Installs Liqo and peers the cluster to NodeRings
- Deploys the operator and monitoring stack on your agent cluster
Installation takes a few minutes depending on your network.
Connect Proxmox
Provide your hypervisor API URL and token so the operator can manage VMs. NodeRings never stores these. They live only in your cluster. Create the token first using Get started (Proxmox) or Get started (VirtFusion).
Verify the agent is healthy
After install, confirm the agent is connected before moving on to platforms and nodes.
| Where | Looks healthy when |
|---|---|
/infrastructure/agents | Agent shows provisioned |
| On the agent VM | kubectl get pods -A shows the operator pod Running |
| Peering | Liqo reports the remote cluster as connected |
NodeRings also infers health from metrics: once your hypervisor is registered, the platform online preflight check passes when pve_up=1 is flowing from Alloy.
Troubleshooting
Next
Continue with Platforms & nodes to register the hypervisor endpoint and hosts this agent manages.