tree: 497fe8f9361341ec57acb2f2124c563318dad93c [path history] [tgz]
  1. .gitignore
  2. .helmignore
  3. Chart.yaml
  5. crds/
  6. requirements.yaml
  7. templates/
  8. values.yaml


NEXUS is an earth science data analytics application, and a component of the Apache Science Data Analytics Platform (SDAP).


The helm chart deploys all the required components of the NEXUS application (Spark webapp, Solr, Cassandra, Zookeeper, and optionally ingress components).

Table of Contents


  • Kubernetes 1.9+
  • Spark Operator
  • Storage class and persistent volume provisioner in the underlying infrastructure

Spark Operator

NEXUS needs the Spark Operator in order to run. Follow their instructions to install the Helm chart, or simply run:

$ kubectl create namespace spark-operator
$ helm repo add incubator
$ helm install incubator/sparkoperator --generate-name --namespace=spark-operator

Persistent Volume Provisioner

NEXUS stores data in Cassandra and Solr. In order to have persistent storage, you need to have a Storage Class defined and have Persistent Volumes provisioned either manually or dynamically. See Persistent Volumes.

Tip: If you are using an NFS server as storage, you can use nfs-client-provisioner to dynamically provision persistent volumes on your NFS server.

Installing the Chart

First clone the NEXUS repository.

$ git clone

Then install the Helm chart.

$ kubectl create namespace sdap
$ helm install nexus incubator-sdap-nexus/helm --namespace=sdap --dependency-update

Tip: It may take a few minutes for the nexus-webapp-driver pod to start up because this depends on Solr and Cassandra being accessible.

Verifying Successful Installation

Check that all the pods are up by running kubectl get pods -n sdap, and make sure all pods have status Running. If any pods have not started within a few minutes, you can look at its status with `kubectl describe pod -n sdap.

Option 1: Local deployment with ingress enabled

If you have installed the Helm chart locally with ingressEnabled set to true (see ingressEnabled under Configuration), you can verify the installation by requesting the list endpoint. If this returns an HTTP 200 response, Nexus is healthy.

$ curl localhost/nexus/list

Option 2: No ingress enabled

If you have installed the Helm chart on a cloud provider, and/or have not enabled a loadbalancer with ingressEnabled=true, you can temporarily port-forward the nexus-webapp port to see if the webapp responds.

First, on the Kubernetes cluster or jump host, create a port-forward to the nexus-webapp service:

$ kubectl port-forward service/nexus-webapp -n sdap 8083:8083

Then open another shell on the same host and request the list endpoint through the forwarded port:

$ curl localhost:8083/list

Note: In this case the list endpoint is /list instead of /nexus/list because we are connecting to the nexus-webapp service directly, instead of through an ingress rule.

If the request returns an HTTP 200 response, NEXUS is healthy. You can now close the first shell to disable the port-forward.

If one of the pods or deployment is not started, you can look at its status with:

kubectl describe pod <pod-name> -n sdap

Uninstalling the Chart

To uninstall/delete the nexus deployment:

$ helm delete nexus -n sdap

The command removes all the Kubernetes components associated with the chart and deletes the release.


There are two ways to override configuration values for the chart. The first is to use the --set flag when installing the chart, for example:

$ helm install nexus incubator-sdap-nexus/helm --namespace=sdap --dependency-update --set cassandra.replicas=3 --set solr.replicas=3

The second way is to create a yaml file with overridden configuration values and pass it in with the -f flag during chart installation.

# overridden-values.yml

  replicas: 2
  replicas: 2
$ helm install nexus incubator-sdap-nexus/helm --namespace=sdap --dependency-update -f ~/overridden-values.yml

The following table lists the configurable parameters of the NEXUS chart and their default values. You can also look at helm/values.yaml to see the available options.

Note: The default configuration values are tuned to run NEXUS in a local environment. Setting ingressEnabled=true in addition will create a load balancer and expose NEXUS at localhost.

storageClassStorage class to use for Cassandra, Solr, and Zookeeper. (Note that hostpath should only be used in local deployments.)hostpath
webapp.distributed.imageDocker image and tag for the webappnexusjpl/nexus-webapp:distributed.0.1.5
webapp.distributed.driver.coresNumber of cores on Spark driver1
webapp.distributed.driver.coreLimitMaximum cores on Spark driver, in millicpus1200m
webapp.distributed.driver.memoryMemory on Spark driver512m
webapp.distributed.driver.tolerationsTolerations for Spark drivernil
webapp.distributed.driver.affinityAffinity (node or pod) for Spark drivernil
webapp.distributed.executor.coresNumber of cores on Spark workers1
webapp.distributed.executor.instancesNumber of Spark workers2
webapp.distributed.executor.memoryMemory on Spark workers512m
webapp.distributed.executor.tolerationsTolerations for Spark workersnil
webapp.distributed.executor.affinityAffinity (node or pod) for Spark workersnil
cassandra.replicasNumber of Cassandra replicas2
cassandra.storageStorage per Cassandra replica13Gi
cassandra.requests.cpuCPUs to request per Cassandra replica1
cassandra.requests.memoryMemory to request per Cassandra replica3Gi
cassandra.limits.cpuCPU limit per Cassandra replica1
cassandra.limits.memoryMemory limit per Cassandra replica3Gi
cassandra.tolerationsTolerations for Cassandra instances[]
cassandra.nodeSelectorNode selector for Cassandra instancesnil
solr.replicasNumber of Solr replicas (this should not be less than 2, or else solr-cloud will not be happy)2
solr.storageStorage per Solr replica10Gi
solr.heapHeap per Solr replica4g
solr.requests.memoryMemory to request per Solr replica5Gi
solr.requests.cpuCPUs to request per Solr replica1
solr.limits.memoryMemory limit per Solr replica5Gi
solr.limits.cpuCPU limit per Solr replica1
solr.tolerationsTolerations for Solr instancesnil
solr.nodeSelectorNode selector for Solr instancesnil
zookeeper.replicasNumber of zookeeper replicas. This should be an odd number greater than or equal to 3 in order to form a valid quorum.3
zookeeper.memoryMemory per zookeeper replica1Gi
zookeeper.cpuCPUs per zookeeper replica0.5
zookeeper.storageStorage per zookeeper replica8Gi
zookeeper.tolerationsTolerations for Zookeeper instancesnil
zookeeper.nodeSelectorNode selector for Zookeeper instancesnil
onEarthProxyIPIP or hostname to proxy /onearth to (leave blank to disable the proxy)""
ingressEnabledEnable nginx-ingressfalse
nginx-ingress.controller.scope.enabledLimit the scope of the ingress controller to this namespacetrue
nginx-ingress.controller.kindInstall ingress controller as Deployment, DaemonSet or BothDaemonSet
nginx-ingress.controller.service.enabledCreate a front-facing controller service (this might be used for local or on-prem deployments)true
nginx-ingress.controller.service.typeType of controller service to createLoadBalancer
nginx-ingress.defaultBackend.enabledUse default backend componentfalse
rabbitmq.replicaCountNumber of RabbitMQ replicas2
rabbitmq.auth.usernameRabbitMQ usernameguest
rabbitmq.auth.passwordRabbitMQ passwordguest
rabbitmq.ingress.enabledEnable ingress resource for RabbitMQ Management consoletrue
ingestion.enabledEnable ingestion by deploying the Config Operator, Collection Manager, Granule Ingestion, and RabbitMQtrue
ingestion.granuleIngester.replicasNumber of Granule Ingester replicas2
ingestion.granuleIngester.imageDocker image and tag for Granule Ingesternexusjpl/granule-ingester:0.0.1
ingestion.granuleIngester.cpuCPUs (request and limit) for each Granule Ingester replica1
ingestion.granuleIngester.memoryMemory (request and limit) for each Granule Ingester replica1Gi
ingestion.collectionManager.imageDocker image and tag for Collection Managernexusjpl/collection-manager:0.0.2
ingestion.collectionManager.cpuCPUs (request and limit) for the Collection Manager0.5
ingestion.collectionManager.memoryMemory (request and limit) for the Collection Manager0.5Gi
ingestion.configOperator.imageDocker image and tag for Config Operatornexusjpl/config-operator:0.0.1
ingestion.granules.nfsServerAn optional URL to an NFS server containing a directory where granule files are stored. If set, this NFS server will be mounted in the Collection Manager and Granule Ingester pods.nil
ingestion.granules.mountPathThe path in the Collection Manager and Granule Ingester pods where granule files will be mounted. Important: the path property on all collections in the Collections Config file should match this value./data
ingestion.granules.pathDirectory on either the local filesystem or an NFS mount where granule files are located. This directory will be mounted onto the Collection Manager and Granule Ingester at ingestion.granules.mountPath./var/lib/sdap/granules
ingestion.collections.git.urlURL to a Git repository containing a Collections Config file. The file should be at the root of the repository. The repository URL should be of the form This property must be configured if ingestion is enabled!nil
ingestion.collections.git.branchBranch to use when loading a Collections Config file from a Git repository.master
ingestion.history.urlAn optional URL to a Solr database in which to store ingestion history. If this is not set, ingestion history will be stored in a directory instead, with the storage class configured by storageClass above.nil

Restricting Pods to Specific Nodes

Sometimes you may wish to restrict pods to run on specific nodes, for example if you have “UAT” and “SIT” nodes within the same cluster. You can configure node selectors and tolerations for all the components, as in the following example:

        - key: environment
          operator: Equal
          value: uat
          effect: NoExecute
            - matchExpressions:
              - key: environment
                operator: In
                - uat
        - key: environment
          operator: Equal
          value: uat
          effect: NoExecute
            - matchExpressions:
              - key: environment
                operator: In
                - uat

    - key: environment
      operator: Equal
      value: uat
      effect: NoExecute
    environment: uat 

    - key: environment
      operator: Equal
      value: uat
      effect: NoExecute
    environment: uat 

    - key: environment
      operator: Equal
      value: uat
      effect: NoExecute
    environment: uat 

Note: The webapp supports affinity instead of nodeSelector because the Spark Operator has deprecated nodeSelector in favor of affinity.