OpenShift installation

Deephaven runs on Red Hat OpenShift with the standard Helm charts and the standard container images. This page covers what differs from the Kubernetes installation guide; follow that guide for everything it does not mention. kubectl is used throughout, since Routes and SecurityContextConstraints are ordinary API resources, but oc works equally well.

Deephaven has been validated on OpenShift 4.22 (Kubernetes 1.35). See the version support matrix.

What is different on OpenShift

This page covers:

  1. SecurityContextConstraints (SCCs). An SCC is an OpenShift admission policy controlling what a pod may ask for — user IDs, capabilities, host access. OpenShift's default SCC, restricted-v2, requires every container to run as a user ID from a range allocated to the namespace. Deephaven's charts ask for the fixed user IDs that its images own their files as (9000, 9001, 9002), so restricted-v2 refuses to admit the pods at all. They must be admitted under the built-in nonroot-v2 SCC instead. No custom SCC is required. See Grant the required SCCs.
  2. Storage. Some OpenShift platforms provide no ReadWriteMany storage class, which makes the bundled NFS chart required rather than optional. See If you use the bundled NFS server and Storage classes.
  3. Ingress. OpenShift fronts services with a Route rather than a cloud LoadBalancer. A LoadBalancer service still works on OpenShift hosted by a cloud provider, but on bare-metal clusters, it never receives an address, so Envoy runs as a ClusterIP service behind a passthrough Route. See Ingress: a passthrough Route.
  4. Image pull credentials. OpenShift nodes have no cloud identity for your registry, so a pull secret is always required, including for the etcd chart. See Image pull credentials.

Compact clusters, where the control-plane nodes are also schedulable, additionally need to account for the platform's own CPU requests; see Sizing note for compact clusters.

Everything else, including the etcd chart, the NFS chart, the Deephaven chart, worker pods launched at runtime, and the images, is unchanged.

Grant the required SCCs

In the commands on this page, deephaven is the namespace you install Deephaven into and dh-nfs is the namespace for the bundled NFS server. Substitute your own names throughout.

Create the namespace, then bind the built-in nonroot-v2 SCC to every ServiceAccount in it. nonroot-v2 only checks that a container does not run as root and accepts whatever user ID the pod requests, so the IDs the images own their files as are admitted unchanged. It is otherwise as strict as the default: all capabilities dropped, no privilege escalation, no host namespaces, and the runtime/default seccomp profile enforced.

Creating this Role and RoleBinding requires more than project administrator rights. Kubernetes RBAC refuses to let you grant a permission you do not hold, so the caller needs use on nonroot-v2 themselves, or escalate on roles. Treat it as a one-time task for a cluster administrator.

The binding targets the namespace's ServiceAccount group rather than named accounts because most Deephaven pods, and every worker pod launched at runtime, run as the namespace's default ServiceAccount. The two accounts the chart does create, for the query and merge servers and for the pre-release hook job, are covered by the same group.

Warning

OpenShift chooses the SCC for a pod by priority first, then restrictiveness. anyuid and privileged carry a higher priority than nonroot-v2, so if any of them is granted to a ServiceAccount the Deephaven pods use, every pod that account runs is admitted under the looser SCC, silently. Grant them only to ServiceAccounts that nothing else uses, and verify with the check below after installing.

If you use the bundled NFS server

The deephaven-nfs chart runs an in-kernel NFS server and needs the built-in privileged SCC. Install it in its own namespace so the grant never reaches the Deephaven namespace:

This binding targets the namespace's ServiceAccount group, matching the tested manifest in testing/openshift/nfs-privileged.yaml and the Deephaven binding above. The deephaven-nfs chart sets no serviceAccountName, so its pod runs as the namespace's default ServiceAccount; binding the group keeps the grant correct if a later version of the chart creates its own account. Because privileged is the most permissive SCC, keep this namespace dedicated to the NFS server.

If your cluster provides a ReadWriteMany storage class, use it with pre-existing PVCs as described in Configure shared storage and skip the NFS chart entirely.

Storage classes

As on any platform, use a storage class appropriate for your environment: list what your cluster offers with kubectl get storageclass and set it in the etcd chart (persistence.storageClassName), the NFS chart (pvc.storageClassName), and the Deephaven chart (global.storageClass). On self-managed OpenShift on Google Cloud, the classes are standard-csi and ssd-csi; on OpenShift Dedicated and on other clouds, the names differ.

Prefer an SSD-backed class. Deephaven's binary log and intraday volumes are small and write-heavy, and on disk types whose IOPS scale with volume size (such as Google Cloud's pd-standard, which backs standard-csi), a few-gigabyte volume receives very few IOPS.

Ingress: a passthrough Route

Envoy terminates TLS itself, so the Route uses passthrough termination. This keeps gRPC and HTTP/2 intact end to end, which Deephaven depends on. Set the Deephaven chart to a ClusterIP service on port 443 and disable external DNS management:

exposedPort is what Deephaven writes into the URLs it generates, so it must match the port the Route publishes rather than Envoy's own listener.

Create the Route before installing the Deephaven chart. A Route may name a Service that does not exist yet. Until the Route exists, the OpenShift router answers the hostname with its own self-signed certificate, and the management shell's dhconfig, which reaches the cluster through envoyFrontProxyUrl, fails TLS verification.

The hostname must resolve to the OpenShift router's address (the router-default LoadBalancer service in openshift-ingress) and be covered by the certificate in the deephaven-tls secret. The router's own wildcard certificate is self-signed and unsuitable; use a certificate from a public or corporate CA that clients trust. A Route whose hostname is outside the cluster's apps. domain is admitted by the default ingress controller.

Image pull credentials

OpenShift nodes have no cloud identity for your registry, so a pull secret is required, including for the etcd chart:

The Deephaven chart takes the same secret through imagePullSecrets, as in the installation guide.

Verify the installation

After the pods are running, confirm which SCC actually admitted them. A healthy-looking deployment admitted under the wrong SCC proves nothing about the configuration.

Every Deephaven pod, including worker pods, should show nonroot-v2. The NFS server pod, if you installed it, shows privileged in its own namespace.

Caution

Testing admission with kubectl apply --dry-run=server as a cluster administrator is misleading. Cluster administrators may use the privileged SCC, so any pod appears to be admitted. Impersonating a ServiceAccount with --as does not help either: it fails earlier, on ordinary RBAC, because the account cannot create pods. Check the openshift.io/scc annotation on a running pod instead, or ask the API server directly with a PodSecurityPolicyReview. Then confirm the images run as their own IDs:

Finally, open https://<route hostname>/ and start a Code Studio and a Persistent Query. Worker pods are created at runtime from the chart's ConfigMap templates rather than by Helm, so this exercises the last admission path.

Sizing note for compact clusters

On a compact OpenShift cluster, where the control-plane nodes also run workloads, the platform's own pods request a substantial share of the cluster before Deephaven gets any. Measured on the three-node, 8 vCPU-per-node cluster described in testing/openshift, OpenShift's own pods requested 7751m of the 22.5 allocatable cores, leaving under 15 for Deephaven. That overhead does not exist on GKE, EKS, or AKS, where the control plane is managed. Add it to the figures in Kubernetes resource requirements when sizing such a cluster; production deployments should use dedicated worker nodes.