Helm Chart Installation

Installation Requirements

  • Kubectl: Default Kubernetes CLI.
  • Helm: Application deployment is done using Helm 3. Download and install the Helm client binary to the workstation that you plan to use for GoodData.CN installation.
  • Permissions: You need admin-level permissions on two Kubernetes namespaces (described below):
    • pulsar - for Apache Pulsar deployment
    • gooddata-cn - for GoodData.CN deployment


Choose Hostname

To make GoodData.CN accessible to users, you need a DNS hostname for the application Ingress resource. This hostname must belong to a domain you have under your control.

You may use, for example, gooddata-cn.company.com or analytics.company.com.

This hostname will be referred to as an Ingress host later in this guide.

You may need an additional hostname for the internal OIDC identity provider bundled with the GoodData.CN helmchart. If you have your own OIDC provider, you do not need this additional hostname.

You may use, for example, auth.company.com.

If you do not use an External DNS as suggested above, add the new hostname to your DNS server manually.

The type of the record should be one of the following:

  • A - if you want to point to the IP address of the Load balancer representing your Ingress host
  • CNAME - if you want to refer to an existing Load balancer hostname.

Note that adding a DNS record is not necessary if you already have a matching wildcard DNS record pointing to your Load balancer (such as *.company.com in our example).

Get TLS Certificate

GoodData.CN does not use (Transport Layer Security) TLS encryption. Instead, it is assumed that the TLS encryption is terminated on the load balancer because hardware load balancers have highly optimized SSL accelerators and offer better throughput.

Acquire the TLS certificate for the Ingress hostname that you chose. This process may vary depending on the Certification Authority you are using. See TLS Configuration under Deployment Considerations.

You should have two files:

  • the public server certificate
  • the private server key

Upload both files to your Load balancer.

Pull Application Images to Your Registry (Air-gapped installations only)

If your Kubernetes cluster runs in a secure, isolated environment without access to the Internet, you need to pull all required images from the GoodData docker registry and Docker hub, and push them to a private docker registry that your cluster can access.

You will need the following images:

  • Apache Pulsar
    • apachepulsar/pulsar:2.9.2
  • GoodData.CN
    • gooddata/afm-exec-api:${TAG}
    • gooddata/analytical-designer:${TAG}
    • gooddata/apidocs:${TAG}
    • gooddata/aqe:${TAG}
    • gooddata/auth-service:${TAG}
    • gooddata/dashboards:${TAG}
    • gooddata/home-ui:${TAG}
    • gooddata/ldm-modeler:${TAG}
    • gooddata/metadata-api:${TAG}
    • gooddata/result-cache:${TAG}
    • gooddata/scan-model:${TAG}
    • gooddata/sql-executor:${TAG}
    • gooddata/tools:${TAG}
    • gooddata/dex:${TAG}
  • GoodData.CN subcharts
    • docker.io/bitnami/minideb:buster
    • docker.io/bitnami/pgpool:4.2.0-debian-10-r20
    • docker.io/bitnami/postgres-exporter:0.8.0-debian-10-r304
    • docker.io/bitnami/postgresql-repmgr:11.10.0-debian-10-r38
    • docker.io/oliver006/redis_exporter:v1.13.1
    • docker.io/library/redis:6.0.7-alpine

Get Helm Charts

Pulsar is deployed from Apache’s Helm repository. Register this repository within your Helm client first.

helm repo add apache https://pulsar.apache.org/charts


"apache" has been added to your repositories

Add the GoodData Helm repository.

helm repo add gooddata https://charts.gooddata.com/


"gooddata" has been added to your repositories

Create Kubernetes Namespaces

As a cluster administrator, create the following two namespaces:

kubectl apply -f - << END
apiVersion: v1
kind: Namespace
  name: pulsar
    metadata.labels.kubernetes.io/metadata.name: pulsar


namespace/pulsar created
kubectl apply -f - << END
apiVersion: v1
kind: Namespace
  name: gooddata-cn
    metadata.labels.kubernetes.io/metadata.name: gooddata-cn


namespace/gooddata-cn created

For the rest of the installation process, the user running Helm has sufficient permissions in these two namespaces.

Install NGINX Ingress

If you already have your Kubernetes cluster with NGINX Ingress deployed, you do not need to perform any actions. GoodData.CN will work with your existing NGINX Ingress installation. Otherwise, it is required to deploy it.

Create NGINX Ingress Namespace

kubectl apply -f - << END
apiVersion: v1
kind: Namespace
  name: ingress-nginx
    metadata.labels.kubernetes.io/metadata.name: ingress-nginx


namespace/ingress-nginx created

Add the NGINX Ingress Helm repository

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx

Prepare customized values.yaml for for NGINX Ingress. Refer AWS specific documentation for additional requirements if you deploy this Ingress Controller behind AWS Elastic LoadBalancer.

    # This should improve performance
    client-body-buffer-size: '1m'
    # This should resolve possible issue with big headers
    proxy-buffer-size: '16k'

Install the NGINX Ingress

helm -n ingress-nginx install ingress-nginx ingress-nginx/ingress-nginx \
  --set controller.replicaCount=2


Use Customized values.yaml for Pulsar

Apache Pulsar is a scalable high-performance message broker. Default values from the original Helm chart are oversized for our needs. To decrease the resource requirements, you should use the following customized settings:

The storageClass will differ on different cloud providers and Kubernetes installations.

Keep the file customized-values-pulsar.yaml for future reference and upgrades.

# file name: customized-values-pulsar.yaml
  functions: false
  proxy: false
  pulsar_manager: false
  toolset: false
  alert_manager: false
  grafana: false
  node_exporter: false
  prometheus: false
    repository: apachepulsar/pulsar
    repository: apachepulsar/pulsar
    repository: apachepulsar/pulsar
    repository: apachepulsar/pulsar
      name: data
      size: 2Gi
      storageClassName: mystorageclass
  # this line is needed only if you're upgrading existing release of Pulsar chart < 2.7.11
  # see https://github.com/apache/pulsar-helm-chart/pull/203#issuecomment-1050973199
  podManagementPolicy: OrderedReady
            -Xms128m -Xmx256m -XX:MaxDirectMemorySize=128m
      repository: apachepulsar/pulsar
  replicaCount: 3
      cpu: 0.2
      memory: 128Mi
      name: journal
      size: 5Gi
      storageClassName: mystorageclass
      name: ledgers
      size: 5Gi
      storageClassName: mystorageclass
    repository: apachepulsar/pulsar
  # this setting is recommended to automatically apply changes in the configuration to the broker
  # uncomment the following line to turn it on
  # restartPodsOnConfigMapChange: true
            -Xms128m -Xmx256m -XX:MaxDirectMemorySize=128m
    subscriptionExpirationTimeMinutes: "5"
    webSocketServiceEnabled: "true"
    systemTopicEnabled: "true"
    topicLevelPoliciesEnabled: "true"
  replicaCount: 2
      cpu: 0.2
      memory: 256Mi

Apache Pulsar Chart

This command will deploy Apache Pulsar from the extracted Helm chart directory ./pulsar. We recommend version 2.9.2 since it was tested with GoodData.CN.

helm install --namespace pulsar --version 2.9.2 \
    -f customized-values-pulsar.yaml \
    pulsar apache/pulsar

Prepare Customized values.yaml for GoodData.CN

To support a broad variety of deployment options, the GoodData.CN Helm chart offers multiple parameters that you may tune to fit your environment. Check default values in the Helm chart to see further options.

Keep the file customized-values-gooddata-cn.yaml for future reference and upgrades.

Installations with SaaS Redis and Postgres

If you are running in public cloud that offers Redis and Postgres as a service and you have decided to use these services, do not deploy the Redis and Postgres subcharts. Refer to Environment Setup for the Redis and Postgres installations in the public clouds.

# file name: customized-values-gooddata-cn.yaml

      - redis.cache
    port: 6379
    clusterMode: false
    # If your Redis service has authentication enabled, uncomment and declare the password
    # password: <REDIS_PASSWORD>
    host: postgres.database
    port: 5432
    username: postgres #If you use Azure Database for PostgreSQL, the username must contain the hostname e.g. postgres@gooddata-cn-pg.
    password: <PG_ADMIN_PASSWORD>

deployRedisHA: false
deployPostgresHA: false

Installations with included Redis and PostgreSQL

If you cannot or do not want to use Redis and PostgreSQL as a service, deploy the Redis and Postgres subcharts (default).

# file name: customized-values-gooddata-cn.yaml

deployRedisHA: true
deployPostgresHA: true

Internal OIDC identity provider settings

Based on your assessment in the Deployment Considerations section you may need to set up the internal OIDC identity provider. You need to set up the hostname for the Ingress, the authHost, and the certificate for the internal OIDC identity provider with either the secret containing the certificate or the annotation for the CertManager that will provide the certificate.

    authHost: 'auth.company.com'
      authSecretName: gooddata-cn-auth-tls
    #  cert-manager.io/cluster-issuer: letsencrypt-production
    storageClass: mystorageclass
    storageClass: mystorageclass

On air-gapped clusters, you need to override all images so they are fetched from your local Docker registry:

  # this is where GoodData.CN images are stored
  repositoryPrefix: "registry.company.com/gooddata"
  # this is where DockerHub repositories are stored
  dockerhubPrefix: "registry.company.com/dockermirror"

# For postgresql-ha subchart, if used
  # usually the same as image.dockerhubPrefix
  imageRegistry: "registry.company.com/dockermirror"

# Used for redis-ha subchart, if used
    repository: "registry.company.com/dockermirror/redis"
    image: "registry.company.com/dockermirror/redis_exporter"

# Used for the internal oidc identity provider component, if used
    name: "registry.company.com/dockermirror/dex"

Add License Key

GoodData.CN requires a valid license key. Use the key you received from GoodData.

You have two options for how to pass the license key during Helm chart installation:

  • Directly pass the license key using custom values file:
      key: "key/eyJhY2NvdW50I...a very long string...IGfMjaRJZcg=="
  • Or use a pre-created Kubernetes Secret resource containing the license key:
    • Create a Secret in the gooddata-cn namespace:
      kubectl -n gooddata-cn create secret generic gooddata-cn-license \
      --from-literal=license=key/eyJhY2NvdW50I...a very long string...IGfMjaRJZcg==
    • Assign the secret with the license key to your custom values file:
        existingSecret: gooddata-cn-license

Custom JDBC Drivers

Due to licensing restrictions, GoodData is not allowed to distribute the JDBC drivers for some databases. However, you can use the init container to mount the drivers from a custom docker image.

Use the following procedure to mount custom JDBC drivers into GoodData.CN:

  1. Download the driver to a local folder. For example, /tmp/db-drivers/BIGQUERY.
  2. Prepare the image:
    # file name: Dockerfile
    # base image can be actually anything containing the `cp` command.
    FROM busybox
    COPY ./db-drivers/ /data/
  3. Build the image and push to your own registry in a place where k8s will have access.
    docker build -t custom.registry.com/gooddata-cn-extra-drivers .
    docker push custom.registry.com/gooddata-cn-extra-drivers
  4. Install the GoodData.CN chart with one of the following methods:
    • Execute the following in the command line: --set sqlExecutor.extraDriversInitContainer=<custom-image-with-drivers>.
    • Directly update the entry for sqlExecutor.extraDriversInitContainer in the helm chart options with the custom image.

GoodData.CN Application Chart

This command will deploy GoodData.CN from extracted Helm chart directory ./gooddata-cn.

helm install --version 2.1.1 --namespace gooddata-cn --wait \
  -f customized-values-gooddata-cn.yaml gooddata-cn gooddata/gooddata-cn


Release "gooddata-cn" has been installed. Happy Helming!
NAME: gooddata-cn
LAST DEPLOYED: Thu Mar 26 14:32:44 2020
NAMESPACE: gooddata-cn
STATUS: deployed
Congratulations, you have just deployed GoodData.CN to your Kubernetes cluster.

All necessary services are up and running in your Kubernetes cluster now.