Node Status Metrics
The CloudPilot Agent exposes a Prometheus-compatible endpoint that reports the current node status and disruption state shown by CloudPilot AI. You can scrape this endpoint directly with Prometheus or use the Prometheus receiver in an OpenTelemetry Collector.
The endpoint is available inside the cluster at:
http://cloudpilot-agent.cloudpilot.svc.cluster.local/metricsNode Status Metrics requires an Agent version that includes the /metrics
endpoint. If the endpoint returns 404, upgrade the CloudPilot Agent.
Metric reference
All metrics are gauges. A value of 1 indicates the current state represented
by the metric’s labels.
| Metric | Labels | Description |
|---|---|---|
cloudpilot_node_status | cluster_id, node_name, node_pool, status | Current effective node status. |
cloudpilot_node_disruption_status | cluster_id, node_name, node_pool, status | Current primary disruption state. |
cloudpilot_node_status_collection_success | source | Whether the Agent has synchronized the source used to calculate node status. 1 means synchronized and 0 means unavailable or still synchronizing. |
node_pool is empty for nodes that are not associated with a Karpenter
NodePool. Some OpenTelemetry backends omit attributes with an empty value.
Effective node status
cloudpilot_node_status reports one of the following values:
| Status | Meaning |
|---|---|
ready | Kubernetes reports the node as Ready and no higher-priority NodeClaim state is active. |
not_ready | Kubernetes or the associated NodeClaim reports that the node is not ready. |
unknown | Kubernetes readiness is unknown, or required NodeClaim data is unavailable. |
resolving | The NodeClaim readiness state is still resolving. |
not_initialized | The NodeClaim has not completed initialization. |
terminating | The node or its NodeClaim is terminating. |
migration_blocked | A recent CloudPilot-requested node migration was blocked. |
drifted | The NodeClaim has drifted from its desired configuration. |
Kubernetes node readiness remains the primary status, matching the CloudPilot
Node List. Use cloudpilot_node_disruption_status when you need the independent
disruption lifecycle.
Disruption status
cloudpilot_node_disruption_status reports one of the following values:
| Status | Meaning |
|---|---|
none | The NodeClaim is available and has no current disruption state. |
drifted | The NodeClaim is drifted. |
migration_blocked | A recent migration attempt was blocked. |
protected | A recent migration attempt was blocked by karpenter.sh/do-not-disrupt. |
terminating | The node or NodeClaim is terminating. |
not_applicable | The node is not associated with a NodeClaim. |
unknown | The node is associated with a NodeClaim, but the required status or Event data is unavailable. |
Migration-blocked observations cover the most recent ten minutes and are not permanent history. Use the CloudPilot Console and Karpenter Events for the full diagnostic message and lifecycle details.
Collection health
cloudpilot_node_status_collection_success uses the following source values:
| Source | Description |
|---|---|
node | Kubernetes Node informer cache. |
nodeclaim | Karpenter NodeClaim informer cache. |
event | Kubernetes Event informer used for disruption-blocked observations. |
The nodeclaim and event source metrics are emitted only for supported
Karpenter integrations. On other clusters, the Agent emits only source="node"
collection health and reports disruption_status="not_applicable".
Verify the endpoint
Port-forward the cluster-local Agent service:
kubectl -n cloudpilot port-forward \
--address 127.0.0.1 \
svc/cloudpilot-agent 24909:80In another terminal, query the endpoint:
curl -fsS http://127.0.0.1:24909/metrics \
| grep -E '^cloudpilot_node_(status|disruption_status|status_collection_success)'The port-forward is attached to the current Agent Pod. Re-create it after an Agent rollout or restart.
OpenTelemetry Collector configuration
Use the Prometheus receiver to scrape the Agent service, then export the data to your OpenTelemetry-compatible backend:
receivers:
prometheus:
config:
scrape_configs:
- job_name: cloudpilot-agent
scrape_interval: 60s
static_configs:
- targets:
- cloudpilot-agent.cloudpilot.svc.cluster.local:80
exporters:
otlp:
endpoint: ${env:OTEL_EXPORTER_OTLP_ENDPOINT}
service:
pipelines:
metrics:
receivers: [prometheus]
exporters: [otlp]Configure TLS and authentication on the OTLP exporter as required by your observability backend.
Query examples
Find nodes whose effective status is not Ready:
cloudpilot_node_status{status!="ready"} == 1Find nodes with an actionable disruption state:
cloudpilot_node_disruption_status{status=~"migration_blocked|protected|terminating"} == 1Detect an unavailable collection source:
cloudpilot_node_status_collection_success == 0Freshness and performance
The Agent calculates metrics from its existing informer caches and does not query the Kubernetes API for each scrape. A calculated snapshot is cached for one minute. Scraping more frequently than once per minute does not increase data freshness, so a 60-second scrape interval is recommended.
After a node or NodeClaim change, allow up to approximately one minute for the new state to appear. Results produced before the Node informer has synchronized are not cached.
Security considerations
The Agent service is a Kubernetes ClusterIP service and is not exposed outside
the cluster by default. The metrics include cluster IDs, node names, NodePool
names, and status labels. Do not expose /metrics publicly. Use Kubernetes
network policies when access must be limited to a dedicated monitoring
namespace.
For the Kubernetes permissions used to collect Node and NodeClaim state, see Permissions Required to Use CloudPilot AI.