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>
Configuring values.yaml
The values.yaml file controls almost all aspects of an XDM installation.
This section explains which parameters you must set, which you should review for most installations, and where to find detailed descriptions.
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:
- 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
-
generator_source
-
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
-
generator_source
-
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
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.