Skip to content

Clusters API

The ClusterService (pivirt.cluster.v1) manages multi-node cluster topology, node lifecycle operations (adding, draining, cordoning, and removing nodes), health telemetry, and cluster-wide rolling upgrades.

package pivirt.cluster.v1;
service ClusterService {
// Cluster operations
rpc CreateCluster(CreateClusterRequest) returns (Cluster);
rpc GetCluster(GetClusterRequest) returns (Cluster);
rpc ListClusters(ListClustersRequest) returns (stream Cluster);
rpc DeleteCluster(DeleteClusterRequest) returns (Operation);
rpc UpdateCluster(UpdateClusterRequest) returns (Cluster);
// Node operations
rpc AddNode(AddNodeRequest) returns (Node);
rpc RemoveNode(RemoveNodeRequest) returns (Operation);
rpc GetNode(GetNodeRequest) returns (Node);
rpc ListNodes(ListNodesRequest) returns (stream Node);
rpc DrainNode(DrainNodeRequest) returns (Operation);
rpc CordonNode(CordonNodeRequest) returns (Operation);
rpc UncordonNode(UncordonNodeRequest) returns (Operation);
// Cluster health
rpc GetHealth(GetHealthRequest) returns (ClusterHealth);
rpc GetMetrics(GetMetricsRequest) returns (ClusterMetrics);
// Cluster upgrade
rpc UpgradeCluster(UpgradeClusterRequest) returns (Operation);
rpc GetUpgradeStatus(GetUpgradeStatusRequest) returns (UpgradeStatus);
}
message Cluster {
string id = 1;
string name = 2;
ClusterStatus status = 3;
string version = 4;
ClusterTopology topology = 5;
map<string, string> labels = 6;
map<string, string> annotations = 7;
google.protobuf.Timestamp created_at = 8;
google.protobuf.Timestamp updated_at = 9;
}
enum ClusterStatus {
CLUSTER_STATUS_UNSPECIFIED = 0;
CLUSTER_STATUS_CREATING = 1;
CLUSTER_STATUS_RUNNING = 2;
CLUSTER_STATUS_DEGRADED = 3;
CLUSTER_STATUS_ERROR = 4;
CLUSTER_STATUS_UPGRADING = 5;
}
message ClusterTopology {
int32 control_plane_count = 1;
int32 worker_count = 2;
repeated string control_plane_nodes = 3;
repeated string worker_nodes = 4;
}
message Node {
string id = 1;
string name = 2;
string cluster_id = 3;
NodeRole role = 4;
NodeStatus status = 5;
string ip = 6;
NodeResources resources = 7;
NodeConditions conditions = 8;
map<string, string> labels = 9;
map<string, string> annotations = 10;
google.protobuf.Timestamp created_at = 11;
google.protobuf.Timestamp updated_at = 12;
}
enum NodeRole {
NODE_ROLE_UNSPECIFIED = 0;
NODE_ROLE_CONTROL_PLANE = 1;
NODE_ROLE_WORKER = 2;
}
enum NodeStatus {
NODE_STATUS_UNSPECIFIED = 0;
NODE_STATUS_READY = 1;
NODE_STATUS_NOT_READY = 2;
NODE_STATUS_DRAINING = 3;
NODE_STATUS_CORDONED = 4;
NODE_STATUS_ERROR = 5;
}
message NodeResources {
int32 cpu_cores = 1;
int64 memory_bytes = 2;
int64 storage_bytes = 3;
int32 cpu_used_cores = 4;
int64 memory_used_bytes = 5;
int64 storage_used_bytes = 6;
}
message NodeConditions {
bool memory_pressure = 1;
bool disk_pressure = 2;
bool pid_pressure = 3;
bool network_unavailable = 4;
}
message ClusterHealth {
string cluster_id = 1;
HealthStatus status = 2;
repeated ComponentHealth components = 3;
repeated NodeHealth nodes = 4;
string message = 5;
}
enum HealthStatus {
HEALTH_STATUS_UNSPECIFIED = 0;
HEALTH_STATUS_HEALTHY = 1;
HEALTH_STATUS_DEGRADED = 2;
HEALTH_STATUS_UNHEALTHY = 3;
}
message ComponentHealth {
string name = 1;
HealthStatus status = 2;
string message = 3;
google.protobuf.Timestamp last_check = 4;
}
message NodeHealth {
string node_id = 1;
string node_name = 2;
HealthStatus status = 3;
string message = 4;
google.protobuf.Timestamp last_check = 5;
}
message CreateClusterRequest {
string name = 1;
ClusterTopology topology = 2;
string version = 3;
map<string, string> labels = 4;
map<string, string> annotations = 5;
}

Example:

Terminal window
grpcurl -plaintext -d '{
"name": "prod-cluster",
"topology": {
"control_plane_count": 3,
"worker_count": 5
},
"version": "v0.0.89"
}' localhost:8443 pivirt.cluster.v1.ClusterService/CreateCluster
message AddNodeRequest {
string cluster_id = 1;
string name = 2;
NodeRole role = 3;
string ip = 4;
map<string, string> labels = 5;
}

Example:

Terminal window
grpcurl -plaintext -d '{
"cluster_id": "cluster-abc123",
"name": "worker-04",
"role": "NODE_ROLE_WORKER",
"ip": "10.0.1.24"
}' localhost:8443 pivirt.cluster.v1.ClusterService/AddNode
message DrainNodeRequest {
string cluster_id = 1;
string node_id = 2;
bool force = 3;
bool ignore_daemonsets = 4;
int32 grace_period_seconds = 5;
}

Example:

Terminal window
grpcurl -plaintext -d '{
"cluster_id": "cluster-abc123",
"node_id": "node-01",
"force": false,
"grace_period_seconds": 300
}' localhost:8443 pivirt.cluster.v1.ClusterService/DrainNode
message UpgradeClusterRequest {
string cluster_id = 1;
string target_version = 2;
UpgradeStrategy strategy = 3;
}
message UpgradeStrategy {
UpgradeType type = 1;
int32 max_surge = 2;
int32 max_unavailable = 3;
int32 partition = 4;
}
enum UpgradeType {
UPGRADE_TYPE_UNSPECIFIED = 0;
UPGRADE_TYPE_ROLLING = 1;
UPGRADE_TYPE_BLUE_GREEN = 2;
UPGRADE_TYPE_CANARY = 3;
}

Example:

Terminal window
grpcurl -plaintext -d '{
"cluster_id": "cluster-abc123",
"target_version": "v0.0.90",
"strategy": {
"type": "UPGRADE_TYPE_ROLLING",
"max_surge": 1,
"max_unavailable": 0
}
}' localhost:8443 pivirt.cluster.v1.ClusterService/UpgradeCluster
message GetHealthRequest {
string cluster_id = 1;
}

Example:

Terminal window
grpcurl -plaintext -d '{
"cluster_id": "cluster-abc123"
}' localhost:8443 pivirt.cluster.v1.ClusterService/GetHealth
Code Description
NOT_FOUND Cluster or node not found
ALREADY_EXISTS Cluster or node with same name exists
INVALID_ARGUMENT Invalid cluster/node configuration
FAILED_PRECONDITION Cluster in wrong state for operation
RESOURCE_EXHAUSTED Insufficient resources for operation