Install
Prerequisites
- You must have a Kubernetes cluster with a minimum of three worker nodes.
- Portworx is installed on your Kubernetes cluster. For details about how you can install Portworx on Kubernetes, see the Portworx on Kubernetes page.
- You must have Stork installed on your Kubernetes cluster. For details about how you can install Stork, see the Stork page.
Install Cassandra
-
Enter the following
kubectl applycommand to create a headless service:kubectl apply -f - <<EOFapiVersion: v1kind: Servicemetadata:labels:app: cassandraname: cassandraspec:clusterIP: Noneports:- port: 9042selector:app: cassandraEOFservice/cassandra createdNote the following about this service:
- The
spec.clusterIPfield is set toNone. - The
spec.selector.appfield is set tocassandra. The Kubernetes endpoints controller will configure the DNS to return addresses that point directly to your Cassandra Pods.
-
Use the following
kubectl applycommand to create a storage class:kubectl apply -f - <<EOFkind: StorageClassapiVersion: storage.k8s.io/v1metadata:name: portworx-scprovisioner: pxd.portworx.comparameters:repl: "1"priority_io: "high"group: "cassandra_vg"fg: "true"EOFstorageclass.storage.k8s.io/px-storageclass createdNote the following about this storage class:
- The provisioner field is set to
pxd.portworx.com. For details about the Portworx-specific parameters, refer to the Portworx Volume section of the Kubernetes documentation - The name of the
StorageClassobject isportworx-sc - Portworx will create one replica of each volume
- Portworx will use a high priority storage pool
-
The following command creates a stateful set with three replicas and uses the STORK scheduler to place your Pods closer to where their data is located:
kubectl apply -f - <<EOFapiVersion: "apps/v1"kind: StatefulSetmetadata:name: cassandraspec:selector:matchLabels:app: cassandraserviceName: cassandrareplicas: 3template:metadata:labels:app: cassandraspec:schedulerName: storkcontainers:- name: cassandraimage: gcr.io/google-samples/cassandra:v12imagePullPolicy: Alwaysports:- containerPort: 7000name: intra-node- containerPort: 7001name: tls-intra-node- containerPort: 7199name: jmx- containerPort: 9042name: cqlresources:limits:cpu: "500m"memory: 1Girequests:cpu: "500m"memory: 1GisecurityContext:capabilities:add:- IPC_LOCKlifecycle:preStop:exec:command: ["/bin/sh", "-c", "PID=$(pidof java) && kill $PID && while ps -p $PID > /dev/null; do sleep 1; done"]env:- name: MAX_HEAP_SIZEvalue: 512M- name: HEAP_NEWSIZEvalue: 100M- name: CASSANDRA_SEEDSvalue: "cassandra-0.cassandra.default.svc.cluster.local"- name: CASSANDRA_CLUSTER_NAMEvalue: "K8Demo"- name: CASSANDRA_DCvalue: "DC1-K8Demo"- name: CASSANDRA_RACKvalue: "Rack1-K8Demo"- name: CASSANDRA_AUTO_BOOTSTRAPvalue: "false"- name: POD_IPvalueFrom:fieldRef:fieldPath: status.podIP- name: POD_NAMESPACEvalueFrom:fieldRef:fieldPath: metadata.namespacereadinessProbe:exec:command:- /bin/bash- -c- /ready-probe.shinitialDelaySeconds: 40timeoutSeconds: 40# These volume mounts are persistent. They are like inline claims,# but not exactly because the names need to match exactly one of# the stateful pod volumes.volumeMounts:- name: cassandra-datamountPath: /var/lib/cassandra# These are converted to volume claims by the controller# and mounted at the paths mentioned above.volumeClaimTemplates:- metadata:name: cassandra-dataannotations:volume.beta.kubernetes.io/storage-class: portworx-scspec:accessModes: [ "ReadWriteOnce" ]resources:requests:storage: 1GiEOFstatefulset.apps/cassandra configured
Validate the cluster functionality
-
Use the
kubectl get pvccommand to verify that the PVCs are bound to your persistent volumes:kubectl get pvcNAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGEcassandra-data-cassandra-0 Bound pvc-a9fbca67-713c-4442-xxxx-cafaaf5e20ad 1Gi RWO portworx-sc <unset> 4m41scassandra-data-cassandra-1 Bound pvc-e6d39f88-0ea0-47a9-xxxx-c8f5a073d0de 1Gi RWO portworx-sc <unset> 3m22scassandra-data-cassandra-2 Bound pvc-2cf36362-12e8-4527-xxxx-1b6a2391c073 1Gi RWO portworx-sc <unset> 2m21s -
Verify that Kubernetes created the
portworx-scstorage class:kubectl get storageclassNAME TYPEportworx-sc pxd.portworx.com -
List your pod:
kubectl get podsNAME READY STATUS RESTARTS AGEcassandra-0 1/1 Running 0 8m47scassandra-1 1/1 Running 0 7m29scassandra-2 1/1 Running 0 6m28s -
Use the
pxctl volume listcommand to display the list of volumes in your cluster by running the following command on one of the pods that has Portworx installed:pxctl volume listID NAME SIZE HA SHARED ENCRYPTED PROXY-VOLUME IO_PRIORITY STATUS SNAP-ENABLED120416509069581339 pvc-2cf36362-12e8-4527-xxxx-1b6a2391c073 1 GiB 1 no no no HIGH up - attached on 10.13.xxx.x6 no583995935441831735 pvc-a9fbca67-713c-4442-xxxx-cafaaf5e20ad 1 GiB 1 no no no HIGH up - attached on 10.13.xxx.xx8 no1014207801779375780 pvc-e6d39f88-0ea0-47a9-xxxx-c8f5a073d0de 1 GiB 1 no no no HIGH up - attached on 10.13.xxx.xx0 noMake a note of the ID of your volume. You'll need it in the next step.
-
To verify that your Portworx volumes has one replica, enter the
pxctl volume inspectcommand, specifying the ID from the previous step. The following example command uses120416509069581339:pxctl volume inspect 120416509069581339Volume : 120416509069581339Name : pvc-2cf36362-12e8-4527-xxxx-1b6a2391c073Group : cassandra_vgSize : 1.0 GiBFormat : ext4HA : 1IO Priority : HIGHCreation time : Sep 23 07:29:14 UTC 2024Shared : noStatus : upState : Attached: xxxxxxxx-xxxx-xxxx-xxxx-7ee8b9b8c659 (10.13.xxx.x6)Last Attached : Sep 23 07:29:16 UTC 2024Device Path : /dev/pxd/pxd120416509069581xx9Labels : app=cassandra,fg=true,group=cassandra_vg,namespace=default,priority_io=high,pvc=cassandra-data-cassandra-2,repl=1Mount Options : discardReads : 51Reads MS : 8Bytes Read : 413696Writes : 31Writes MS : 88Bytes Written : 16867328IOs in progress : 0Bytes used : 624 KiBReplica sets on nodes:Set 0Node : 10.13.xxx.x6Pool UUID : 99c52975-711a-47ed-xxxx-8a2eeb68615aReplication Status : UpVolume consumers :- Name : cassandra-2 (f6a48a84-3da1-48d7-xxxx-18493effc8bf) (Pod)Namespace : defaultRunning on : ip-10-13-xxx-x6.pwx.purestorage.comControlled by : cassandra (StatefulSet)Note that this volume is up and the volume consumer is the
cassandra-2pod. If you want to have more replicas of volume, increase the replica count while creating the StorageClassportworx-sc. Please ensure you accordingly increase the worker nodes also and Portworx is installed on all the node to avoid preemption issues. -
Show the list of your Pods and the hosts on which Kubernetes scheduled them:
kubectl get pods -l app=cassandra -o json | jq '.items[] | {"name": .metadata.name,"hostname": .spec.nodeName, "hostIP": .status.hostIP, "PodIP": .status.podIP}'{"name": "cassandra-0","hostname": "ip-10-13-xxx-xx8.pwx.purestorage.com","hostIP": "10.xx.xxx.xx8","PodIP": "10.xxx.xx.xx8"}{"name": "cassandra-1","hostname": "ip-10-13-xxx-xx0.pwx.purestorage.com","hostIP": "10.xx.xxx.xx0","PodIP": "10.xxx.xx.xx0"}{"name": "cassandra-2","hostname": "ip-10-13-xxx-x6.pwx.purestorage.com","hostIP": "10.xx.xxx.xx6","PodIP": "10.xx.xxx.x"} -
To open a shell session into one of your Pods, enter the following
kubectl execcommand, specifying your Pod name. This example opens thecassandra-0Pod:kubectl exec -it cassandra-0 -- bash -
Use the
nodetool statuscommand to retrieve information about your Cassandra set up:nodetool statusDatacenter: DC1-K8Demo======================Status=Up/Down|/ State=Normal/Leaving/Joining/Moving-- Address Load Tokens Owns (effective) Host ID RackUN 10.2xx.xx.xx0 65.66 KiB 32 64.7% 315bd721-aadd-40a0-xxxx-10ac4e5ff668 Rack1-K8DemoUN 10.2xx.xx.xx8 101.01 KiB 32 61.9% 2e686b0f-fd34-4456-xxxx-f664dbd36da6 Rack1-K8DemoUN 10.2xx.xx.x 65.66 KiB 32 73.4% 6eccbd09-8641-43b3-xxxx-bac12293b1f9 Rack1-K8Demo -
Terminate the shell session:
exit