Chapter 4. Track experiments with MLflow in workbenches
You can track machine learning experiments in workbench notebooks with the MLflow SDK. OpenShift AI provides automatic MLflow SDK configuration for workbenches, which removes the need to manually set tracking URIs, configure authentication, or manage RBAC permissions.
To use MLflow experiment tracking, a cluster administrator must first enable the MLflow Operator component, and then a data scientist can enable and use the integration in individual workbenches.
4.1. MLflow workbench integration Copy linkLink copied to clipboard!
You can enable automatic MLflow SDK configuration in your workbenches by annotating notebook resources with the opendatahub.io/mlflow-instance annotation. When this annotation is present, OpenShift AI automatically injects MLflow environment variables and provisions the required RBAC permissions, so that you can track experiments without manual SDK configuration.
The MLflow workbench integration removes the need to manually set tracking URIs, configure authentication tokens, or create Kubernetes RBAC resources. When an administrator enables the MLflow Operator component in the DataScienceCluster and creates an MLflow custom resource (CR), the platform handles the remaining configuration at the workbench level.
4.1.1. How the integration works Copy linkLink copied to clipboard!
The integration uses two mechanisms in the notebook controller to configure MLflow access:
- Environment variable injection
When a workbench notebook resource has the
opendatahub.io/mlflow-instanceannotation, the notebook controller’s mutating webhook injects three environment variables into the notebook container before the pod starts:-
MLFLOW_TRACKING_URI: The URL of the MLflow tracking server, constructed from the GatewayAPI hostname and the MLflow instance name. -
MLFLOW_K8S_INTEGRATION: Set totrueto enable Kubernetes service account token authentication with the MLflow server. -
MLFLOW_TRACKING_AUTH: Set tokubernetes-namespacedto configure namespace-scoped authentication.
These variables allow the MLflow Python SDK to connect to the tracking server without additional configuration in your notebook code.
-
- RBAC provisioning
-
The notebook controller’s reconciler creates a namespace-scoped
RoleBindingnamed__<notebook_name>__-mlflowthat grants the workbench service account the permissions defined in themlflow-operator-mlflow-integrationClusterRole. TheRoleBindinguses a controller owner reference to the notebook resource, so it is automatically deleted when the notebook is deleted.
4.1.2. Configuration methods Copy linkLink copied to clipboard!
You can enable MLflow integration for workbenches in two ways:
- Dashboard-managed
-
If you use the OpenShift AI dashboard with the Dashboard, MLflow, and Workbenches components set to
Managedin theDataScienceCluster, the dashboard automatically adds theopendatahub.io/mlflow-instanceannotation when you create or update a workbench. No manual configuration is required. - Manual
-
If you manage workbenches through GitOps, Helm charts, or direct YAML manifests without the OpenShift AI dashboard, you must manually add the
opendatahub.io/mlflow-instanceannotation to the notebook resource.
4.1.3. Annotation lifecycle Copy linkLink copied to clipboard!
The opendatahub.io/mlflow-instance annotation controls the MLflow integration for each workbench:
- Adding the annotation
-
You can add the annotation to a stopped notebook or include it when you create a new notebook. The annotation value must be the name of the MLflow instance CR. Environment variables are injected on the next pod start, and the
RoleBindingis created by the reconciler. - Removing the annotation
-
You must stop the workbench before removing the annotation. The
RoleBindingis deleted immediately when the annotation is removed, but environment variables in the running pod persist until restart. This mismatch can cause authentication failures if the workbench continues to send requests to the MLflow tracking server after theRoleBindingis removed. A validating webhook checks that thekubeflow-resource-stoppedannotation is present on the notebook resource before it allows removal of the MLflow annotation. The webhook validates the annotation state, not the actual pod state. If you try to remove the annotation without first stopping the workbench through the dashboard or by setting the stop annotation, the API request is rejected with a webhook error.
4.1.4. Non-blocking behavior Copy linkLink copied to clipboard!
MLflow integration failures do not block workbench admission. If the tracking URI cannot be determined, for example because the GatewayAPI hostname is not yet available, the webhook skips the MLFLOW_TRACKING_URI injection but still allows the notebook to start. In this case, MLFLOW_K8S_INTEGRATION and MLFLOW_TRACKING_AUTH are still injected, which creates a degraded state in which the MLflow SDK is configured for Kubernetes authentication but has no tracking server to connect to. If MLflow operations such as mlflow.set_experiment() fail with a ConnectionError, verify that the MLFLOW_TRACKING_URI environment variable is set in your workbench pod.
Similarly, if the mlflow-operator-mlflow-integration ClusterRole does not yet exist, the reconciler requeues the RoleBinding creation with a warning event every 30 seconds until the ClusterRole becomes available.
4.1.5. Limitations Copy linkLink copied to clipboard!
Artifact-serving configuration with S3 connection types is not supported. You can log parameters, metrics, and tags, but mlflow.log_artifact() functionality that relies on an S3-backed artifact store requires additional configuration that is outside the scope of the automatic integration.
4.2. Enable the MLflow operator component Copy linkLink copied to clipboard!
You can enable the MLflow operator as a managed component in the DataScienceCluster so that the MLflow tracking server and workbench integration are available on the platform. When the MLflow operator component is enabled, workbench notebooks can use automatic MLflow SDK configuration.
Prerequisites
- The Red Hat OpenShift AI Operator is installed on your OpenShift cluster.
-
A
DataScienceClusterobject exists. - You have cluster administrator privileges.
-
You have installed the OpenShift CLI (
oc).
Procedure
Log in to your OpenShift cluster as a cluster administrator:
$ oc login --token=__<token>__ --server=__<openshift_cluster_url>__Identify the name of the
DataScienceClusterobject:$ oc get datascienceclusterEdit the
DataScienceClusterobject to enable the MLflow operator component:$ oc edit datasciencecluster __<dsc_name>__In the
spec.componentssection, add or update themlflowoperatorfield and setmanagementStatetoManaged:spec: components: # ... mlflowoperator: managementState: Managed # ...NoteThe default
managementStatefor themlflowoperatorcomponent isRemoved. You must explicitly set it toManagedto enable MLflow on the platform.Save and close the editor.
When you set
mlflowoperatortoManaged, the Red Hat OpenShift AI Operator automatically configures the notebook controller withMLFLOW_ENABLED=trueand sets the appropriateGATEWAY_URLfor the cluster.- Create an MLflow CR to deploy a tracking server instance. The MLflow CR structure and namespace requirements depend on the MLflow operator version. For more information, consult the MLflow operator documentation for the CR specification.
Verification
Confirm that the MLflow operator pod is running:
$ oc get pods -n redhat-ods-applications -l app=mlflow-operator --field-selector status.phase=RunningThe output shows one or more MLflow operator pods in
Runningstatus. If the command returns no results, verify that themlflowoperatorcomponentmanagementStateis set toManagedand wait for the operator pods to start.Confirm that the
mlflowoperatorcomponent status istruein theDataScienceCluster:$ oc get datasciencecluster __<dsc_name>__ -o jsonpath='{.status.installedComponents.mlflowoperator}'The expected output is
true.
4.2.1. MLflow dashboard feature flag deprecation Copy linkLink copied to clipboard!
Starting with Red Hat OpenShift AI 3.4, the mlflow field in the OdhDashboardConfig CR is deprecated. MLflow availability in the dashboard is now determined by the mlflowoperator component state in the DataScienceCluster, and the dashboard feature flag is no longer required.
4.2.1.1. Deprecated field Copy linkLink copied to clipboard!
The mlflow field in spec.dashboardConfig of the OdhDashboardConfig CR is deprecated and no longer controls MLflow visibility in the dashboard. You do not need to set this field to enable MLflow. The field has no effect on MLflow functionality.
4.2.1.2. Current behavior Copy linkLink copied to clipboard!
MLflow features in the OpenShift AI dashboard are automatically available when the mlflowoperator component is set to Managed in the DataScienceCluster. No additional dashboard configuration is required.
4.2.1.3. mlflowPipelines field Copy linkLink copied to clipboard!
The mlflowPipelines field in the OdhDashboardConfig CR is not deprecated and remains active. This field controls whether pipeline run tables display the MLflow experiment column. Do not confuse the deprecated mlflow field with the active mlflowPipelines field.
| Field | Status | Description |
|---|---|---|
|
| Deprecated |
In earlier releases, this field controlled MLflow visibility in the dashboard. No longer required; MLflow is enabled automatically by the |
|
| Active | Controls whether the MLflow experiment column is displayed in pipeline run tables. |
4.3. Enable MLflow integration for a workbench Copy linkLink copied to clipboard!
You can enable automatic MLflow SDK configuration for a workbench by adding the opendatahub.io/mlflow-instance annotation to the notebook resource. When the workbench starts, the platform injects MLflow environment variables and provisions the required RBAC resources.
When you create or update a workbench, the OpenShift AI dashboard automatically adds the MLflow annotation. For this to occur, the following components in the DataScienceCluster object must be set to Managed:
- Dashboard
- MLflow
- Workbenches
The following procedure is for environments where you manage workbenches through GitOps, Helm charts, or direct YAML manifests without the OpenShift AI dashboard.
Prerequisites
-
A cluster administrator has enabled the MLflow Operator component in the
DataScienceClusterobject. For more information, see Enable the MLflow Operator component. - An MLflow CR has been created in the same namespace as the workbench.
- The workbench is stopped.
-
You have installed the OpenShift CLI (
oc).
Procedure
Log in to your OpenShift cluster:
$ oc login --token=__<token>__ --server=__<openshift_cluster_url>__Add the
opendatahub.io/mlflow-instanceannotation to the notebook resource.In the following command, replace
__<notebook_name>__with the name of your workbench notebook and__<mlflow_instance_name>__with the name of your MLflow instance CR:$ oc annotate notebook -n __<namespace>__ __<notebook_name>__ opendatahub.io/mlflow-instance=__<mlflow_instance_name>__If the MLflow instance name is
mlflow, the tracking URI path is/mlflow. If the instance name is different, the path is/mlflow-__<mlflow_instance_name>__.Alternatively, you can add the annotation directly in the notebook resource YAML:
apiVersion: kubeflow.org/v1 kind: Notebook metadata: name: __<notebook_name>__ namespace: __<namespace>__ annotations: opendatahub.io/mlflow-instance: "__<mlflow_instance_name>__" spec: # ...- Start or restart the workbench so that the environment variables are injected into the new pod.
Verification
Verify that the MLflow environment variables are present in the running workbench pod.
First, find the pod name for your notebook:
$ oc get pods -n __<namespace>__ -l notebook-name=__<notebook_name>__Then verify that the MLflow environment variables are present, where
__<notebook_pod_name>__is the pod name from the previous command and__<notebook_name>__is the notebook resource name:$ oc exec -n __<namespace>__ __<notebook_pod_name>__ -c __<notebook_name>__ -- env | grep MLFLOWThe expected output shows the following environment variables:
MLFLOW_TRACKING_URI=https://<gateway_hostname>/mlflow MLFLOW_K8S_INTEGRATION=true MLFLOW_TRACKING_AUTH=kubernetes-namespacedThe
<gateway_hostname>value is cluster-specific and matches the GatewayAPI public endpoint for your cluster.Verify that the MLflow
RoleBindingexists in the namespace:$ oc get rolebinding -n __<namespace>__ __<notebook_name>__-mlflowThe output shows a
RoleBindingreferencing themlflow-operator-mlflow-integrationClusterRole.
4.4. Use the MLflow SDK in a workbench notebook Copy linkLink copied to clipboard!
After MLflow integration is enabled for your workbench, you can use the MLflow Python SDK to create experiments, log parameters and metrics, and track runs. The required environment variables are already configured, so the SDK connects to the tracking server automatically.
Prerequisites
-
A cluster administrator has enabled the MLflow operator component in the
DataScienceCluster. For more information, see Enable the MLflow operator component. - An MLflow CR has been created in the namespace.
-
The workbench notebook resource has the
opendatahub.io/mlflow-instanceannotation. For more information, see Enable MLflow integration for a workbench. - The workbench is started and the MLflow environment variables are injected.
The
mlflowPython package is installed in the workbench. Starting with OpenShift AI 3.4, all workbench images except the minimal image include the MLflow SDK. For older images or custom images, install the package by runningpip install mlflowin a notebook cell.NoteIf you need only basic tracking functionality, you can install the
mlflow-skinnypackage instead for a smaller footprint. Themlflow-skinnypackage contains the core tracking and logging features but does not include model serving integrations or the full MLflow CLI.
Procedure
- Open a notebook in the workbench.
Verify that the MLflow environment variables are available:
import os print(os.environ.get("MLFLOW_TRACKING_URI")) print(os.environ.get("MLFLOW_K8S_INTEGRATION")) print(os.environ.get("MLFLOW_TRACKING_AUTH"))All three variables display their configured values.
Import the MLflow SDK and set an experiment:
import mlflow mlflow.set_experiment("my-experiment")The
set_experiment()call returns anExperimentobject and prints the experiment ID. If you see aConnectionError, verify that theMLFLOW_TRACKING_URIenvironment variable is set correctly by re-running the check in step 2.Start a run and log parameters and metrics:
with mlflow.start_run(): mlflow.log_param("learning_rate", 0.01) mlflow.log_param("epochs", 10) mlflow.log_metric("accuracy", 0.95) mlflow.log_metric("loss", 0.05)You can log any number of parameters, metrics, and tags within a run. If
start_run()raises aConnectionErroror an authentication or authorization error, verify that the MLflow tracking server is running and that the workbenchRoleBindingexists.- View the experiment results in the MLflow UI, which is accessible from the OpenShift AI dashboard.
Verification
- Confirm that the experiment and run are displayed in the MLflow UI. Navigate to the MLflow tracking server URL in your browser or through the OpenShift AI dashboard and verify that the logged parameters and metrics are visible.
Artifact-serving configuration with S3 connection types is not supported. You can log parameters, metrics, and tags, but mlflow.log_artifact() functionality that relies on an S3-backed artifact store requires additional configuration. For more information, see MLflow workbench integration.
4.5. Disable MLflow integration for a workbench Copy linkLink copied to clipboard!
You can disable MLflow integration for a workbench by removing the opendatahub.io/mlflow-instance annotation from the notebook resource. You must stop the workbench before removing the annotation.
When you remove the annotation, the platform deletes the associated RoleBinding resource immediately, but environment variables in the running pod persist until the pod restarts. If the workbench is running when you remove the annotation, the MLflow SDK continues to send requests to the tracking server without a valid RoleBinding resource in place, which causes authentication failures.
Prerequisites
-
Your workbench has the
opendatahub.io/mlflow-instanceannotation. -
The workbench is stopped. The validating webhook requires the
kubeflow-resource-stoppedannotation to be present on the notebook resource before it allows removal of the MLflow annotation. -
You have installed the OpenShift CLI (
oc).
Procedure
Log in to your OpenShift cluster:
$ oc login --token=__<token>__ --server=__<openshift_cluster_url>__Verify that the workbench pod has stopped:
$ oc get pods -n __<namespace>__ -l notebook-name=__<notebook_name>__The command produces no output when the pod has stopped.
Remove the
opendatahub.io/mlflow-instanceannotation from the notebook resource.In the following command, replace
__<notebook_name>__with the name of your workbench notebook:$ oc annotate notebook -n __<namespace>__ __<notebook_name>__ opendatahub.io/mlflow-instance-The trailing dash (
-) removes the annotation.
Verification
Start the workbench and verify that the MLflow environment variables are no longer present.
First, find the pod name for your notebook:
$ oc get pods -n __<namespace>__ -l notebook-name=__<notebook_name>__Then verify that the MLflow environment variables are no longer present, where
__<notebook_pod_name>__is the pod name from the previous command and__<notebook_name>__is the notebook resource name:$ oc exec -n __<namespace>__ __<notebook_pod_name>__ -c __<notebook_name>__ -- env | grep MLFLOWThe command produces no output, confirming that the MLflow variables have been removed.
Verify that the MLflow
RoleBindingresource has been removed:$ oc get rolebinding -n __<namespace>__ __<notebook_name>__-mlflowThe expected output is:
Error from server (NotFound): rolebindings.rbac.authorization.k8s.io "__<notebook_name>__-mlflow" not found
Troubleshooting
If the annotation removal is rejected with a webhook error, see Resolve MLflow annotation removal rejection.
4.6. Resolve MLflow annotation removal rejection Copy linkLink copied to clipboard!
If you try to remove the opendatahub.io/mlflow-instance annotation from a running workbench, the API request is rejected by a validating webhook. You can resolve this issue by stopping the workbench before removing the annotation.
The validating webhook checks that the kubeflow-resource-stopped annotation is present on the notebook resource before it allows removal of the MLflow annotation. The webhook validates the annotation state, not the actual pod state. If the pod was stopped without setting the stop annotation, for example by deleting the pod directly, the webhook still rejects the annotation removal.
Prerequisites
-
The workbench has the
opendatahub.io/mlflow-instanceannotation. - You received a webhook error when trying to remove the annotation.
-
You have installed the OpenShift CLI (
oc).
Procedure
Stop the workbench. You can stop the workbench from the OpenShift AI dashboard or by applying the stop annotation:
$ oc annotate notebook -n __<namespace>__ __<notebook_name>__ kubeflow-resource-stopped=trueThe value of the
kubeflow-resource-stoppedannotation is not significant for this purpose. The validating webhook checks only for the presence of the annotation key.Wait for the notebook pod to stop fully:
$ oc get pods -n __<namespace>__ -l notebook-name=__<notebook_name>__The command produces no output when the pod has stopped.
Remove the MLflow annotation:
$ oc annotate notebook -n __<namespace>__ __<notebook_name>__ opendatahub.io/mlflow-instance-
Verification
Confirm that the annotation has been removed:
$ oc get notebook -n __<namespace>__ __<notebook_name>__ -o jsonpath='{.metadata.annotations.opendatahub\.io/mlflow-instance}'The command produces no output, confirming the annotation is removed.
4.7. MLflow workbench environment variables and annotations Copy linkLink copied to clipboard!
When MLflow integration is enabled for a workbench, the notebook controller injects environment variables and creates RBAC resources automatically. You can use this reference to understand the annotation, environment variables, and RoleBinding that the platform manages on your behalf.
4.7.1. Annotation Copy linkLink copied to clipboard!
| Annotation | Description |
|---|---|
|
| Specifies the name of the MLflow instance CR to connect to. When this annotation is present and non-empty on a notebook resource, the notebook controller enables MLflow integration for the workbench. The annotation value determines the path segment in the tracking URI. |
| Annotation value | Tracking URI path |
|---|---|
|
|
|
|
|
|
4.7.2. Environment variables Copy linkLink copied to clipboard!
The following environment variables are injected into the notebook container when the opendatahub.io/mlflow-instance annotation is present.
| Variable | Value | Description |
|---|---|---|
|
|
|
Specifies the URL of the MLflow tracking server. The hostname is derived from the GatewayAPI public endpoint. If the instance name is |
|
|
| Specifies that the MLflow client uses Kubernetes service account token authentication. |
|
|
| Specifies the authentication method for the MLflow client. This value configures namespace-scoped authentication using the workbench service account. |
4.7.3. RoleBinding Copy linkLink copied to clipboard!
The notebook controller creates a namespace-scoped RoleBinding for each annotated workbench.
| Property | Value |
|---|---|
| Name |
|
| Namespace | Same as the notebook resource namespace |
| Subject |
|
| RoleRef |
|
| Controller owner reference |
Set to the notebook resource, so the |
| Labels |
|
4.7.4. ClusterRole availability Copy linkLink copied to clipboard!
The RoleBinding references the mlflow-operator-mlflow-integration ClusterRole, which is created by the MLflow operator. If this ClusterRole does not yet exist when the reconciler attempts to create the RoleBinding, the reconciler requeues the request with a warning event every 30 seconds until the ClusterRole becomes available. These events are generated only when a notebook resource has the opendatahub.io/mlflow-instance annotation but the ClusterRole does not yet exist. If no annotated notebooks exist, no events are generated. You can observe these events by running the following command, where __<namespace>__ is the namespace containing your workbench notebook:
$ oc get events -n __<namespace>__ --field-selector reason=MLflowClusterRolePending
4.7.5. Controller environment variables Copy linkLink copied to clipboard!
The Red Hat OpenShift AI Operator automatically configures the following environment variables on the notebook controller when the mlflowoperator component is set to Managed in the DataScienceCluster. You do not need to set these variables manually.
| Variable | Description |
|---|---|
|
|
Set to |
|
|
Set based on the cluster’s Gateway configuration. The notebook controller uses this value to construct the |