> ## Documentation Index
> Fetch the complete documentation index at: https://docs.2501.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Clusters

> Run task executors inside your own Kubernetes cluster or Docker Swarm to reach isolated hosts

A cluster lets the engine run task executors inside a network it cannot reach; [Clusters](/0.18/core-concepts/clusters) explains how. This page covers registering and using one.

## Security properties

* **No inbound flow.** The engine talks to your cluster's API server, and the pod connects out to the engine. Nothing from the outside ever dials into your network.
* **No credentials at rest in your cluster.** The target host's credentials are sent over the session's TLS connection when it starts; they never appear in the pod spec and are never written to disk in the cluster.
* **An unprivileged pod.** The executor runs as a non-root user with privilege escalation denied, all capabilities dropped, and no Kubernetes service-account token - it fits a `restricted` Pod Security Standard namespace. On Swarm, the service runs as an unprivileged user with every capability dropped, publishes no port, and mounts neither host files nor the Docker socket.
* **Nothing resident.** The pod or service is deleted when the task ends. Between tasks, 2501 has no footprint in your cluster. A Swarm executor also stops on its own after four hours, and an engine that crashed removes the services it left behind when it starts again.

## Registering a cluster

Go to **Command Center** → **Clusters** → **Create Cluster**, give it a **Name** - the handle hosts refer to - and pick its **Cluster type**: Kubernetes or Docker Swarm (in-cluster). The type cannot be changed later. An option this engine cannot run executors in is greyed out, with the reason.

### Kubernetes

* **Where executors run** - the cluster the engine itself runs in (no credentials needed; only offered when the engine runs in Kubernetes), or a remote cluster.
* **API server** - for a remote cluster, its API URL, e.g. `https://cluster.example.com:6443`.
* **Cluster CA certificate** - the CA to verify the API server against, stored as a [Credential](/0.18/configure/credentials). A remote cluster without a CA is refused unless you explicitly opt into skipping TLS verification.
* **Authentication** - required: either a client certificate + key pair or a bearer token, each stored as a Credential. Use a long-lived service-account token: one from `kubectl create token` expires within hours, and the cluster then stops spawning executors.

The service account behind the credentials needs to create, read and delete pods in the namespaces you grant - nothing else. Scoping it is your RBAC: the grant is auditable and revocable on your side like any other external operator's.

### Docker Swarm

A Swarm cluster is the Swarm the engine runs in: the engine must run on an active Swarm manager with its Docker socket mounted. Remote Swarm managers are not supported, so a Swarm cluster takes no API server or credentials.

* **Overlay network** - optional. Empty, executors use the node's own network and route. Name an existing Swarm overlay when the engine or the target is only reachable on it, or to use an encrypted overlay.

The engine must also have `SATELLITE_DIALBACK_URL` set: a Swarm executor may run on another node, so the engine never derives its own address for it, and registering a Swarm cluster is refused without it.

### Both types

* **Keep finished executor workloads** - off by default; on, finished pods or services stay in the cluster so you can inspect a run, and cleaning them up is yours to do.
* **Skip dial-back TLS verification** - off by default. On, executors in this cluster accept the engine's certificate without verifying it, for a cluster whose trust store cannot be made to match the engine's listener. Turn it on only where you cannot fix the trust store instead - the "No credentials at rest in your cluster" guarantee above rests on the pod verifying that it is really the engine on the other end, so a cluster with this switch on still gets an encrypted session, but no longer one that proves who terminates it. It does not cover an HTTPS egress proxy, which is a separate TLS peer and stays verified.
* **Executor placement** - where workloads that serve no host run: a [Central](/0.18/configure/centrals) on this cluster, and the executors that send the requests of an [HTTP API](/0.18/configure/plugins#add-an-http-api) running from this cluster. It takes the settings a host's placement takes on the cluster's type (see [Connecting a host through a cluster](#connecting-a-host-through-a-cluster)), and a setting that type cannot read is refused when the cluster is saved. Empty, HTTP API executors run on any node: on Kubernetes in the default namespace, or the engine's own namespace in the engine's own cluster. A Central on Kubernetes needs a dedicated namespace set here.

## Network prerequisites

* On Kubernetes, the engine must reach a remote cluster's API server.
* Executors - pods, or Swarm tasks - must be able to open outbound connections to the engine's dial-back address, on port 443 on the engine side - traffic always flows outbound from the pod to the engine. If the cluster's only egress is an HTTP proxy, set the cluster's dial-back proxy: executors then tunnel through it, and the proxy only needs to allow CONNECT to that address - the TLS still terminates at the engine, so the proxy carries ciphertext it cannot read.
* The cluster's nodes must be able to pull the executor image from the registry your deployment publishes it to (`SATELLITE_EXECUTOR_IMAGE` on the engine). If the registry is private, give the nodes their own pull access, or attach an image pull secret to the namespace's `default` service account. Executors in the engine's own namespace reuse the engine's pull secret (`EXECUTOR_MCP_IMAGE_PULL_SECRET`).
* On Swarm, every node an executor may land on must be able to pull that image itself: log the nodes in to a private registry, or preload the image. The engine sends no registry credential. The executor's network - the overlay, or the node's own route - must reach both the target and the dial-back address.

The dial-back side is part of the engine deployment: `SATELLITE_DIALBACK_URL` is the address executors dial, and the `SATELLITE_TLS_*` variables configure the TLS listener that answers them. An executor authenticates its first dial with a single-use token: the token is spent when the connection is established, and its two-minute expiry bounds how long the executor has to start and dial back, not how long the task may run.

## Connecting a host through a cluster

In the host's **Executor placement** section, pick the cluster in **Executor cluster**. The settings below follow the cluster's type, and a setting that type cannot read is refused when the host is saved.

On a Kubernetes cluster, three optional settings shape where its executors run:

* **Namespace** - where this host's executor pods are created. Left empty, they are created in `default` - or, when the engine runs in that same cluster, in the engine's own namespace. The cluster's service account must have rights there.
* **Placement** - Kubernetes nodeSelector lines (`key=value`), limiting the executor to the nodes that can actually reach the host. The typical case is one cluster whose nodes span network zones: the selector names the nodes inside the host's zone.
* **Tolerations** - `key[=value]:effect` lines, needed when those nodes are tainted to keep general workloads off them.

On a Swarm cluster, the only setting is **Placement**: Swarm constraints, one per line (`node.labels.zone==shared`, `node.hostname!=build-1`), choosing the nodes the executor may run on. They do not make the container privileged. Swarm has no taints: to keep other workloads off the nodes reserved for executors, give those services their own constraints.

## Testing with a dry run

The **Dry run** action on the Clusters page proves the whole round-trip without running a task or touching any host: it spawns a probe executor, waits for it to dial back and complete the handshake, then tears it down. Each stage reports live with its timing, and a failure comes with the pod's or Swarm task's own status (such as `Unschedulable`, `ImagePullBackOff` or `no suitable node`) and a hint on where to look. You can pass a placement (and, on Kubernetes, tolerations) to prove a host's placement schedules before that host depends on it.

## Deleting a cluster

Deleting a cluster is refused while hosts still connect through it, HTTP API plugins run from it, or a Central workload on it is not yet confirmed stopped. Point those hosts elsewhere and delete those HTTP APIs first: an HTTP API's location is fixed, so it cannot move to another cluster. Connectivity never silently degrades to a direct connection.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.