Installation On Kubernetes
XDM can be installed and operated on a Kubernetes or OpenShift cluster. XDM provides a Helm chart that simplifies configuration and deployment. This section explains how configuration is managed, how to install the Helm chart, and how to maintain the installation.
Configuration Concept
When installing XDM on Kubernetes or OpenShift, configuration is managed in two main places:
-
The
values.yamlfile used by Helm -
Kubernetes objects that are created or referenced by the chart
Helm Values (values.yaml)
The Helm chart is configured through a values.yaml file.
This file contains all XDM‑specific settings, such as:
-
XDM release version and environment metadata
-
License and security settings
-
Database configuration (internal or external PostgreSQL)
-
User management (local, LDAP, OAuth2)
-
Task execution limits and platforms
-
Loki and Tempo for Logging
-
Persistence, Ingress, and optional services (Grafana, Elasticsearch, sample database)
You pass your customized values.yaml file to the helm install and helm upgrade commands.
For an overview of all available parameters, refer to Configuration Parameters.
Kubernetes Objects
The Helm chart creates and uses several standard Kubernetes objects:
-
ConfigMaps – Store non‑sensitive configuration that is injected into the XDM services. Most of this configuration is derived from the values in
values.yaml. -
Secrets – Store sensitive data such as:
-
XDM license (or a reference to a license secret)
-
Database credentials
-
LDAP / OAuth2 client secrets
-
Password seed and JWT secrets These secrets can either be created by the chart (from values) or referenced as existing Kubernetes secrets.
-
PersistentVolumeClaims (PVCs) – Provide persistent storage for:
-
XDM task working directories and logs
-
The internal PostgreSQL database
-
Optional services like Grafana, Elasticsearch, or the sample database
You define how these objects are created and used via the persistence, database, security, and related sections in values.yaml.
For details, see "Persistence" and the related configuration chapters.
Prerequisites
To install XDM on Kubernetes or OpenShift, you need:
-
A running Kubernetes or OpenShift cluster.
-
A local installation of Helm version 3.
-
Helm configured to access the target cluster (for example, via
kubectl config). -
Sufficient access rights in the target namespace to create:
-
Deployments, StatefulSets, Services, Ingresses
-
ConfigMaps, Secrets
-
PersistentVolumeClaims
-
Network and resource prerequisites that match your planned XDM usage
-
A valid XDM license key with the CloudSupport option enabled.
-
For resource and hardware requirements, refer to System Requirements.
Installing The Helm Chart
Installing XDM with Helm consists of three basic steps:
-
Add the XDM Helm repository.
-
Update the local repository index.
-
Install the chart with your customized
values.yaml.
Adding The Helm Repository
First, add the XDM Helm repository to your local Helm installation:
helm repo add ubs https://www.ubs-hainer.com/downloads/XDM3/helm
This command registers the repository under the name ubs.
You only need to do this once per Helm setup.
Updating The Repository Index
Before installing or upgrading XDM, update the local repository index:
helm repo update
This command downloads the latest index of the ubs chart repository so that Helm can resolve the available XDM versions.
Installing The Chart
Prepare a values.yaml file that contains at least all mandatory parameters (see Configuring values.yaml).
Then install XDM with:
helm install <NAME> ubs/xdm \
-f <VALUES_FILE> \
--version <XDM_RELEASE> \
--namespace <NAMESPACE> \
--create-namespace
<NAME>-
Logical name of the Helm release (for example
xdm-prodorxdm-test). You will use this name for futurehelm upgradecommands. <VALUES_FILE>-
Specify the name to the helm chart file. For more information on the values.yaml file, see Configuring values.yaml.
<XDM_RELEASE>-
The XDM version to install. If you omit
--version, Helm installs the latest stable XDM version. <NAMESPACE>-
Kubernetes namespace for the XDM installation. All deployments, pods, services, and other resources will be created in this namespace. If you omit
--create-namespace, the namespace must already exist.
To list all available XDM versions in the repository, run:
helm search repo ubs/xdm -l
After the installation, verify that all pods in the namespace reach the Running state, for example:
kubectl get pods --namespace <NAMESPACE>
Optional Rootless configuration
For security reasons, the default to run the XDM containers is using non-root users. For more Information about the non-root user Configuration for XDM, see Non-Root User Container Configuration.
Updating The Release
For further information on updating XDM, refer to the article Update.
Once XDM is installed, you will regularly apply configuration changes and version upgrades using helm upgrade.
To change configuration values or upgrade to a newer XDM version, update your values.yaml and run:
helm upgrade <NAME> ubs/xdm \
-f <VALUES_FILE> \
--version <NEW_XDM_RELEASE> \
--namespace <NAMESPACE>
-
Reuse the same
<NAME>and<NAMESPACE>you used forhelm install. -
Define the Chart configuration file (values.yaml).
-
Adjust
xdm.versioninvalues.yamlto match<NEW_XDM_RELEASE>. -
Review the release notes for any migration steps or deprecated settings before upgrading.
After the upgrade, monitor the pods and logs to ensure that XDM starts correctly:
kubectl get pods --namespace <NAMESPACE>
kubectl logs deploy/xdm-core --namespace <NAMESPACE>
Enterprise Deployment With CI/CD
In enterprise environments, XDM is usually not installed or upgraded manually from a local workstation. Instead, the Helm-based deployment is typically integrated into an existing CI/CD or GitOps process.
The Helm commands shown in the previous section can still be used as a technical reference. In an enterprise setup, these commands are usually executed by predefined pipeline jobs or by a deployment controller. The exact process depends on the customer’s internal platform, repository structure, security requirements, and approval workflow.
Basic Deployment Model
A typical enterprise deployment separates the following concerns:
-
the XDM Helm chart
-
the XDM default values provided with the chart
-
environment-specific configuration
-
secrets, certificates, and credentials
-
container images
-
deployment automation
-
monitoring and verification
The following diagram shows a generalized deployment flow:
This model can be implemented in different ways. Some organizations store the Helm chart and the environment-specific configuration in the same repository. Other organizations keep the Helm chart in one repository and maintain the customer-specific values in a separate repository. Some environments use a central deployment platform that combines chart defaults, environment values, secrets, certificates, and additional configuration at deployment time.
Before defining the XDM deployment process, verify which mechanism is used in the target organization.
Repository And Configuration Layout
The repository layout is organization-specific. Common layouts include:
-
a single Git repository that contains the Helm chart and the environment-specific values files
-
one repository for the Helm chart and another repository for the environment-specific configuration
-
an internal Helm repository for chart packages and a Git repository for values files
-
a GitOps repository that contains the desired deployment state for each environment
The following diagram shows two common repository models:
Common tools and platforms used for these purposes include:
-
Git repositories, such as GitLab, GitHub, Bitbucket, Azure Repos, or Gerrit
-
CI/CD systems, such as Jenkins, GitLab CI/CD, GitHub Actions, Azure DevOps, TeamCity, or Tekton
-
GitOps tools, such as Argo CD or Flux CD
-
internal artifact or container registries, such as JFrog Artifactory, Sonatype Nexus Repository, Harbor, Azure Container Registry, Amazon ECR, Google Artifact Registry, or OpenShift Image Registry
These tools are examples only. Use the tools and approval processes that are defined by the operating organization.
Managing values.yaml In Git
The environment-specific values.yaml file is typically stored in Git.
This makes the deployment configuration version-controlled, reviewable, and reproducible.
Use separate values files, directories, branches, or repositories for different environments. For example:
-
Development
-
Test
-
Staging
-
Production
Typical file names are:
dev-values.yaml
test-values.yaml
staging-values.yaml
prod-values.yaml
Some organizations use the file extension .yml instead of .yaml.
Both formats are technically common.
Use the naming convention that is defined for the respective repository.
Configuration changes should be committed and reviewed before they are deployed to a Kubernetes cluster. For production environments, use the approval workflow required by the organization, for example a merge request, pull request, change request, or release approval.
Avoid making direct, undocumented changes to Helm templates. If direct template changes are required, document them explicitly and review them during every XDM version update. Where possible, implement environment-specific behavior through values files instead of changing chart templates.
Obtaining The XDM Helm Chart
The XDM Helm chart can be obtained from the UBS Hainer Helm repository.
helm repo add ubs https://www.ubs-hainer.com/downloads/XDM3/helm
helm repo update
helm search repo xdm -l
Use helm search repo xdm -l to list the available chart versions.
Select the chart version that matches the XDM version planned for the deployment.
If the chart package must be downloaded for review, archiving, or mirroring, use helm pull.
For example:
helm pull ubs/xdm --version <XDM_RELEASE>
For an enterprise deployment, the CI/CD process can use the UBS Hainer Helm repository directly if external access is permitted. If the Kubernetes or CI/CD environment is not allowed to access external repositories, mirror the required chart version to an internal Helm repository first. In that case, the deployment job should reference the internal Helm repository instead of the UBS Hainer repository.
Mirroring Container Images
Many enterprise Kubernetes environments do not allow workloads to pull container images directly from external registries. In such environments, the required XDM images must be copied to an internal container registry first.
After mirroring the images, update the image references in the relevant values file so that Kubernetes pulls the images from the internal registry.
A simplified values fragment can look like this:
image:
repository: <INTERNAL_REGISTRY>
The exact configuration depends on the registry structure and on the image settings used by the Helm chart and the values file.
This list shows the available XDM images that must be mirrored to the internal registry.
- Mandatory images
docker.ubs-hainer.com/xdm3-core:<version>
docker.ubs-hainer.com/xdm3-dataflow:<version>
docker.ubs-hainer.com/xdm3-ui:<version>
docker.ubs-hainer.com/xdm3-prime-ui:<version>
docker.ubs-hainer.com/postgres:15
docker.ubs-hainer.com/xdm3-grafana:<version>
docker.ubs-hainer.com/xdm3-prometheus:<version>
docker.ubs-hainer.com/xdm3-loki:<version>
docker.ubs-hainer.com/xdm3-tempo:<version>
- Optional for Data Generation
docker.ubs-hainer.com/xdm3-ai-assistance:<version>
docker.ubs-hainer.com/xdm3-file-sink:<version>>
docker.ubs-hainer.com/xdm3-graph-store:<version>
docker.ubs-hainer.com/xdm3-mcp:<version>
- Optional for Global Search
docker.ubs-hainer.com/elasticsearch:8.19.19
- Optional for Test Data Finder
docker.ubs-hainer.com/neo4j:4.4
- Optional for Sample Environment
docker.ubs-hainer.com/linuxserver/openssh-server:version-9.0_p1-r2
docker.ubs-hainer.com/sample-environment:<version>
Recommended checks after image mirroring:
-
Verify that all required XDM images are available in the internal registry.
-
Verify that the image tags match the XDM version and the Helm chart version that will be deployed.
-
Verify that the Kubernetes cluster can pull the images from the internal registry.
-
Verify that required image pull secrets are available in the target namespace, if the registry requires authentication.
It is recommended to create a dedicated CI/CD job for image mirroring. This job should copy the required XDM images from the external source registry to the internal registry and make the result visible in the pipeline log. Depending on the organization’s process, this job can run manually for each XDM update or automatically when a new approved XDM version is prepared.
CI/CD Jobs For Deployment
The actual installation or upgrade is usually executed by predefined CI/CD jobs. These jobs run the required Helm commands with the correct chart version, namespace, release name, and values file.
A deployment job typically defines or receives the following parameters:
-
target environment
-
Kubernetes namespace
-
Helm release name
-
Helm chart name or chart package
-
Helm chart version
-
values file or values source
-
container registry configuration
-
credentials or references to existing secrets
For example, a CI/CD job may execute a command similar to the example in Installing The Helm Chart:
helm upgrade <NAME> ubs/xdm \
-f <VALUES_FILE> \
--version <XDM_RELEASE> \
--namespace <NAMESPACE>
Depending on the internal process, the command can also reference an internal chart repository or a locally checked-out chart instead of the external Helm repository.
If the chart was mirrored to an internal Helm repository, replace ubs/xdm with the chart reference used by the internal repository.
In GitOps-based environments, the pipeline may not run helm upgrade directly.
Instead, it updates the desired state in Git.
A GitOps controller then applies the change to the Kubernetes cluster.
The following diagram shows the difference between a CI/CD-based deployment and a GitOps-based deployment:
Recommended Deployment Process
A typical deployment process in an enterprise environment is:
-
Update the environment-specific values file or deployment configuration in Git.
-
Commit the changes.
-
Create a merge request or pull request.
-
Review and approve the changes.
-
Mirror the required XDM container images to the internal registry, if required.
-
Run the predefined CI/CD deployment job or let the GitOps controller apply the approved change.
-
Verify the deployment in the target Kubernetes namespace.
-
Continue with the next environment only after the previous environment has been verified.
For staged rollouts, use the environment sequence defined by the operating organization. A common sequence is:
Update Procedure
When updating XDM to a new version, review both the Helm chart and the environment-specific configuration.
A typical update procedure is:
-
Obtain the new XDM Helm chart version.
-
Compare the new chart with the currently deployed chart.
-
Review changes in the chart templates and in the default
values.yaml. -
Identify new, changed, removed, or renamed configuration parameters.
-
Check whether existing environment-specific values are still valid.
-
Check whether direct template modifications exist and whether they must be reapplied or can be replaced by values.
-
Update the environment-specific values files.
-
Update the chart version in the deployment configuration or CI/CD job.
-
Mirror the required XDM container images to the internal registry.
-
Deploy the update to the first non-production environment.
-
Verify the deployment.
-
Continue through the remaining environments according to the organization’s rollout process.
The following diagram summarizes the update procedure:
During the chart comparison, pay special attention to the following areas:
-
image repositories and image tags
-
environment variables
-
resource requests and limits
-
persistence settings
-
services and ingress settings
-
secrets and certificate mounts
-
volume definitions
-
configuration keys that were added, removed, or renamed
If direct changes were made to Helm templates in an earlier version, review each change explicitly. Direct template changes can make updates more complex because they must be compared and possibly re-applied for every new chart version.
Verification After Deployment
After the CI/CD job or GitOps synchronization has completed, verify the deployment in the target Kubernetes namespace.
Check the pod status:
kubectl get pods --namespace <NAMESPACE>
Typically, there is also a monitoring platform that provides a central overview of the cluster and the deployed services.
All required pods should reach the expected running state. If a pod does not start, inspect the pod events and logs.
Check logs if required:
kubectl logs deploy/<XDM-SERVICE> --namespace <NAMESPACE>
Depending on the organization’s monitoring setup, also check the central monitoring platform for:
-
failed deployments
-
pods in an error state
-
repeated restarts
-
unavailable services
-
resource pressure
-
image pull errors
-
configuration or startup errors
Only continue with the next environment after the deployment has been verified successfully.
Overview Of Parameters
The Helm chart exposes many configuration options, grouped into logical sections such as:
-
General XDM settings (release, environment metadata)
-
Security and user management
-
Database and persistence
-
Ingress and network access
-
Optional services (Grafana, Elasticsearch, sample database)
-
Configuration as Code (CaSC)
A complete reference of all common parameters is available in Configuration Parameters.
In this section, we focus on the most important settings for a basic installation.
| When installing on an OpenShift system, refer also to Open Shift Customization |
Configuring Mandatory Parameters
For a functional and licensed XDM installation all mandatory Docker images must be available and all services are running.
Furthermore, you must at least configure:
Furthermore, it is possible to set the XDM release version, but in most cases it is predefined in the helm chart.
Example skeleton:
xdm:
license: |
LICENSE = ...
LIC0001 = COMPANY:...
...
# Or reference an existing secret instead of inline license:
# licenseSecret: xdm-license-secret
security:
passwordSeed: "<secure-random-string>"
# Or reference an existing secret:
# secret: xdm-password-seed-secret
database:
extern: false
# For external database set extern: true and configure url, user, and secret.
xdm.license/xdm.licenseSecret-
Provide either the license content directly or reference a Kubernetes secret.
security.passwordSeed/security.secret-
Required for secure password handling.
database-
Controls whether you use the internal PostgreSQL container or an external PostgreSQL instance. See Admin Database configuration for details.
| Never use trivial or guessable password seeds in production. For secrets, prefer Kubernetes secrets rather than plain text values. |
Configuring Recommended Parameters
For most real‑world installations you should also configure:
-
Environment settings (ID, name, color)
-
User management (local user/roles, LDAP, or OAuth2/OpenID Connect)
Example:
repository: docker.ubs-hainer.com
imagePullSecrets:
- name: xdm-pull-secret
xdm:
timezone: Europe/Berlin
environment:
id: "prod"
name: "Production"
color: "blue"
certificates:
- xdm-ca-certificates
jdbcDriversCommand: |-
wget -P /xdm/config/jdbc-drivers/ -v --no-check-certificate \
https://jdbc.postgresql.org/download/postgresql-42.3.3.jar
security:
jwt:
expireTime: 3600
validTime: 3600
secret: "<jwt-secret-value>"
userManagement:
# Example: ldap configuration
ldap: ...
For environments that must integrate with corporate identity providers, configure:
-
userManagement.ldapfor LDAP / Active Directory -
userManagement.oauth2for OAuth2 / OpenID Connect providers
See the dedicated configuration chapters for details on each option:
Persistence (PVCs)
Persistence is configured in the persistence section:
persistence:
data:
storageClass: <storage-class>
accessMode: ReadWriteMany
size: 100Gi
postgres:
storageClass: <storage-class>
accessMode: ReadWriteOnce
size: 50Gi
# Optional volumes, depending on enabled services:
# sample:
# grafana:
# elasticsearch:
data-
Stores XDM task working directories, logs, and reports. This volume is shared by multiple pods (core and dataflow).
postgres-
Stores data of the integrated PostgreSQL database. Not required if you use an external database.
sample,grafana,elasticsearch,graph_store,neo4j,file_sink,loki,tempo-
Only needed if the respective services are enabled.
We highly recommend using a cloud storage solution that supports the ReadWriteMany access mode.
Without ReadWriteMany, the core and dataflow pods must run on the same node, which removes many of the advantages of
Kubernetes (such as flexible scheduling and better resilience).
If you still want to use this approach as a temporary workaround to ensure both pods are scheduled on the same node, see Configuring Pod Affinity.
|
For a detailed description of all persistence options, see Persistence.
Configuring Ingress
To expose the XDM web UI via HTTP/HTTPS, configure the ingress section:
ingress:
enabled: true
domain: xdm.example.com
annotations:
# Example for NGINX basic auth:
# nginx.ingress.kubernetes.io/auth-type: basic
# nginx.ingress.kubernetes.io/auth-secret: basic-auth
# nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required'
tls:
- hosts:
- xdm.example.com
secretName: xdm-tls
ingressClassName: nginx
domain-
Public domain name for the XDM UI.
annotations-
Ingress‑specific options, for example authentication, rate limiting, or older ingress class settings.
tls-
Hosts and TLS secret to enable HTTPS access.
ingressClassName-
Ingress controller class (Kubernetes 1.18+). For older clusters, use
kubernetes.io/ingress.classviaannotations.
Configuring Optional Services
Depending on your use case, you can enable additional services such as:
-
Grafana and Prometheus for monitoring
-
Elasticsearch for central search
-
Sample database for tutorials
-
Configuration as Code (CaSC)
These are typically controlled via dedicated sections in values.yaml, for example:
casc:
enabled: true
url: https://git.example.com/xdm-config.git
branch: main
path: config
cron: "0 * * * *"
secret: xdm-casc-git-credentials
Security context
A securityContext in Kubernetes defines security and access control settings for a pod or container.
These settings can be used to control how the container runs, such as whether it runs as a root user, what user and group memberships it has, and what file system permissions it has.
The following represents a list of the most significant fields that may be used in a securityContext:
- runAsUser
-
Specify the user ID under which the container is running.
- runAsGroup
-
Specify the group ID under which the container is executed.
- runAsNonRoot
-
Forces the container not to be executed as the root user.
- fsGroup
-
Specify the group ID used for all files in the container’s file system.
<service>:
securityContext:
runAsUser: 1002
runAsGroup: 1000
runAsNonRoot: true
fsGroup: 2000
- service
-
The name of the service. Possible service are:
-
core
-
dataflow
-
file_sink
-
elasticsearch
-
grafana
-
graph_store
-
loki
-
postgres
-
prometheus
-
sample
-
tempo
-
ui
-
webservice_apply_sink
-
webservice_extract_source
-
ai_assistance
-
Service account
In a Kubernetes environment, the service account section refers to the configuration of service accounts for a range of services within a Kubernetes cluster. A service account in Kubernetes is a specific type of account that pods use to facilitate communication with the Kubernetes API server.
In addition to the global defaultServiceAccount setting which applies to all containers / pods, the serviceAccount can be overridden for individual containers.
To specify a serviceAccount per container, use the following syntax:
<service>:
serviceAccount: "xdm-<service>-account"
- service
-
The name of the service for which the service account is configured. Possible services are:
-
core
-
dataflow
-
file_sink
-
elasticsearch
-
grafana
-
graph_store
-
loki
-
postgres
-
prometheus
-
sample
-
tempo
-
ui
-
webservice_apply_sink
-
webservice_extract_source
-
ai_assistance
-
Task execution platforms
XDM allows the definition of different execution platforms.
An own Kubernetes Pod is started for each task execution.
The system settings of the Pod are based on the platform settings.
XDM defines a default platform.
The settings of the default platform can be customized as seen below.
To add a new platform add a new sub-entry to the deployer.platform setting.
| The platform name must not start with a number or contain special characters. |
deployer:
platform:
default:
limits:
cpu: 500m
memory: 1024Mi
requests:
cpu: 500m
memory: 1024Mi
The following example adds the new platform example. Each task execution that runs on that platform can use up to 4GB main storage.
deployer:
platform:
example:
limits:
memory: 4096Mi
requests:
memory: 4096Mi
Deactivation of role, role binding and service account creation
If it is not allowed to create roles, role bindings and service accounts from the helm chart, you can deactivate the creation of these resources by setting the following values in your values.yaml file:
xdm:
createRole: false
When setting createRole to false, the helm chart will not create any roles, role bindings or service accounts for the XDM services.
| The creation of roles, role bindings and service accounts must be done manually by the cluster administrator, without this it is not possible to run the XDM executions in the cluster. |
OpenShift specific customization
In open shift it is not allowed to run the docker container as root user.
Therefore, you have to customize your images to grant access to the internal directories and use ports > 1024
which can be bound by a none root user. In this case, the property runAsNonRoot: must set to true in all security contexts.