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 deploymentgooddata-cn
- for GoodData.CN deployment
Preparation
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 hostCNAME
- 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.
Note
It is possible that you already have a wildcard certificate matching your chosen Ingress hostname loaded into load balancer. In this case, you don’t need another certificate, and you can use the wildcard certificate to encrypt client traffic between your users and GoodData.CN.
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:3.1.2
- GoodData.CN
gooddata/afm-exec-api:${TAG}
gooddata/analytical-designer:${TAG}
gooddata/apidocs:${TAG}
gooddata/api-gateway:${TAG}
gooddata/auth-service:${TAG}
gooddata/calcique:${TAG}
gooddata/dashboards:${TAG}
gooddata/dex:${TAG}
gooddata/export-controller:${TAG}
gooddata/home-ui:${TAG}
gooddata/ldm-modeler:${TAG}
gooddata/measure-editor:${TAG}
gooddata/metadata-api:${TAG}
gooddata/organization-controller:${TAG}
gooddata/pdf-stapler-service:${TAG}
gooddata/quiver:${TAG}
gooddata/result-cache:${TAG}
gooddata/scan-model:${TAG}
gooddata/sql-executor:${TAG}
gooddata/tabular-exporter:${TAG}
gooddata/tools:${TAG}
gooddata/visual-exporter-chromium:${TAG}
gooddata/visual-exporter-proxy:${TAG}
gooddata/visual-exporter-service:${TAG}
gooddata/web-components:${TAG}
- GoodData.CN subcharts
docker.io/bitnami/bitnami-shell:11-debian-11-r43
docker.io/bitnami/etcd:3.5.10-debian-11-r0
docker.io/bitnami/pgpool:4.3.3-debian-11-r20
docker.io/bitnami/postgres-exporter:0.11.1-debian-11-r20
docker.io/bitnami/postgresql:13.13.0-debian-11-r28
docker.io/oliver006/redis_exporter:v1.43.0
docker.io/library/redis:7.0.9-alpine3.17
Note
The variable ${TAG}
depends on the GoodData.CN release that you plan to install. You can obtain its value from Release Notes for the particular version of the GoodData.CN application.
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
Response:
"apache" has been added to your repositories
Add the GoodData Helm repository.
helm repo add gooddata https://charts.gooddata.com/
Response:
"gooddata" has been added to your repositories
Create Kubernetes Namespaces
As a cluster administrator, create the following two namespaces:
Important
It is important to set the proper namespace label because Network Policies rely on it.
kubectl apply -f - << END
apiVersion: v1
kind: Namespace
metadata:
name: pulsar
labels:
metadata.labels.kubernetes.io/metadata.name: pulsar
END
Response:
namespace/pulsar created
kubectl apply -f - << END
apiVersion: v1
kind: Namespace
metadata:
name: gooddata-cn
labels:
metadata.labels.kubernetes.io/metadata.name: gooddata-cn
END
Response:
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 Controller
If you already have your Kubernetes cluster with NGINX Ingress Controller deployed, you do not need to perform any actions. GoodData.CN will work with your existing NGINX Ingress Controller installation. Otherwise, it is required to deploy it.
Create NGINX Ingress Controller Namespace
Important
It is important to set the proper namespace label because Network Policies rely on it.
kubectl apply -f - << END
apiVersion: v1
kind: Namespace
metadata:
name: ingress-nginx
labels:
metadata.labels.kubernetes.io/metadata.name: ingress-nginx
END
Response:
namespace/ingress-nginx created
Add the NGINX Ingress Controller Helm repository
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
Prepare customized values.yaml for for NGINX Ingress Controller. Refer AWS specific documentation for additional requirements if you deploy this Ingress Controller behind AWS Elastic LoadBalancer.
controller:
config:
# 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 Controller
helm -n ingress-nginx install ingress-nginx ingress-nginx/ingress-nginx \
--set controller.replicaCount=2
Installation
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:
Notes
- On air-gapped installations, update all occurrences of
apachepulsar/pulsar
to point to your local Docker registry. - Update
storageClassName
according to your setup (seekubectl get storageclass
output). - Gooddata.CN does not require a dedicated Pulsar instance. However, you should consider whether to utilize your current Pulsar instance, based on potential security, performance etc. assessments.
Warning
If you are upgrading existing Apache Pulsar helm chart from version 2.9 or older, you must update
the customized-values-pulsar.yaml
file and review the changes. There were multiple important changes
and using older values file with new chart version will result in broken Pulsar deployment.
- set
securityContext.fsGroupChangePolicy
toAlways
inzookeeper
andbookkeeper
to update file permissions on persistent volumes. - (Optional): If your cluster-wide Prometheus accepts
PodMonitor
CRDs, you may want to enable all pod monitors by removing allpodMonitor.enabled=false
from thecustomized-values-pulsar.yaml
example below.
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
components:
functions: false
proxy: false
toolset: false
pulsar_manager: false
# default image tag for pulsar images
# uses chart's appVersion when unspecified
defaultPulsarImageTag: 3.1.2
images:
zookeeper:
repository: apachepulsar/pulsar
bookie:
repository: apachepulsar/pulsar
autorecovery:
repository: apachepulsar/pulsar
broker:
repository: apachepulsar/pulsar
zookeeper:
replicaCount: 3
podManagementPolicy: OrderedReady
podMonitor:
enabled: false
restartPodsOnConfigMapChange: true
annotations:
# This is workaround until https://github.com/apache/pulsar-helm-chart/pull/348 is merged
# Needed on deployments that don't set custom annotations and use restartPodsOnConfigMapChange=truw
foo: bar
# IMPORTANT: If you're upgrading from version < 2.10, enable this option or the upgrade will fail
# securityContext:
# fsGroupChangePolicy: "Always"
volumes:
data:
name: data
size: 2Gi
storageClassName: mystorageclass
bookkeeper:
replicaCount: 3
podMonitor:
enabled: false
restartPodsOnConfigMapChange: true
resources:
requests:
cpu: 0.2
memory: 128Mi
# IMPORTANT: If you're upgrading from version < 2.10, enable this option or the upgrade will fail
# securityContext:
# fsGroupChangePolicy: "Always"
volumes:
journal:
name: journal
size: 5Gi
storageClassName: mystorageclass
ledgers:
name: ledgers
size: 5Gi
storageClassName: mystorageclass
configData:
nettyMaxFrameSizeBytes: "10485760"
autorecovery:
podMonitor:
enabled: false
restartPodsOnConfigMapChange: true
configData:
BOOKIE_MEM: >
-Xms64m -Xmx128m -XX:MaxDirectMemorySize=128m
pulsar_metadata:
image:
repository: apachepulsar/pulsar
broker:
replicaCount: 2
podMonitor:
enabled: false
restartPodsOnConfigMapChange: true
resources:
requests:
cpu: 0.2
memory: 256Mi
configData:
PULSAR_MEM: >
-Xms128m -Xmx256m -XX:MaxDirectMemorySize=128m
managedLedgerDefaultEnsembleSize: "2"
managedLedgerDefaultWriteQuorum: "2"
managedLedgerDefaultAckQuorum: "2"
subscriptionExpirationTimeMinutes: "5"
systemTopicEnabled: "true"
topicLevelPoliciesEnabled: "true"
proxy:
podMonitor:
enabled: false
kube-prometheus-stack:
enabled: false
Apache Pulsar Chart
This command will deploy Apache Pulsar from the Helm repository apache
registred above.
We recommend version 3.1.0
since it was tested with GoodData.CN.
helm install --namespace pulsar --version 3.1.0 \
-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
service:
redis:
hosts:
- redis.cache
port: 6379
clusterMode: false
# If your Redis service has authentication enabled, uncomment and declare the password
# password: <REDIS_PASSWORD>
postgres:
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.
Note
You need to ensure that a DNS record is created for the authHost
Ingress.
See DNS Configuration section for more details.
dex:
ingress:
authHost: 'auth.company.com'
tls:
authSecretName: gooddata-cn-auth-tls
annotations:
# cert-manager.io/cluster-issuer: letsencrypt-production
Note
If you do not want to use the default storageClass
of your Kubernetes cluster for Redis and/or Postgres helm charts, you need to set storageClass
according to your setup (see kubectl get storageclass
output).
redis-ha:
persistentVolume:
storageClass: mystorageclass
postgresql-ha:
persistence:
storageClass: mystorageclass
On air-gapped clusters, you need to override all images so they are fetched from your local Docker registry:
image:
# 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
global:
# usually the same as image.dockerhubPrefix
imageRegistry: "registry.company.com/dockermirror"
# Used for redis-ha subchart, if used
redis-ha:
image:
repository: "registry.company.com/dockermirror/redis"
exporter:
image: "registry.company.com/dockermirror/redis_exporter"
# Used for the internal oidc identity provider component, if used
dex:
image:
name: "registry.company.com/dockermirror/dex"
Set Up Encryption for Data Source Credentials
You must provide a set of keys in the GoodData.CN helm chart options that will be used to encrypt your data source related metadata and your OIDC secret.
See Encrypt Data Source Credentials to learn how to generate your keysets and implement the encryption.
Note that this feature can be disabled, though from a security point of view we discourage you from doing this.
Add License Key
GoodData.CN requires a valid license key. Use the key you received from GoodData.
Note
You can find your license key in the welcome email from GoodData. If you are having trouble finding the license key, please contact our support team.
You have two options for how to pass the license key during Helm chart installation:
- Directly pass the license key using custom values file:
license: 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:
license: existingSecret: gooddata-cn-license
- Create a Secret in the
License key format
Make sure you enter the license key exactly as you received it. Do not omit any letters, remove all spaces and make sure it is entered on a single line.
If you modify the license key, it becomes invalid and GoodData.CN won’t start.
Update the License Key
Once you’ve successfully deployed GoodData.CN with an initial license key, there might come a time when you need to update this key, especially if you’re renewing your license for continued use of GoodData.CN. Below are the steps to guide you through this process. The method you choose will depend on how you initially deployed the license.
Note
It’s crucial to ensure that while updating the license key, other configurations remain unchanged.
Using the Customized Values YAML for GoodData.CN
If you provided the license key during the initial installation using the customized-values-gooddata-cn.yaml
, follow these steps:
Open the
customized-values-gooddata-cn.yaml
file that you used during the initial installation.Locate the license section in the file.
Update the key field with your new license key. Ensure it looks something like this:
license: key: "key/eyJhY2NvdW50I...a new and updated long string...IGfMjaRJZcg=="
Save the file.
Use the helm upgrade command to apply the changes. Replace
[YOUR_HELM_RELEASE_NAME]
with the name of your Helm release, and ensure you’re using the corresponding GoodData.CN version:helm upgrade [YOUR_HELM_RELEASE_NAME] --version 3.13.0 --namespace gooddata-cn \ -f customized-values-gooddata-cn.yaml gooddata/gooddata-cn
Using a Kubernetes Secret
If you initially set up the license key using a Kubernetes Secret, you can update it directly:
Check that the
customized-values-gooddata-cn.yaml
references the existing secret, and make note of its name for the next step:license: existingSecret: gooddata-cn-license
First, create or update the Secret in the
gooddata-cn
namespace:kubectl -n gooddata-cn create secret generic gooddata-cn-license \ --from-literal=license=key/eyJhY2NvdW50I...a new and updated long string...IGfMjaRJZcg== \ --dry-run=client -o yaml | kubectl apply -f -
This command checks if the secret already exists. If it does, it updates it, and if it doesn’t, it creates a new one.
License key should be reloaded automatically within a few minutes.
Attention
After updating the license key, ensure that the GoodData.CN instance functions correctly. Always keep a backup of your configurations and be prepared for rollback procedures if needed.
If you encounter any challenges or have further questions, please reach out to our support team.
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:
- Download the driver to a local folder. For example,
/tmp/db-drivers/BIGQUERY
.Notes
- Store each driver inside a dedicated folder.
- Unpack the driver files if necessary.
- Complete any additional steps for your database as described in Supported databases.
- Prepare the image:
# file name: Dockerfile # base image can be actually anything containing the `cp` command. FROM busybox COPY ./db-drivers/ /data/
- 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
- 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.
- Execute the following in the command line:
Limiting access from IP ranges
If you need to limit access to GoodData.CN from chosen IP address ranges, it
is possible to do so using annotations on Ingress resources. While the name and
format of this annotation is specific to type of ingress controller, here we
provide example for NGINX Ingress Controller annotation
nginx.ingress.kubernetes.io/whitelist-source-range
that is used in this installation guide.
The following example configuration enables access from IP address range
1.2.3.0-1.2.3.255
and from single IP address 5.6.7.8
.
dex:
ingress:
annotations:
nginx.ingress.kubernetes.io/whitelist-source-range: 1.2.3.0/24,5.6.7.8/32
ingress:
annotations:
nginx.ingress.kubernetes.io/whitelist-source-range: 1.2.3.0/24,5.6.7.8/32
Using Internal Load Balancer
In some cases, you may want to use internal load balancer instead of publicly accessible load balancer. In that case you may experience problems with PDF exports. Visual Exporter component is configured to disable access to IP addresses from RFC-1918, RFC-1700, and RFC-3927 ranges:
- 0.0.0.0/8
- 10.0.0.0/8
- 127.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16
- 169.254.0.0/16
If you want to use internal load balancer, Organizations will have IP address
belonging to one of these ranges, so Visual Exporter will fail to load dashboard
to be exported to PDF. In order to fix this issue, add your internal load
balancer IP addresses (or address ranges) to permittedDestinations
variable in
customized-values-gooddata-cn.yaml
, as shown in the following example:
visualExporterProxy:
permittedDestinations: "10.1.2.3/32 172.16.0.0/24"
GoodData.CN Application Chart
This command will deploy GoodData.CN from extracted Helm chart directory ./gooddata-cn
.
helm install --version 3.13.0 --namespace gooddata-cn --wait \
-f customized-values-gooddata-cn.yaml gooddata-cn gooddata/gooddata-cn
Response:
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
REVISION: 1
TEST SUITE: None
NOTES:
Congratulations, you have just deployed GoodData.CN to your Kubernetes cluster.
All necessary services are up and running in your Kubernetes cluster now.
Connect to GoodData.CN
At this point of the installation, you do not have an endpoint/hostname to connect to. To proceed with the configuration, refer to Create Organizations to learn to create Organization(s) from a custom resource.
The hostname for accessing GoodData.CN platform will be provisioned by the Organization resource.