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:

  • 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 ImageStream CRD.

Procedure

  1. 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>
    Copy to Clipboard Toggle word wrap
  2. Define the Notebook CRD.

    1. Create a YAML manifest file named notebook.yaml.
    2. Copy the following configuration and paste it in the notebook.yaml file:

      Example Notebook

      apiVersion: kubeflow.org/v1
      kind: Notebook
      metadata:
        annotations:
          notebooks.opendatahub.io/inject-oauth: 'true' 
      1
      
          opendatahub.io/image-display-name: My Custom Notebook 
      2
      
          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 Workbench 
      4
      
          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-workbench 
      5
      
        namespace: my-project 
      6
      
        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-tls
      Copy to Clipboard Toggle word wrap

      The example YAML file includes the following information:

      1
      The inject-oauth annotation generates other OAUTH-based configurations, such as, the oauth-proxy, automatically. The default value is true.
      2
      The Notebook image name is visible in the OpenShift AI dashboard. In this example, the image name is My 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-name label to the spec.template.metadata.labels of the Notebook CR. Set the value to the name of an existing LocalQueue in your project. This is required only if your project is enabled for Kueue.
      8
      The deployment size for the container. You can set limits and requests values for CPU and memory.
      9
      Environment variables for configuring values, for example, for Jupyter Notebook arguments and SSL/TLS certificates.
      10
      The Notebook image. In this example, image-registry.openshift-image-registry.svc:5000/redhat-ods-applications/my-custom-notebook:1.0 is the Notebook image. You can select the image version based on the packages included in the image.
      11
      The inject-oauth annotation configures the oauth-proxy container section of the Notebook.
  3. Edit the notebooks.opendatahub.io/oauth-logout-url field, annotated as (1) in the following example. Replace my-project with the name of the project that you created.

    Example Notebook

    apiVersion: kubeflow.org/v1
    kind: Notebook
    metadata:
      annotations:
        ...
        notebooks.opendatahub.io/oauth-logout-url: '<dashboard_URL>/projects/my-project?notebookLogout=my-workbench' 
    1
    
        ...
    Copy to Clipboard Toggle word wrap

  4. Edit the --logout-url= field, annotated as (1) in the following example. Replace my-project with the name of the project that you created.

    Example Notebook

    apiVersion: 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
    
           ...
    Copy to Clipboard Toggle word wrap

  5. Edit the value field of the JUPYTER_IMAGE environment variable, annotated as (1) in the following example. Replace the image URL with the URL of the custom image that you created.

    Example Notebook

    apiVersion: 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
    Copy to Clipboard Toggle word wrap

  6. Edit the image field, annotated as (1) in the following example. Replace the image URL with the URL of the custom image that you created.

    Example Notebook

    apiVersion: 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
          ...
    Copy to Clipboard Toggle word wrap

  7. To create the Notebook CR, run the following command, where the Notebook CRD YAML manifest filename is notebook.yaml.

    oc create -f notebook.yaml
    Copy to Clipboard Toggle word wrap

Verification

  • To verify that the workbench was successfully created, run the following command, replacing my-project with the name of the project where you created the Notebook CR.

    oc describe notebook -n my-project
    Copy to Clipboard Toggle word wrap

    You 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
    Copy to Clipboard Toggle word wrap

Red Hat logoGithubredditYoutubeTwitter

Learn

Try, buy, & sell

Communities

About Red Hat Documentation

We help Red Hat users innovate and achieve their goals with our products and services with content they can trust. Explore our recent updates.

Making open source more inclusive

Red Hat is committed to replacing problematic language in our code, documentation, and web properties. For more details, see the Red Hat Blog.

About Red Hat

We deliver hardened solutions that make it easier for enterprises to work across platforms and environments, from the core datacenter to the network edge.

Theme

© 2026 Red Hat
Back to top