在线 IDE

创建/使用在线开发环境(Jupyter、VSCode、RStudio、Matlab),SSH 远程连接、端口预留、环境持久化、定时清理与续期等问题时读这篇

03-平台使用 / 在线开发
在线IDEnotebookjupytertheiavscoderstudiomatlabsshProxyJumptensorboardsparkgitNOTEBOOK_PORTPORT1PORT2SERVICE_EXTERNAL_IP

在线 IDE

在线开发是一个很重要的功能,对于大部分用户来说,在线的 IDE 比命令行 vim 要方便很多。CubeStudio 主要提供了 VSCode 和 Jupyter 两种在线 IDE,并没有将代码和数据进行分割存储。所以在 Notebook 中打开的就是完全用户自己的代码和数据,可以方便地进行调试。

VSCode

theia 是一个在线 VSCode,更像本地 IDE,主要服务纯代码开发(多实例,一个人可以同时开多个 theia)。

在线 VSCode

工作目录默认是 /mnt,归档目录是 /archives,可以把一些想永久保存、不易被误删的文件放在归档目录。

工作目录与归档目录

在 VSCode 里面(本质为 theia),用户跟本地 VSCode 基本一致,可以上传下载文件/文件夹,也可以在 theia 中打开命令行终端。并且其中封装了用户的基本环境需求,比如 Python。

需要说明的是,由于 theia 的功能中有些进程(例如 rg 进程)会不停地搜索扫描目录下的所有文件。由于个人目录下包含了用户的代码和数据,文件可能非常多(千万到亿级别的文件数量),这些进程扫描会严重拖慢分布式存储的性能。所以 CubeStudio 做了定时检杀的功能,能够及时检杀 rggit 进程,提高在线 VSCode 的响应速度。

Jupyter

数据挖掘的用户使用 Jupyter 会更多一些。在 Jupyter 里面跟 VSCode 里面相同,也安装了一些实用的插件,比如 tensorboard,使用 Jupyter Pro 版本可以在 Jupyter 里面打开。

比如我们在 pipeline/example/tensorboard 中有一个示例文件 demo.py,运行这个文件会生成一个 fit_logs 文件夹,这就是 TF 的 log 目录,进入这个目录后使用 tensorboard 按钮启动 tensorboard,就可以查看该训练的情况。

大数据版本

大数据版本的 Jupyter Notebook,创建 Notebook 时选择 Jupyter(bigdata)镜像,集成了大数据常用的基础包,比如 Spark、Flink 等。支持爬虫、数据分析、数据挖掘和可视化等常用 Python 包的使用。

机器学习版本

机器学习版本的 Jupyter Notebook,创建 Notebook 时选择 Jupyter(machinelearning)镜像,集成了机器学习常用的基础包,比如 sklearn、scipy 等。

深度学习版本

深度学习版本的 Jupyter Notebook,创建 Notebook 时选择 Jupyter(DeepLearning)镜像,集成了深度学习常用的基础包,比如 TensorFlow、Keras 等。

RStudio

R 版本的 Notebook,创建 Notebook 时选择 rstudio(bigdata)镜像,集成了 R 语言的在线 IDE,IDE 名称为 RStudio。

Matlab

MATLAB 版本的 Notebook,创建 Notebook 时选择 matlab(deeplearning)镜像,集成了 MATLAB 的在线 IDE。

注意:Matlab 需要企业申请 Matlab 有效账户,并开通 r2023a 版本的 license。

依据:可选镜像由配置项 NOTEBOOK_IMAGES 决定(myapp/config.py:998)。当前默认配置中 Matlab 镜像(matlab-ubuntu-deeplearning)是被注释掉的myapp/config.py:1017),即开箱默认不可选;管理员如需启用,需在 NOTEBOOK_IMAGES 中放开该行并具备有效 license。其余 jupyter(bigdata/machinelearning/deeplearning)jupyter-conda-pro(cpu)rstudio(bigdata) 均为默认启用。

Pro 版本

Pro 版本的 Jupyter 中可使用不同版本的 Python 内核,从 Python 2.7 到 Python 3.9 均可支持。

Jupyter Pro 多内核

tensorboard 可视化训练

Pro 版本的 Jupyter 有 tensorboard,创建 Notebook 时镜像选择 jupyter-conda-pro(cpu),创建一个 Pro 版本的 Jupyter,运行 /mnt/$username/pipeline/example/tensorboard/demo.py,运行结束会产生结果文件。进入结果文件夹,此时点击"+"符号,打开 tensorboard,再选择需要进行可视化的文件,即可查看可视化结果,如下图所示。

tensorboard 可视化

需要注意的是,集成了 tensorboard 的 Notebook 是 CPU 版本的。因此,如果我们需要用 GPU 来训练模型,并且用 tensorboard 做可视化,可以用 GPU 版本的 Notebook 来做模型训练,把需要可视化的结果文件写到分布式存储中,再在 Pro 版本的 Notebook 中打开 tensorboard。

密码保护

需要修改 config.py 配置文件中 ENABLE_JUPYTER_PASSWORD 设置为 True(默认值为 False)并更新到线上,重启后端,则会在每个 Jupyter 后面自动生成密码,每次进入 Jupyter 要使用这个密码。

依据:myapp/config.py:988 默认 ENABLE_JUPYTER_PASSWORD = Falsemyapp/views/view_notebook.py:713if conf.get('ENABLE_JUPYTER_PASSWORD', False): 时为 Jupyter 生成登录密码。

生成密码

登录 Jupyter 时需要密码:

登录需要密码

SSH 远程连接 Jupyter 功能

实现原理

Jupyter 版本的 Notebook 中提供了 sshd,会在 Notebook 创建时自动启动 ssh-server,并且会自动生成配置文件 example/ssh链接

并为每个 Notebook 的 Pod 配置一个单独的 Service,支持通过 ip:port 访问。

端口分配以 config.pyNOTEBOOK_PORT 为准(仓库默认配置为 10000+2*ID),平台会在该基准端口上预留多个端口:

  • 基准端口+0:IDE Web 服务端口(例如 JupyterLab / Theia / RStudio / Matlab 等)
  • 基准端口+1sshd 端口(用于 ssh 远程连接,对应环境变量 SSH_PORT
  • 基准端口+2/+3:预留给用户在 Notebook 内启动自定义服务(对应环境变量 PORT1/PORT2

依据(与代码核对):仓库默认 config.py:1105 配置为 NOTEBOOK_PORT='10000+2*ID'(注释"至少间隔 4");仅当该配置缺失时,代码兜底默认才取 10000+10*IDmyapp/views/view_notebook.py:689conf.get('NOTEBOOK_PORT','10000+10*ID'))。端口分配的 +0/+1/+2/+3 含义与 view_notebook.py:688 注释及 697-699 行环境变量赋值一致。实际端口以你部署的 config.py 取值为准。

需要公司网络能通过 ip+端口 的形式访问 Notebook 的服务。

操作方法

按照 example/ssh链接 文件中的描述,在本地 ~/.ssh/config 中添加链接配置:

# 将此文件内容追加到 ~/.ssh/config
# root 登录密码为 notebook 的英文名称
# ssh-copy-id -p PORT root@HOST  本地设置免密登录

Host cube-studio
  HostName xx.xx.xx.xx
  Port xx
  User root
  ServerAliveInterval 10
  ControlMaster auto

然后就可以 SSH 链接远程 Notebook 了,并且可以在本地将文件拖拽到本地 VSCode,这样文件就会自动同步到在线 Notebook 中。

单端口代理 Jupyter 内部 ssh server

使用 ProxyJump 功能:

Host proxy
  HostName jumpserver_host     #  这里是内网代理机器的 ip
  User jumpserver_user         #  这里是内网代理机器的用户名
  Port jumpserver_port         #  这里是内网代理机器的端口

# 下面就是 CubeStudio 的原始 ssh 连接
Host cube-studio-admin-pro
  HostName xxxxx
  Port xxx
  User root
  ServerAliveInterval 10
  ControlMaster auto
  ProxyJump proxy               # 添加此处代理

SSH 链接时 matplotlib 弹窗的问题

Mac 电脑:

本地安装 XQuartz,本地 VSCode 安装 remote-ssh 插件,SSH 连接在线 IDE,连接后在容器命令行执行:

apt-get install -y openssh-server xauth x11-apps python3 python3-pip python3-tk
pip install matplotlib
export DISPLAY=:10.0

然后就可以运行 matplotlib 画图的 Python 代码了。

Windows 设置:

参考:https://blog.csdn.net/beginner_921/article/details/142493855

  1. 本地和远程 VSCode 都安装 Remote X11
  2. 本地安装 VcXsrv,vcxsrv-64.1.20.14.0.installer
  3. 安装后打开 XLaunch,不修改配置
  4. 本地安装 VcXsrv(or XMing)的目录下会有一个 X0.hosts 文件,在其中增加一行服务器 ip
  5. 在远程 IDE 命令行增加 export DISPLAY="xx.xx.xx.xx:0.0",其中 xx.xx.xx.xx 是你电脑的内网 ip

Jupyter 里面连接 Spark

对于需要连接数据中台的场景(例如连接 Hive 或 Spark 集群),我们可以在自定义 Notebook 中预先配置好相关的 XML 文件,以便用户直接使用。这样开发者只需要配置一次,普通用户就可以直接使用,无需再次配置。

在 Jupyter 中启动提交 Spark 任务,作为 driver 端需要监听端口。每个 Notebook 在创建的时候会预留 $PORT1$PORT2 两个环境变量代表的端口来对外监听,同时在 $SERVICE_EXTERNAL_IP 环境变量代表的主机上进行监听,所以需要告诉 Spark 的 master,driver 的服务监听地址,这样能让 master 返回数据到 driver 端。

依据:PORT1/PORT2/SERVICE_EXTERNAL_IP 等环境变量由 myapp/views/view_notebook.py:663-699 注入 Notebook Pod。

# 创建 SparkSession
spark = SparkSession.builder \
    .appName("PythonPi") \
    .master('spark://myspark-master-0.myspark-headless.kubeflow.svc.cluster.local:7077') \
    .config("spark.executor.memory", "2g") \
    .config("spark.executor.cores", "2") \
    .config("spark.cores.max", "8") \
    .config("spark.driver.memory", "2g") \
    .config("spark.ui.enabled", False) \
    .config("spark.driver.port", os.getenv('PORT1')) \
    .config("spark.blockManager.port", os.getenv('PORT2')) \
    .config("spark.driver.bindAddress", '0.0.0.0') \
    .config("spark.driver.host", os.getenv('SERVICE_EXTERNAL_IP')) \
    .getOrCreate()

tensorboard

使用 Pro 版本的 Jupyter,在左侧目录树进入到 tensorboard 对应的日志目录,再打开右侧的 tensorboard 按钮。

打开 tensorboard 按钮

就可以查看日志目录中所包含的训练过程中的信息和模型的信息。

tensorboard 展示

git 功能

Pro 版本的 Notebook 中可以直接使用 git。比如直接 clone 一个项目到 Notebook 中,修改文件,点击 git 图标,就能直接看到原文件和修改后文件的对比。

git 对比

GPU、CPU、内存监控

图示按钮可帮助用户在 Notebook 中查看资源的使用情况。需要注意的是,只有 GPU 版本的 Notebook 可以在 Notebook 中查看 GPU 监控,其他版本的 Notebook 即使调用了 GPU,也只能在 Grafana 中统一查看 GPU 资源的监控。

Notebook 内资源监控

Jupyter 多内核态

在使用自定义 Notebook 时,需要注意安装包时应该先激活对应的环境,然后再进行安装。这是因为 Jupyter 的内核和 conda 环境是两个不同的概念,需要分别进行管理。

在线 IDE 的资源占用问题

CubeStudio 采用的方案是只设置 Notebook 的 Pod 的 limit,而不设置 request。这种方案就对资源不进行独占,这样也就不用清理 Notebook,只是允许了 Notebook 中的资源干扰。

GPU 的占用方式上,允许独占、共享、VGPU 三种方式。GPU 申请(单位卡)示例:填写 12,表示训练任务每个容器独占整卡;填写 -1 为共享占用方式;填写小数(0.1)为 vGPU 方式;申请具体的卡型号可以类似 1(V100),目前支持 T4 / V100 / A100。

GPU 申请方式

在线 IDE 的环境重置问题

如果 Notebook 因为 OOM、定时清理、机器故障、主动 reset 等可能原因而重启,Notebook 中的环境就会丢失,但分布式存储下的内容都会保留,也就是 /mnt/$username 文件夹下的内容都会保留。

所以如果我们需要环境保存,有两个方案:

  1. CubeStudio 添加了 Notebook 启动后自动执行 /mnt/$username/init.sh 脚本的功能,用户只需要在 init.sh 中定义 Notebook 特定的环境,就可以在启动 Notebook 后拥有自己独特的环境。
  2. 在 Notebook 中有一个"镜像保存"按钮,每次 Notebook 环境更改之后都可以点击这个按钮保存环境,下次重启就会自动用这个镜像来启动 Notebook,如下图所示。

依据:Notebook 启动命令中会执行 /init.sh/mnt/$username/init.shmyapp/views/view_notebook.py:558708)。

Notebook 镜像保存

多实例的 VirtualService 代理

多实例在线 IDE 图示:

多实例在线 IDE

每个用户可以配置多个在线 IDE,可以自己配置资源、镜像、类型。每个在线 IDE 都是通过 istio VirtualService 来代理的。所以只要在线 IDE 的镜像启动的 web 服务支持 URL prefix,就可以被加进来作为在线 IDE,比如 Matlab、RStudio。每个在线 IDE 实例都有独立的、以名称为 prefix 的 URL 地址,在 VirtualService 配置绑定 istio ingressgateway,这样来实现多实例。

名为 admin-9d3d 的在线 IDE 的 URL prefix:

URL prefix 示例1

名为 admin-e00f 的在线 IDE 的 URL prefix:

URL prefix 示例2

在线 IDE 镜像保存

如果想保存自己 Notebook 中的环境,可以在 Notebook 列表中点击"镜像保存"的按钮,平台将自动将该 Notebook 的 Pod 通过 docker commit 成镜像,镜像名称默认为 ccr.ccs.tencentyun.com/cube-studio/jupyter-user:$notebook-name,并推送到仓库,所以还需要管理员提前配置自己内网的仓库地址和账号密码。

依据:镜像名由配置项 NOTEBOOK_TARGET_IMAGES 决定,默认 ccr.ccs.tencentyun.com/cube-studio/jupyter-user:{name}{name} 为 Notebook 名称),见 myapp/views/view_notebook.py:1091

在线 IDE 清理和续期

默认情况下,定时清理任务只是关闭容器、不会清理文件;重启容器后环境会丢失(分布式存储 /mnt/$username 内容仍保留)。每次有效期为 3 天,清理前一天会提醒用户进行续期。

依据(与代码核对):

  • 定时任务 task.delete_notebookmyapp/tasks/schedules.py 的 celery beat 调度中默认是注释掉的myapp/config.py:708-712),即开箱默认不自动清理,需要手动开启调度。
  • 有效期由配置项 ENABLE_JUPYTER_EXPIRY 控制,默认 60*60*24*3 秒 = 3 天(myapp/tasks/schedules.py:189)。
  • 当前实现中,delete_notebook 任务仅清理 GPU 版本 的过期 Notebook(代码 filter(Notebook.resource_gpu!='0')myapp/tasks/schedules.py:198),过期前一天会推送续期提醒。 清理范围与开启状态以你部署的实际版本与配置为准。

定时清理任务的配置

config.py 中的 task_delete_notebook(celery beat 调度项)控制是否定时清理 Notebook。修改配置以后要重启 infra 命名空间的 schedule 和 worker 组件。

任务续期

点击对应 Notebook 后的续期按钮,可以为当前 Notebook 续期使用时间(实现上把 changed_on 刷新为当前时间,从而重新计算过期时间,见 myapp/views/view_notebook.pyrenew)。

续期按钮


集群级 GPU / 节点资源监控统一在 Grafana 查看,参见 整体资源 与运维管理段的 监控部署与看板

最后更新 2026-07-04完整文档以官方仓库为准:GitHub Wiki