You are looking at the documentation of a prior release. To read the documentation of the latest release, please
visit here.
New to KubeDB? Please start here.
Cassandra QuickStart
This tutorial will show you how to use KubeDB to run an Apache Cassandra.
Before You Begin
At first, you need to have a Kubernetes cluster, and the kubectl
command-line tool must be configured to communicate with your cluster. If you do not already have a cluster, you can create one by using kind.
Now, install KubeDB cli on your workstation and KubeDB operator in your cluster following the steps here and make sure to include the flags --set global.featureGates.Cassandra=true
to ensure Cassandra CRD with helm command.
To keep things isolated, this tutorial uses a separate namespace called demo
throughout this tutorial.
$ kubectl create namespace demo
namespace/demo created
$ kubectl get namespace
NAME STATUS AGE
demo Active 9s
Note: YAML files used in this tutorial are stored in guides/cassandra/quickstart/overview/yamls folder in GitHub repository kubedb/docs.
Find Available StorageClass
We will have to provide StorageClass
in Cassandra CRD specification. Check available StorageClass
in your cluster using the following command,
$ kubectl get storageclass
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 14h
Here, we have standard
StorageClass in our cluster from Local Path Provisioner.
Find Available CassandraVersion
When you install the KubeDB operator, it registers a CRD named CassandraVersion. The installation process comes with a set of tested CassandraVersion objects. Let’s check available CassandraVersions by,
$ kubectl get cassandraversion
NAME VERSION DB_IMAGE DEPRECATED AGE
4.1.8 4.1.8 ghcr.io/appscode-images/cassandra-management:4.1.8 3m50s
5.0.3 5.0.3 ghcr.io/appscode-images/cassandra-management:5.0.3 3m50s
In this tutorial, we will use 5.0.3
CassandraVersion CR to create a Cassandra cluster.
Create a Cassandra Cluster
The KubeDB operator implements a Cassandra CRD to define the specification of Cassandra.
The Cassandra instance used for this tutorial:
apiVersion: kubedb.com/v1alpha2
kind: Cassandra
metadata:
name: cassandra-quickstart
namespace: demo
spec:
version: 5.0.3
topology:
rack:
- name: r0
replicas: 2
storage:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 600Mi
deletionPolicy: Delete
Here,
spec.version
- is the name of the CassandraVersion CR. Here, a Cassandra of version5.0.3
will be created.spec.topology
- is the definition of the topology that will be deployed. This contains an array of racks definition.spec.deletionPolicy
specifies what KubeDB should do when a user try to delete Cassandra CR. Deletion policyDelete
will delete the database pods and PVC when the Cassandra CR is deleted.
Let’s create the Cassandra CR that is shown above:
$ kubectl apply -f https://github.com/kubedb/docs/raw/v2025.10.17/docs/examples/cassandra/quickstart/cassandra-quickstart.yaml
cassandra.kubedb.com/cassandra-quickstart created
The Cassandra’s STATUS
will go from Provisioning
to Ready
state within few minutes. Once the STATUS
is Ready
, you are ready to use the newly provisioned Cassandra cluster.
$ kubectl get cassandra -n demo -w
NAME TYPE VERSION STATUS AGE
cassandra-quickstart kubedb.com/v1alpha2 5.0.3 Provisioning 17s
cassandra-quickstart kubedb.com/v1alpha2 5.0.3 Provisioning 28s
.
.
cassandra-quickstart kubedb.com/v1alpha2 5.0.3 Ready 82s
Describe the Cassandra object to observe the progress if something goes wrong or the status is not changing for a long period of time:
$ kubectl describe cassandra -n demo cassandra-quickstart
Name: cassandra-quickstart
Namespace: demo
Labels: <none>
Annotations: <none>
API Version: kubedb.com/v1alpha2
Kind: Cassandra
Metadata:
Creation Timestamp: 2025-07-14T05:57:35Z
Finalizers:
kubedb.com/cassandra
Generation: 3
Resource Version: 4981
UID: 702f26e3-a02a-428a-9688-f0f2508ec662
Spec:
Auth Secret:
Name: cassandra-quickstart-auth
Auto Ops:
Deletion Policy: Delete
Health Checker:
Failure Threshold: 3
Period Seconds: 20
Timeout Seconds: 10
Topology:
Rack:
Name: r0
Pod Template:
Controller:
Metadata:
Spec:
Containers:
Name: cassandra
Resources:
Limits:
Memory: 1Gi
Requests:
Cpu: 500m
Memory: 1Gi
Security Context:
Allow Privilege Escalation: false
Capabilities:
Drop:
ALL
Run As Non Root: true
Run As User: 999
Seccomp Profile:
Type: RuntimeDefault
Init Containers:
Name: cassandra-init
Resources:
Security Context:
Allow Privilege Escalation: false
Capabilities:
Drop:
ALL
Run As Non Root: true
Run As User: 999
Seccomp Profile:
Type: RuntimeDefault
Pod Placement Policy:
Name: default
Security Context:
Fs Group: 999
Replicas: 2
Storage:
Access Modes:
ReadWriteOnce
Resources:
Requests:
Storage: 600Mi
Storage Type: Durable
Version: 5.0.3
Status:
Conditions:
Last Transition Time: 2025-07-14T06:02:12Z
Message: All replicas are ready
Observed Generation: 3
Reason: AllReplicasReady
Status: True
Type: ReplicaReady
Last Transition Time: 2025-07-14T05:57:38Z
Message: The KubeDB operator has started the provisioning of Cassandra: demo/cassandra-quickstart
Observed Generation: 2
Reason: ProvisioningStarted
Status: True
Type: ProvisioningStarted
Last Transition Time: 2025-07-14T07:44:35Z
Message: The Cassandra: demo/cassandra-quickstart is accepting client requests
Observed Generation: 3
Reason: AcceptingConnection
Status: True
Type: AcceptingConnection
Last Transition Time: 2025-07-14T07:44:35Z
Message: database demo/cassandra-quickstart is ready
Observed Generation: 3
Reason: AllReplicasReady
Status: True
Type: Ready
Last Transition Time: 2025-07-14T06:03:39Z
Message: The Cassandra: demo/cassandra-quickstart is successfully provisioned.
Observed Generation: 3
Reason: DatabaseSuccessfullyProvisioned
Status: True
Type: Provisioned
Phase: Ready
Events: <none>
KubeDB Operator Generated Resources
On deployment of a Cassandra CR, the operator creates the following resources:
$ kubectl get all,secret,petset -n demo -l 'app.kubernetes.io/instance=cassandra-quickstart'
NAME READY STATUS RESTARTS AGE
pod/cassandra-quickstart-rack-r0-0 1/1 Running 0 108m
pod/cassandra-quickstart-rack-r0-1 1/1 Running 0 103m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/cassandra-quickstart ClusterIP 10.43.56.40 <none> 9042/TCP,7000/TCP,7199/TCP,7001/TCP 108m
service/cassandra-quickstart-rack-r0-pods ClusterIP None <none> 9042/TCP,7000/TCP,7199/TCP,7001/TCP 108m
NAME TYPE VERSION AGE
appbinding.appcatalog.appscode.com/cassandra-quickstart kubedb.com/cassandra 5.0.3 108m
NAME TYPE DATA AGE
secret/cassandra-quickstart-auth kubernetes.io/basic-auth 2 108m
secret/cassandra-quickstart-config Opaque 1 108m
NAME AGE
petset.apps.k8s.appscode.com/cassandra-quickstart-rack-r0 108m
PetSet
- In topology mode, the operator creates 1 PetSet for each rack with name{Cassandra-Name}-rack-{Rack-Name}
.Services
- For topology mode, 1 headless service for each PetSet with name{PetSet-Name}-{pods}
is created. Other than that, 1 more service with name{Cassandra-Name}-{Sufix}
is created.AppBinding
- an AppBinding which hold to connect information for the Cassandra. Like other resources, it is named after the Cassandra instance.Secrets
- A secret is generated for each Cassandra cluster.{Cassandra-Name}-auth
- the auth secrets which hold theusername
andpassword
for the Cassandra users. Operator generates credentials foradmin
user and creates a secret for authentication.
Connect with Cassandra database
Now, you can connect to this database using cqlsh
. You will need username
and password
to connect to this database from kubeclt exec
command. In this example, cassandra-quickstart-auth
secret holds username and password.
$ kubectl get secrets -n demo cassandra-quickstart-auth -o jsonpath='{.data.\username}' | base64 -d
admin
$ kubectl get secrets -n demo cassandra-quickstart-auth -o jsonpath='{.data.\password}' | base64 -d
9sPN85ctoRTnWEQV
We will exec into the pod cassandra-quickstart-rack-r0-0
and connect to the database using username
and password
.
kubectl exec -it -n demo cassandra-quickstart-rack-r0-0 -- cqlsh -u admin -p '9sPN85ctoRTnWEQV'
Defaulted container "cassandra" out of: cassandra, cassandra-init (init), medusa-init (init)
Warning: Using a password on the command line interface can be insecure.
Recommendation: use the credentials file to securely provide the password.
Connected to Test Cluster at 127.0.0.1:9042
[cqlsh 6.2.0 | Cassandra 5.0.3 | CQL spec 3.4.7 | Native protocol v5]
Use HELP for help.
admin@cqlsh> describe keyspaces;
kubedb_keyspace system_auth system_schema system_views
system system_distributed system_traces system_virtual_schema
Cleaning up
To clean up the Kubernetes resources created by this tutorial, run:
$ kubectl patch -n demo cassandra cassandra-quickstart -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge"
cassandra.kubedb.com/cassandra-quickstart patched
$ kubectl delete cas cassandra-quickstart -n demo
cassandra.kubedb.com "cassandra-quickstart" deleted
$ kubectl delete namespace demo
namespace "demo" deleted
Next Steps
- Want to hack on KubeDB? Check our contribution guidelines.