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
NodeRings only ever applies resources in dedicated, permissioned namespaces on your cluster:
| Namespace | Holds |
|---|---|
{agent_uuid}-operator | ProxmoxVM / VNCRequest Custom Resources reconciled by your operator |
{agent_uuid}-vnc-gateway | The VNC relay for browser console sessions |
{agent_uuid}-monitoring | Metrics collection (pve-exporter + Alloy) |
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 |
| Proxmox API | URL + scoped API token (see Get started) |
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
You can install from the dashboard (recommended for your first agent) or scripted with the nr CLI.
Create the agent
Open /infrastructure/agents → Create agent 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
Generate the install command
On the new agent, click Generate install command. NodeRings returns a one-liner that embeds your cluster ID and a short-lived install token:
curl -sfL https://get.nrings.io | CLUSTER_ID=<your-cluster-id> TOKEN=<install-token> LIQO_GW_SERVICE_TYPE=LoadBalancer sh -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 Proxmox API URL and API 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 API user and token.
The nr CLI runs the same end-to-end flow and adds system pre-checks and resumable installs.
Authenticate
nr loginRegister the cluster
nr cluster register \
--name "Frankfurt production" \
--agent-ip <public-ipv4> \
--gateway-region <region>This creates the agent record, then installs k3s, Calico, Liqo, and peers the cluster, all in one command.
Resume if interrupted
nr cluster register --resumeThe 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 CLI & automation for using a service-account token in CI.
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.