Chapter 4. Deploy Distributed Inference with llm-d on Openshift Container Platform
Deploy the Distributed Inference with llm-d infrastructure stack on your Openshift Container Platform cluster by using a Helm chart packaged as an OCI container image. The chart installs required operators through Operator Lifecycle Manager (OLM) and configures all dependencies automatically.
Prerequisites
- You have an Openshift Container Platform 4.19+ cluster with GPU nodes provisioned
-
You have installed the OpenShift CLI (
oc) and configured access to your cluster - You have installed Helm 3.17+ with OCI support
-
Your cluster pull secret includes credentials for
registry.redhat.io. For more information, see Configuring image streams and image registries. -
You have logged in to the Helm OCI registry by running
helm registry login registry.redhat.io - All Openshift Container Platform cluster prerequisites are satisfied
- If your cluster operates in a disconnected environment, you have configured image mirroring
Procedure
Deploy the Distributed Inference with llm-d infrastructure stack by running the Helm chart:
$ helm upgrade --install rhoai \ oci://registry.redhat.io/rhai/rhai-on-openshift-chart:v3.4 \ -n rhoai-gitops --create-namespace \ --set profile=rhaii \ --set operator.type=rhoai \ --skip-schema-validation \ --set operator.rhoai.olm.channel=3.4-stableThe chart performs a two-phase installation:
- Phase 1: Creates OLM subscriptions for the RHOAI operator and its dependencies
- Phase 2: After operators are ready, creates Custom Resources that configure the operators to install all dependencies automatically, including cert-manager, Istio Sail Operator, Gateway API, LeaderWorkerSet, and KServe
ImportantDo not use
helm install --wait. Using--waitcan cause the installation to time out or fail.ImportantThe default Helm configuration creates a
Gatewayresource withallowedRoutes.namespaces.from: All, which permits any namespace in the cluster to attach routes to the inference gateway. For production deployments, disable the default Gateway and create a secure Gateway manually. For more information, see Configure the inference gateway on Openshift Container Platform.Wait for the operator
CSVCRs to be installed.$ oc get csv -AWait until all CSVs show
Succeededbefore proceeding.Re-run the same Helm command to create Custom Resources.
The first run registered CRDs and created OLM subscriptions. Now that the CRDs are available and the operators are running, the second run creates the Custom Resources that configure the Operators.
$ helm upgrade --install rhoai \ oci://registry.redhat.io/rhai/rhai-on-openshift-chart:v3.4 \ -n rhoai-gitops --create-namespace \ --set profile=rhaii \ --set operator.type=rhoai \ --skip-schema-validation \ --set operator.rhoai.olm.channel=3.4-stableOptional: If you plan to use Red Hat Connectivity Link (RHCL) for authentication and rate limiting, enable Authorino TLS.
The Helm chart installs Kuadrant and Authorino as part of the RHCL dependency. To enable TLS for Authorino, configure it manually:
$ oc annotate svc/authorino-authorino-authorization \ service.beta.openshift.io/serving-cert-secret-name=authorino-server-cert \ -n kuadrant-system$ oc patch authorino/authorino -n kuadrant-system --type=merge \ -p '{"spec":{"clusterWide":true,"listener":{"tls":{"enabled":true,"certSecretRef":{"name":"authorino-server-cert"}}},"oidcServer":{"tls":{"enabled":false}}}}'Verify that the RHOAI Operator is running:
$ oc get pods -n redhat-ods-operatorVerify that the KServe LLMISvc controller is running:
$ oc get pods -n redhat-ods-applicationsNoteThe
dashboard-redirectandmodel-serving-apipods in theredhat-ods-applicationsnamespace are not required for Distributed Inference with llm-d.Verify that all managed dependencies are deployed and ready:
$ oc get pods -n cert-manager$ oc get pods -n istio-systemAll pods should be in a running state.
Configure the inference gateway.
The gateway enables mTLS communication between inference components.
Create an application namespace for deploying inference services:
$ oc new-project llm-inferenceDeploy an
LLMInferenceServicecustom resource (CR) for the language model.NoteOn Openshift Container Platform, the cluster-wide pull secret handles image authentication automatically. Unlike managed Kubernetes deployments, you do not need to specify
imagePullSecretsor scheduler container stubs in theLLMInferenceServicespec.Create a file called
inference-service.yaml:apiVersion: serving.kserve.io/v1alpha2 kind: LLMInferenceService metadata: name: single-gpu namespace: llm-inference spec: model: uri: hf://Qwen/Qwen3-0.6B name: Qwen/Qwen3-0.6B replicas: 1 router: scheduler: {} route: {} gateway: {} template: containers: - name: main resources: limits: cpu: "4" memory: 32Gi nvidia.com/gpu: "1" requests: cpu: "2" memory: 16Gi nvidia.com/gpu: "1" livenessProbe: httpGet: path: /health port: 8000 scheme: HTTPS initialDelaySeconds: 120 periodSeconds: 30 timeoutSeconds: 30 failureThreshold: 5Deploy the inference service:
$ oc apply -f inference-service.yamlVerify that the inference service is ready:
$ oc get llmisvc -n llm-inferenceExpected output:
NAME READY AGE single-gpu True 5mWait until the
READYcolumn showsTruebefore proceeding. This might take several minutes while the model downloads and loads.Test inference by sending a request to the deployed service:
$ SERVICE_URL=$(oc get llmisvc single-gpu -n llm-inference \ -o jsonpath='{.status.url}')$ curl -X POST "${SERVICE_URL}/v1/chat/completions" \ -H "Content-Type: application/json" \ -d '{ "model": "Qwen/Qwen3-0.6B", "messages": [{"role": "user", "content": "What is Kubernetes?"}], "max_tokens": 100 }'The model returns a valid JSON response answering your question.
Verification
Verify the end-to-end deployment by confirming:
The Operator CSV shows
Succeeded:$ oc get csv -A | grep rhodsAll infrastructure pods are in Running state:
$ oc get pods -n redhat-ods-operator $ oc get pods -n redhat-ods-applicationsLLMInferenceService shows
READY=True:$ oc get llmisvc -n llm-inference- Inference requests return valid responses from the model
No error logs in the KServe LLMISvc controller:
$ oc logs -n redhat-ods-applications deployment/kserve-controller-manager --tail=50If deployment fails or inference is not working:
Check the Operator subscription status:
$ oc get subscription -n redhat-ods-operator -o yamlCheck pod logs for errors:
$ oc logs -n <namespace> <pod-name>Verify GPU availability:
$ oc describe nodes | grep -A 5 "nvidia.com/gpu"- Review the troubleshooting guide for common issues