Skip to main content

Install on OpenShift with GreyMatter

This page installs Kamiwaza into one namespace of an OpenShift cluster whose service mesh is GreyMatter. You publish Kamiwaza's GreyMatter configuration, then run a single helm upgrade --install as a namespace-scoped identity. The chart creates only namespaced objects.

Before you start​

You needNotes
A prepared clusterEvery check in Platform Prerequisites passes, and you have the facts it told you to record.
The installer kubeconfigThe namespace-scoped identity from Installer identity. Never install with a cluster-admin kubeconfig.
oc or kubectl, and Helm 3.14 or laterHelm pulls the chart from an OCI registry. With Helm 4, add --server-side=false to every helm upgrade --install on this page; see step 4.
jq, curl, and gitUsed by the configuration and verification steps.
Push access to the tenant configuration repositoryThe repository and branch from Tenant configuration repository. If the platform administrator keeps that access, they run step 3.
A license filelicense.lic, issued by Kamiwaza. See License File.

No internet access? Do Install Without Internet Access first. It copies the release into your registry and gives you values to merge into your values file in step 2. In steps 3 and 4, use the chart from your registry in place of the release location.

Point kubectl and helm at the installer identity for every command on this page:

export KUBECONFIG=<path to the installer kubeconfig>

Kamiwaza installs into the kamiwaza namespace. The examples use kamiwaza.example.com as the domain; substitute your own.

Step 1: Add the license​

Create a Secret from the license file. The key must be license.lic:

kubectl -n kamiwaza create secret generic kamiwaza-license \
--from-file=license.lic=./license.lic --dry-run=client -o yaml \
| kubectl apply -f -

This also works on a reinstall: uninstalling keeps this Secret, and the command updates it in place.

The chart refuses to render until a license is configured and the EULA is accepted. You do both in the values file in the next step.

Step 2: Write your values file​

Your values file selects the OpenShift with GreyMatter platform and carries this cluster's facts and your acceptance of the EULA. Everything else is the chart's defaults for that platform. Keep the file somewhere safe and outside any shared repository; you will need it again for upgrades.

Required values​

ValueSet it to
global.platformosgm. This switches the chart to GreyMatter routing and OpenShift's security model.
global.eula.acceptedtrue, after reading the EULA. The render fails without it.
core.license.existingSecretkamiwaza-license, the Secret from step 1. The render fails without it.
global.domainThe Kamiwaza domain.
core.inferenceResources.enabled, .ownerPublicKey, .clusterBindingId, .bundleConfigMapenabled defaults to true; leave it there, because false fails the render. From 1.4.1, leave the other three unset: the install needs no cluster owner, local CPU models (including the default embedding model) run under Kamiwaza's built-in CPU baseline profile, which is not owner-attested, and GPU models are refused; see Owner trust levels. Optional hardening, and what GPU models need: owner-attested mode, with a profile the cluster owner signs; see Move to owner-attested mode. If you set ownerPublicKey and clusterBindingId, set both: with only one, an install into an existing namespace stops with owner trust is half-configured: .... On 1.4.0 both are required, and the render fails without them: leaving them unset needs 1.4.1 or later, so check the --version in your install command; see Owner trust on 1.4.0. To serve models on GPUs, prepare the nodes first; see GPU nodes.
global.namespaces.platform, .extensions, .sandboxes, .observability, .ca, .registry, .systemkamiwaza, for each one. Everything runs in that one namespace.
global.storage.stateful.standard, .postgres, .etcd, .registry, .extensionsThe StorageClass you recorded, for each one.
core.extensionRuntime.kubernetesApi.egressCidrsEvery Kubernetes API Service address and every endpoint address you recorded, each as /32 (IPv4) or /128 (IPv6). Copy them exactly: a wrong address installs cleanly and then fails at runtime. The render fails without this value.
global.greymatter.proxy.imageThe GreyMatter proxy image you recorded, split into registry, repository, and tag. It must match the proxy version your GreyMatter platform runs.
global.trust.edgeAnchor.pemThe mesh CA that signs the edge certificate, the contents of edge-ca.crt from Edge certificate. Kamiwaza's workloads verify the edge with it. Without it (or one of the other fixes), the install stops with the Context TLS preflight error. Even with another fix, extensions cannot verify the platform without it; see Edge certificates minted outside the chart. Do not create the kamiwaza-edge-trust ConfigMap yourself.
core.inferenceResources.allocationVerification, global.greymatter.sidecarEnrollment.sidecarResourceReadlabel and false, as the example file sets them. They let the installer hold only the built-in admin role; see Installer identity.

Values that depend on your cluster​

ValueSet it when
global.greymatter.proxy.imagePullSecretGreyMatter's image pull Secret in the namespace is not named greymatter-image-pull.
global.greymatter.edge.imageThe edge's proxy image must not be the GreyMatter platform's default: for example, the default is a digest, or the edge image was set by hand in the tenant repository. Use the same proxy as global.greymatter.proxy.image, with a tag and no digest: {repository: greymatter-proxy, tag: "1.17.2"} (the registry defaults to oci.download.greymatter.io, and global.airgap.registry.url relocates it), or one reference such as oci.download.greymatter.io/greymatter-proxy:1.17.2, used as written. On an air-gapped site, a reference must name your mirror. Step 3 writes it into the edge's configuration; see Keep site settings across publishes.
global.imagePullSecretsKamiwaza images come from a registry that needs credentials. List the pull Secret you created, for example [{name: kamiwaza-pull}].

Optional values​

ValueNotes
registry.persistence.size, seaweedfs.persistence.sizeVolume sizes for the model registry cache (default 500Gi) and the built-in object store (default 100Gi). Lower them when storage is small; see Block storage. Set them before the first install; they can't be reduced later.
core.userDefaults.adminPasswordThe password for the admin user. Leave it unset and Kamiwaza generates one, which you read back in step 5. Setting it here stores it in the Helm release. It applies at first install only; changing it later does not rotate the password.

Example​

The chart ships an example values file for this environment, examples/openshift-greymatter.yaml. Pull the chart for the version you install and copy the file:

helm pull oci://ghcr.io/kamiwaza-ai/releases/kamiwaza/charts/kamiwaza --version 1.4.1 --untar
cp kamiwaza/examples/openshift-greymatter.yaml kamiwaza-values.yaml

Without internet access, pull the chart from your registry instead.

Then edit kamiwaza-values.yaml: replace this cluster's facts as the tables above list, and set global.eula.accepted to true once you have read the EULA. The file comments out its global.trust.edgeAnchor blocks: uncomment the pem block and set it as Required values describes.

Step 3: Publish the GreyMatter configuration​

GreyMatter needs Kamiwaza's configuration before the install. It defines the edge that serves the Kamiwaza domain, the routes to Kamiwaza's services, and the sidecars GreyMatter adds to them. The chart generates this configuration from your values file, so it always matches the release you install. You render it, commit it to the tenant configuration repository, and GreyMatter Sync applies it. On an upgrade, first check the edge's proxy image, as in Keep site settings across publishes.

  1. Clone the tenant configuration repository on its branch, and go to the project the platform administrator created:

    git clone -b tenant/kamiwaza https://git.example.com/org/kamiwaza-gsl.git kamiwaza-gsl
    cd kamiwaza-gsl/_tenants/kamiwaza

    If you already have a clone, run git switch tenant/kamiwaza and git pull in it instead.

  2. Render the configuration and write its files into the project. This does not change the cluster.

    helm template kamiwaza \
    oci://ghcr.io/kamiwaza-ai/releases/kamiwaza/charts/kamiwaza \
    --version 1.4.1 \
    --namespace kamiwaza \
    --values <absolute path to kamiwaza-values.yaml> \
    --show-only charts/network/templates/greymatter/gsl-bundle.yaml \
    | kubectl create --dry-run=client --validate=false -f - -o json > gsl-bundle.json

    jq -r '.data["file-list.txt"]' gsl-bundle.json | grep '^greymatter/' \
    | while read -r f; do
    case "$f" in greymatter/generated/*) [ -e "$f" ] && continue ;; esac
    mkdir -p "$(dirname "$f")"
    jq -r --arg k "${f//\//__}" '.data[$k]' gsl-bundle.json > "$f"
    done
    rm gsl-bundle.json

    This writes the greymatter/ directory. It leaves the .greymatter file and cue.mod/ directory that the GreyMatter CLI created unchanged. It creates the files under greymatter/generated/ only if they do not exist: Kamiwaza records its app and model routes there while it runs, so an upgrade must keep them.

    Every file the chart renders under greymatter/ is replaced, including greymatter/edges/edge.cue. A change made by hand in those files is lost; see Keep site settings across publishes.

  3. Check that the configuration names your domain and the edge image you expect, then commit and push:

    grep -rh 'api_endpoint' greymatter | sort -u
    # Expect https://kamiwaza.example.com, and paths under it
    grep -hE '^[[:space:]]*image:' greymatter/edges/*.cue
    # Expect your global.greymatter.edge.image; no output means the platform default
    git diff --stat greymatter
    git add greymatter
    git diff --cached --quiet || git commit -m "Kamiwaza 1.4.1 GreyMatter configuration"
    git pull --rebase
    git push

    On a reinstall or an upgrade that changes nothing here, there is nothing to commit, and the push is a no-op.

Check that GreyMatter applied it and the edge serves the domain:

kubectl -n kamiwaza get route \
-o custom-columns='NAME:.metadata.name,HOST:.spec.host,TLS:.spec.tls.termination'
# Expect a Route for kamiwaza.example.com with TLS "passthrough"
kubectl -n kamiwaza get pods -l app.kubernetes.io/name=edge
# Expect the edge pod Running and ready

curl -sk -o /dev/null -w '%{http_code}\n' https://kamiwaza.example.com/
# Any HTTP status from the edge proves the Route and edge certificate work.
# Before Kamiwaza is installed, expect 404 or 503.

GreyMatter can take a few minutes to sync. A connection that fails, or ends during the TLS handshake, is not a sync delay: see Troubleshooting.

Keep site settings across publishes​

Publishing replaces the files the chart renders. Put every site-specific edge setting in your values file, not in the tenant repository:

ValueEdge setting
global.greymatter.edge.imageThe edge's proxy image. Unset, the edge uses the GreyMatter platform's default.
global.greymatter.edge.gatewayType, .exposedPortHow the edge is exposed (OpenshiftRoute and 443 under osgm).
global.greymatter.edge.tlsSecretNameThe edge certificate Secret (default greymatter-edge-ingress).
global.greymatter.edge.deltaXdsDelta xDS on the edge (true under osgm).

Before the first publish of an upgrade, compare the edge's running image with the platform default:

kubectl -n kamiwaza get deploy edge \
-o jsonpath='{.spec.template.spec.containers[0].image}{"\n"}'

If it shows a digest (@sha256:), or you set it by hand earlier, set global.greymatter.edge.image to that proxy's registry, repository and tag, with no digest, before you publish. A digest-only edge image makes the GreyMatter edge operator build a version label longer than 63 characters, and Kubernetes refuses the edge Deployment: the edge Deployment disappears, kubectl -n kamiwaza get events shows must be no more than 63 characters, and the site is down until the edge image is fixed. The chart refuses a digest in global.greymatter.edge.image for the same reason. Check that the tag resolves to the digest you expect before you use it:

skopeo inspect --format '{{.Digest}}' docker://oci.download.greymatter.io/greymatter-proxy:1.17.2

Step 4: Install​

Record the start time first. The verification step uses it to ignore events from before this install.

INSTALL_START=$(date -u +%Y-%m-%dT%H:%M:%SZ)

helm upgrade --install kamiwaza \
oci://ghcr.io/kamiwaza-ai/releases/kamiwaza/charts/kamiwaza \
--version 1.4.1 \
--namespace kamiwaza \
--values <absolute path to kamiwaza-values.yaml> \
--timeout 70m
  • Do not add --create-namespace. The namespace belongs to the platform administrator.
  • With Helm 4, add --server-side=false, on the first install and every upgrade. OpenShift adds its own pull Secret to each of Kamiwaza's service accounts, and Helm 4's default server-side apply then refuses every later upgrade with conflict with "openshift.io/image-registry-pull-secrets_service-account-controller". Helm 3 is not affected.
  • A typical install takes 5 to 15 minutes, most of it pulling images.

To upgrade to a later release in the same line:

  1. Make sure your values file sets allocationVerification: label and sidecarResourceRead: false (see Installer identity).
  2. If an earlier release was installed with the kamiwaza-namespace-admin-prerequisites chart, the platform administrator binds admin to the installer as Installer identity shows, sets up the node read in GPU nodes if you serve models on GPUs, and then removes the chart: helm uninstall kamiwaza-prerequisites --namespace kamiwaza-installer.
  3. Repeat step 3 with the new version.
  4. Rerun the command in this step with the new --version and the same values file.

When step 3 (publishing the GreyMatter configuration) commits changes, run it and the install command back to back: between them, the API can be unavailable. To upgrade from 1.3, see Upgrade Kamiwaza.

Install with Argo CD​

On OpenShift with GreyMatter, an upgrade from 1.3 through Argo CD is not supported in 1.4.1: Argo CD's render of the chart contains no Keycloak password migration here, so local accounts, the administrators included, could not sign in afterwards. Upgrade from 1.3 with Helm, as Upgrade Kamiwaza describes, then move the installation to Argo CD.

A fresh install through Argo CD was not tested on OpenShift with GreyMatter. Argo CD was tested with 1.4.1 on Kubernetes with the standalone Envoy edge and no Istio only. Never sync 1.4.0 or earlier with Argo CD, or with any other tool that applies a rendered chart.

If you install through Argo CD here, follow Install with Argo CD for the Application, the checks and the limits, with these differences:

  • Where that section says to prepare as for a Helm install, prepare as this page does: Platform Prerequisites for OpenShift with GreyMatter and steps 1 to 3 of this page. The edge certificate here is the one those prerequisites describe, not the Secret that network.tls.secretName names; the kamiwaza-edge-trust ConfigMap and the network.tls values named in that section belong to the Kubernetes pages.
  • Argo CD's application controller applies the chart and creates its Roles, with its own identity. Ask the platform team to confirm that it holds, in the kamiwaza namespace, the rights that Installer identity gives the installer: the built-in admin role.
  • To change the version: first publish the GreyMatter configuration for the version (step 3). Then sync.
  • The kamiwaza-namespace-prepare Job calls the Kubernetes API. Where the namespace denies traffic by default, its pod needs the API access that Network policy lists. The pod carries the label app.kubernetes.io/name: core-upgrade-migration.
  • Verify with step 5. Set INSTALL_START to the time you noted before the sync.

With Helm or with Argo CD, step 3 of this page renders only the GreyMatter configuration files, which contain no generated secrets, and applies nothing to the cluster.

Step 5: Verify​

Check what the platform does, not only its status fields.

Wait for the platform to start. Helm can return before every pod is ready and every setup job has finished:

kubectl -n kamiwaza wait deployment -l app.kubernetes.io/managed-by=Helm \
--for=condition=Available --timeout=30m
kubectl -n kamiwaza wait job -l app.kubernetes.io/managed-by=Helm \
--for=condition=Complete --timeout=70m

Pods are running and ready:

kubectl -n kamiwaza get pods --no-headers \
| awk '$3 != "Completed" { split($2, r, "/"); if ($3 != "Running" || r[1] != r[2]) print }'
# Expect no output

An Error pod whose Job later completed is a retried attempt, not a failure. Confirm with kubectl -n kamiwaza get jobs: every Job should show all completions.

GreyMatter sidecars are in place. The chart adds one to the core-api and core-raycluster pods; GreyMatter adds one to frontend and keycloak. A pod without it cannot receive traffic from the edge.

kubectl -n kamiwaza get pods \
-o custom-columns='POD:.metadata.name,INIT:.spec.initContainers[*].name' \
| grep -E '^(core-api|core-raycluster|frontend|keycloak)-' | grep -v '^keycloak-postgres'
# Expect greymatter-sidecar listed for each pod

Every pod runs under OpenShift's default security context constraint:

kubectl -n kamiwaza get pods \
-o jsonpath='{range .items[*]}{.metadata.name} {.metadata.annotations.openshift\.io/scc}{"\n"}{end}' \
| grep -v -E ' restricted-v2$' | grep -v -E '^greymatter-'
# Expect no output

GreyMatter's own controllers in the namespace (greymatter-*) use GreyMatter's SCCs and are left out.

No image pulls failed during this install. Older events in the namespace are ignored. Run this in the same shell as step 4, or set INSTALL_START to the time you started the install, in the same format:

kubectl -n kamiwaza get events -o json | jq --arg start "$INSTALL_START" '
[.items[]
| select((.lastTimestamp // .eventTime // .metadata.creationTimestamp) >= $start)
| select((.message // "") | test("ErrImagePull|ImagePullBackOff|Failed to pull image|Back-off pulling image"))
] | length'
# Expect 0

The platform answers at its domain:

curl -sk -o /dev/null -w '%{http_code}\n' https://kamiwaza.example.com/ # expect 200
curl -sk -o /dev/null -w '%{http_code}\n' https://kamiwaza.example.com/api/ # expect 401

Log in. If you did not set an admin password, read the generated one:

kubectl -n kamiwaza get secret kamiwaza-user-admin \
-o jsonpath='{.data.password}' | base64 -d; echo

Open https://kamiwaza.example.com/ and log in as admin. With a certificate your browser does not trust, accept the warning first.

admin is the Kamiwaza application administrator. It is not the installer identity and not the Keycloak management account.

Call the API. Exchange the same credentials for a token, and use it as a bearer token:

TOKEN=$(kubectl -n kamiwaza get secret kamiwaza-user-admin -o jsonpath='{.data.password}' \
| base64 -d | curl -sk https://kamiwaza.example.com/api/auth/token \
--data-urlencode username=admin --data-urlencode password@- | jq -r .access_token)
curl -sk -o /dev/null -w '%{http_code}\n' -H "Authorization: Bearer $TOKEN" \
https://kamiwaza.example.com/api/auth/users/me # expect 200

Step 6: Deploy the default embedding model​

Kamiwaza ships a default embedding model, all-MiniLM-L6-v2, inside the release and adds it to the model catalog during the install. On OpenShift with GreyMatter it does not deploy it for you. Until you do, embedding requests fail with HTTP 503 and the code embedding_unavailable, and features that embed text, such as semantic search in documents, are unavailable. Deploying it needs no internet access. From 1.4.1 it needs no cluster owner either: with no owner trust configured, it runs under Kamiwaza's built-in CPU baseline profile; see Owner trust levels.

  1. Log in as admin and open Models.
  2. In the all-MiniLM-L6-v2 row, click Deploy.
  3. Select the embedding configuration and click Deploy.

Deploy it once. The model's first pod can start before GreyMatter has added its sidecar to the model; Kamiwaza replaces that pod with one that has the sidecar, usually within a minute.

Check that the embedding answers, using the TOKEN from step 5 (rerun the step 5 command that sets it if the token has expired):

curl -sk -X POST -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"text":"embedding check"}' https://kamiwaza.example.com/api/embedding/generate \
| jq 'if .embedding then (.embedding | length) else . end'
# Expect 384. Otherwise the response is printed: the code embedding_deploying
# means the model is still starting; retry after a minute.

kubectl -n kamiwaza get pods \
-o custom-columns='POD:.metadata.name,INIT:.spec.initContainers[*].name' | grep '^tmi-'
# Expect one pod, with greymatter-sidecar listed. Within the first minute you
# can also see the replaced pod terminating.

Model pods are named tmi-<id>; see Tenant-mode inference.

The platform is installed. Deploying models and apps is covered in the Quickstart.

Troubleshooting​

The install stops before creating anything. The chart checks its values before rendering. A missing EULA acceptance or license prints INSTALLATION HALTED; a missing egressCidrs value names the value it needs. Nothing was installed. Fix the values file and rerun step 4.

no Kamiwaza license is configured, with the license set. The license value belongs under core:. Check that it is core.license.existingSecret, not license.existingSecret. To see values Helm received but no chart reads, run helm get values kamiwaza -n kamiwaza.

The domain gives a TLS error, or no response, after step 3. Check that the Route's TLS termination is passthrough, that the edge pod is ready, and that greymatter-edge-ingress holds tls.crt and tls.key for the domain. An admitted Route with a ready edge still fails the handshake when the edge cannot read its certificate.

No Route or edge pod appears after step 3. GreyMatter has not applied the configuration. Ask the platform administrator to check that the namespace is enrolled, that the tenant controllers (for example greymatter-tcm) are ready, and that greymatter-tenant-repo names the repository, branch, and _tenants/kamiwaza path you pushed to. If greymatter-tcm is running but its log repeats Failed to connect to a NATS cluster, the edge certificate isn't issued by the mesh CA; see Edge certificate.

Pods do not start: container has runAsNonRoot and image has non-numeric user, or image will run as root. The pod was admitted under an SCC other than restricted-v2. See which with kubectl -n kamiwaza get pod <pod> -o jsonpath='{.metadata.annotations.openshift\.io/scc}', and ask the platform administrator to remove the extra SCC from Kamiwaza's service accounts, as in Security context constraints. Then delete the pod so it is recreated.

Pods stay in CreateContainerConfigError, naming greymatter-tenant-repo. The Secret is missing or lacks a key. core-scheduler, core-api, and core-raycluster need url, branch, relative_path, http_username, and http_password.

The core-api or core-raycluster pods cannot pull the GreyMatter proxy image. Check global.greymatter.proxy.image against the image you recorded, and that the pull Secret exists: kubectl -n kamiwaza get secret greymatter-image-pull.

The edge disappears after a publish, and its events say must be no more than 63 characters. The edge took a digest-only proxy image. Set global.greymatter.edge.image to the proxy's tag and repeat step 3; see Keep site settings across publishes.

The install hangs for about 15 minutes, then fails on a post-install job. Check core-scheduler first: kubectl -n kamiwaza logs deploy/core-scheduler. A license problem shows here as License check failed; see License File. If frontend or keycloak are not ready, GreyMatter has not given them sidecars; check step 3. While the job runs, every helm upgrade fails with another operation (install/upgrade/rollback) is in progress.

Pods are Pending on their volumes. A StorageClass named in the values does not exist or cannot provision. Compare kubectl get storageclass with global.storage.stateful.*.

Images fail to pull with unauthorized. The pull Secret named in global.imagePullSecrets does not exist in the namespace, or has the wrong credentials. Compare it with kubectl -n kamiwaza get secret.

Apps install but cannot reach the Kubernetes API. egressCidrs is missing the endpoint addresses. Add every address from Kubernetes API addresses and rerun step 4.

An app returns "Page Not Found" or the platform's own page, or a model's endpoint returns no healthy upstream. Kamiwaza adds each app's and model's route to the tenant configuration repository, and GreyMatter then applies it. Wait a minute or two after its pods are ready, or after the model shows as deployed. If it stays unreachable, check the core-scheduler and core-api logs for Git errors: the branch must accept direct pushes, and the namespace must reach the Git server.

Embedding requests return HTTP 503 with embedding_unavailable. No embedding model is deployed. Deploy the default one as in step 6.

A GPU model deployment fails with HTTP 422 and Core cannot see a GPU on this install. Core is running with tenant-mode inference off. The chart refuses to render that, so core's configuration was changed outside Helm. Upgrade the release with your values file; see Tenant-mode inference. If the core pods do not restart during the upgrade, restart them to load the restored configuration:

kubectl -n kamiwaza rollout restart deployment/core-scheduler \
deployment/core-raycluster-head deployment/core-raycluster-worker

If your installation runs core-api, restart it separately:

kubectl -n kamiwaza rollout restart deployment/core-api

A model or app fails with K8S_ADMISSION_REFUSED. OpenShift refused its pod. The message quotes the refused field and gives the remedy. A refused runAsUser, runAsGroup, or fsGroup with This cluster assigns UIDs (global.platform: osgm) but Kamiwaza is configured for fixed UIDs means the values file is missing global.platform: osgm: set it, rerun step 4, then redeploy the model or app. For any other field, ask the platform administrator to confirm that restricted-v2, and no other SCC, applies to Kamiwaza's service accounts; if it does, contact Kamiwaza support with the message.

A PostgreSQL pod stays in Init and its check-pgdata-ownership container fails. The data directory belongs to a different user ID than the one the pod runs as. kubectl -n kamiwaza describe pod <pod> shows a message that starts with PostgreSQL will not start (RS-16), PostgreSQL cannot initialize (RS-16), or PostgreSQL cannot reach PGDATA (RS-16). It names both user IDs and the likely cause, for example:

  • The namespace's openshift.io/sa.scc.uid-range annotation changed, usually because the namespace was recreated and the volume reattached. Ask the platform administrator to restore the original annotation, or to change the volume's owner to the user ID in the message once.
  • The data was written by the chart's fixed user ID 70 or 65532 before the installation moved to global.platform: osgm. Ask the platform administrator to change the volume's owner to the new user ID once.
  • The data directory belongs to root (user ID 0), created by the kubelet or a root process. Follow the message: it names the owner change, or the dataMount values that let PostgreSQL create the directory itself.

Install stops with a workload identity error​

On OpenShift, Kamiwaza supports only the default restricted-v2 SCC with global.platform: osgm, where OpenShift assigns each pod's user ID. The legacy restricted (v1) SCC is not supported. When values would make a chart workload pin a user ID, the render stops with INSTALLATION HALTED before anything is installed or changed. The message names the value and the fix:

The message starts withFix
OpenShift is enabled but workload identity is fixedSet global.platform: osgm, and remove global.openshift.restrictedV2AssignedUid: false if the file sets it.
kamiwaza-openshift-greymatter.yaml is retiredRemove that file, and kamiwaza-openshift.yaml, from the values files, and set global.platform: osgm. On an upgrade, keep the route-publishing values, as described in Upgrade from the OpenShift overlay files.
core.postgresql.podSecurityContext.runAsUser=70 is set, or another ...SecurityContext.<field>=<id> is setRemove the value; it usually comes from the retired kamiwaza-openshift.yaml. On an upgrade, keep the existing PostgreSQL data layout as described in Upgrade from the OpenShift overlay files.
global.openshift.platformNonrootSCC was removed in 1.3Remove the key and set global.platform: osgm.
core.extensionRuntime.mode=operator is not supportedKeep the chart's default direct extension runtime: core.extensionRuntime.mode: direct, extensionOperator.enabled: false.
global.security.runAsUser=<id> is a dev-only knobRemove global.security.runAsUser.
core.scheduler.extraEnv sets KAMIWAZA_OPENSHIFT_RESTRICTED_V2_ASSIGNED_UIDRemove that entry; global.platform sets it.
core.modelsStorage.sharedHostPath.enabled is not supportedSet it to false.
datahub.enabled is not supportedSet datahub.enabled: false.
Context TLS preflight: Context runtime model calls verify TLSSet global.trust.edgeAnchor.pem to the ca.crt of Secret greymatter-edge-ingress. See Edge certificates minted outside the chart.

The message also names global.openshift.fixedUidAcknowledged. Setting it lets the chart pin fixed user IDs, which only a custom SCC granted by the cluster administrator admits. That is outside the supported configuration; see Security context constraints.

After the install, NOTES print the workload identity in effect. Expect Workload identity: assigned by OpenShift (restricted-v2).

Next steps​