Skip to content

Kubernetes Clusters

The b'nerd platform supports two cluster types, distinguished by the kind field:

Kind Description
gardener Managed clusters provisioned and operated by Gardener. b'nerd handles the control plane.
generic Clusters you bring yourself — register an existing cluster by providing a kubeconfig.

Endpoints

Method Path Description
GET /k8s/clusters?project_id=<uuid> List clusters in a project
POST /k8s/clusters?project_id=<uuid> Create a cluster
GET /k8s/clusters/{id}?project_id=<uuid> Show a cluster
PATCH /k8s/clusters/{id}?project_id=<uuid> Update a cluster
DELETE /k8s/clusters/{id}?project_id=<uuid> Delete a cluster
GET /k8s/cloudprofiles List Gardener cloud profiles (available regions/versions)

project_id is required on all cluster requests.

List clusters

GET /k8s/clusters?project_id=<uuid>
Authorization: Bearer <token>

Returns both Gardener-managed and generic clusters in one array. Use the kind field to differentiate.

Create a Gardener-managed cluster

POST /k8s/clusters?project_id=<uuid>
Authorization: Bearer <token>
Content-Type: application/json

{
  "name": "prod-cluster",
  "project_id": "<uuid>",
  "cloud": "openstack",
  "version": "1.29",
  "node_pools": [
    {
      "name": "workers",
      "machine_type": "m1.large",
      "min": 2,
      "max": 5
    }
  ]
}

Returns 201 Created. Provisioning is asynchronous — watch status and lastOperation on subsequent GET calls.

Register a generic cluster

POST /k8s/clusters?project_id=<uuid>
Authorization: Bearer <token>
Content-Type: application/json

{
  "kind": "generic",
  "name": "on-prem-k3s",
  "kubeconfig": "<base64-or-raw-yaml>"
}

The kubeconfig field is write-only — it is stored encrypted and never returned in responses. Use has_kubeconfig: true in the response to confirm it was saved.

Show a cluster

GET /k8s/clusters/{id}?project_id=<uuid>
Authorization: Bearer <token>

Key response fields:

Field Description
kind gardener or generic
id Cluster identifier
name Display name
status Gardener shoot status object (Gardener clusters only)
lastOperation Most recent Gardener operation (Gardener clusters only)
creating true while the cluster is still being provisioned
api_server Kubernetes API server URL (Gardener clusters only)
has_kubeconfig true if a kubeconfig is stored (generic clusters only)
connection_status reachable or unreachable — API server probe result (generic only)
cloud Cloud provider name
version Kubernetes version
node_pools Array of node pool objects

Update a cluster

PATCH /k8s/clusters/{id}?project_id=<uuid>
Authorization: Bearer <token>
Content-Type: application/json

{
  "name": "new-name"
}

For generic clusters you can also rotate the kubeconfig:

{ "kubeconfig": "<new-kubeconfig-yaml>" }

Delete a cluster

DELETE /k8s/clusters/{id}?project_id=<uuid>
Authorization: Bearer <token>

Returns 204 No Content. For Gardener clusters, deletion is asynchronous and involves deprovisioning the cloud resources; the cluster disappears from list results once Gardener confirms teardown.

Cloud profiles

Cloud profiles enumerate the Kubernetes versions, machine types, and regions available for Gardener-managed clusters:

GET /k8s/cloudprofiles
Authorization: Bearer <token>

Use this to discover valid values for version, cloud, and machine_type when creating a Gardener cluster.

  • Node Pools — manage worker node pools within a cluster