cara-agent instance. Caravanserai uses Nodes as scheduling targets: the Scheduler assigns Projects only to Nodes in the Ready state.
cara-agent self-registers its Node with the control plane on startup using the NODE_NAME environment variable. You only need to write a Node manifest manually when you want to pre-register a node before the agent starts, or to update node configuration such as labels or schedulability.Schema
Top-level fields
Must be
caravanserai/v1.Must be
Node.Identity metadata for the resource.
Unique identifier for the Node within the cluster. This is the name the agent registers under and the name you use in
caractrl commands. Typically matches the machine hostname or a descriptive label such as edge-node-01.Arbitrary key/value pairs for grouping and selection. Common uses include zone or region labels, for example
caravanserai.io/zone: ed312.spec
The OS-level hostname of the machine, for example
pve-03 or edge-01.local. Used for informational purposes and audit trails.When
true, prevents the scheduler from assigning new Projects to this Node. Projects already running on the Node continue to run. Set this field to true before draining a node for maintenance.Example
node.yaml
Marking a node unschedulable
Setspec.unschedulable: true to cordon a node. The control plane stops scheduling new Projects onto it while existing workloads continue running.
Apply the change
unschedulable: false and reapply.Status fields (read-only)
The following fields are written by the system — bycara-agent (heartbeat data) and the Controller Manager (aggregated state). Do not include them in your manifests.
status.state
status.state
High-level health summary of the Node. One of:
| Value | Meaning |
|---|---|
Ready | Node is healthy and accepting work |
NotReady | Agent heartbeat has timed out or the node is unhealthy |
Draining | Node is being drained; no new Projects are scheduled |
status.network
status.network
Overlay-network connectivity reported by the Headscale/Tailscale integration.
| Field | Description |
|---|---|
ip | Headscale-assigned overlay IP address, e.g. 100.64.0.5 |
dnsName | MagicDNS FQDN for service discovery |
mode | Direct when a peer-to-peer path exists; DERP otherwise |
agentPort | TCP port the agent’s HTTP server listens on |
throughput.download | Last measured download speed |
throughput.upload | Last measured upload speed |
throughput.lastTestTime | Timestamp of the last speed measurement |
status.capacity and status.allocatable
status.capacity and status.allocatable
Resource totals reported by the agent.
| Field | Description |
|---|---|
capacity | Raw physical resource totals (cpu, memory, disk). Values use Kubernetes quantity format: "4Gi", "2000m". |
allocatable | Capacity minus system-reserved amounts. The Scheduler uses this to determine available headroom for new Projects. |
status.lastHeartbeat
status.lastHeartbeat
RFC 3339 timestamp of the most recent heartbeat received from the agent. The control plane uses this to detect unresponsive nodes and transition them to
NotReady.status.conditions
status.conditions
A list of granular observable conditions on the Node. Each condition has:
| Field | Description |
|---|---|
type | Machine-readable identifier, e.g. Ready |
status | True, False, or Unknown |
reason | CamelCase word summarising the current status |
message | Human-readable explanation |
lastHeartbeatTime | When this condition was last sampled |
lastTransitionTime | When the status last changed |