Migrate K8ssandra clusters to Mission Control

This guide explains how to migrate your existing K8ssandra-managed clusters to Mission Control management without requiring data migration or creating new clusters. This is an in-place migration that preserves your existing cluster, data, and operational tools, including Reaper and Medusa.

This migration path is only for clusters currently managed by the K8ssandra operator. If you have a standalone Apache Cassandra® cluster not managed by K8ssandra, see Migrate Apache Cassandra® clusters by adding a new cluster.

The migration works by:

  1. Scaling down the standalone K8ssandra operator deployments (not the Cassandra cluster itself).

  2. Installing Mission Control with its embedded k8ssandra-operator.

  3. Allowing Mission Control’s embedded operator to automatically adopt and manage the existing K8ssandraCluster resources.

After migration, you manage your clusters through MissionControlCluster objects instead of K8ssandraCluster objects directly. The underlying K8ssandraCluster resources still exist, but Mission Control owns and configures them. Any direct changes made to a K8ssandraCluster object after migration will be reverted the next time the Mission Control reconciler runs. There are no competing operators because Mission Control includes the same cass-operator that K8ssandra uses, plus additional management capabilities.

Prerequisites

  • An existing K8ssandra-managed cluster with the following:

    • K8ssandra operator installed

    • One or more K8ssandraCluster resources

    • Optional: Reaper and Medusa configured

  • Access to the Kubernetes cluster with kubectl configured

  • Cluster admin permissions

  • An IBMid: An IBMid account with MFA enabled is required. If you don’t have one, create an IBMid account. If your organization uses Enterprise Federation (EF) for authentication with corporate credentials, see the IBMid EF documentation.

  • An IBM entitlement key:

    1. Go to IBM Container Library.

    2. Sign in with an IBM ID.

    3. Click Get entitlement key (or Copy key if one already exists).

  • Helm 3.8 or later

Verify and back up your existing cluster configuration

Before migration, verify that your K8ssandra clusters are healthy, and then document their configuration:

  1. List your K8ssandra clusters:

    kubectl get k8ssandracluster --all-namespaces
  2. Check the cluster status:

    kubectl describe k8ssandracluster CLUSTER_NAME -n NAMESPACE

    Replace the following:

    • CLUSTER_NAME: The name of your K8ssandra cluster

    • NAMESPACE: The namespace where your cluster is running

  3. Verify all pods are running:

    kubectl get pods -n NAMESPACE

    Replace NAMESPACE with the namespace where your cluster is running.

  4. Document your cluster configuration details:

    • Cluster name and namespace

    • The number of datacenters and nodes

    • The Cassandra version

    • Reaper and Medusa configuration

    • Storage class and volume sizes

    • Superuser secret name

  5. Export the K8ssandraCluster specification:

    kubectl get k8ssandracluster CLUSTER_NAME -n NAMESPACE -o yaml > k8ssandra-cluster-backup.yaml

    Replace the following:

    • CLUSTER_NAME: The name of your K8ssandra cluster

    • NAMESPACE: The namespace where your cluster is running

Scale down K8ssandra operators

Scale down both K8ssandra operator deployments to prevent conflicts with Mission Control.

You must scale down both the main K8ssandra operator and the cass-operator deployment. Scaling down only one results in competing operators.

  1. Scale down the main K8ssandra operator:

    kubectl scale deployment RELEASE_NAME -n K8SSANDRA_NAMESPACE --replicas=0

    Replace the following:

    • RELEASE_NAME: The Helm release name used when installing the K8ssandra operator.

    • K8SSANDRA_NAMESPACE: The namespace where the K8ssandra operator is installed.

  2. Scale down the cass-operator:

    kubectl scale deployment RELEASE_NAME-cass-operator -n K8SSANDRA_NAMESPACE --replicas=0
  3. Verify that both operators are scaled down:

    kubectl get deployments -n K8SSANDRA_NAMESPACE

    Both deployments should show 0/0 ready replicas.

  4. Remove K8ssandra webhooks to prevent validation conflicts:

    kubectl delete validatingwebhookconfiguration RELEASE_NAME-validating-webhook-configuration
    kubectl delete mutatingwebhookconfiguration RELEASE_NAME-mutating-webhook-configuration

    Your Cassandra cluster continues running during this step. Only the operator management layer is affected.

Install Mission Control

Using Helm and your entitlement key, install Mission Control on the same cluster where you had installed K8ssandra:

  1. Create the namespace:

    kubectl create namespace NAMESPACE

    Replace NAMESPACE with the namespace where you want to install Mission Control.

  2. Install Mission Control.

  3. Verify the Mission Control installation:

    kubectl get pods -n NAMESPACE

    Wait for all Mission Control pods to be in Running state.

  4. Verify the embedded operators are running:

    kubectl get deployment -n NAMESPACE | grep -E "operator|ui"

    You should see the following deployments ready:

    • mission-control-k8ssandra-operator

    • mission-control-cass-operator

    • mission-control-operator

    • mission-control-ui

Create a MissionControlCluster object

Create a MissionControlCluster object that wraps your existing K8ssandraCluster spec. The object must use the same name as your existing K8ssandraCluster so that Mission Control can adopt it.

  1. Retrieve your existing K8ssandraCluster spec:

    kubectl get k8ssandracluster CLUSTER_NAME -n NAMESPACE -o yaml

    Replace the following:

    • CLUSTER_NAME: The name of your K8ssandra cluster

    • NAMESPACE: The namespace where your cluster is running

  2. Create a MissionControlCluster manifest that embeds the K8ssandraCluster spec in the spec.k8ssandra field.

    The metadata.name must match the name of your existing K8ssandraCluster exactly. The spec.k8ssandra field must contain the full contents of your existing K8ssandraCluster spec section. Omit apiVersion, kind, metadata, and status.

    apiVersion: mission-control.k8ssandra.io/v1alpha1
    kind: MissionControlCluster
    metadata:
      name: CLUSTER_NAME
      namespace: NAMESPACE
    spec:
      k8ssandra:
        # Paste the full spec section from your existing K8ssandraCluster here.
        datacenters:
          - metadata:
              name: DATACENTER_NAME
            size: NODE_COUNT
            # ... remaining K8ssandraCluster spec fields

    Replace the following:

    • CLUSTER_NAME: The name of your existing K8ssandra cluster

    • NAMESPACE: The namespace where your cluster is running

    • DATACENTER_NAME: The name of your datacenter

    • NODE_COUNT: The number of nodes in your datacenter

  3. Apply the manifest:

    kubectl apply -f missioncontrolcluster.yaml
  4. Verify the MissionControlCluster object was created:

    kubectl get missioncontrolcluster CLUSTER_NAME -n NAMESPACE

Verify cluster adoption

After creating the MissionControlCluster object, verify that Mission Control adopts your existing cluster:

  1. Monitor the Mission Control k8ssandra-operator logs:

    kubectl logs -f deployment/mission-control-k8ssandra-operator -n NAMESPACE

    Replace NAMESPACE with the namespace where your cluster is running.

    Look for log entries indicating the operator has discovered and is managing your K8ssandraCluster.

  2. Verify the K8ssandraCluster status:

    kubectl get k8ssandracluster CLUSTER_NAME -n NAMESPACE

    Replace the following:

    • CLUSTER_NAME: The name of your K8ssandra cluster

    • NAMESPACE: The namespace where your cluster is running

    The cluster should show a healthy status.

  3. Check the CassandraDatacenter status:

    kubectl get cassandradatacenter -n NAMESPACE

    The datacenter should show Ready status.

  4. Verify all Cassandra pods are running:

    kubectl get pods -n NAMESPACE | grep cassandra

    All Cassandra pods should show Running state with all containers ready.

  5. Verify cross-namespace RBAC is configured:

    kubectl get clusterrolebinding | grep mission-control

Validate data integrity

Verify that your data remains intact and accessible after migration:

  1. Connect to the database and query your data:

    1. Get the superuser credentials for you database:

      CASS_USERNAME=$(kubectl get secret SUPERUSER_SECRET -n NAMESPACE -o jsonpath='{.data.username}' | base64 -d)
      CASS_PASSWORD=$(kubectl get secret SUPERUSER_SECRET -n NAMESPACE -o jsonpath='{.data.password}' | base64 -d)

      Replace the following:

      • SUPERUSER_SECRET: The name of your superuser secret

      • NAMESPACE: The namespace where your cluster is running

    2. Query a table in your database:

      kubectl exec POD_NAME -n NAMESPACE -c cassandra -- \
        cqlsh -u $CASS_USERNAME -p $CASS_PASSWORD \
        -e "SELECT * FROM KEYSPACE.TABLE;"

      Replace the following:

      • POD_NAME: Name of a Cassandra pod

      • NAMESPACE: The namespace where your cluster is running

      • KEYSPACE: Your keyspace name

      • TABLE: Your table name

  2. Verify cluster health with nodetool:

    kubectl exec POD_NAME -n NAMESPACE -c cassandra -- nodetool status

    Replace the following:

    • POD_NAME: Name of a Cassandra pod

    • NAMESPACE: The namespace where your cluster is running

      All nodes should show UN (Up/Normal) status.

  3. If using Reaper, verify that it is still running:

    kubectl get pods -n NAMESPACE | grep reaper
  4. If using Medusa, verify that it is still running:

    kubectl get pods -n NAMESPACE | grep medusa

Post-migration tasks

After successful migration, verify that you can access the management capabilities provided by Mission Control, and, after a period of stability, remove the original K8ssandra operator resources.

If you encounter any issues or need to rollback the migration, see Troubleshooting or Rollback a failed migration.

  1. If you installed the Mission Control UI, you can now manage your cluster through the web interface.

    For UI access instructions, see Access Mission Control’s UI.

  2. If you have Reaper configured:

    1. Access the Reaper UI or use the Mission Control UI to view repair schedules.

    2. Verify existing repair schedules remain active.

    3. Test running a new repair to confirm Reaper integration.

  3. If you have Medusa configured:

    1. Check that backup schedules remain active:

      kubectl get cassandratask -n NAMESPACE

      Replace NAMESPACE with the namespace where your cluster is running.

    2. Verify backup storage connectivity.

    3. Test creating a new backup to confirm Medusa integration.

  4. Check that the Mission Control observability components are running:

    kubectl get pods -n mission-control | grep -E "loki|mimir|minio"
  5. After Mission Control successfully manages your cluster for at least 30 days, you can remove the original K8ssandra operator resources.

    Only do this after your cluster has been stable for at least 30 days after migrating to Mission Control.

    kubectl delete deployment K8SSANDRA_RELEASE_NAME -n K8SSANDRA_NAMESPACE
    kubectl delete deployment K8SSANDRA_RELEASE_NAME-cass-operator -n K8SSANDRA_NAMESPACE
    kubectl delete serviceaccount K8SSANDRA_RELEASE_NAME -n K8SSANDRA_NAMESPACE
    kubectl delete clusterrolebinding K8SSANDRA_RELEASE_NAME
    kubectl delete clusterrole K8SSANDRA_RELEASE_NAME

    Replace the following:

    • K8SSANDRA_RELEASE_NAME: The Helm release name of your K8ssandra operator installation

    • K8SSANDRA_NAMESPACE: The namespace where K8ssandra operator is installed

Troubleshooting

If you encounter issues during or after migration, use the following troubleshooting steps to resolve common problems.

If these troubleshooting steps don’t resolve the issue, see Support for Mission Control.

Competing operators error

If you see errors about competing operators or webhook conflicts, do the following:

  1. Verify that both K8ssandra operators are scaled to zero:

    kubectl get deployments -n K8SSANDRA_NAMESPACE

    Replace K8SSANDRA_NAMESPACE with the namespace where K8ssandra operator is installed.

  2. Verify that you deleted all webhooks for your original K8ssandra release:

    kubectl get validatingwebhookconfiguration | grep k8ssandra
    kubectl get mutatingwebhookconfiguration | grep k8ssandra
  3. If any of the original webhooks still exist, delete them manually.

    Only delete the webhooks belonging to your original K8ssandra release. Do not delete the webhooks belonging to your new Mission Control release, or your migrated cluster will stop working correctly.

    kubectl delete validatingwebhookconfiguration RELEASE_NAME-validating-webhook-configuration
    kubectl delete mutatingwebhookconfiguration RELEASE_NAME-mutating-webhook-configuration

    Replace RELEASE_NAME with the Helm release name for your original K8ssandra operator installation.

Pods not starting

If pods are in a restart loop, do the following:

  1. Check the pod logs:

    kubectl logs POD_NAME -n NAMESPACE -c cassandra

    Replace the following:

    • POD_NAME: Name of the pod that is not starting

    • NAMESPACE: The namespace where your cluster is running

  2. Verify that the Management API is responding:

    kubectl exec POD_NAME -n NAMESPACE -c cassandra -- \
      curl -s http://localhost:8080/api/v0/probes/readiness
  3. Check for resource constraints or storage issues:

    kubectl describe pod POD_NAME -n NAMESPACE

Mission Control pods not starting

If Mission Control pods fail to start, do the following:

  1. Check pod logs:

    kubectl logs -n mission-control POD_NAME

    Replace POD_NAME with the name of the pod that is not starting.

  2. Check PVC binding:

    kubectl get pvc -n mission-control
  3. Verify storage class configuration:

    kubectl get storageclass

Cluster not being adopted

If Mission Control doesn’t adopt your existing cluster, do the following:

  1. Verify the cluster name matches exactly:

    kubectl get k8ssandracluster -n NAMESPACE

    Replace NAMESPACE with the namespace where your cluster is running.

  2. Review Mission Control k8ssandra-operator logs:

    kubectl logs -n mission-control deployment/mission-control-k8ssandra-operator
  3. Check for RBAC issues:

    kubectl get clusterrolebinding | grep mission-control

Operator version drift

If you encounter issues due to operator version differences, do the following:

  1. Check the K8ssandra operator version you were using:

    kubectl get deployment RELEASE_NAME -n K8SSANDRA_NAMESPACE -o jsonpath='{.spec.template.spec.containers[0].image}'

    Replace K8SSANDRA_NAMESPACE with the namespace where K8ssandra operator is installed.

  2. Verify that Mission Control includes a compatible cass-operator version. Review the Mission Control release notes for compatibility information.

Rollback a failed migration

Only perform a rollback if the migration has failed and your cluster is not functioning properly.

If you need to rollback to K8ssandra management, do the following:

  1. Scale down Mission Control operators:

    kubectl scale deployment mission-control-k8ssandra-operator -n mission-control --replicas=0
    kubectl scale deployment mission-control-cass-operator -n mission-control --replicas=0
  2. Reinstall K8ssandra webhooks with the original configuration.

  3. Scale K8ssandra operators back up:

    kubectl scale deployment RELEASE_NAME -n K8SSANDRA_NAMESPACE --replicas=1
    kubectl scale deployment RELEASE_NAME-cass-operator -n K8SSANDRA_NAMESPACE --replicas=1

    Replace the following:

    • RELEASE_NAME: The Helm release name of your K8ssandra operator installation

    • K8SSANDRA_NAMESPACE: The namespace where K8ssandra operator is installed

  4. Verify that K8ssandra resumes management of your cluster:

    kubectl get k8ssandraclusters -n NAMESPACE
    kubectl logs deployment/RELEASE_NAME -n K8SSANDRA_NAMESPACE --tail=50

    Replace the following:

    • RELEASE_NAME: The Helm release name of your K8ssandra operator installation

    • NAMESPACE: The namespace where your cluster is running

    • K8SSANDRA_NAMESPACE: The namespace where K8ssandra operator is installed

  5. For a permanent rollback, remove Mission Control:

    helm uninstall mission-control -n mission-control
    kubectl delete namespace mission-control
  6. If needed, restore your K8ssandra configuration from the backup YAML file:

    kubectl apply -f k8ssandra-cluster-backup.yaml
    kubectl apply -f superuser-secret-backup.yaml

Next steps

Was this helpful?

Give Feedback

How can we improve the documentation?

© Copyright IBM Corporation 2026 | Privacy policy | Terms of use Manage Privacy Choices

Apache, Apache Cassandra, Cassandra, Apache Tomcat, Tomcat, Apache Lucene, Apache Solr, Apache Hadoop, Hadoop, Apache Pulsar, Pulsar, Apache Spark, Spark, Apache TinkerPop, TinkerPop, Apache Kafka and Kafka are either registered trademarks or trademarks of the Apache Software Foundation or its subsidiaries in Canada, the United States and/or other countries. Kubernetes is the registered trademark of the Linux Foundation.

General Inquiries: Contact IBM