Deploy a Managed Kubernetes Cluster on CubePath

Managed Kubernetes gives you a real Kubernetes cluster without running the hard part yourself. CubePath manages the control plane (the API server and everything that keeps the cluster healthy), and your workers run on CubePath VPS that you size and scale. You get a kubeconfig, point kubectl at it, and deploy.

It's the way to run containers in production: web apps, APIs, background workers, and anything you'd otherwise hand-roll on a pile of servers.

How it works

You create a cluster in a project and location, choosing a Kubernetes version and one or more node pools. A node pool is a group of identical worker servers (same plan); CubePath provisions them as VPS, joins them to the cluster, and keeps the managed control plane running in front. Workers can have public IPs or sit on a private network, and pods and services get their own internal networks. Once the cluster is ready you download its kubeconfig and use it with kubectl or any Kubernetes tooling, exactly like any other cluster. You manage the cluster, its node pools, and add-ons from the dashboard or the API.

Before you start

  • In the dashboard: my.cubepath.com → Kubernetes.
  • Over the API: base URL https://api.cubepath.com, authenticate with Authorization: Bearer <token> (scopes kubernetes:read / kubernetes:write), and add X-Requested-With: XMLHttpRequest on writes. Get a token under Account → API Tokens.
  • Your organization must be verified, not suspended, and carry a positive balance. Each worker is a VPS on the plan you pick and is billed like any VPS.
  • Have kubectl installed locally to talk to the cluster once it's up.

Create a cluster

List the available versions (GET /kubernetes/versions) and worker plans (GET /kubernetes/plans) first, then create the cluster with at least one node pool:

curl -X POST https://api.cubepath.com/kubernetes/ \
  -H "Authorization: Bearer $CUBEPATH_TOKEN" \
  -H "X-Requested-With: XMLHttpRequest" \
  -H "Content-Type: application/json" \
  -d '{
    "project_id": 1,
    "name": "prod",
    "location_name": "us-mia-1",
    "version": "v1.30",
    "ha_control_plane": true,
    "node_pools": [
      { "name": "default", "plan": "ck2-2-4", "count": 3, "auto_scale": true }
    ]
  }'

The options:

  • version: leave it out to use the current default.
  • ha_control_plane: a redundant, highly available control plane. Recommended for production; leave false for dev/test.
  • allocate_ipv4 / allocate_ipv6: give workers public IPs (both default to true). If you turn off public IPv6, the cluster needs a private network (below).
  • network: optional. Attach to an existing private network with network_id, or have one created by passing a node_cidr. Pods and services use their own ranges (pod_cidr default 10.42.0.0/16, service_cidr default 10.43.0.0/16); they must not overlap.
  • node_pools: one to ten pools, each with a plan and a node count (1 to 100).

The cluster provisions in the background. Watch its status with GET /kubernetes/{uuid}.

Node pools

A node pool is a set of workers that share a plan and scheduling settings. Splitting workers into pools lets you mix sizes (for example a small general pool plus a large memory pool) and target workloads with labels and taints.

  • Create a pool: POST /kubernetes/{cluster_uuid}/node-pools.
  • Scale or retune it: PATCH /kubernetes/{cluster_uuid}/node-pools/{pool_uuid} to change desired_nodes, turn auto_scale on or off, set min_nodes / max_nodes, or update labels and taints. With autoscaling on, the pool grows and shrinks between min and max based on demand.
  • Add or remove individual workers: POST .../node-pools/{pool_uuid}/nodes and DELETE .../node-pools/{pool_uuid}/nodes/{vps_id}.
  • Delete a pool: DELETE /kubernetes/{cluster_uuid}/node-pools/{pool_uuid}.

Connect with kubectl

Download the cluster's kubeconfig and point kubectl at it:

curl https://api.cubepath.com/kubernetes/<cluster_uuid>/kubeconfig \
  -H "Authorization: Bearer $CUBEPATH_TOKEN" -o kubeconfig.yaml

export KUBECONFIG=$PWD/kubeconfig.yaml
kubectl get nodes

From here it's a standard cluster: apply manifests, install Helm charts, run whatever you like.

Add-ons

CubePath has a catalog of one-click add-ons (ingress controllers, monitoring, and more) you can install into a cluster instead of wiring up Helm yourself.

  • Browse the catalog: GET /kubernetes/addons (and GET /kubernetes/addons/{slug} for details).
  • Install into a cluster: POST /kubernetes/{cluster_uuid}/addons/{slug}/install, optionally with custom_values to override the defaults.
  • See what's installed: GET /kubernetes/{cluster_uuid}/addons.
  • Uninstall: DELETE /kubernetes/{cluster_uuid}/addons/{addon_uuid}.

Exposing your apps

To take traffic from the internet to services in the cluster, put a Load Balancer in front of it; you can see the load balancers targeting a cluster with GET /kubernetes/{cluster_uuid}/loadbalancers. For internal-only clusters, attach a private network at create time and skip public worker IPs.

Managing the cluster

  • Rename: PATCH /kubernetes/{uuid} (name and label).
  • Protect: POST /kubernetes/{uuid}/protection blocks deletion until you turn it off.
  • Move project: POST /kubernetes/{uuid}/move.
  • Delete: DELETE /kubernetes/{uuid} tears down the cluster and its workers. Disable protection first if it's on.

Limits

ThingLimit
Node pools per cluster1 to 10
Nodes per pool1 to 100
Labels / taints per pool50 each

What this doesn't do

  • You don't manage the control plane, and you don't get SSH to it. CubePath runs it. You interact with the cluster through the Kubernetes API (kubeconfig), not by logging into control-plane machines.
  • It doesn't expose your apps by itself. A fresh cluster has no public ingress until you add an ingress add-on and a Load Balancer.
  • A cluster lives in one location. Worker placement and its private network are within a single location.

API reference

GET    /kubernetes/versions                               List Kubernetes versions.        (scope: kubernetes:read)
GET    /kubernetes/plans                                  List worker plans.               (scope: kubernetes:read)
POST   /kubernetes/   { project_id, name, location_name, node_pools }  Create a cluster.   (scope: kubernetes:write)
GET    /kubernetes/                                       List your clusters.              (scope: kubernetes:read)
GET    /kubernetes/{uuid}                                 Get a cluster.                   (scope: kubernetes:read)
PATCH  /kubernetes/{uuid}   { name, label }               Rename a cluster.                (scope: kubernetes:write)
DELETE /kubernetes/{uuid}                                 Delete a cluster.                (scope: kubernetes:write)
POST   /kubernetes/{uuid}/protection   { enabled }        Toggle deletion protection.      (scope: kubernetes:write)
GET    /kubernetes/{uuid}/kubeconfig                      Download the kubeconfig.         (scope: kubernetes:read)
POST   /kubernetes/{uuid}/move   { project_id }           Move to another project.         (scope: kubernetes:write)
GET    /kubernetes/{uuid}/loadbalancers                   Load balancers targeting it.     (scope: kubernetes:read)
GET    /kubernetes/{cluster_uuid}/node-pools              List node pools.                 (scope: kubernetes:read)
POST   /kubernetes/{cluster_uuid}/node-pools   { name, plan, count }  Create a node pool.  (scope: kubernetes:write)
PATCH  /kubernetes/{cluster_uuid}/node-pools/{pool_uuid}  Scale or update a pool.          (scope: kubernetes:write)
DELETE /kubernetes/{cluster_uuid}/node-pools/{pool_uuid}  Delete a pool.                   (scope: kubernetes:write)
POST   /kubernetes/{cluster_uuid}/node-pools/{pool_uuid}/nodes   { count }  Add workers.   (scope: kubernetes:write)
DELETE /kubernetes/{cluster_uuid}/node-pools/{pool_uuid}/nodes/{vps_id}  Remove a worker.  (scope: kubernetes:write)
GET    /kubernetes/addons                                 Browse the add-on catalog.       (scope: kubernetes:read)
GET    /kubernetes/{cluster_uuid}/addons                  List installed add-ons.          (scope: kubernetes:read)
POST   /kubernetes/{cluster_uuid}/addons/{slug}/install   Install an add-on.               (scope: kubernetes:write)
DELETE /kubernetes/{cluster_uuid}/addons/{addon_uuid}     Uninstall an add-on.             (scope: kubernetes:write)

All requests authenticate with Authorization: Bearer <token> (or X-API-Key). Write requests also need X-Requested-With: XMLHttpRequest.