OpenShift installation
OpenShift enforces strict Security Context Constraints (SCC) policies that prevent certain resources from being managed inside a standard Helm release. Deploying DataQI on OpenShift (or Azure Red Hat OpenShift - ARO) therefore requires a two-phase installation process.
- Phase 1 — Install the CloudNativePG (CNPG) operator and its
SecurityContextConstraintsas raw manifests, outside of Helm. - Phase 2 — Install the DataQI Helm chart with the embedded CNPG sub-chart disabled.
Why two phases?
Section titled “Why two phases?”The CNPG operator requires a custom SecurityContextConstraints (SCC) to run with its required UID (10001). The SCC is a cluster-scoped, OpenShift-specific resource. It cannot be cleanly managed inside a namespaced Helm release alongside the application resources. Installing it separately keeps the Helm release idempotent and avoids conflicts if the CNPG operator is already present on the cluster.
Phase 1: Cluster bootstrap (run once per cluster)
Section titled “Phase 1: Cluster bootstrap (run once per cluster)”1a. Create the DataQI namespace
Section titled “1a. Create the DataQI namespace”kubectl create namespace <namespace>1b. Install the CNPG operator
Section titled “1b. Install the CNPG operator”Apply the CNPG operator as a raw manifest. Use the version pinned in the chart’s Chart.yaml:
# Apply the operator manifest using server-side applykubectl apply --server-side --force-conflicts -f https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/release-1.25/releases/cnpg-1.25.1.yamlWait for the operator to become ready:
kubectl rollout status deployment/cnpg-controller-manager -n cnpg-system1c. Apply the CNPG SecurityContextConstraints
Section titled “1c. Apply the CNPG SecurityContextConstraints”The SCC grants the CNPG operator the permissions it needs to run under OpenShift’s restricted-v2 policy.
Download the cnpg-scc.yaml manifest and apply it to your cluster:
kubectl apply -f cnpg-scc.yaml1d. Ensure there is a RWX storage class available
Section titled “1d. Ensure there is a RWX storage class available”The DataQI cache and persistent filesystem claims both require a ReadWriteMany (RWX) storage class. On Azure and many other cloud providers, this must be created manually as the default storage classes are RWO only, for example:
apiVersion: storage.k8s.io/v1kind: StorageClassmetadata: name: azure-fileprovisioner: file.csi.azure.comparameters: skuName: Standard_LRSreclaimPolicy: RetainallowVolumeExpansion: truevolumeBindingMode: Immediatekubectl apply -f azure-file-storage-class.yaml1e. Create a NetworkPolicy for Operator Communication
Section titled “1e. Create a NetworkPolicy for Operator Communication”If your OpenShift cluster enforces a default-deny network policy, the CNPG operator (running in cnpg-system) will be unable to communicate with the Postgres pods (running in your DataQI namespace). The operator requires access to port 8000 on the Postgres pods to check their health and status.
Apply a NetworkPolicy in your DataQI namespace to allow this ingress traffic:
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: allow-cnpg-operator # Change this to your DataQI installation namespace namespace: dataqispec: podSelector: {} # Selects all pods in the DataQI namespace ingress: - from: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: cnpg-system ports: - protocol: TCP port: 8000Phase 2: Install the DataQI Helm chart
Section titled “Phase 2: Install the DataQI Helm chart”With the cluster bootstrapped, install the main chart. The CNPG sub-chart must be disabled because the operator is already running from Phase 1.
helm upgrade --install dataqi ./dataqi-<chart-version>.tgz \ --namespace <namespace> \ -f <values-file>.yamlYour customer values file must include the following OpenShift-specific configurations:
# Disable CNPG sub-chart — operator was installed in Phase 1cloudnative-pg: enabled: false
platform: openshift: enabled: true # Enables SCC and Ingress resources azureAlb: healthCheckPolicy: enabled: false # Azure ALB must be disabled on non-Azure clusters storageClass: shared: "<rwx-storage-class>" # RWX default for cache and persistent claims # Optional: use separate RWX classes when persistent storage has a different backup policy. # sharedFilesystem: # storageClass: "<cache-rwx-storage-class>" # persistentFilesystem: # storageClass: "<backed-up-rwx-storage-class>"
routing: type: "ingress" provider: "openshift" # Configures routing for OpenShift routes/ingressDomain naming on ARO / OpenShift
Section titled “Domain naming on ARO / OpenShift”Some pre-configured OpenShift clusters (such as ARO) typically provide a wildcard DNS entry (e.g., *.apps.<cluster>.aroapp.io). All three DataQI hostnames must be single-level subdomains of that wildcard.
Set global.domain to a subdomain of apps.*, not to apps.* itself:
global: # Correct — all three generated hostnames match *.apps.<cluster> domain: "dataqi.apps.<cluster>.aroapp.io"
# Wrong — generated hostnames (e.g., api-apps) do not match the wildcardglobal: domain: "apps.<cluster>.aroapp.io"