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:
-
Scaling down the standalone K8ssandra operator deployments (not the Cassandra cluster itself).
-
Installing Mission Control with its embedded
k8ssandra-operator. -
Allowing Mission Control’s embedded operator to automatically adopt and manage the existing
K8ssandraClusterresources.
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
K8ssandraClusterresources -
Optional: Reaper and Medusa configured
-
-
Access to the Kubernetes cluster with
kubectlconfigured -
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:
-
Go to IBM Container Library.
-
Sign in with an IBM ID.
-
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:
-
List your K8ssandra clusters:
kubectl get k8ssandracluster --all-namespaces -
Check the cluster status:
kubectl describe k8ssandracluster CLUSTER_NAME -n NAMESPACEReplace the following:
-
CLUSTER_NAME: The name of your K8ssandra cluster -
NAMESPACE: The namespace where your cluster is running
-
-
Verify all pods are running:
kubectl get pods -n NAMESPACEReplace
NAMESPACEwith the namespace where your cluster is running. -
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
-
-
Export the
K8ssandraClusterspecification:kubectl get k8ssandracluster CLUSTER_NAME -n NAMESPACE -o yaml > k8ssandra-cluster-backup.yamlReplace 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 |
-
Scale down the main K8ssandra operator:
kubectl scale deployment RELEASE_NAME -n K8SSANDRA_NAMESPACE --replicas=0Replace the following:
-
RELEASE_NAME: The Helm release name used when installing the K8ssandra operator. -
K8SSANDRA_NAMESPACE: The namespace where the K8ssandra operator is installed.
-
-
Scale down the
cass-operator:kubectl scale deployment RELEASE_NAME-cass-operator -n K8SSANDRA_NAMESPACE --replicas=0 -
Verify that both operators are scaled down:
kubectl get deployments -n K8SSANDRA_NAMESPACEBoth deployments should show
0/0ready replicas. -
Remove K8ssandra webhooks to prevent validation conflicts:
kubectl delete validatingwebhookconfiguration RELEASE_NAME-validating-webhook-configuration kubectl delete mutatingwebhookconfiguration RELEASE_NAME-mutating-webhook-configurationYour 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:
-
Create the namespace:
kubectl create namespace NAMESPACEReplace
NAMESPACEwith the namespace where you want to install Mission Control. -
Verify the Mission Control installation:
kubectl get pods -n NAMESPACEWait for all Mission Control pods to be in
Runningstate. -
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.
-
Retrieve your existing
K8ssandraClusterspec:kubectl get k8ssandracluster CLUSTER_NAME -n NAMESPACE -o yamlReplace the following:
-
CLUSTER_NAME: The name of your K8ssandra cluster -
NAMESPACE: The namespace where your cluster is running
-
-
Create a
MissionControlClustermanifest that embeds theK8ssandraClusterspec in thespec.k8ssandrafield.The
metadata.namemust match the name of your existingK8ssandraClusterexactly. Thespec.k8ssandrafield must contain the full contents of your existingK8ssandraClusterspecsection. OmitapiVersion,kind,metadata, andstatus.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 fieldsReplace 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
-
-
Apply the manifest:
kubectl apply -f missioncontrolcluster.yaml -
Verify the
MissionControlClusterobject 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:
-
Monitor the Mission Control
k8ssandra-operatorlogs:kubectl logs -f deployment/mission-control-k8ssandra-operator -n NAMESPACEReplace
NAMESPACEwith the namespace where your cluster is running.Look for log entries indicating the operator has discovered and is managing your
K8ssandraCluster. -
Verify the
K8ssandraClusterstatus:kubectl get k8ssandracluster CLUSTER_NAME -n NAMESPACEReplace 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.
-
-
Check the
CassandraDatacenterstatus:kubectl get cassandradatacenter -n NAMESPACEThe datacenter should show
Readystatus. -
Verify all Cassandra pods are running:
kubectl get pods -n NAMESPACE | grep cassandraAll Cassandra pods should show
Runningstate with all containers ready. -
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:
-
Connect to the database and query your data:
-
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
-
-
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
-
-
-
Verify cluster health with
nodetool:kubectl exec POD_NAME -n NAMESPACE -c cassandra -- nodetool statusReplace the following:
-
POD_NAME: Name of a Cassandra pod -
NAMESPACE: The namespace where your cluster is runningAll nodes should show
UN(Up/Normal) status.
-
-
If using Reaper, verify that it is still running:
kubectl get pods -n NAMESPACE | grep reaper -
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.
-
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.
-
If you have Reaper configured:
-
Access the Reaper UI or use the Mission Control UI to view repair schedules.
-
Verify existing repair schedules remain active.
-
Test running a new repair to confirm Reaper integration.
-
-
If you have Medusa configured:
-
Check that backup schedules remain active:
kubectl get cassandratask -n NAMESPACEReplace
NAMESPACEwith the namespace where your cluster is running. -
Verify backup storage connectivity.
-
Test creating a new backup to confirm Medusa integration.
-
-
Check that the Mission Control observability components are running:
kubectl get pods -n mission-control | grep -E "loki|mimir|minio" -
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_NAMEReplace 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:
-
Verify that both K8ssandra operators are scaled to zero:
kubectl get deployments -n K8SSANDRA_NAMESPACEReplace
K8SSANDRA_NAMESPACEwith the namespace where K8ssandra operator is installed. -
Verify that you deleted all webhooks for your original K8ssandra release:
kubectl get validatingwebhookconfiguration | grep k8ssandra kubectl get mutatingwebhookconfiguration | grep k8ssandra -
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-configurationReplace
RELEASE_NAMEwith the Helm release name for your original K8ssandra operator installation.
Pods not starting
If pods are in a restart loop, do the following:
-
Check the pod logs:
kubectl logs POD_NAME -n NAMESPACE -c cassandraReplace the following:
-
POD_NAME: Name of the pod that is not starting -
NAMESPACE: The namespace where your cluster is running
-
-
Verify that the Management API is responding:
kubectl exec POD_NAME -n NAMESPACE -c cassandra -- \ curl -s http://localhost:8080/api/v0/probes/readiness -
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:
-
Check pod logs:
kubectl logs -n mission-control POD_NAMEReplace
POD_NAMEwith the name of the pod that is not starting. -
Check PVC binding:
kubectl get pvc -n mission-control -
Verify storage class configuration:
kubectl get storageclass
Cluster not being adopted
If Mission Control doesn’t adopt your existing cluster, do the following:
-
Verify the cluster name matches exactly:
kubectl get k8ssandracluster -n NAMESPACEReplace
NAMESPACEwith the namespace where your cluster is running. -
Review Mission Control
k8ssandra-operatorlogs:kubectl logs -n mission-control deployment/mission-control-k8ssandra-operator -
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:
-
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_NAMESPACEwith the namespace where K8ssandra operator is installed. -
Verify that Mission Control includes a compatible
cass-operatorversion. 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:
-
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 -
Reinstall K8ssandra webhooks with the original configuration.
-
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=1Replace the following:
-
RELEASE_NAME: The Helm release name of your K8ssandra operator installation -
K8SSANDRA_NAMESPACE: The namespace where K8ssandra operator is installed
-
-
Verify that K8ssandra resumes management of your cluster:
kubectl get k8ssandraclusters -n NAMESPACE kubectl logs deployment/RELEASE_NAME -n K8SSANDRA_NAMESPACE --tail=50Replace 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
-
-
For a permanent rollback, remove Mission Control:
helm uninstall mission-control -n mission-control kubectl delete namespace mission-control -
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
-
Explore Mission Control features like automated backups
-
Configure monitoring and alerting
-
Learn about cluster upgrades