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 apply
command to create a headless service:kubectl apply -f - <<EOF
apiVersion: v1
kind: Service
metadata:
labels:
app: cassandra
name: cassandra
spec:
clusterIP: None
ports:
- port: 9042
selector:
app: cassandra
EOFservice/cassandra created
Note the following about this service:
- The
spec.clusterIP
field is set toNone
. - The
spec.selector.app
field 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 apply
command to create a storage class:kubectl apply -f - <<EOF
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: portworx-sc
provisioner: pxd.portworx.com
parameters:
repl: "1"
priority_io: "high"
group: "cassandra_vg"
fg: "true"
EOFstorageclass.storage.k8s.io/px-storageclass created
Note 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
StorageClass
object 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 - <<EOF
apiVersion: "apps/v1"
kind: StatefulSet
metadata:
name: cassandra
spec:
selector:
matchLabels:
app: cassandra
serviceName: cassandra
replicas: 3
template:
metadata:
labels:
app: cassandra
spec:
schedulerName: stork
containers:
- name: cassandra
image: gcr.io/google-samples/cassandra:v12
imagePullPolicy: Always
ports:
- containerPort: 7000
name: intra-node
- containerPort: 7001
name: tls-intra-node
- containerPort: 7199
name: jmx
- containerPort: 9042
name: cql
resources:
limits:
cpu: "500m"
memory: 1Gi
requests:
cpu: "500m"
memory: 1Gi
securityContext:
capabilities:
add:
- IPC_LOCK
lifecycle:
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_SIZE
value: 512M
- name: HEAP_NEWSIZE
value: 100M
- name: CASSANDRA_SEEDS
value: "cassandra-0.cassandra.default.svc.cluster.local"
- name: CASSANDRA_CLUSTER_NAME
value: "K8Demo"
- name: CASSANDRA_DC
value: "DC1-K8Demo"
- name: CASSANDRA_RACK
value: "Rack1-K8Demo"
- name: CASSANDRA_AUTO_BOOTSTRAP
value: "false"
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
readinessProbe:
exec:
command:
- /bin/bash
- -c
- /ready-probe.sh
initialDelaySeconds: 40
timeoutSeconds: 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-data
mountPath: /var/lib/cassandra
# These are converted to volume claims by the controller
# and mounted at the paths mentioned above.
volumeClaimTemplates:
- metadata:
name: cassandra-data
annotations:
volume.beta.kubernetes.io/storage-class: portworx-sc
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 1Gi
EOFstatefulset.apps/cassandra configured
Validate the cluster functionality
-
Use the
kubectl get pvc
command to verify that the PVCs are bound to your persistent volumes:kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
cassandra-data-cassandra-0 Bound pvc-a9fbca67-713c-4442-xxxx-cafaaf5e20ad 1Gi RWO portworx-sc <unset> 4m41s
cassandra-data-cassandra-1 Bound pvc-e6d39f88-0ea0-47a9-xxxx-c8f5a073d0de 1Gi RWO portworx-sc <unset> 3m22s
cassandra-data-cassandra-2 Bound pvc-2cf36362-12e8-4527-xxxx-1b6a2391c073 1Gi RWO portworx-sc <unset> 2m21s -
Verify that Kubernetes created the
portworx-sc
storage class:kubectl get storageclass
NAME TYPE
portworx-sc pxd.portworx.com -
List your pod:
kubectl get pods
NAME READY STATUS RESTARTS AGE
cassandra-0 1/1 Running 0 8m47s
cassandra-1 1/1 Running 0 7m29s
cassandra-2 1/1 Running 0 6m28s -
Use the
pxctl volume list
command 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 list
ID NAME SIZE HA SHARED ENCRYPTED PROXY-VOLUME IO_PRIORITY STATUS SNAP-ENABLED
120416509069581339 pvc-2cf36362-12e8-4527-xxxx-1b6a2391c073 1 GiB 1 no no no HIGH up - attached on 10.13.xxx.x6 no
583995935441831735 pvc-a9fbca67-713c-4442-xxxx-cafaaf5e20ad 1 GiB 1 no no no HIGH up - attached on 10.13.xxx.xx8 no
1014207801779375780 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 inspect
command, specifying the ID from the previous step. The following example command uses120416509069581339
:pxctl volume inspect 120416509069581339
Volume : 120416509069581339
Name : pvc-2cf36362-12e8-4527-xxxx-1b6a2391c073
Group : cassandra_vg
Size : 1.0 GiB
Format : ext4
HA : 1
IO Priority : HIGH
Creation time : Sep 23 07:29:14 UTC 2024
Shared : no
Status : up
State : Attached: xxxxxxxx-xxxx-xxxx-xxxx-7ee8b9b8c659 (10.13.xxx.x6)
Last Attached : Sep 23 07:29:16 UTC 2024
Device Path : /dev/pxd/pxd120416509069581xx9
Labels : app=cassandra,fg=true,group=cassandra_vg,namespace=default,priority_io=high,pvc=cassandra-data-cassandra-2,repl=1
Mount Options : discard
Reads : 51
Reads MS : 8
Bytes Read : 413696
Writes : 31
Writes MS : 88
Bytes Written : 16867328
IOs in progress : 0
Bytes used : 624 KiB
Replica sets on nodes:
Set 0
Node : 10.13.xxx.x6
Pool UUID : 99c52975-711a-47ed-xxxx-8a2eeb68615a
Replication Status : Up
Volume consumers :
- Name : cassandra-2 (f6a48a84-3da1-48d7-xxxx-18493effc8bf) (Pod)
Namespace : default
Running on : ip-10-13-xxx-x6.pwx.purestorage.com
Controlled by : cassandra (StatefulSet)Note that this volume is up and the volume consumer is the
cassandra-2
pod. 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 exec
command, specifying your Pod name. This example opens thecassandra-0
Pod:kubectl exec -it cassandra-0 -- bash
-
Use the
nodetool status
command to retrieve information about your Cassandra set up:nodetool status
Datacenter: DC1-K8Demo
======================
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
-- Address Load Tokens Owns (effective) Host ID Rack
UN 10.2xx.xx.xx0 65.66 KiB 32 64.7% 315bd721-aadd-40a0-xxxx-10ac4e5ff668 Rack1-K8Demo
UN 10.2xx.xx.xx8 101.01 KiB 32 61.9% 2e686b0f-fd34-4456-xxxx-f664dbd36da6 Rack1-K8Demo
UN 10.2xx.xx.x 65.66 KiB 32 73.4% 6eccbd09-8641-43b3-xxxx-bac12293b1f9 Rack1-K8Demo -
Terminate the shell session:
exit