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

# Runlayer Operator (Kubernetes)

> Install the unified Runlayer operator for multi-tenant EKS clusters

The unified **Runlayer operator** reconciles two custom resources in one controller:

| CRD                | Purpose                                                                            |
| ------------------ | ---------------------------------------------------------------------------------- |
| `RunlayerInstance` | Tenant platform stack (backend, frontend, worker, migrations, optional components) |
| `MCPServer`        | Hosted MCP server Deployments (Runlayer Deploy)                                    |

Use this path when you want **multiple isolated Runlayer tenants** on a shared EKS cluster. For single-tenant installs, the legacy [Helm + Kubernetes](/deployment/helm) (`anysource-chart`) path remains supported until you cut over.

<Warning>
  Do **not** install the unified operator on a cluster that already runs `runlayer-deploy-operator` or `anysource-chart`. Both reconcile `MCPServer` CRs. Cut over one cluster at a time — see [Migration](#migration-from-legacy-charts).
</Warning>

## Prerequisites

* Kubernetes 1.24+ (EKS recommended)
* Helm 3.8+
* External platform dependencies provisioned per tenant: RDS/Aurora, Redis, IAM roles, ingress/TLS, Secrets
* Cluster admin access to install CRDs and a cluster-scoped `ClusterRole`

## Install the operator

```bash theme={null}
helm upgrade --install runlayer-operator oci://412677576004.dkr.ecr.us-east-1.amazonaws.com/runlayer-helm-charts/runlayer-operator \
  --version 0.1.1 \
  --namespace runlayer-system --create-namespace \
  -f values-runlayer-operator.yaml
```

Or install from the monorepo chart directory during development:

```bash theme={null}
helm upgrade --install runlayer-operator infra/aws-helm/runlayer-operator \
  --namespace runlayer-system --create-namespace \
  -f infra/aws-helm/runlayer-operator/values.example.yaml
```

The chart ships CRDs under `crds/` on first install. Helm does not upgrade CRDs on subsequent releases — apply CRD updates explicitly before upgrading when the schema changes:

```bash theme={null}
kubectl apply -f infra/aws-helm/runlayer-operator/crds/platform.runlayer.com_runlayerinstances.yaml
kubectl apply -f infra/aws-helm/runlayer-operator/crds/deploy.runlayer.com_mcpservers.yaml
```

Monorepo contributors regenerate chart CRDs from the operator with `cd runlayer-operator && make sync-helm-crds`.

## Configure the operator

Copy and customize values:

```bash theme={null}
cp infra/aws-helm/runlayer-operator/values.example.yaml values-runlayer-operator.yaml
```

Common settings:

| Values key                       | Purpose                                                                                                                    |
| -------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `image.repository` / `image.tag` | Operator container image                                                                                                   |
| `telemetryProxy.*`               | Cluster-wide default MCP telemetry proxy sidecar (overridable per tenant on `RunlayerInstance.spec.deploy.telemetryProxy`) |
| `mcpWorkloads.dedicatedNodes.*`  | Fallback MCP node scheduling when `MCPServer.spec.infrastructure.scheduling` is unset                                      |
| `otel.*`                         | Operator OpenTelemetry traces                                                                                              |
| `metrics.*`                      | Controller-runtime metrics + optional Prometheus `ServiceMonitor`                                                          |

See the chart [README](https://github.com/runlayer/Runlayer/tree/main/infra/aws-helm/runlayer-operator/README.md) and [CHART-DOCS.md](https://github.com/runlayer/Runlayer/tree/main/infra/aws-helm/runlayer-operator/CHART-DOCS.md) for the full values reference.

## Create a tenant

1. **Provision external resources** for the tenant (database, Redis, WorkOS credentials, TLS cert Secret, optional S3/IAM).
2. **Create platform-namespace Secrets** in the tenant platform namespace (default `runlayer-<customerId>`) — the operator never reads Secret payloads; it only references names/keys.

| Secret           | Required keys                                 | Referenced in CR                              |
| ---------------- | --------------------------------------------- | --------------------------------------------- |
| `runlayer-db`    | `username`, `password`                        | `database.credentials.*From`                  |
| `runlayer-redis` | `password` or `REDIS_URL`                     | `redis.credentials.passwordFrom` or `urlFrom` |
| `runlayer-auth`  | `AUTH_CLIENT_ID`, `AUTH_API_KEY`              | `auth.clientIdFrom`, `auth.apiKeyFrom`        |
| `runlayer-app`   | `SECRET_KEY`, `MASTER_SALT` (+ optional keys) | `appSecretRef.name`                           |

See the [RunlayerInstance secrets reference](https://github.com/runlayer/Runlayer/tree/main/runlayer-operator/docs/design/runlayerinstance-crd.md#secrets) for optional component Secrets and env-var mapping.

3. **Apply a `RunlayerInstance`** in `runlayer-system`:

```yaml theme={null}
apiVersion: platform.runlayer.com/v1alpha1
kind: RunlayerInstance
metadata:
  name: acme
  namespace: runlayer-system
spec:
  customerId: acme
  domain: acme.example.com
  environment: production
  version: "1.0.0"
  images:
    backend: <ecr>/runlayer-backend:1.0.0
    frontend: <ecr>/runlayer-frontend:1.0.0
    worker: <ecr>/runlayer-worker:1.0.0
  database:
    host: acme-db.cluster-xxx.us-east-1.rds.amazonaws.com
    credentials:
      usernameFrom: { name: runlayer-db, key: username }
      passwordFrom: { name: runlayer-db, key: password }
  redis:
    host: acme-redis.xxx.cache.amazonaws.com
    credentials:
      passwordFrom: { name: runlayer-redis, key: password }
  auth:
    clientIdFrom: { name: runlayer-auth, key: AUTH_CLIENT_ID }
    apiKeyFrom: { name: runlayer-auth, key: AUTH_API_KEY }
  appSecretRef:
    name: runlayer-app
  deploy:
    enabled: true
  components:
    backend: { enabled: true, replicas: 2 }
    frontend: { enabled: true, replicas: 2 }
    worker: { enabled: true, replicas: 1 }
```

4. Wait for `status.phase: Ready` on the `RunlayerInstance`.
5. Create MCP env Secrets in the tenant MCP namespace, then create `MCPServer` CRs (`runlayer-<customerId>-mcps` by default) or enable backend-managed deploy (`RUNLAYER_DEPLOY=K8S`, ENG-3531).

CRD references:

* [RunlayerInstance](https://github.com/runlayer/Runlayer/tree/main/runlayer-operator/docs/design/runlayerinstance-crd.md) — all spec fields, status, and platform Secrets
* [MCPServer](https://github.com/runlayer/Runlayer/tree/main/runlayer-operator/docs/design/mcpserver-crd.md) — MCP env Secrets and scheduling

## Namespace layout

| Namespace                    | Contents                                            |
| ---------------------------- | --------------------------------------------------- |
| `runlayer-system`            | Operator Deployment, `RunlayerInstance` CRs         |
| `runlayer-<customerId>`      | Platform workloads for one tenant                   |
| `runlayer-<customerId>-mcps` | MCP Deployments and `MCPServer` CRs for that tenant |

## Migration from legacy charts

Per-cluster cutover (high level):

1. Provision unified-path prerequisites if missing.
2. Install `runlayer-operator` on a **greenfield cluster** or during a maintenance window.
3. Create `RunlayerInstance`; verify platform Ready.
4. Migrate MCP workloads to `MCPServer` CRs in the tenant MCP namespace.
5. Switch DNS/traffic to the unified platform ingress.
6. Uninstall legacy `runlayer-deploy-operator` and `anysource-chart` on **that cluster only**.

Detailed plan: [gradual migration plan](https://github.com/runlayer/Runlayer/tree/main/runlayer-operator/docs/design/migration-plan.md).

## Related docs

<CardGroup cols={2}>
  <Card title="Legacy Helm (single tenant)" icon="kubernetes" href="/deployment/helm">
    anysource-chart for traditional single-tenant installs
  </Card>

  <Card title="EKS + Terraform" icon="aws" href="/deployment/eks-terraform">
    Provision EKS, RDS, and Redis before Helm
  </Card>
</CardGroup>
