Chapter 3. Creating a workbench by using the Notebook CRD
In OpenShift AI, you can create a workbench object by using the Notebook Custom Resource Definition (CRD).
In the following procedure, you configure a Notebook CRD and then use it to create the Notebook Custom Resource (CR) that defines the workbench.
Prerequisites
- You have cluster administrator privileges for your OpenShift cluster.
You have installed the OpenShift CLI (
oc) as described in the appropriate documentation for your cluster:- Installing the OpenShift CLI for OpenShift Container Platform
- Installing the OpenShift CLI for Red Hat OpenShift Service on AWS
-
You have created a project. In the example in this procedure, the project is named
my-project. -
You know the URL for the image that you want to use in the workbench. The example in this procedure uses the custom image that you created in Creating a custom image by using the
ImageStreamCRD.
Procedure
In a terminal window, if you are not already logged in to your OpenShift cluster as a cluster administrator, log in as shown in the following example:
oc login <openshift_cluster_url> -u <admin_username> -p <password>Define the
NotebookCRD.-
Create a YAML manifest file named
notebook.yaml. Copy the following configuration and paste it in the
notebook.yamlfile:Example
NotebookapiVersion: kubeflow.org/v1 kind: Notebook metadata: annotations: notebooks.opendatahub.io/inject-oauth: 'true'1 opendatahub.io/image-display-name: My Custom Notebook2 notebooks.opendatahub.io/oauth-logout-url: 'https://<dashboard_URL>/projects/my-project?notebookLogout=my-workbench' opendatahub.io/accelerator-name: '' openshift.io/description: ''3 openshift.io/display-name: My Workbench4 notebooks.opendatahub.io/last-image-selection: 'my-custom-notebook:1.0' notebooks.kubeflow.org/last_activity_check_timestamp: '2024-07-30T20:43:25Z' notebooks.opendatahub.io/last-size-selection: Small opendatahub.io/username: 'kube:admin' notebooks.kubeflow.org/last-activity: '2024-07-30T20:27:25Z' opendatahub.io/connections: 'my-project/my-s3-connection' opendatahub.io/connections: 'my-project/my-uri-connection' opendatahub.io/connections: 'my-project/my-oci-connection' name: my-workbench5 namespace: my-project6 labels: kueue.x-k8s.io/queue-name: <local-queue-name>7 spec: template: spec: affinity: {} containers: - resources:8 limits: cpu: '2' memory: 8Gi requests: cpu: '1' memory: 8Gi readinessProbe: failureThreshold: 3 httpGet: path: /notebook/my-project/my-workbench/api port: notebook-port scheme: HTTP initialDelaySeconds: 10 periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 name: my-workbench livenessProbe: failureThreshold: 3 httpGet: path: /notebook/my-project/my-workbench/api port: notebook-port scheme: HTTP initialDelaySeconds: 10 periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 env:9 - name: NOTEBOOK_ARGS value: |- --ServerApp.port=8888 --ServerApp.token='' --ServerApp.password='' --ServerApp.base_url=/notebook/my-project/my-workbench --ServerApp.quit_button=False --ServerApp.tornado_settings={"user":"<user>","hub_host":"<dashboard_URL>", "hub_prefix":"/projects/my-project"} - name: JUPYTER_IMAGE value: 'image-registry.openshift-image-registry.svc:5000/redhat-ods-applications/my-custom-notebook:1.0' - name: PIP_CERT value: /etc/pki/tls/custom-certs/ca-bundle.crt - name: REQUESTS_CA_BUNDLE value: /etc/pki/tls/custom-certs/ca-bundle.crt - name: SSL_CERT_FILE value: /etc/pki/tls/custom-certs/ca-bundle.crt - name: PIPELINES_SSL_SA_CERTS value: /etc/pki/tls/custom-certs/ca-bundle.crt - name: GIT_SSL_CAINFO value: /etc/pki/tls/custom-certs/ca-bundle.crt ports: - containerPort: 8888 name: notebook-port protocol: TCP imagePullPolicy: Always volumeMounts: - mountPath: /opt/app-root/src name: my-workbench - mountPath: /dev/shm name: shm - mountPath: /etc/pki/tls/custom-certs/ca-bundle.crt name: trusted-ca readOnly: true subPath: ca-bundle.crt image: 'image-registry.openshift-image-registry.svc:5000/redhat-ods-applications/my-custom-notebook:1.0'10 workingDir: /opt/app-root/src - resources:11 limits: cpu: 100m memory: 64Mi requests: cpu: 100m memory: 64Mi readinessProbe: failureThreshold: 3 httpGet: path: /oauth/healthz port: oauth-proxy scheme: HTTPS initialDelaySeconds: 5 periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 name: oauth-proxy livenessProbe: failureThreshold: 3 httpGet: path: /oauth/healthz port: oauth-proxy scheme: HTTPS initialDelaySeconds: 30 periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 env: - name: NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace ports: - containerPort: 8443 name: oauth-proxy protocol: TCP imagePullPolicy: Always volumeMounts: - mountPath: /etc/oauth/config name: oauth-config - mountPath: /etc/tls/private name: tls-certificates image: 'registry.redhat.io/openshift4/ose-oauth-proxy-rhel9@sha256:ca21e218e26c46e3c63d926241846f8f307fd4a586cc4b04147da49af6018ef5' args: - '--provider=openshift' - '--https-address=:8443' - '--http-address=' - '--openshift-service-account=my-workbench' - '--cookie-secret-file=/etc/oauth/config/cookie_secret' - '--cookie-expire=24h0m0s' - '--tls-cert=/etc/tls/private/tls.crt' - '--tls-key=/etc/tls/private/tls.key' - '--upstream=http://localhost:8888' - '--upstream-ca=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt' - '--email-domain=*' - '--skip-provider-button' - '--openshift-sar={"verb":"get","resource":"notebooks","resourceAPIGroup":"kubeflow.org","resourceName":"my-workbench","namespace":"$(NAMESPACE)"}' - '--logout-url=<dashboard_URL>/projects/my-project?notebookLogout=my-workbench' enableServiceLinks: false serviceAccountName: my-workbench volumes: - name: my-workbench persistentVolumeClaim: claimName: my-workbench - emptyDir: medium: Memory name: shm - configMap: items: - key: ca-bundle.crt path: ca-bundle.crt name: workbench-trusted-ca-bundle optional: true name: trusted-ca - name: oauth-config secret: defaultMode: 420 secretName: my-workbench-oauth-config - name: tls-certificates secret: defaultMode: 420 secretName: my-workbench-tlsThe example YAML file includes the following information:
- 1
- The
inject-oauthannotation generates other OAUTH-based configurations, such as, theoauth-proxy, automatically. The default value istrue. - 2
- The
Notebookimage name is visible in the OpenShift AI dashboard. In this example, the image name isMy custom notebook. Optionally, you can name the image according to your use case. - 3
- An optional description of the workbench.
- 4
- The workbench name that is displayed in the OpenShift AI dashboard. In this example, the display name is
My Workbench. - 5
- The name for the workbench. In this example, the workbench name is
my-workbench. - 6
- The project for the workbench. In this example, the project name is
my-project. - 7
- To queue your workbench (Notebook) Pods and manage their resources, add the
kueue.x-k8s.io/queue-namelabel to thespec.template.metadata.labelsof theNotebookCR. Set the value to the name of an existingLocalQueuein your project. This is required only if your project is enabled for Kueue. - 8
- The deployment size for the container. You can set
limitsandrequestsvalues for CPU and memory. - 9
- Environment variables for configuring values, for example, for Jupyter Notebook arguments and SSL/TLS certificates.
- 10
- The
Notebookimage. In this example,image-registry.openshift-image-registry.svc:5000/redhat-ods-applications/my-custom-notebook:1.0is theNotebookimage. You can select the image version based on the packages included in the image. - 11
- The
inject-oauthannotation configures theoauth-proxycontainer section of theNotebook.
-
Create a YAML manifest file named
Edit the
notebooks.opendatahub.io/oauth-logout-urlfield, annotated as (1) in the following example. Replacemy-projectwith the name of the project that you created.Example
NotebookapiVersion: kubeflow.org/v1 kind: Notebook metadata: annotations: ... notebooks.opendatahub.io/oauth-logout-url: '<dashboard_URL>/projects/my-project?notebookLogout=my-workbench'1 ...Edit the
--logout-url=field, annotated as (1) in the following example. Replacemy-projectwith the name of the project that you created.Example
NotebookapiVersion: kubeflow.org/v1 kind: Notebook metadata: annotations: ... spec: template: spec: affinity: {} containers: ... - resources: ... args: - '--logout-url=<dashboard_URL>/projects/my-project?notebookLogout=my-workbench'1 ...Edit the
valuefield of theJUPYTER_IMAGEenvironment variable, annotated as (1) in the following example. Replace the image URL with the URL of the custom image that you created.Example
NotebookapiVersion: kubeflow.org/v1 kind: Notebook metadata: annotations: ... spec: template: spec: affinity: {} containers: ... - resources: ... env: ... - name: JUPYTER_IMAGE value: 'image-registry.openshift-image-registry.svc:5000/redhat-ods-applications/my-custom-notebook:1.0'1 Edit the
imagefield, annotated as (1) in the following example. Replace the image URL with the URL of the custom image that you created.Example
NotebookapiVersion: kubeflow.org/v1 kind: Notebook metadata: annotations: ... spec: template: spec: affinity: {} containers: ... - resources: ... env: ... ports: .. imagePullPolicy: Always volumeMounts: ... image: 'image-registry.openshift-image-registry.svc:5000/redhat-ods-applications/my-custom-notebook:1.0'1 workingDir: /opt/app-root/src ...To create the
NotebookCR, run the following command, where theNotebookCRD YAML manifest filename isnotebook.yaml.oc create -f notebook.yaml
Verification
To verify that the workbench was successfully created, run the following command, replacing
my-projectwith the name of the project where you created theNotebookCR.oc describe notebook -n my-projectYou should see output similar to the following example:
Example output
Name: my-workbench Namespace: my-project Labels: <none> Annotations: notebooks.kubeflow.org/last-activity: 2024-07-30T20:27:25Z notebooks.kubeflow.org/last_activity_check_timestamp: 2024-07-30T20:43:25Z notebooks.opendatahub.io/inject-oauth: true notebooks.opendatahub.io/last-image-selection: my-custom-notebook:1.0 notebooks.opendatahub.io/last-size-selection: Small notebooks.opendatahub.io/oauth-logout-url: <dashboard_URL>/projects/my-project?notebookLogout=my-workbench opendatahub.io/accelerator-name: opendatahub.io/image-display-name: My Custom Notebook opendatahub.io/username: kube:admin openshift.io/description: openshift.io/display-name: My Workbench API Version: kubeflow.org/v1 Kind: Notebook Metadata: Creation Timestamp: 2025-03-06T13:27:25Z Generation: 1 Resource Version: 42316914 UID: 89f4....9e9-7c48-4f53-9397-05c....d21a Spec: Template: Spec: Affinity: Containers: Env: Name: NOTEBOOK_ARGS Value: --ServerApp.port=8888 --ServerApp.token='' --ServerApp.password='' --ServerApp.base_url=/notebook/my-project/my-workbench --ServerApp.quit_button=False --ServerApp.tornado_settings={"user":"kube-3aadmin","hub_host":"<dashboard_URL>", "hub_prefix":"/projects/my-project"} Name: JUPYTER_IMAGE Value: image-registry.openshift-image-registry.svc:5000/redhat-ods-applications/my-custom-notebook:1.0 Name: PIP_CERT Value: /etc/pki/tls/custom-certs/ca-bundle.crt Name: REQUESTS_CA_BUNDLE Value: /etc/pki/tls/custom-certs/ca-bundle.crt Name: SSL_CERT_FILE Value: /etc/pki/tls/custom-certs/ca-bundle.crt Name: PIPELINES_SSL_SA_CERTS Value: /etc/pki/tls/custom-certs/ca-bundle.crt Name: GIT_SSL_CAINFO Value: /etc/pki/tls/custom-certs/ca-bundle.crt Image: image-registry.openshift-image-registry.svc:5000/redhat-ods-applications/my-custom-notebook:1.0 Image Pull Policy: Always Liveness Probe: Failure Threshold: 3 Http Get: Path: /notebook/my-project/my-workbench/api Port: notebook-port Scheme: HTTP Initial Delay Seconds: 10 Period Seconds: 5 Success Threshold: 1 Timeout Seconds: 1 Name: my-workbench Ports: Container Port: 8888 Name: notebook-port Protocol: TCP Readiness Probe: Failure Threshold: 3 Http Get: Path: /notebook/my-project/my-workbench/api Port: notebook-port Scheme: HTTP Initial Delay Seconds: 10 Period Seconds: 5 Success Threshold: 1 Timeout Seconds: 1 Resources: Limits: Cpu: 2 Memory: 8Gi Requests: Cpu: 1 Memory: 8Gi Volume Mounts: Mount Path: /opt/app-root/src Name: my-workbench Mount Path: /dev/shm Name: shm Mount Path: /etc/pki/tls/custom-certs/ca-bundle.crt Name: trusted-ca Read Only: true Sub Path: ca-bundle.crt Working Dir: /opt/app-root/src Args: --provider=openshift