# Migrate with the Catalyst Kubernetes operator

The Catalyst Kubernetes operator is a Kubernetes-native way to migrate your workloads from Dapr OSS. It can read your existing Dapr resources directly from Kubernetes and only requires you to migrate from the `dapr.io` annotations to the `catalyst.diagrid.io` annotations. It will manage configuring Catalyst for you and integrating your workloads without manual intervention.

## 1. Deploy the operator

**CLI**

You can use the Diagrid CLI to install the Catalyst Kubernetes operator Helm chart into your cluster.

```bash
diagrid k8s-operator install
```

You can also override the Helm values using the `--set` flag:

```bash
diagrid k8s-operator install --set some.helm.value=foo
```

To uninstall the Catalyst Kubernetes operator, run:

```bash
diagrid k8s-operator uninstall
```

**Helm**

You can directly use Helm to install the Catalyst Kubernetes operator into your cluster.

```bash
helm install catalyst-operator oci://public.ecr.aws/diagrid/catalyst-operator \
  --namespace catalyst-system --create-namespace
```

You can uninstall the Catalyst Kubernetes operator with:

```bash
helm uninstall catalyst-operator --namespace catalyst-system
```

See the [Helm chart reference](https://docs.diagrid.io/operate/hosting/enterprise-self-hosted/reference) for the full list of values you can set on the chart.

## 2. Migrate resources

You can use the Diagrid CLI to automatically migrate an existing namespace or you can manually annotation your workloads and Dapr resources within a namespace.

### Add the annotations with the CLI

You can migrate a namespace in-place, which will update the annotations and sidecar on your existing workloads and CRDs to use Catalyst instead of Dapr OSS.

```bash
diagrid k8s-operator migrate my-namespace --project my-project
```

Or you can copy your existing namespace to a new one and only update the copy, leaving the original namespace untouched.

```bash
diagrid k8s-operator migrate my-namespace --project my-project \
  --new-namespace my-namespace-copy
```

We recommend using `--new-namespace` on any real use cases to ensure you can validate the migrated workloads before removing the existing workloads.

If you want to use `local` Dapr Servers, you must add the `--host local` flag to the migrate command:

```bash
diagrid k8s-operator migrate my-namespace --project my-project \
  --host local
```

### Add the annotations manually

You can also manually apply the necessary `catalyst.diagrid.io` annotations to your workloads and Dapr resources.

#### Workloads

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: orders
spec:
  template:
    metadata:
      annotations:
        catalyst.diagrid.io/enabled: "true"
        catalyst.diagrid.io/app-id: "orders"
        catalyst.diagrid.io/provider: "catalyst"          # tells the Catalyst operator to claim this pod
        catalyst.diagrid.io/project: "my-project"         # which Catalyst project to register against
        catalyst.diagrid.io/host: "remote"                # or "local" to inject the sidecar
        catalyst.diagrid.io/app-port: "8080"              # optional
        catalyst.diagrid.io/app-protocol: "grpc"          # optional
```

`catalyst.diagrid.io/host` is the switch between [remote and local location](https://docs.diagrid.io/dapr-open-source/migrate-to-catalyst#dapr-server-location-remote-or-local). The operator reads only the annotations listed above — any `dapr.io/*` annotations on the pod are ignored. To prevent the Dapr OSS operator from also acting on the pod, the Catalyst operator disables the `dapr.io/enabled` annotation whenever `catalyst.diagrid.io/enabled` is present, so you don't get conflicting sidecars.

#### Dapr resources

```yaml
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: orderstate
  annotations:
    catalyst.diagrid.io/project: "my-project"
spec:
  type: state.redis
  version: v1
  metadata:
    - name: redisHost
      value: redis:6379
```

CRDs without `catalyst.diagrid.io/project` are left alone, which is useful for keeping in-cluster Dapr OSS resources side-by-side with Catalyst-managed ones during a phased migration.

## Connecting Catalyst to your app endpoints

Some Dapr APIs require the Dapr server to be able to call endpoints on your application, such as service invocation, input bindings or programmatic pub/sub subscriptions.
When using the Catalyst Kubernetes Operator, all you need to do is ensure you have the following annotation:

```yaml
catalyst.diagrid.io/app-port: "8080" # or whatever port your app listens on
```

For **remote** Dapr servers, the operator will establish a secure tunnel between Catalyst and your app so that traffic can flow without you having to expose the app directly to the Catalyst network.

For **local** Dapr servers (external apps), the operator will set the app's `appEndpoint` to `https://localhost:<app-port>` and the sidecar will route traffic from Catalyst to your app over localhost.

## Next steps

Once your workloads are running on Catalyst, [cut over your traffic and decommission Dapr OSS](https://docs.diagrid.io/dapr-open-source/migrate-to-catalyst/cut-over).
