Creating a Cassandra data store on Linux on Power (ppc64le)

You can install the Cassandra operator and set up the data store.

Before you begin

Make sure that you prepared your online and offline host to pull images from the external repository. Also, ensure that the correct Helm repo is added.

For more information, see Preparing for data store installation.

Cassandra operator versions and image tags for deployment

The following images are needed for the pinned Helm chart or operator versions.

Table 1. Cassandra operator versions and image tags
Platform Operator versions Helm chart version Image with tag
Linux® on Power® (ppc64le) 1.24.0 0.57.4 artifact-public.instana.io/self-hosted-images/3rd-party/operator/cass-operator:1.24.0_v0.25.0

artifact-public.instana.io/self-hosted-images/3rd-party/datastore/k8ssandra-client:0.7.0_v0.16.0

artifact-public.instana.io/self-hosted-images/3rd-party/datastore/cassandra:4.1.8_v0.23.0

artifact-public.instana.io/self-hosted-images/3rd-party/datastore/system-logger:1.24.0_v0.12.0

Creating Security Context Constraints (online and offline)

If you are using a Red Hat® OpenShift® cluster, create a Security Context Constraints (SCC) resource before you deploy the Cassandra operator. You need the SCC resource in both online and offline deployments.

To create the SCC resource, complete the following steps:

  1. Create a file, such as cassandra-scc.yaml, as follows:

    apiVersion: security.openshift.io/v1
    kind: SecurityContextConstraints
    metadata:
      name: cassandra-scc
    runAsUser:
      type: MustRunAs
      uid: 999
    seLinuxContext:
      type: RunAsAny
    fsGroup:
      type: RunAsAny
    allowHostDirVolumePlugin: false
    allowHostNetwork: true
    allowHostPorts: true
    allowPrivilegedContainer: false
    allowHostIPC: true
    allowHostPID: true
    readOnlyRootFilesystem: false
    users:
      - system:serviceaccount:instana-cassandra:cass-operator
      - system:serviceaccount:instana-cassandra:cassandra
    
  2. Apply the file by running the following command:

    kubectl apply -f cassandra-scc.yaml
    

Installing Cassandra online

To install the Cassandra data store in an online environment, complete the following steps:

  1. Create the instana-cassandra namespace:

    kubectl create namespace instana-cassandra
    
  2. Create the cassandra service account.

    kubectl create serviceaccount cassandra -n instana-cassandra
    
  3. Create image pull secrets. Update the <download_key> value with your own download key.

    kubectl create secret docker-registry instana-registry --namespace instana-cassandra \
    --docker-username=_ \
    --docker-password=<download_key> \
    --docker-server=artifact-public.instana.io
    
  4. Install the Cassandra operator.

    helm install cass-operator instana/cass-operator -n instana-cassandra --create-namespace --version=0.57.4 --set securityContext.runAsGroup=999 --set securityContext.runAsGroup=999 --set securityContext.runAsUser=999 --set image.registry=artifact-public.instana.io --set image.repository=self-hosted-images/3rd-party/operator/cass-operator --set image.tag=1.24.0_v0.25.0 --set appVersion=1.24.0  --set imageConfig.k8ssandraClient=artifact-public.instana.io/self-hosted-images/3rd-party/datastore/k8ssandra-client:0.7.0_v0.16.0 --set imageConfig.systemLogger=artifact-public.instana.io/self-hosted-images/3rd-party/datastore/system-logger:1.24.0_v0.12.0 --set imagePullSecrets[0].name="instana-registry"
    
  5. Create a YAML file, for example cassandra.yaml, with the Cassandra configuration.

    apiVersion: cassandra.datastax.com/v1beta1
    kind: CassandraDatacenter
    metadata:
      name: cassandra
    spec:
      clusterName: instana
      serverType: cassandra
      serverImage: artifact-public.instana.io/self-hosted-images/3rd-party/datastore/cassandra:4.1.8_v0.23.0
      systemLoggerImage: artifact-public.instana.io/self-hosted-images/3rd-party/datastore/system-logger:1.24.0_v0.12.0
      k8ssandraClientImage: artifact-public.instana.io/self-hosted-images/3rd-party/datastore/k8ssandra-client:0.7.0_v0.16.0
      serverVersion: "4.1.8"
      imagePullPolicy: IfNotPresent
      podTemplateSpec:
        spec:
          serviceAccountName: cassandra
          imagePullSecrets:
          - name: instana-registry
          containers:
            - name: cassandra
              image: 'artifact-public.instana.io/self-hosted-images/3rd-party/datastore/cassandra:4.1.8_v0.23.0'
              imagePullPolicy: IfNotPresent
              resources:
                requests:
                  memory: "8Gi"  # Adjust based on your available resources
                  cpu: "2"       # Adjust as needed
                limits:
                  memory: "16Gi"  # Adjust to your available resources
                  cpu: "4"        # Adjust as needed
              readinessProbe:
                httpGet:
                  path: /api/v0/probes/readiness
                  port: 8080
                  scheme: HTTP
                initialDelaySeconds: 60  
                timeoutSeconds: 15       
                periodSeconds: 20        
                successThreshold: 1
                failureThreshold: 3
              livenessProbe:
                httpGet:
                  path: /api/v0/probes/liveness
                  port: 8080
                  scheme: HTTP
                initialDelaySeconds: 30  
                timeoutSeconds: 15       
                periodSeconds: 20        
                successThreshold: 1
                failureThreshold: 3
              terminationMessagePath: /dev/termination-log
              lifecycle:
                preStop:
                  exec:
                    command:
                      - curl
                      - '-X'
                      - POST
                      - '-s'
                      - '-m'
                      - '30'  
                      - '-o'
                      - /dev/null
                      - '--show-error'
                      - '--fail'
                      - 'http://localhost:8080/api/v0/ops/node/drain'
              env:
                - name: POD_NAME
                  valueFrom:
                    fieldRef:
                      apiVersion: v1
                      fieldPath: metadata.name
                - name: NODE_NAME
                  valueFrom:
                    fieldRef:
                      apiVersion: v1
                      fieldPath: spec.nodeName
                - name: DS_LICENSE
                  value: accept
                - name: USE_MGMT_API
                  value: 'true'
                - name: MGMT_API_NO_KEEP_ALIVE
                  value: 'true'
                - name: MGMT_API_EXPLICIT_START
                  value: 'true'
              ports:
                - name: native
                  containerPort: 9042
                  protocol: TCP
                - name: tls-native
                  containerPort: 9142
                  protocol: TCP
                - name: internode
                  containerPort: 7000
                  protocol: TCP
                - name: tls-internode
                  containerPort: 7001
                  protocol: TCP
                - name: jmx
                  containerPort: 7199
                  protocol: TCP
                - name: mgmt-api-http
                  containerPort: 8080
                  protocol: TCP
                - name: prometheus
                  containerPort: 9103
                  protocol: TCP
                - name: metrics
                  containerPort: 9000
                  protocol: TCP
              volumeMounts:
                - name: server-logs
                  mountPath: /var/log/cassandra
                - name: server-data
                  mountPath: /var/lib/cassandra
                - name: server-config
                  mountPath: /config
              terminationMessagePolicy: File
            - name: server-system-logger
              image: 'artifact-public.instana.io/self-hosted-images/3rd-party/datastore/system-logger:1.24.0_v0.12.0'
              env:
                - name: POD_NAME
                  valueFrom:
                    fieldRef:
                      apiVersion: v1
                      fieldPath: metadata.name
                - name: NODE_NAME
                  valueFrom:
                    fieldRef:
                      apiVersion: v1
                      fieldPath: spec.nodeName
                - name: CLUSTER_NAME
                  value: instana
                - name: DATACENTER_NAME
                  value: cassandra
                - name: RACK_NAME
                  valueFrom:
                    fieldRef:
                      apiVersion: v1
                      fieldPath: 'metadata.labels[''cassandra.datastax.com/rack'']'
                - name: NAMESPACE
                  valueFrom:
                    fieldRef:
                      apiVersion: v1
                      fieldPath: metadata.namespace
              resources:
                limits:
                  memory: 256Mi  
                requests:
                  cpu: 100m
                  memory: 128Mi
      managementApiAuth:
        insecure: {}  
      size: 3
      allowMultipleNodesPerWorker: false
      storageConfig:
        cassandraDataVolumeClaimSpec:
          accessModes:
            - ReadWriteOnce
          resources:
            requests:
              storage: 200Gi  # Adjust the storage size if necessary
      config:
      jvm-server-options:
        initial_heap_size: "12G"
        max_heap_size: "12G"
        additional-jvm-opts:
          - -Dcassandra.allow_unsafe_aggressive_sstable_expiration=true
      cassandra-yaml:
        authenticator: org.apache.cassandra.auth.PasswordAuthenticator
        authorizer: org.apache.cassandra.auth.CassandraAuthorizer
        role_manager: org.apache.cassandra.auth.CassandraRoleManager
        memtable_flush_writers: 8
        auto_snapshot: false
        gc_warn_threshold_in_ms: 10000
        otc_coalescing_strategy: DISABLED
        memtable_allocation_type: offheap_objects
        num_tokens: 256
        drop_compact_storage_enabled: true
    
  6. Complete the steps in Deploying and verifying Cassandra (online and offline).

Installing Cassandra offline

If you didn't yet pull the Cassandra images from the external registry when you prepared for installation, you can pull them now. Run the following commands on your bastion host. Then, copy the images to your Instana host that is in your air-gapped environment.

docker pull artifact-public.instana.io/ppc64le-oss/cass-operator-ppc64le:1.24.0_v0.25.0
docker pull artifact-public.instana.io/ppc64le-oss/k8ssandra-client-ppc64le:0.7.0_v0.16.0
docker pull artifact-public.instana.io/ppc64le-oss/cass-management-api-ppc64le:4.1.8_v0.23.0
docker pull artifact-public.instana.io/ppc64le-oss/system-logger-ppc64le:1.24.0_v0.12.0

Complete the following steps on your Instana host.

  1. Retag the images to your internal image registry.

    docker tag artifact-public.instana.io/self-hosted-images/3rd-party/operator/cass-operator:1.24.0_v0.25.0 <internal-image-registry>/ppc64le-oss/cass-operator-ppc64le:1.24.0_v0.25.0
    docker tag artifact-public.instana.io/self-hosted-images/3rd-party/datastore/k8ssandra-client:0.7.0_v0.16.0 <internal-image-registry>/ppc64le-oss/k8ssandra-client-ppc64le:0.7.0_v0.16.0
    docker tag artifact-public.instana.io/self-hosted-images/3rd-party/datastore/cassandra:4.1.8_v0.23.0 <internal-image-registry>/ppc64le-oss/cass-management-api-ppc64le:4.1.8_v0.23.0
    docker tag artifact-public.instana.io/self-hosted-images/3rd-party/datastore/system-logger:1.24.0_v0.12.0<internal-image-registry>/ppc64le-oss/system-logger-ppc64le:1.24.0_v0.12.0
    
  2. Push the images to your internal image registry on your bastion host.

    docker push <internal-image-registry>/ppc64le-oss/cass-operator-ppc64le:1.24.0_v0.25.0
    docker push <internal-image-registry>/ppc64le-oss/k8ssandra-client-ppc64le:0.7.0_v0.16.0
    docker push <internal-image-registry>/ppc64le-oss/cass-management-api-ppc64le:4.1.8_v0.23.0
    docker push <internal-image-registry>/ppc64le-oss/system-logger-ppc64le:1.24.0_v0.12.0
    
  3. Create the instana-cassandra namespace:

    kubectl create namespace instana-cassandra
    
  4. Create the cassandra service account.

    kubectl create serviceaccount cassandra -n instana-cassandra
    
  5. Optional: Create an image pull secret if your internal image registry needs authentication.

    kubectl create secret docker-registry <secret_name> --namespace instana-cassandra \
    --docker-username=<registry_username> \
    --docker-password=<registry_password> \
    --docker-server=<internal-image-registry>:<internal-image-registry-port> \
    --docker-email=<registry_email>
    
  6. Install the Cassandra operator. If you created an image pull secret in the previous step, add --set imagePullSecrets[0].name="<internal-image-registry-pull-secret>" to the following command.

    helm install cass-operator cass-operator-0.57.4.tgz -n instana-cassandra --create-namespace --version=0.57.4 --set securityContext.runAsGroup=999 --set securityContext.runAsGroup=999 --set securityContext.runAsUser=999 --set image.registry=<internal-image-registry> --set image.repository=ppc64le-oss/cass-operator-ppc64le --set image.tag=1.24.0_v0.25.0 --set appVersion=1.24.0  --set imageConfig.k8ssandraClient=<internal-image-registry>/ppc64le-oss/k8ssandra-client-ppc64le:0.7.0_v0.16.0 --set imageConfig.systemLogger=<internal-image-registry>/ppc64le-oss/system-logger-ppc64le:1.24.0_v0.12.0
    
  7. Create a YAML file, for example cassandra.yaml, with the Cassandra configuration:

    apiVersion: cassandra.datastax.com/v1beta1
    kind: CassandraDatacenter
    metadata:
      name: cassandra
    spec:
      clusterName: instana
      serverType: cassandra
      serverImage: <internal-image-registry>/ppc64le-oss/cass-management-api-ppc64le:4.1.8_v0.23.0
      systemLoggerImage: <internal-image-registry>/ppc64le-oss/system-logger-ppc64le:1.24.0_v0.12.0
      k8ssandraClientImage: <internal-image-registry>/ppc64le-oss/k8ssandra-client-ppc64le:0.7.0_v0.16.0
      serverVersion: "4.1.2"
      imagePullPolicy: IfNotPresent
      podTemplateSpec:
        spec:
        # Optional: if you created an image pull secret for your internal registry, uncomment the following lines and update the image pull secret information.
        # imagePullSecrets:
        #   - name: <internal-image-registry-pull-secret>
          serviceAccountName: cassandra
          containers:
          - name: cassandra
      managementApiAuth:
        insecure: {}
      size: 3
      allowMultipleNodesPerWorker: false
      storageConfig:
        cassandraDataVolumeClaimSpec:
          accessModes:
            - ReadWriteOnce
          resources:
            requests:
              storage: 200Gi
      config:
        jvm-server-options:
          initial_heap_size: "12G"
          max_heap_size: "12G"
          additional-jvm-opts:
            - -Dcassandra.allow_unsafe_aggressive_sstable_expiration=true
        cassandra-yaml:
          authenticator: org.apache.cassandra.auth.PasswordAuthenticator
          authorizer: org.apache.cassandra.auth.CassandraAuthorizer
          role_manager: org.apache.cassandra.auth.CassandraRoleManager
          memtable_flush_writers: 8
          auto_snapshot: false
          gc_warn_threshold_in_ms: 10000
          otc_coalescing_strategy: DISABLED
          memtable_allocation_type: offheap_objects
          num_tokens: 256
          drop_compact_storage_enabled: true
    
  8. Complete the steps in Deploying and verifying Cassandra (online and offline).

Deploying and verifying Cassandra (online and offline)

When you deploy Cassandra, the CassandraDatacenter by default creates a superuser, for example <clustername>-superuser. The <clustername> is the value that is specified in .spec.clusterName section in the cassandra.yaml file. In the following commands, the secret name instana-superuser is used as an example.

To deploy the Cassandra instance and create the data store, complete the following steps:

  1. Deploy Cassandra by running the following command.

    kubectl apply -f cassandra.yaml --namespace=instana-cassandra
    
  2. Retrieve the password of the instana-superuser.

    kubectl get secret instana-superuser -n instana-cassandra --template='{{index .data.password | base64decode}}' && echo
    
  3. Store the password in the config.yaml file. Replace <RETRIEVED_FROM_SECRET> with the password that you got in the previous step.

    datastoreConfigs:
      ...
      cassandraConfigs:
        - user: instana-superuser
          password: <RETRIEVED_FROM_SECRET>
          adminUser: instana-superuser
          adminPassword: <RETRIEVED_FROM_SECRET>
      ...
    
  4. Verify the deployment of the Cassandra data store.

    kubectl get all -n instana-cassandra
    
  5. If the Cassandra data store is deployed successfully, then the result of the command might be as the following output:

    NAME                                  READY   STATUS    RESTARTS   AGE
    pod/cass-operator-57dcc8884f-92knc    1/1     Running   0          36m
    pod/instana-cassandra-default-sts-0   2/2     Running   0          26m
    pod/instana-cassandra-default-sts-1   2/2     Running   0          26m
    pod/instana-cassandra-default-sts-2   2/2     Running   0          26m
    
    NAME                                                TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)                                        AGE
    service/cass-operator-webhook-service               ClusterIP   192.168.1.55   <none>        443/TCP                                        36m
    service/instana-cassandra-additional-seed-service   ClusterIP   None           <none>        <none>                                         26m
    service/instana-cassandra-all-pods-service          ClusterIP   None           <none>        9042/TCP,8080/TCP,9103/TCP,9000/TCP            26m
    service/instana-cassandra-service                   ClusterIP   None           <none>        9042/TCP,9142/TCP,8080/TCP,9103/TCP,9000/TCP   26m
    service/instana-seed-service                        ClusterIP   None           <none>        <none>                                         26m
    
    NAME                            READY   UP-TO-DATE   AVAILABLE   AGE
    deployment.apps/cass-operator   1/1     1            1           36m
    
    NAME                                       DESIRED   CURRENT   READY   AGE
    replicaset.apps/cass-operator-57dcc8884f   1         1         1       36m
    
    NAME                                             READY   AGE
    statefulset.apps/instana-cassandra-default-sts   3/3     26m