
# Notebook
在AI模型的研发全生命周期中，数据探索（Data Exploration）与算法实验（Prototyping）是最为耗时且迭代频繁的环节。传统本地开发模式正面临三大严峻挑战：
- 算力瓶颈：本地笔记本或工作站难以承载大模型微调及海量数据预处理的高并发计算需求，导致迭代周期漫长。
- 环境依赖困境：深度学习框架（PyTorch、MindSpore）、底层驱动（CUDA、CANN）及Python依赖库版本错综复杂，团队间环境一致性极难维护。
- 数据搬运成本：企业级训练数据规模常达TB甚至PB级，存储于云端对象存储（OBS）或文件存储（SFS）。将数据拉取至本地不仅耗时巨大，更存在显著的数据泄露风险。
为突破上述瓶颈，基于JupyterLab和VS Code Server的云原生IDE已成为行业标准。通过引入本插件，实现了将开发环境的算力直接下沉到了底层的CCE集群中。开发者只需通过浏览器，即可零配置获得拥有顶级GPU/NPU算力、直连高速共享存储、且运行环境开箱即用的沉浸式研发工作台。
**开源地址：** [Notebook Controller](https://github.com/kubeflow/kubeflow/tree/v1.10-branch/components/notebook-controller)
#### 基本概念
在使用本插件前，了解以下几个云原生核心概念，有助于您更好地管理开发环境：
- Notebook CRD（自定义资源声明）：这是本插件引入的核心概念。您提交的kind: Notebook YAML文件就是一份声明。您只需告诉集群"我需要什么配置"，背后的控制器会自动处理所有底层细节（例如，创建Pod、挂载卷、配置网络）。
- 持久化存储声明（PVC-PersistentVolumeClaim）：在云原生环境中，容器具有"阅后即焚"的特性，即Pod重启后内部数据会丢失。PVC就像是挂载到容器上的"云U盘"。通过配置PVC，您的代码文件、Conda环境和个人配置文件可以独立于计算资源永久保存。
- 有状态副本集（StatefulSet）：Notebook在底层的实际运行载体。相比于普通的Deployment，它能确保您的环境拥有稳定的网络标识，并在被系统重新调度（例如，节点故障转移）时，能够准确无误地重新挂载之前的个人PVC。
- 资源闲置回收（Culling）：一种成本优化机制。控制器会监控环境的活跃状态（例如，Jupyter的内核运行状态或终端连接），当检测到环境长时间处于完全空闲时，会自动将其休眠（缩容至0），从而释放昂贵的算力卡归还给集群资源池，同时保留所有持久化数据。
 
#### 前提条件
- 已创建一个CCE Standard/Turbo集群，且集群版本为v1.29及以上，具体操作请参见[购买Standard/Turbo集群](https://support.huaweicloud.com/usermanual-cce/cce_10_0028.html)。
- 请根据业务类型创建对应类型的节点和插件，并确保节点资源充足。
  - NPU业务：已创建NPU节点，且已安装CCE AI套件（Ascend NPU）插件。
  
  - GPU业务：已创建GPU节点，且已安装CCE AI套件（NVIDIA GPU）插件。
   
 
#### 注意事项
在卸载插件时，Notebook对应的CRD和CR资源不会自动删除。如需彻底清理，请手动删除这些资源。
#### 约束与限制
- 该插件仅安装并管理Notebook容器的控制器（notebook-controller）及相关配置，Notebook镜像需根据业务需求自行构建或从社区获取。

- 该插件当前正处于上线阶段，**已发布区域请以控制台实际为准**。
- **该插件处于公测阶段** ，您可体验最新插件特性，但**需要注意该版本的稳定性未得到完全的验证，不适用于CCE服务SLA**。
 
#### 计费说明
如果您需要访问Notebook实例，则需要为集群中任一节点绑定EIP。其中，EIP需要涉及一定费用，具体请参见[EIP价格计算器](https://www.huaweicloud.com/pricing/calculator.html#/eip)。
#### 安装插件
1. 登录[CCE控制台](https://console.huaweicloud.com/cce2.0/?#/cce/cluster/list)，单击集群名称进入集群。
2. 单击左侧导航栏的"插件中心"，在右侧找到notebook插件，单击"安装"。
3. 在安装插件页面，进行"规格配置"。 
   
   | **参数**                                     | **示例**   | **说明**                                                   |
   |:---|:---|:---|
   | 实例数                                        | 1        | 表示安装该插件时，会创建至少1个notebook-controller的Pod实例。               |
   | CPU配额  | 申请：100m  | 表示容器的最小CPU需求。                                            |
   | CPU配额  | 限制：500m  | 表示容器能使用的CPU最大值。当CPU使用率超出设置的CPU限制值时，该实例可能会被重启进而影响插件的正常使用。 |
   | 内存配额   | 申请：100Mi | 表示容器的最小内存需求。                                             |
   | 内存配额   | 限制：500Mi | 表示容器能使用的内存最大值。当内存使用率超出设置的内存限制值时，该实例可能会被重启进而影响插件的正常使用。    |
      
   
   
4. 在"参数配置"区域，请根据实际使用场景，合理配置以下参数。 
   
   | **参数**              | **示例**        | **说明**                                                                                                                                                                                                                                                                                                                                                                                                                   |
   |:---|:---|:---|
   | clusterDomain       | cluster.local | Kubernetes集群内部服务的DNS域名后缀。控制器依赖该参数生成Notebook实例Service的完整FQDN。例如，notebook-name.namespace.svc.cluster.local。 默认值为cluster.local。若创建CCE集群时自定义了内部域名，请务必同步修改此值，否则会导致服务间通信失败。                                                                                                                                                                                                                     |
   | enableCulling       | false         | 是否启用"空闲实例自动回收"功能（Culling）。 - true：开启回收。控制器将定期扫描无活动Notebook实例，并将其缩容至0以释放底层计算资源（数据盘持久化，不丢失）。  - false：关闭回收。实例一旦启动将长期运行，直到用户手动删除或缩容。 说明： 在GPU/NPU等高成本算力场景中，建议生产环境启用此功能（设为true），以显著降低资源闲置成本。    |
   | cullIdleTime        | 1440          | 触发空闲回收的超时阈值（单位：分钟）。指Notebook实例在连续无任何操作（如无连接、无代码执行）的情况下，最长允许存活的时间。 示例值1440，即24小时，表示如果环境连续24小时无人使用，系统将自动将其挂起休眠。您可以根据企业的资源紧张程度将其缩短，例如： 120（2小时）或 240（4小时）。 注意： 此参数仅在enableCulling设置为true时生效。                                                                                                                                       |
   | idlenessCheckPeriod | 1             | 空闲状态的轮询周期（单位：分钟）。定义控制器每隔多久向Notebook实例内部的活跃状态接口发起一次探测（监控HTTP流量与Jupyter Kernel状态）。 示例值1表示每1分钟检测并计算一次闲置时间。 说明： 通常保持默认值即可。如果集群规模极大（数千个实例），可以适当调大该值（例如，设定为5），以减轻Kubernetes API Server和控制器的查询压力。                                                                                                                                      |
      
   
   
5. 单击"安装"。
 
#### 组件说明
表1Notebook组件 
| 容器组件                | 说明                 | 资源类型       |
|:---|:---|:---|
| notebook-controller | 管理Notebook实例的生命周期。 | Deployment |
   
#### Notebook CR配置说明
Notebook CRD是一个非常轻量级的控制器外壳。将其spec.template.spec字段映射为完整的、原生的Kubernetes PodSpec。这意味着，只要是K8s体系支持的底层高阶能力，Notebook实例全部原生支持。
- Notebook CR常见配置说明
  ```
  apiVersion: kubeflow.org/v1
  kind: Notebook
  metadata:
    name: advanced-ai-workspace
    namespace: team-algorithm
    labels:
      project: llm-pretraining
    annotations:
      # [专属配置] 允许前端Dashboard显示自定义描述
      notebooks.kubeflow.org/title: "LLM核心开发环境"
      # [高级调度] 声明使用Volcano调度器接管，优化NPU/GPU拓扑
      volcano.sh/scheduler-name: volcano
  spec:
    template:
      spec:
        # [安全策略] 指定容器内所有进程默认以非root用户 (UID 1000, 通常是jovyan) 运行
        securityContext:
          runAsUser: 1000
          fsGroup: 100
        # [节点调度] 确保Pod只会被调度到拥有特定标签的异构计算节点池
        nodeSelector:
          node.kubernetes.io/instance-type: "accelerated-compute-pool"
        # [污点容忍] 容忍专用AI节点上的Taints，防止普通业务Pod抢占
        tolerations:
        - key: "nvidia.com/gpu"
          operator: "Exists"
          effect: "NoSchedule"
        containers:
        - name: notebook
          image: custom-registry.io/jupyter-ai-base:v2.0
          imagePullPolicy: Always
          # [环境变量] 注入通用环境配置或业务参数
          env:
          - name: JUPYTER_ENABLE_LAB
            value: "yes"
          - name: MODEL_CACHE_DIR
            value: "/data/models"
          # [资源声明] 核心算力配置
          resources:
            requests:
              cpu: "8"
              memory: "32Gi"
            limits:
              cpu: "8"
              memory: "32Gi"
              # [异构算力] 独占分配加速卡，按需修改为GPU或NPU标识
              nvidia.com/gpu: 1           
              # huawei.com/Ascend910: 1   
          volumeMounts:
          - mountPath: /home/jovyan/work       # 个人工作区 (读写)
            name: workspace-pvc
          - mountPath: /data/public-datasets   # 公共数据集区 (只读)
            name: dataset-pvc
          - mountPath: /dev/shm                # 共享内存优化 (解决多进程数据加载瓶颈)
            name: dshm
        volumes:
        # 1. 挂载持久化云盘 (存放代码)
        - name: workspace-pvc
          persistentVolumeClaim:
            claimName: workspace-claim-user01
        # 2. 挂载高性能文件系统 (SFS Turbo等，存放庞大数据集)
        - name: dataset-pvc
          persistentVolumeClaim:
            claimName: public-datasets-claim
        # 3. 内存文件系统 (加速PyTorch DataLoader等多进程读取)
        - name: dshm
          emptyDir:
            medium: Memory
            sizeLimit: "8Gi"
  ```
  
- 生产环境使用建议
  - 镜像无状态化 + 存储有状态化 禁止在Notebook内直接通过pip install或apt-get安装耗时较长的底层依赖（例如，指定版本的CUDA/CANN、需大规模编译的C++库等）。此类依赖安装操作在实例回收或重启后会完全丢失，导致环境不可复现、业务反复重建。推荐做法如下：
    - 底层驱动、核心深度学习框架（PyTorch/MindSpore等）统一固化至Docker基础镜像，实现环境标准化与可复用。
    
    - 轻量级纯Python业务依赖（例如，requests等工具库），通过挂载持久化存储至"/home/jovyan/work"目录，使用venv或Conda虚拟环境实现持久化安装与版本管理。
     
  
  - 统一的网络与路由命名规范 当大规模并发创建Notebook时，集群内部会产生大量同名的Service，引发网络冲突、资源混乱与管理困难。管理规范如下：
    - 强制各业务团队拥有独立的Kubernetes Namespace实现环境隔离。
    
    - Notebook实例的名称严格遵循"\[用户名\]-\[项目简称\]-\[日期\]"的格式，以便于账单审计与僵尸实例的批量排查与清理。
     
   
 
#### 使用示例
本示例基于GPU P4卡演示Notebook运行CUDA代码的能力，要求CCE集群中已包含GPU类型的节点，并安装GPU插件与Notebook插件。
1. 创建Notebook实例。 
   1. 在已有的ECS中安装kubectl，并使用kubectl连接集群，具体操作请参见[通过kubectl连接集群](https://support.huaweicloud.com/usermanual-cce/cce_10_0107.html)。
   
   2. 执行以下命令，创建一个YAML文件，用于创建需要GPU虚拟化Burst调度的容器。
      ```
      vim notebook-sample.yaml
      ```
      文件内容如下：
      ```
      apiVersion: kubeflow.org/v1
      kind: Notebook
      metadata:
        name: notebook-sample-v1    # Notebook实例的名称
      spec:
        template:
          spec:
            containers:
              - name: notebook-sample-v1     # 容器名称
                image: quay.io/jupyter/pytorch-notebook:cuda13-latest  #使用的Notebook镜像地址
                resources:
                  limits:
                    cpu: 250m
                    memory: 512Mi
                    nvidia.com/gpu: '1'
                  requests:
                    cpu: 250m
                    memory: 512Mi
                    nvidia.com/gpu: '1'
      ```
      本示例中的镜像地址quay.io/jupyter/pytorch-notebook:cuda13-latest为外部Docker镜像仓库地址，需要您的CCE节点网络具备访问该地址的能力。如果您的集群节点无法访问该镜像地址，建议将镜像提前拉取并上传到华为云的SWR。
      
   
   3. 执行以下命令，创建Notebook实例。
      ```
      kubectl apply -f notebook-sample.yaml
      ```
      回显结果如下，则说明Notebook实例已创建。
      ```
      notebook.kubeflow.org/notebook-sample-v1 created
      ```
      
   
   4. 执行以下命令，查看Notebook CR状态。
      ```
      kubectl get Notebook
      ```
      返回信息如下所示。
      ```
      NAME                 AGE
      notebook-sample-v1   25h
      ```
      若列表中显示您的Notebook名称（例如，notebook-sample-v1），则说明CR资源已注册。
      
   
   5. 执行以下命令，查看已创建的Pod状态。
      ```
      kubectl get pod |grep notebook-sample-v1
      ```
      返回信息如下所示。
      ```
      notebook-sample-v1-0             1/1     Running   0               28m
      ```
      若回显中包含Running，则表示实例正在运行。
      
   
   
   
   
2. 访问Notebook实例。 
   1. 查看Notebook实例Pod的标签信息。
      ```
      kubectl describe pod notebook-sample-v1-0
      ```
      输出关键信息如下。
      ```
      Labels:           apps.kubernetes.io/pod-index=0
                        controller-revision-hash=notebook-sample-v1-6bb8bb48ff
                        notebook-name=notebook-sample-v1
                        statefulset=notebook-sample-v1
                        statefulset.kubernetes.io/pod-name=notebook-sample-v1-0
      ```
      ![](https://support.huaweicloud.com/usermanual-cce/public_sys-resources/note_3.0-zh-cn.png)
      建议使用statefulset=notebook-sample-v1作为标签，因为它是Kubernetes 原生且稳定、可预测的管理标签。
      
   
   2. 创建Service。
      1. 执行以下命令，创建notebook-service.yaml文件，用于配置NodePort的Service，文件名称可自定义。该Service主要用于对外暴露服务，以便从浏览器直接访问Notebook实例。
         ```
         vim notebook-service.yaml
         ```
         文件内容如下。
         ```
         apiVersion: v1
         kind: Service
         metadata:
           name: notebook-sample-v1
           namespace: default
         spec:
           externalTrafficPolicy: Cluster
           internalTrafficPolicy: Cluster
           ports:
           - name: http-notebook-sample-v1
             port: 80                # 访问Service的端口
             protocol: TCP
             targetPort: 8888  # Service访问目标容器的端口，此端口与容器中运行的应用强相关，一般Notebook实例端口为8888
           selector:
             statefulset: notebook-sample-v1
           sessionAffinity: None
           type: NodePort  # Service的类型，NodePort表示在通过节点端口访问
         ```
         
      
      2. 执行以下命令，创建Service。
         ```
         kubectl create -f notebook-service.yaml
         ```
         当回显中包含created字样时，表示Service已经创建。
         
      
      3. 执行以下命令，查看该Service的节点端口信息。
         ```
         kubectl get services
         ```
         回显结果如下，其中32666即为节点端口。
         ```
         NAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
         notebook-sample-v1   NodePort    10.247.**.**     <none>        80:32666/TCP   24h
         ```
         
       
   
   3. 获取Token。
      1. 执行以下命令，进入Notebook实例容器内部。
         ```
         kubectl exec -it notebook-sample-v1-0 -- bash
         ```
         
      
      2. 执行如下命令，获取Token。
         ```
         jupyter server list
         ```
         回显结果如下。
         ```
         Currently running servers:
         http://localhost:8888/?token=ab23a4dfd63b... :: /home/jovyan
         ```
         
       
   
   4. 访问Jupyter UI，在浏览器中输入"**http://\<任意节点的EIP\>:32666** "，访问Notebook实例页面。
      请确保集群中已存在绑定EIP的节点，您可以在CCE控制台单击对应集群名称，在"节点管理 \> 节点"页面单击对应节点名称进入ECS页面绑定EIP，具体请参见[绑定弹性公网IP](https://support.huaweicloud.com/usermanual-ecs/zh-cn_topic_0174917535.html)。
      
   
   5. 在登录页面，输入前面步骤中获取到的Token，然后单击"Log in"。 ![](https://support.huaweicloud.com/usermanual-cce/zh-cn_image_0000002544437172.png "点击放大")
      
   
   
   
   
3. 测试连通性。 
   1. 在Jupyter页面，单击Python 3。 ![](https://support.huaweicloud.com/usermanual-cce/zh-cn_image_0000002574957065.png "点击放大")
      
   
   2. 输入以下命令运行。
      ```
      import torch
      # 1. Check if GPU is available
      print("1. Is GPU available:", torch.cuda.is_available())
      if torch.cuda.is_available():
          # 2. Try creating a simple Tensor in GPU memory
          x = torch.tensor([1.0, 2.0], device='cuda')
          print("2. Tensor located on device:", x.device)
      else:
          print("No GPU detected, please check your environment configuration.")
      ```
      返回信息如下所示。
      ```
      Is GPU available: True
      Tensor located on device: cuda:0
      ```
      ![](https://support.huaweicloud.com/usermanual-cce/zh-cn_image_0000002575085939.png "点击放大")
      
   
   
   
   
 
#### 常见问题
- 如何获取与选择合适的Notebook实例镜像？ 容器镜像决定了启动的开发环境中预装的软件、框架和底层驱动。为保证环境能够顺利拉起，配置的image需满足基本的容器化交互标准。以下是几种常用的优质镜像获取途径：
  - Kubeflow官方社区镜像（适用于通用CPU/GPU场景） Kubeflow社区维护了一系列经过严格测试的基础镜像，涵盖了最常用的数据科学栈。您可以直接在公共镜像仓库拉取：
    - 基础数据科学版（含Pandas、Scikit-learn）**：**kubeflow/jupyter-scipy:latest
    
    - PyTorch官方集成版：kubeflow/jupyter-pytorch:latest
    
    - TensorFlow官方集成版：kubeflow/jupyter-tensorflow:latest 获取方式：可直接在Docker Hub（hub.docker.com/u/kubeflow）搜索并获取特定版本的tag。
      
     
  
  - Jupyter Docker Stacks（上游开源镜像）
    - 全能型数据科学栈：jupyter/datascience-notebook 获取方式：访问Jupyter官方文档的[Selecting an Image](https://jupyter-docker-stacks.readthedocs.io/en/latest/using/selecting.html)章节或Docker Hub（jupyter/命名空间）。
      
     
   
 
#### 版本记录
表2Notebook插件版本记录 
| 插件版本   | 支持的集群版本                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | 更新特性         |
|:---|:---|:---|
| 1.10.1 | - v1.29  - v1.30  - v1.31  - v1.32  - v1.33  - v1.34  - v1.35   | 新增Notebook插件 |
   
