Skip to content

OpenShift Installation

This guide covers installing Traceable Platform on OpenShift clusters with two storage options.

Overview

OpenShift installations have specific requirements:

  • Custom namespace with restricted permissions
  • No cluster-scoped permissions (ingress-nginx cannot be used)
  • OpenShift Route for ingress instead of Ingress Controller
  • Security Context Constraints (SCC) compliance

For Route TLS termination modes (passthrough, edge, reencrypt) and the underlying traceable-router configuration, see Connecting to the Traceable Platform.

Prerequisites

  • OpenShift 4.x cluster
  • oc CLI configured with cluster access
  • Namespace-level permissions
  • Storage class supporting RWO and RWX access modes
  • TLS certificates for the platform DNS

Storage Options

Choose one of the following storage configurations:

Option Storage Class RWO RWX Use Case
Option 1 External NFS External NFS server available
Option 2 OpenShift Data Foundation (ODF) Native OpenShift storage with CephFS

Installation Steps

Step 1: Create Namespace

kubectl create ns traceable

Step 2: Get Security Context IDs

Get the UID range and supplemental groups for the namespace:

kubectl describe ns traceable

Look for:

  • openshift.io/sa.scc.uid-range - Use the first number for runAsUser
  • openshift.io/sa.scc.supplemental-groups - Use the first number for fsGroup

Example output:

openshift.io/sa.scc.uid-range=1000800000/10000
openshift.io/sa.scc.supplemental-groups=1000800000/10000

Step 3: Export Variables

export NAMESPACE=traceable
export DNS=<your-platform-dns>
export REPO_USER=<registry-username>
export REPO_PWD=<registry-password>
export WORKFLOW_VERSION=<version>

Step 4: Common Values File

Create openshift-common-values.yaml:

cluster:
  triggerInstall: false
  workflows:
    - name: install
      items:
        - name: traceable-nginx
          initCfg:
            remove: true
        - name: upload_install_tls_certs
          initCfg:
            runOnInit: true
        - name: traceable-router
          create: true
          initCfg:
            runOnInit: true
        - name: traceable-ingress
          initCfg:
            runOnInit: true
        - name: ratelimit
          create: true
        - name: collaborator
          create: false
          localCfg:
            lockVersion: true
  helmValues:
    global: |
      kstreams-app-version-checker:
        securityContext:
          runAsUser: {{int .tfi.runAsUser }}

      selfSignedCertificates:
        enabled: true
        securityContext:
          runAsUser: {{ int .tfi.runAsUser }}
          runAsNonRoot: false

      podSecurityContext:
        fsGroup: {{ int .tfi.fsGroup }}
        runAsUser: {{ int .tfi.runAsUser }}

      kafkaTopicPartitionChecker:
        securityContext:
          runAsUser: {{int .tfi.runAsUser }}

    traceable-prometheus: |
      prometheus:
        prometheus-node-exporter:
          service:
            port: 9101    # OpenShift has its own Prometheus installed    

    traceable-keycloak: |
      keycloak:
        bootstrap:
          securityContext:
            fsGroup: {{int .tfi.fsGroup }}
            runAsUser: {{int .tfi.runAsUser }}

    mongodb: |
      exporter:
        serviceMonitor:
          enabled: false
        dashboard:
          namespace: {{.info.namespace}}
        securityContext:
          runAsUser: {{int .tfi.runAsUser}}

    postgresql: |
      postgresql:
        primary:
          podSecurityContext:
            fsGroup: {{int .tfi.fsGroup}}
          containerSecurityContext:
            runAsUser: {{int .tfi.runAsUser}}
        metrics:
          containerSecurityContext:
            runAsUser: {{int .tfi.runAsUser}}
satellite:
  enabled: false
ingress:
  enabled: false
installScope: namespace

Option 1: Installation with External NFS

Use this option when you have an external NFS server available.

NFS Prerequisites

  • NFS server accessible from all OpenShift nodes
  • NFS export path configured with appropriate permissions
  • Network connectivity between nodes and NFS server

TI Values File (NFS)

Create openshift-ti-values-nfs.yaml:

storageClassName: nfs-client
cluster:
  tfi:
    storageClass: nfs-client
    sharedPvStorageClass: nfs-client
    runAsUser: 1000800000    # Replace with your namespace uid-range
    fsGroup: 1000800000      # Replace with your namespace supplemental-groups

nfs-provisioner:
  enabled: true
  nfs:
    server: <nfs-server-ip>      # Replace with your NFS server IP
    path: <nfs-path>           # Replace with your NFS export path

Install with NFS

./clustermgr install-ti \
    --dns=${DNS} \
    --email admin@example.com \
    --password <secure-password> \
    --version ${WORKFLOW_VERSION} \
    --registry-host="pkg.harness.io/ieq3j_9otlwbpfz-uryoda/docker-external" \
    --registry-prefix="" \
    --registry-user ${REPO_USER} \
    --registry-password ${REPO_PWD} \
    --namespace ${NAMESPACE} \
    --ti-values openshift-common-values.yaml \
    --ti-values openshift-ti-values-nfs.yaml

NFS SCC Configuration

Grant the NFS provisioner the required SCC:

oc adm policy add-scc-to-user hostmount-anyuid \
    system:serviceaccount:${NAMESPACE}:traceable-installer-nfs-provisioner \
    -n ${NAMESPACE}

Option 2: Installation with OpenShift Data Foundation (ODF)

Use this option to leverage OpenShift's native storage with CephFS for RWX support.

ODF Prerequisites

  • OpenShift Data Foundation (ODF) installed and configured
  • CephFS storage class available for RWX volumes
  • Ceph RBD storage class available for RWO volumes

Verify ODF Storage Classes

oc get storageclass | grep -E "cephfs|rbd"

Expected output:

ocs-storagecluster-ceph-rbd      openshift-storage.rbd.csi.ceph.com    Delete   Immediate   true
ocs-storagecluster-cephfs        openshift-storage.cephfs.csi.ceph.com Delete   Immediate   true

TI Values File (ODF)

Create openshift-ti-values-odf.yaml:

storageClassName: ocs-storagecluster-ceph-rbd
cluster:
  profile: medium
  tfi:
    storageClass: ocs-storagecluster-ceph-rbd           # RWO storage class
    sharedPvStorageClass: ocs-storagecluster-cephfs     # RWX storage class
    runAsUser: 1000800000    # Replace with your namespace uid-range
    fsGroup: 1000800000      # Replace with your namespace supplemental-groups

Install with ODF

./clustermgr install-ti \
    --dns=${DNS} \
    --email admin@example.com \
    --password <secure-password> \
    --version ${WORKFLOW_VERSION} \
    --registry-host="pkg.harness.io/ieq3j_9otlwbpfz-uryoda/docker-external" \
    --registry-prefix="" \
    --registry-user ${REPO_USER} \
    --registry-password ${REPO_PWD} \
    --namespace ${NAMESPACE} \
    --ti-values openshift-common-values.yaml \
    --ti-values openshift-ti-values-odf.yaml

Post-Installation Steps

1. Create DNS Record

Create a CNAME record for your platform DNS pointing to the OpenShift Route canonical hostname:

oc get route traceable-router -n ${NAMESPACE} -o jsonpath='{.status.ingress[0].routerCanonicalHostname}'

2. Grant Node Exporter SCC

oc adm policy add-scc-to-user node-exporter \
    -z traceable-prometheus \
    -n ${NAMESPACE}

Storage Comparison

Feature NFS ODF (CephFS/RBD)
RWO Support ✓ (Ceph RBD)
RWX Support ✓ (CephFS)
Pod Mobility
External Dependency NFS Server None (native)
Performance Network dependent High (local Ceph)
HA/Replication External Built-in
Management External OpenShift Console

Namespace Resource Quotas

Note: Ignore this section if Resource Quotas are not set on the namespace.

If Resource quotas are set on the namespace, allocate 2x of the request value to limits.

Why 2x Ratio?

OpenShift enforces resource quotas at the namespace level. Setting appropriate limits ensures:

  • Pods can burst when needed
  • Resource allocation is predictable
  • The cluster scheduler can make informed decisions

Example LimitRange

apiVersion: v1
kind: LimitRange
metadata:
  name: traceable-limit-range
  namespace: traceable
spec:
  limits:
    - max:
      cpu: "16"
      memory: "64Gi"
    min:
      cpu: "100m"
      memory: "128Mi"
    default:
      cpu: "1"
      memory: "2Gi"
    defaultRequest:
      cpu: "500m"
      memory: "1Gi"
    type: Container

Troubleshooting

SCC Permission Errors

If pods fail to start due to SCC restrictions:

# Check pod events
oc describe pod <pod-name> -n ${NAMESPACE}

# Verify SCC assignments
oc get scc -o wide

Storage Class Issues

Verify storage classes are available:

oc get storageclass
oc get pvc -n ${NAMESPACE}

Route Not Working

Check route status:

oc get route traceable-router -n ${NAMESPACE}
oc describe route traceable-router -n ${NAMESPACE}

Support

For OpenShift-specific deployment assistance, contact support@harness.io.

Provide:

  • OpenShift version
  • Storage configuration (NFS or ODF)
  • Namespace SCC settings
  • Pod events and logs