Skip to content

Latest commit

 

History

History

helm

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

README.md

Tolerant Match Helm Chart

This chart deploys the TOLERANT Match backend and loads its configuration from files packaged under files.

The chart now:

  • reads file contents into ConfigMaps with .Files.Get
  • uses one ConfigMap per file
  • can source large normalizer and synonyms files from a PVC instead of ConfigMaps
  • selects SQL or RocksDB matchserviceconfig.xml based on global.db.type
  • supports both embedded and external SQL database wiring for Postgres and MariaDB modes
  • can optionally expose Hazelcast member communication for Match cluster synchronization
  • mounts the selected config files into /opt/tolerant/config
  • configures Match liveness probe against /health/liveness
  • configures Match readiness probe against /health/readiness
  • configures Match startup probe against /health/readiness (configurable)
  • can optionally expose Match through a Kubernetes Ingress
  • sets a stable TLMATCH_SERVICE_ID, with pod-specific IDs in Postgres and MariaDB modes
  • renders the Match env block from values.yaml (common, backend-specific, and optional Hazelcast entries)
  • renders a dedicated hazelcast.yaml ConfigMap when Hazelcast is enabled
  • uses a StatefulSet with persistent PVC or pod-lifecycle ephemeral PVC (ephemeral.volumeClaimTemplate) at /opt/tolerant/data for rocksdb
  • supports config.managementMode (declarative or runtime) for Kubernetes config ownership
  • can run an optional match-gui sidecar container in the Match pod
  • supports optional master mode (single master deployment + worker replicas)

Requirements

  • Kubernetes: use a currently supported Kubernetes version for your Helm/client stack.
  • Helm: Helm 3.x.
  • Optional test plugin: helm-unittest for local chart test suites.

Install

helm install tolerant-match ./helm

Image Overrides

Base values.yaml uses release image URLs for Match backend/GUI. For environment-specific image registries/tags, use an additional overlay values file from your deployment repository.

Example:

helm upgrade --install tolerant-match ./helm \
  -f /path/to/your/image-overrides.yaml

Full values are documented in values.yaml. For faster navigation, start with:

  • global.db.*
  • config.managementMode
  • persistence.*
  • master.*
  • containers.match.* and containers.gui.*
  • ingress.*

Profile overlays

The chart keeps overlays purpose-based.

  • Master/runtime cluster example: docs/examples/values-master-runtime.yaml
  • GUI standalone example: docs/examples/values-gui-standalone.yaml
  • GUI cluster example: docs/examples/values-gui-cluster.yaml
    • default in this overlay: RocksDB cluster + Hazelcast
    • switch same overlay to Postgres with:
      • --set global.db.type=postgres
      • --set global.db.rocksdbCluster.enabled=false

Examples:

helm upgrade --install tolerant-match ./helm \
  -f /path/to/your/image-overrides.yaml

helm upgrade --install tolerant-match ./helm \
  -f helm/docs/examples/values-master-runtime.yaml \
  -f /path/to/your/image-overrides.yaml

helm upgrade --install tolerant-match ./helm \
  -f helm/docs/examples/values-gui-cluster.yaml \
  --set global.db.type=postgres \
  --set global.db.rocksdbCluster.enabled=false \
  -f /path/to/your/image-overrides.yaml

Quickstart

NS=tolerant-match
RELEASE=tolerant-match

kubectl create namespace ${NS}
helm upgrade --install ${RELEASE} ./helm --namespace ${NS}
kubectl -n ${NS} rollout status statefulset/${RELEASE}-match
kubectl -n ${NS} port-forward svc/${RELEASE}-match 18080:8080

Then open http://127.0.0.1:18080/health/readiness.

Ingress

Ingress is enabled by default. Current defaults:

ingress:
  enabled: true
  className: nginx
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/proxy-body-size: "101m"
  backend:
    paths: []
    pathType: Prefix
  hosts:
    - host: match.tolerant-software.de
      paths:
        - path: /
          pathType: Prefix
  gui:
    enabled: false
    redirectToTrailingSlash: true
    paths:
      - path: /ui
        pathType: Prefix
  tls: []

Example install:

helm install tolerant-match ./helm \
  --set ingress.enabled=true \
  --set ingress.className=nginx \
  --set ingress.hosts[0].host=match.example.com

Recommended routing is backend on / and GUI on /ui (longest-prefix matching routes /ui to GUI and everything else to backend):

ingress:
  hosts:
    - host: match.example.com
      paths:
        - path: /
          pathType: Prefix
  gui:
    enabled: true
    paths:
      - path: /ui
        pathType: Prefix

If your GUI requires a trailing slash base path, enable automatic nginx redirect from /ui to /ui/:

ingress:
  gui:
    enabled: true
    redirectToTrailingSlash: true

If your ingress policy requires explicit backend paths, configure every backend route you need:

ingress:
  backend:
    paths:
      - /api
      - /admin
      - /health
    pathType: Prefix
  gui:
    enabled: true
    paths:
      - path: /ui
        pathType: Prefix

Port Map

Component Container port Purpose
Match backend (match) 8080 API, health, metrics
Match GUI (match-gui) containers.gui.port (default 8081) GUI HTTP endpoint; must match the GUI container listen port
Cluster sync 10100 (default) Match cluster sync socket
Hazelcast 5701 (default) Hazelcast member communication

Metrics (Prometheus)

The backend Prometheus endpoint is controlled via backend env var TL_PROMETHEUS_METRICS_ENABLED, rendered from:

metrics:
  enabled: false
  path: /prometheus
  port: "8080"
  scheme: http
  service:
    annotations: {}
  serviceMonitor:
    enabled: false
    namespace: ""
    labels: {}
    interval: 30s
    scrapeTimeout: 10s

When metrics.enabled=true, chart services get Prometheus scrape annotations.

If you use Prometheus Operator, enable metrics.serviceMonitor.enabled=true to render a ServiceMonitor.

/prometheus should stay internal and not be exposed through ingress.

Grafana dashboard (Kubernetes/Helm adjusted, based on cluster dashboard):

Cluster state metrics:

Metric Labels Description
cluster.member.state none local member state; 0 when clustering is disabled or unavailable
cluster.project.member-count projectId number of known members for the project; 0 when clustering is disabled or unavailable
cluster.project.state projectId project cluster state; 0 when clustering is disabled or unavailable

State codes (cluster.member.state / ClusterMemberState):

Code Meaning
0 not available / cluster disabled
1 UNCONFIGURED, CONFIGURED, CONNECTED
2 SPLIT_BRAIN (merge/recovery in progress)
4 ERROR

State codes (cluster.project.state / ClusterProjectState):

Code Meaning
0 not available / cluster disabled
1 UNCONFIGURED, CONFIGURED_ACTIVE, CONFIGURED_INACTIVE
2 SYNCHRONIZING, SYNCHRONIZING_WAITING
3 SYNCHRONIZED
4 ERROR

Security (OIDC / External IdP)

Enable OIDC wiring for backend/GUI config with:

security:
  enabled: true
  oidc:
    identityProviderUrl: "https://idp.example.com/keycloak"
    realm: "tolerant"
    clientId: "match"

When enabled, the chart renders:

  • SECURITY_ENABLED=true
  • IDENTITY_PROVIDER_URL=<identityProviderUrl>
  • INTERNAL_IDENTITY_PROVIDER_URL=<identityProviderUrl> (same external URL)
  • TOLERANT_REALM=<realm>
  • TOLERANT_CLIENT_ID=<clientId>

When disabled, only SECURITY_ENABLED=false is rendered and OIDC variables are omitted.

Security Notes

  • Prefer Kubernetes Secrets (global.db.passwordSecretName, license secret, JDBC password secret) over inline plaintext values.
  • Keep /prometheus internal-only.
  • When exposing ingress publicly, apply auth/network policy and only expose required paths.

Deployment Modes

Mode Matrix

Mode Workload shape Data storage Notes
RocksDB single-node (default) StatefulSet (replicaCount=1) Persistent PVC (persistence.data.*) by default simplest production default
RocksDB cluster StatefulSet (replicaCount>1) per-pod persistent PVC requires global.db.rocksdbCluster.enabled=true and Hazelcast enabled
SQL (Postgres/MariaDB) StatefulSet SQL database + optional embedded paging DB pod-specific TLMATCH_SERVICE_ID/MATCH_DB_PREFIX
Master + workers (RocksDB) master Deployment + worker StatefulSet master persistent PVC, workers ephemeral PVC by default initial load targets master; worker GUI_ENABLED=false

Optional Master + Workers (RocksDB)

Enable master mode to run:

  • Deployment <release>-match-master (single master)
  • StatefulSet <release>-match (workers / replicas)

Behavior:

  • initial load job targets master automatically
  • workers use ephemeral RocksDB data volume by default in master mode (pod-local, non-persistent on pod replacement)
  • GUI_ENABLED on workers is forced to false
  • master backend GUI_ENABLED is configurable via master.guiEnabled

Relevant values:

master:
  enabled: true
  guiEnabled: true
  updateStrategy:
    type: Recreate
  gui:
    enabled: true
  persistence:
    existingClaim: ""
    accessMode: ReadWriteOnce
    size: 20Gi
    storageClassName: ""

Mode contracts:

  • master.enabled=true currently supports only global.db.type=rocksdb
  • containers.gui.enabled must be false when master mode is enabled
  • use master.gui.enabled for master-side GUI container instead
  • default master deployment strategy is Recreate to avoid old/new master pod overlap (for example file-lock conflicts on shared runtime config)

Values no longer needed in master mode:

  • containers.gui.* (worker GUI settings)
  • worker GUI ingress assumptions based on containers.gui.enabled

RocksDB

RocksDB is the default. The chart deploys:

  • a single-replica StatefulSet
  • a headless service
  • a PVC mounted at /opt/tolerant/data (default)
  • config files projected into /opt/tolerant/config

Install with defaults:

helm install tolerant-match ./helm

Install explicitly with RocksDB:

helm install tolerant-match ./helm \
  --set global.db.type=rocksdb

Example with a storage class override:

helm install tolerant-match ./helm \
  --set global.db.type=rocksdb \
  --set persistence.data.storageClassName=fast-local-ssd \
  --set persistence.data.size=20Gi

To run RocksDB with an ephemeral data volume instead of a PVC:

helm install tolerant-match ./helm \
  --set global.db.type=rocksdb \
  --set persistence.data.ephemeral.enabled=true \
  --set persistence.data.storageClassName=scratch-storage-class \
  --set persistence.data.size=10Gi

When persistence.data.ephemeral.enabled=true, the chart renders volumes[].ephemeral.volumeClaimTemplate and reuses:

  • persistence.data.accessMode
  • persistence.data.size
  • persistence.data.storageClassName

By default, the chart rejects replicaCount > 1 in RocksDB mode.

To opt in to multi-pod RocksDB cluster mode (with per-pod PVCs and Hazelcast sync), set:

global:
  db:
    type: rocksdb
    rocksdbCluster:
      enabled: true
  match:
    hazelcast:
      enabled: true

Postgres

Postgres mode deploys:

  • the Match backend as a StatefulSet
  • config files projected into /opt/tolerant/config
  • a headless Match service for stable pod names

If global.db.embeddedPagingDatabase.enabled=true (default), it also deploys:

  • an in-cluster Postgres Deployment
  • a Postgres service
  • a Postgres PVC

When you scale Match in Postgres mode, each pod gets its own stable:

  • TLMATCH_SERVICE_ID
  • MATCH_DB_PREFIX

Both default to the StatefulSet pod name, so each pod writes to its own set of Match tables in the shared Postgres database.

To enable Hazelcast-based cluster synchronization between Match pods:

global:
  db:
    type: postgres
  match:
    hazelcast:
      enabled: true
      port: 5701
      clusterName: match-cluster
      kubernetesServiceDNS: ""
    clusterSyncServicePort: 10100

When enabled, the chart:

  • adds the Hazelcast container port on Match pods
  • adds the cluster sync socket port on Match pods (clusterSyncServicePort)
  • exposes that port on the headless Match service
  • injects CLUSTER_SYNC_SERVICE_PORT and HAZELCAST_PORT env vars used by integer fields in matchserviceconfig.xml

The chart always injects CLUSTER_SYNC_SERVICE_PORT and HAZELCAST_PORT. If global.match.hazelcast.enabled=true, it also injects POD_NAME and HAZELCAST_CLUSTER_NAME, and mounts a generated hazelcast.yaml into /opt/tolerant/config.

Runtime Hazelcast config file lookup order in Match is:

  1. hazelcast.yaml
  2. hazelcast.yml
  3. hazelcast.xml
  4. clusterconfig.yaml
  5. clusterconfig.yml
  6. clusterconfig.xml

Hazelcast join mode in generated hazelcast.yaml can be controlled with:

  • global.match.hazelcast.joinMode: kubernetes, tcp, aws, or empty ("") for auto mode

Auto mode behavior:

  • environmentProfile=k8s -> kubernetes
  • other profiles -> tcp

Join mode details:

  • kubernetes: Kubernetes join (service-dns)
  • tcp: TCP/IP join (member-list from global.match.hazelcast.tcpMembers)
  • aws: AWS discovery join (aws.enabled=true) with:
    • global.match.hazelcast.aws.region
    • either global.match.hazelcast.aws.securityGroupName
    • or both global.match.hazelcast.aws.tagKey and global.match.hazelcast.aws.tagValue

Validation:

  • if Hazelcast is enabled and joinMode=tcp, global.match.hazelcast.tcpMembers must be non-empty
  • if Hazelcast is enabled and joinMode=aws:
    • environmentProfile must be aws
    • global.match.hazelcast.aws.region is required
    • set security group name or tag selector as noted above
  • entries in global.match.hazelcast.tcpMembers and AWS selector values in example files are placeholders and must be replaced for your environment

global.match.hazelcast.enabled is valid with:

  • global.db.type=postgres, or
  • global.db.type=mariadb, or
  • global.db.type=rocksdb with global.db.rocksdbCluster.enabled=true

Sync State Store

The chart configures Match sync-state persistence through:

  • global.match.syncState.store: file (default), hazelcast, or jdbc
  • global.match.syncState.hazelcastMapName: Hazelcast map name (default ProjectSyncState)
  • global.match.syncState.hazelcastCursorMapName: Hazelcast map name for transfer cursors (default ProjectSyncCursor)
  • global.match.syncState.jdbc.*: JDBC connection settings when store=jdbc

Default values:

global:
  match:
    environmentProfile: k8s
    syncLease:
      ttlMillis: 1800000
      heartbeatMillis: 10000
      waitAllSynchronizedTimeoutMillis: 300000
    syncEvent:
      watermarkGraceMillis: 60000
      watermarkCheckIntervalMillis: 60000
      reconciliationBlockTimeoutMillis: 10800000
      recoveryBufferMaxEvents: 100000
      gapRecovery:
        maxAttempts: 6
        retryMillis: 2000
        maxConcurrentProjects: 2
    initialLoadMetadata:
      allowSameEpochVersionMismatch: false
    syncState:
      store: file
      hazelcastMapName: ProjectSyncState
      hazelcastCursorMapName: ProjectSyncCursor
      jdbc:
        url: ""
        user: ""
        password: ""
        passwordSecretName: ""
        passwordSecretKey: sync-state-jdbc-password
        table: TMATCH_CLUSTER_SYNC_STATE
        cursorTable: TMATCH_CLUSTER_SYNC_CURSOR

Validation rules:

  • global.match.syncState.store must be one of file, hazelcast, jdbc
  • store=hazelcast requires global.match.hazelcast.enabled=true
  • store=jdbc requires global.match.syncState.jdbc.url

Example (Hazelcast-backed sync state):

global:
  match:
    hazelcast:
      enabled: true
    syncState:
      store: hazelcast
      hazelcastMapName: ProjectSyncState
      hazelcastCursorMapName: ProjectSyncCursor

Example (JDBC-backed sync state, secret-based password):

global:
  match:
    syncState:
      store: jdbc
      jdbc:
        url: jdbc:postgresql://my-postgres:5432/match
        user: match
        passwordSecretName: sync-state-secret
        passwordSecretKey: password
        table: TMATCH_CLUSTER_SYNC_STATE
        cursorTable: TMATCH_CLUSTER_SYNC_CURSOR

Cluster Environment Variables

Cluster-related backend variables are chart-managed through global.match.* and rendered in the Match env block by templates/match-worker-deployment.yaml and templates/match-master-deployment.yaml.

For the full variable reference, use:

Install with the embedded Postgres database:

helm install tolerant-match ./helm \
  --set global.db.type=postgres \
  --set global.db.name=match \
  --set global.db.user=match \
  --set global.db.password=change-me

Use an external Postgres service instead of the embedded DB:

helm install tolerant-match ./helm \
  --set global.db.type=postgres \
  --set global.db.embeddedPagingDatabase.enabled=false \
  --set global.db.host=my-postgres.my-namespace.svc.cluster.local \
  --set global.db.port=5432 \
  --set global.db.name=match \
  --set global.db.user=match \
  --set global.db.passwordSecretName=external-db-secret \
  --set global.db.passwordSecretKey=password

When embeddedPagingDatabase.enabled=false, global.db.host is required. When embeddedPagingDatabase.enabled=true, global.db.host must not be set. global.db.port is used for external SQL services; embedded Postgres always listens on 5432.

Example with a larger Postgres PVC:

helm install tolerant-match ./helm \
  --set global.db.type=postgres \
  --set global.db.name=match \
  --set global.db.user=match \
  --set global.db.password=change-me \
  --set containers.postgres.persistence.size=20Gi

MariaDB

MariaDB mode deploys:

  • the Match backend as a StatefulSet
  • config files projected into /opt/tolerant/config
  • a headless Match service for stable pod names

If global.db.embeddedPagingDatabase.enabled=true (default), it also deploys:

  • an in-cluster MariaDB Deployment
  • a MariaDB service
  • a MariaDB PVC

Install with the embedded MariaDB database:

helm install tolerant-match ./helm \
  --set global.db.type=mariadb \
  --set global.db.name=match \
  --set global.db.user=match \
  --set global.db.password=change-me

Use an external MariaDB service instead of the embedded DB:

helm install tolerant-match ./helm \
  --set global.db.type=mariadb \
  --set global.db.embeddedPagingDatabase.enabled=false \
  --set global.db.host=my-mariadb.my-namespace.svc.cluster.local \
  --set global.db.port=3306 \
  --set global.db.name=match \
  --set global.db.user=match \
  --set global.db.passwordSecretName=external-db-secret \
  --set global.db.passwordSecretKey=password

global.db.port is used for external SQL services; embedded MariaDB always listens on 3306. When embeddedPagingDatabase.enabled=true, global.db.host must not be set.

Example with a larger MariaDB PVC:

helm install tolerant-match ./helm \
  --set global.db.type=mariadb \
  --set global.db.name=match \
  --set global.db.user=match \
  --set global.db.password=change-me \
  --set containers.mariadb.persistence.size=20Gi

Service ID

TLMATCH_SERVICE_ID is persisted by Match in the database.

In RocksDB mode, the default is:

<release-name>-match

In Postgres and MariaDB modes, the default is the StatefulSet pod name, which stays stable across pod restarts and gives each replica its own identity.

If you need to override either value explicitly, set them in values:

global:
  db:
    tablePrefix: custom-prefix
  match:
    serviceId: tolerant-match

Match Probes

The chart configures livenessProbe, readinessProbe, and startupProbe for the Match container.

Default startupProbe:

containers:
  match:
    startupProbe:
      httpGet:
        path: /health/readiness
        port: http
      initialDelaySeconds: 10
      periodSeconds: 5
      timeoutSeconds: 5
      failureThreshold: 24

To disable it:

containers:
  match:
    startupProbe: null

Database Credentials

By default, the chart creates a secret named:

<release-name>-db-secret

with key:

db-password

To reuse an existing secret instead, set:

global:
  db:
    passwordSecretName: external-db-secret
    passwordSecretKey: password

Rendered config

By default, the following ConfigMaps are rendered:

  • <release-name>-match-config-postgres
  • <release-name>-match-config-mariadb
  • <release-name>-match-config-rocksdb
  • <release-name>-match-normalizer
  • <release-name>-match-synonyms

When global.match.hazelcast.enabled=true, the chart also renders:

  • <release-name>-match-hazelcast-config containing hazelcast.yaml (including required compact serializer registrations for cluster payload types)

In default mode (persistence.configFiles.enabled=false), the deployment mounts a single projected volume at /opt/tolerant/config that combines chart-managed config files:

  • matchserviceconfig.xml
  • normalizer.ini
  • synonymsDemo.ini

If persistence.configFiles.enabled=true, the chart mounts the PVC directly at /opt/tolerant/config (full directory ownership). Use this mode when matchserviceconfig.xml references multiple or custom file names and you want customer-managed config content.

Example:

persistence:
  configFiles:
    enabled: true
    existingClaim: ""
    accessMode: ReadWriteOnce
    size: 5Gi
    storageClassName: ""

When this mode is enabled, the claim must contain all required files for your matchserviceconfig.xml (including matchserviceconfig.xml itself and any referenced files).

Set existingClaim to use a pre-populated PVC. If existingClaim is left empty, the chart creates a PVC that you can populate out of band.

Runtime Config Ownership

Use config.managementMode to control config ownership:

  • declarative (default): chart-managed ConfigMaps mounted into /opt/tolerant/config
  • runtime: writable PVC mounted into /opt/tolerant/config so runtime/GUI edits are persisted

Value mapping by mode:

  • declarative:
    • active: persistence.configFiles.* (optional full-directory PVC ownership for /opt/tolerant/config)
    • ignored: persistence.runtimeConfig.*
  • runtime:
    • active: persistence.runtimeConfig.*
    • disallowed: persistence.configFiles.enabled=true

Runtime mode example:

config:
  managementMode: runtime

persistence:
  runtimeConfig:
    existingClaim: ""
    accessMode: ReadWriteOnce
    size: 5Gi
    storageClassName: ""
    seedFromConfigMaps:
      enabled: true
      image: busybox:1.36

Behavior in runtime mode:

  • chart mounts persistence.runtimeConfig at /opt/tolerant/config
  • chart does not mount the declarative projected config volume
  • persistence.configFiles.enabled is not allowed with runtime mode
  • for replicaCount > 1 with chart-managed runtime claim, persistence.runtimeConfig.accessMode must be ReadWriteMany
  • when persistence.runtimeConfig.seedFromConfigMaps.enabled=true, missing files are auto-seeded from chart ConfigMaps without overwriting existing files
  • seed step copies all files provided by the match-runtime-config-seed projected ConfigMap volume

If Hazelcast or license is enabled, the chart still mounts:

  • hazelcast.yaml (from chart ConfigMap)
  • match.lic (from chart Secret)

These are mounted as files into /opt/tolerant/config.

GUI Sidecar

The chart can run the GUI as an additional container in the same pod:

containers:
  gui:
    enabled: true
    image: registry.example.com/tolerant-products/match-gui:RELEASE
    imagePullPolicy: IfNotPresent
    port: 8081
    basePath: /ui
    apiBasePath: /
    env: []
    resources: {}

GUI_BASE_PATH and API_BASE_PATH are rendered from containers.gui.basePath and containers.gui.apiBasePath. Use containers.gui.env only for additional GUI container variables. Set containers.gui.port to the actual listen port of your GUI image (default 8081 in this chart).

The GUI should call the backend through localhost within the pod network namespace. Because the GUI runs in the same pod network namespace as the backend, containers.gui.port must not be 8080 when the GUI sidecar is enabled. The backend uses 8080.

To expose GUI through the same Ingress controller, enable GUI sidecar and GUI ingress path:

containers:
  gui:
    enabled: true
    port: 8081

ingress:
  enabled: true
  gui:
    enabled: true
    paths:
      - path: /ui
        pathType: Prefix

This adds:

  • Service port gui-http on the Match service (targeting GUI container port)
  • Ingress path routing to that GUI service port

In master mode (master.enabled=true):

  • worker GUI settings (containers.gui.*) must stay disabled
  • configure GUI on master via master.gui.enabled

GUI Compatibility Matrix

Scenario Required settings Not allowed / notes
GUI without cluster (single worker) containers.gui.enabled=true, ingress.gui.enabled=true, containers.gui.basePath=/ui, containers.gui.apiBasePath=/ containers.gui.basePath must start with /, must not be / when API path is /, and must not use reserved backend segments
GUI with SQL/RocksDB cluster workers same as above + clustered DB/Hazelcast settings (`global.db.type=postgres mariadb` or RocksDB cluster + Hazelcast)
GUI in master mode master.enabled=true, master.gui.enabled=true, master.guiEnabled=true, ingress.gui.enabled=true containers.gui.enabled must be false in master mode
Runtime config editing via GUI config.managementMode=runtime + shared runtime PVC for multi-replica (ReadWriteMany or existing shared claim) restart workloads after edits so all members reload config

Configuration Change Flow (Runtime Mode)

When config.managementMode=runtime, configuration files are writable on the runtime PVC and can be changed through GUI/API.

Use the full runtime operational flow (enable GUI, edit, restart workloads, optional GUI disable) in:

PVC Retention

By default, chart-created PVCs are kept on uninstall:

persistence:
  keepPVCOnUninstall: true

Set this to false if you want Helm to delete chart-managed PVC resources during helm uninstall:

persistence:
  keepPVCOnUninstall: false

Upgrade Lock Handling

If Match keeps a database lock during upgrades, enable the pre-upgrade stop hook to stop Match workloads before new pods are created.

upgrade:
  stopMatchBeforeUpgrade:
    enabled: true
    kubectlImage: bitnami/kubectl:1.32.4
    timeoutSeconds: 600

Behavior when enabled:

  • creates a Helm pre-upgrade hook Job
  • scales <release>-match StatefulSet to 0
  • scales <release>-match-master Deployment to 0 when master.enabled=true
  • waits until all Match pods are terminated (or fails on timeout)
  • allows Helm to continue with the upgraded release

Manual Initial Load

Initial load is manual-only and never auto-starts on pod startup.

Use the complete flow (CSV copy target selection, run/verify/disable job) in:

Large CSV mount

For large CSV input files, use the optional PVC-backed mount instead of a ConfigMap.

Enable it with values like:

persistence:
  largeCsv:
    enabled: true
    size: 20Gi
    storageClassName: ""
    mountPath: /opt/tolerant/incoming

This creates or uses a dedicated PVC and mounts it into the backend pod. In your Match XML you can then reference files under:

/opt/tolerant/incoming/<your-file>.csv

Example:

<csvFileInput filepath="/opt/tolerant/incoming/customers.csv" ...>

If you already have a PVC, set persistence.largeCsv.existingClaim instead of creating a new one.

Operational Playbooks

Tests

This chart includes helm-unittest suites under tests.

Run them with:

helm plugin install https://github.com/helm-unittest/helm-unittest
helm unittest ./helm

The test suites cover:

  • default RocksDB deployment behavior
  • Postgres multi-replica deployment behavior
  • MariaDB multi-replica deployment behavior
  • Postgres config table prefix rendering
  • validation behavior for rocksdb scaling and cluster-mode guards

Template File Map

Use this map to quickly find where to edit a specific rendered Kubernetes resource.

  • templates/_helpers.tpl: shared naming/labels/env/helper rendering functions.
  • templates/_validation.tpl: shared validation rules and error helpers used by validate.yaml.
  • templates/validate.yaml: chart input validation gate (db mode, clustering, runtime config guards).
  • templates/match-worker-deployment.yaml: main Match StatefulSet (workers or single-node deployment path).
  • templates/match-master-deployment.yaml: optional master Deployment for master+worker mode.
  • templates/match-headless-service.yaml: headless Service for Match pod identity and stable DNS.
  • templates/match-service.yaml: primary Service exposing backend (and optional GUI service port).
  • templates/match-master-service.yaml: Service for optional master deployment.
  • templates/match-configmap.yaml: Match config ConfigMaps for chart-managed default config files.
  • templates/match-hazelcast-configmap.yaml: generated hazelcast.yaml ConfigMap when Hazelcast is enabled.
  • templates/match-license-secret.yaml: optional Match license Secret.
  • templates/match-runtime-config-pvc.yaml: runtime config PVC for config.managementMode=runtime.
  • templates/match-config-files-pvc.yaml: optional PVC for large declarative config files.
  • templates/match-master-pvc.yaml: optional master data PVC in master mode.
  • templates/large-csv-pvc.yaml: optional PVC for large CSV inputs mounted into Match pods.
  • templates/match-initial-load-job.yaml: manual initial-load Job template.
  • templates/upgrade-stop-match-hook.yaml: pre-upgrade Helm hook that scales Match workloads down.
  • templates/pagingdb-deployment.yaml: embedded paging DB deployment (Postgres or MariaDB mode).
  • templates/pagingdb-service.yaml: Service for embedded paging DB.
  • templates/pagingdb-pvc.yaml: PVC for embedded paging DB persistence.
  • templates/pagingdb-secret.yaml: Secret for embedded paging DB credentials.
  • templates/ingress.yaml: optional Ingress routing for backend and GUI paths.
  • templates/servicemonitor.yaml: optional Prometheus Operator ServiceMonitor.
  • templates/NOTES.txt: post-install/upgrade output instructions.

Reference