Deploy MassAccess on-premise on Kubernetes with Helm

A public operator guide for selecting a data-placement profile, preparing a Kubernetes cluster, verifying an authorized release, bootstrapping Secret references, and running the install, verification, upgrade, rollback, backup, restore, diagnostics, and safe uninstall lifecycle.

InformationThis page applies only to the Kubernetes/Helm delivery. Docker Compose remains a separate supported self-contained package; do not combine Compose and Helm commands in one installation.

Release and responsibility boundary

Kubernetes uses two independently managed namespaced Helm releases. The reusable charts contain no customer Secret values and install no cluster-scoped controller or CRD.

ReleaseOwnsDoes not own
massaccess 0.12.1Nine application Deployments, ClusterIP Services, probes, optional routes, and NetworkPolicyData StatefulSets and PVCs, Secrets, licensor, controllers, and CRDs
massaccess-data 0.2.0Selected single-node bundled data StatefulSets, Services, and retained PVC templatesApplication Deployments, external stores, Secrets, and cluster-scoped resources

Supported matrix

These values come from the current chart metadata and administrator contract. Re-check the versioned artifact before every installation or upgrade.

AreaSupported contract
Kubernetes1.33–1.36
Helm4.2; apiVersion v2 chart format
Application identityImmutable X.Y or dev-<7–40 lowercase hex>; never latest
Configurationmassaccess.io/onprem-values/v1alpha1 with deployment.method=kubernetes
Bundled topologyOne instance per selected store, non-HA, RWO PVC, Retain/Retain claim retention
External PostgreSQL18.x, stable DNS, seven isolated roles, verify-full TLS or explicitly approved plaintext disable mode
External Kafka4.2.x, at least two bootstrap endpoints and three brokers, SASL_SSL or explicitly approved SASL_PLAINTEXT, RF 3 and min ISR 2
External ClickHouse26.4.x, single node, separate HTTP and native ports, three identities, optional verified TLS
External Redis8.6.x, stable writable-primary DNS, ACL namespace, AOF persistence, noeviction, optional verified TLS
Application scheduling floorNine Pods: 2025m/3425m CPU requests/limits and 1632Mi/2944Mi memory requests/limits in the local reference profile
Bundled-data scheduling floorFour Pods: 400m/1250m CPU requests/limits and 1024Mi/1920Mi memory requests/limits in the local reference profile

Cluster prerequisites and exact target

The customer operator provides and validates the Kubernetes platform before Helm can be used.

  • A reviewed non-system namespace and distinct application and data release names for one single-tenant installation
  • Working cluster DNS and a CNI whose default-deny NetworkPolicy enforcement is proven with allowed and denied traffic
  • Registry access and fresh pulls of every immutable image digest from a customer-managed imagePullSecret
  • For bundled stores, a reviewed CSI StorageClass with RWO, binding mode, reclaim policy, expansion capability, capacity, and topology facts
  • Enough quota and node allocatable CPU, memory, ephemeral storage, Pod count, and storage capacity for workloads plus platform overhead
  • An existing Ingress controller or Gateway API implementation and TLS Secret when external access is enabled
  • Customer monitoring, encrypted off-cluster backup target, retention, and restore-test procedure
bash
export MA_CONTEXT='customer-nonproduction'
export MA_NAMESPACE='massaccess'
export MA_APP_RELEASE='massaccess'
export MA_DATA_RELEASE='massaccess-data'

kubectl --context "$MA_CONTEXT" config current-context
kubectl --context "$MA_CONTEXT" get namespace "$MA_NAMESPACE" -o name
helm --kube-context "$MA_CONTEXT" list --namespace "$MA_NAMESPACE"
WarningChecked-in requests and limits are only a scheduling floor measured in a local reference environment. They are not customer sizing, capacity, performance, HA, or production-SLA evidence.

Data-placement profiles

The configurator generates one explicit placement decision for PostgreSQL, Kafka, ClickHouse, and Redis. The profile name must match all four modes.

ProfileBoundary
external-dataAll four stores are customer-operated external services; the data release renders no StatefulSet or PVC.
bundled-dataAll four stores use the separate single-node massaccess-data release with retained RWO PVCs.
mixed-dataEach store is explicitly external or bundled; only stores marked bundled are rendered by the data release.

Configurator and non-secret values

Choose Kubernetes and a placement profile in the on-premise configurator. Download the generated non-secret values only through the authorized product delivery path and keep platform overrides separate.

  • Confirm contractVersion is massaccess.io/onprem-values/v1alpha1 and deployment.method is kubernetes
  • Review endpoints, versions, TLS modes, Secret names and keys, public URLs, CIDRs, scheduling, resources, and exposure settings
  • Keep generated values, application platform overrides, data platform overrides, and digest-only image values as separate reviewed inputs
  • Do not use an ad hoc or temporary CI artifact as a customer download; use only the complete authorized release bundle

Verify the release candidate

Before install, upgrade, or rollback, verify the complete bundle's checksums, chart and image SBOM inventory, SLSA v1 provenance subjects, trusted source/ref/builder policy, and digest-only image overlay.

bash
python3 files/release/release.py verify \
  --bundle-dir ./massaccess-kubernetes-release \
  --policy files/release/policy.json

Validate schema and rendered inventory

Run strict lint and render every selected profile before cluster access. Review the diff, require zero Secret objects and secret values, and confirm external mode renders no data StatefulSet or PVC.

bash
helm lint ./massaccess --strict \
  -f ./massaccess/files/examples/generated-external-values.yaml \
  -f ./massaccess/files/examples/application-platform-values.yaml
helm template massaccess ./massaccess --namespace "$MA_NAMESPACE" \
  -f /secure/non-secret/generated-values.yaml \
  -f /secure/non-secret/application-platform-values.yaml \
  -f ./massaccess-kubernetes-release/values-images.json \
  > /tmp/massaccess-rendered.yaml
helm lint ./massaccess-data --strict \
  -f ./massaccess/files/examples/generated-bundled-values.yaml \
  -f /secure/non-secret/data-platform-values.yaml

Authorized bootstrap and Secret references

Reusable charts and non-secret values are separate from the authorized activation/bootstrap bundle. Charts reference pre-created namespaced Secrets and never own their values.

  • Validate the redacted bootstrap plan before applying it to the exact context, API server, and namespace
  • Use the customer's approved Vault, External Secrets, sealed-secret, or protected file process for store credentials and TLS material
  • Use --verify-only in pre-install and pre-upgrade automation and stop on missing keys or mismatching identity
  • Limit each Secret mount to the workloads that require it; the application ServiceAccount has no Secret-reader RBAC
bash
export MA_API_SERVER='https://kubernetes.example.invalid'

python3 files/bootstrap-secrets.py \
  --bundle /secure/path/massaccess-kubernetes-bootstrap.tar.gz \
  --context "$MA_CONTEXT" \
  --expected-server "$MA_API_SERVER" \
  --namespace "$MA_NAMESPACE" \
  --acknowledge-namespace "$MA_NAMESPACE"

# Apply only after reviewing the redacted plan above.
python3 files/bootstrap-secrets.py \
  --bundle /secure/path/massaccess-kubernetes-bootstrap.tar.gz \
  --context "$MA_CONTEXT" \
  --expected-server "$MA_API_SERVER" \
  --namespace "$MA_NAMESPACE" \
  --acknowledge-namespace "$MA_NAMESPACE" \
  --apply
WarningNever place credentials, Secret values, kubeconfig data, customer endpoints, or private material in Git, values files, --set arguments, shell history, logs, screenshots, issue text, or CI artifacts.

Install and repeat safely

After release, target, capacity, storage, backup, network, and Secret preflights pass, install the data release first and the application release second with the same generated hand-off.

  1. Verify immutable release identity and the exact context, namespace, and free release names
  2. Run authenticated preflights for every external dependency or the packaged bundled-storage preflight
  3. Install or upgrade massaccess-data, wait for every selected bundled store, then provision required roles, schemas, topics, and ACLs
  4. Install or upgrade massaccess, wait for all nine application workloads, then run helm test
  5. Run the same upgrade --install commands again and require unchanged healthy inventory without duplicate resources or lost Secret/PVC identity
bash
helm --kube-context "$MA_CONTEXT" upgrade --install "$MA_DATA_RELEASE" ./massaccess-data \
  --namespace "$MA_NAMESPACE" \
  -f /secure/non-secret/generated-values.yaml \
  -f /secure/non-secret/data-platform-values.yaml \
  --rollback-on-failure --wait --timeout 15m
helm --kube-context "$MA_CONTEXT" upgrade --install "$MA_APP_RELEASE" ./massaccess \
  --namespace "$MA_NAMESPACE" \
  -f /secure/non-secret/generated-values.yaml \
  -f /secure/non-secret/application-platform-values.yaml \
  -f ./massaccess-kubernetes-release/values-images.json \
  --rollback-on-failure --wait --timeout 15m
helm --kube-context "$MA_CONTEXT" test "$MA_APP_RELEASE" \
  --namespace "$MA_NAMESPACE" --logs
kubectl --context "$MA_CONTEXT" --namespace "$MA_NAMESPACE" \
  get deployment,statefulset,pod,service,job,persistentvolumeclaim

Post-install verification

Resource readiness is necessary but is not application acceptance.

  • Read back Helm revisions, Deployments, StatefulSets, Pods, Services, Jobs, PVCs, Events, readiness, and restart counts
  • Verify dashboard sign-in, API, WebSocket upgrade, webhook paths, licensing and metering through the configured TLS entry point
  • Perform authenticated application write/read flows for PostgreSQL, Kafka, ClickHouse, and Redis; a TCP connection alone is insufficient
  • Verify metrics discovery, bounded redacted logs and Events, and the deterministic diagnostic bundle without Secret or payload values

Ingress, Gateway API, TLS, WebSocket, and webhooks

Ingress and Gateway API are mutually exclusive chart integrations. Select exactly one when external access is required, or keep both disabled for internal verification.

  • The customer installs and operates the controller or Gateway, DNS, TLS termination, and certificate lifecycle
  • Reference only an existing TLS Secret and verify hostname, certificate chain, routes, and forwarded headers
  • Test dashboard, API, /web/api/ws/ WebSocket upgrade, messenger callbacks, and customer webhook routes end to end
  • The chart does not install a controller, Gateway, CRD, DNS record, or certificate automation

Upgrade, failed-upgrade recovery, and rollback

Treat application and data releases independently. Record history, immutable identities, values/rendered diff, dependency preflights, and a compatible restore result before changing either release.

  • A failed preflight must leave the last healthy revision in place and report a bounded component category
  • Correct only the proven contract defect, repeat the upgrade, then read back history, workloads, Secret/PVC identity, and application markers
  • Helm rollback changes controllers and images only; it does not reverse schema or data mutations
  • Roll back massaccess-data only when the storage format is backward compatible; otherwise use a verified forward migration or restore
bash
helm --kube-context "$MA_CONTEXT" history "$MA_APP_RELEASE" --namespace "$MA_NAMESPACE"
helm --kube-context "$MA_CONTEXT" upgrade "$MA_APP_RELEASE" ./massaccess \
  --namespace "$MA_NAMESPACE" \
  -f /secure/non-secret/generated-values.yaml \
  -f /secure/non-secret/application-platform-values.yaml \
  -f ./massaccess-kubernetes-release/values-images.json \
  --rollback-on-failure --wait --timeout 15m
helm --kube-context "$MA_CONTEXT" rollback "$MA_APP_RELEASE" PREVIOUS_REVISION \
  --namespace "$MA_NAMESPACE" --wait --timeout 15m

Backup and restore

External-store backup, HA, failover, retention, and RPO/RTO are customer responsibilities. Bundled mode requires encrypted off-cluster, component-consistent backups and a restore drill in a clean isolated target.

  • PostgreSQL: consistent logical dump; Kafka: quiesced single-broker backup; ClickHouse: consistent backup interface; Redis: persistence-safe AOF/RDB copy after sync
  • Record the backup identity, retention, encryption, and restore result without credentials or customer data
  • Accept restore only after the original application marker is read through each component's client protocol on fresh storage identities
  • Application uninstall does not own data; data release uninstall removes controllers and Services but retains PVCs
WarningA Bound PVC, an archive, or a zero exit code is not restore evidence. Numerical RPO/RTO requires repeated proof on the customer's CSI and backup target.

Diagnostics and incident flow

Stop broad mutations, collect bounded evidence, classify the failing contract, and prove the exact failing path before recovery.

  • Schema or render failure: fix the reported values path; do not remove values.schema.json or weaken validation
  • Preflight Job failure: inspect the bounded category, Job log, Events, DNS, routes, CIDRs, credentials, TLS, ACLs, grants, and storage facts
  • CreateContainerConfigError: verify the referenced Secret and key names without printing or decoding values
  • ImagePullBackOff: verify registry access, imagePullSecret reference, immutable digest, and release provenance
  • NotReady with an open TCP port: inspect the application's readiness endpoint and authenticated dependency flow
  • Pending PVC: stop and inspect StorageClass binding, topology, and capacity; never substitute hostPath
  • Recover the dependency or controller, then verify readiness, restart counts, authenticated application markers, and the redacted diagnostic hash

Safe uninstall

Read back the exact context, namespace, releases, and PVC inventory before each action. Uninstall the application separately from the data controllers.

bash
kubectl --context "$MA_CONTEXT" get namespace "$MA_NAMESPACE" -o name
helm --kube-context "$MA_CONTEXT" status "$MA_APP_RELEASE" --namespace "$MA_NAMESPACE"
helm --kube-context "$MA_CONTEXT" uninstall "$MA_APP_RELEASE" --namespace "$MA_NAMESPACE"
helm --kube-context "$MA_CONTEXT" status "$MA_DATA_RELEASE" --namespace "$MA_NAMESPACE"
helm --kube-context "$MA_CONTEXT" uninstall "$MA_DATA_RELEASE" --namespace "$MA_NAMESPACE"
kubectl --context "$MA_CONTEXT" --namespace "$MA_NAMESPACE" get persistentvolumeclaim
WarningRoutine uninstall deliberately has no PVC, PV, snapshot, backup, Secret, or namespace deletion command. Data or identity deletion is a separate explicitly authorized procedure after restore verification and retention approval.

Confirmed limits

  • Bundled data is single-node and non-HA; multi-node topology, drain, replication, failover, and PDB claims are not supported
  • The charts do not provision or harden Kubernetes, DNS, CNI, CSI, StorageClass, Ingress/Gateway controllers, TLS automation, monitoring, or backup infrastructure
  • Docker Desktop hostpath and local reference-CNI evidence does not prove customer CSI/CNI, HA, capacity, performance, disaster recovery, or production SLA
  • The release contract does not claim cryptographic signing or absence of vulnerabilities; use the documented checksum, SBOM, SLSA provenance, and policy verification boundary