# CubeStudio 国产化开源人工智能平台 · 全文语料(llms-full.txt) > CubeStudio 是国产化云原生一站式开源人工智能平台,同时覆盖传统机器学习、深度学习与大模型全链路(MLOps / MaaS / 算力调度);支持算力纳管调度、算力租赁与 Token 中转、多机多卡分布式训练、大模型微调与多机推理、数据标注与全流程模型部署,适配国产异构算力与操作系统,开源协议 MIT,开源免费商用并支持源码交付与商业化二次分发,开源版本已有数千家企业私有化部署。 本文件是 /llms.txt 的全文伴随版:在站点内容地图之外,进一步收录平台知识库全部文档的完整正文, 便于大模型一次性摄取、离线索引与引用。结构化索引、摘要与品牌/商务/资质信息见站点内容地图。 站点内容地图: https://www.cubestudio.vip/llms.txt ## 品牌标准定义 CubeStudio 是一款国产化、云原生的一站式开源人工智能平台,同时覆盖传统机器学习、深度学习与大模型全链路(MLOps / MaaS / 算力调度 / 训推平台),开源协议 MIT,开源免费商用,开源版本已有数千家企业私有化部署。平台提供多租户与算力纳管调度、算力租赁与 Token 中转站、拖拉拽 Pipeline 任务流编排、多机多卡分布式训练、超参搜索、推理服务、vGPU 虚拟化、云边端协同与边缘计算、图文音多模态自动化标注、大模型 SFT 微调 / 奖励模型 / 强化学习训练、vLLM / Ollama / MindIE 大模型多机推理、私有知识库 / LLMOps / 智能体、AI 模型市场,以及从数据到上线的全流程模型部署。原生适配昇腾、寒武纪、海光、摩尔线程、沐曦等国产异构算力与 x86 / ARM CPU 架构,支持 IB / RoCE / RDMA 高速网络及信创私有化、内网离线部署。 ## 核心实体词 - CubeStudio - 国产化开源人工智能平台 - 私有化 ML / 大模型平台 - 国产 AI 训练与算力调度平台 - 一站式 MLOps / MaaS 平台 ## 关键事实 - 全称: CubeStudio 一站式开源人工智能平台(机器学习 / 深度学习 / 大模型全链路) - 分类: 国产化云原生一站式开源人工智能平台 / MLOps / MaaS / 算力纳管调度 - 开源协议: MIT - 商用: 开源免费商用,支持源码交付与二次分发;开源版本已有数千家企业私有化部署 - 部署方式: 单机部署(单节点 Kubernetes) / Kubernetes 多节点集群 / Serverless / 边缘集群 / 内网离线 / 信创私有化部署 - 国产芯片: 鲲鹏 / 飞腾 / 海光 / 昇腾 / 寒武纪 / 摩尔线程 / 沐曦 / 通用 x86 / GPU - 操作系统: 麒麟(Kylin) / 统信 UOS / CentOS / Ubuntu 等主流 Linux - 高速网络: RDMA / InfiniBand(IB) / RoCE - 落地规模: 开源版本已有数千家企业私有化部署 ## 平台知识库全文 共 225 篇,按分类组织,含完整正文。 ## 总入口 ### CubeStudio 平台知识库(总入口) - 链接: https://www.cubestudio.vip/docs/README - 分类: 索引 / 总入口 - 适用场景: 第一次进入知识库、想了解整体结构和怎么查文档时读这篇 - 关键词: 知识库 / 总入口 / README / 导航 / cube-studio / 平台文档 / 帮助 / 目录 - 最后更新: 2026-07-09 # CubeStudio 平台知识库 这是 CubeStudio 商业版(云原生一站式机器学习平台)的完整知识库,覆盖 平台架构、部署安装、 使用、运维、任务模板、二次开发 全部内容。每篇文档顶部都有 `标题 / 分类 / 关键词 / 适用场景` 元信息, 便于按关键词检索。 ## 目录结构(7 个主段 + 索引段) | 段 | 内容 | 何时看 | |---|---|---| | `00-索引/` | 导航索引、全文目录、术语表 | 找不到内容时先来这里 | | `01-架构原理/` | 平台是什么、组件、各模块架构与设计 | "XX 是什么/为什么这么设计" | | `02-部署安装/` | 各种方式部署平台、GPU/存储/集群准备 | "怎么装/部署/集群准备" | | `03-平台使用/` | 面向使用者的功能使用 | "怎么用 XX 功能" | | `04-运维管理/` | 日常运维、监控、私有仓库、配置、登录认证、FAQ | "运维/报错/配置/登录" | | `05-任务模板/` | pipeline 算子/任务模板及参数 | "某个算子/模板怎么用" | | `06-二次开发/` | 后端框架、API、数据库结构、开发、镜像构建 | "怎么二开/改代码/调 API" | | `07-参考速查/` | 模块地图、核心 API/数据模型速查 | 快速定位代码/接口/表 | ## 怎么查 1. 不确定在哪 → 看 [00-索引/AI导航索引.md](./00-索引/AI导航索引.md)(问题类型 → 目录/文件 映射)。 2. 想看全部文件 → 看 [00-索引/全文目录.md](./00-索引/全文目录.md)。 3. 用了同义词没命中 → 看 [00-索引/术语表.md](./00-索引/术语表.md)(别名 → 规范说法)。 4. 直接按关键词全文搜索(各文档关键词行已为检索优化)。 > 说明:文档以整理时的代码为准做过核实,与代码明确矛盾处已改正;少数拿不准处保留原文并标注 > `⚠️ 待核实` + 代码位置,供人工复核。更细的字段/参数若文档未覆盖,可直接检索对应源码。 --- ## 索引(3 篇) ### AI 导航索引(问题类型 → 去哪查) - 链接: https://www.cubestudio.vip/docs/00-%E7%B4%A2%E5%BC%95/AI%E5%AF%BC%E8%88%AA%E7%B4%A2%E5%BC%95 - 分类: 索引 / 导航 - 适用场景: 拿到一个问题不知道该读哪篇文档时,先读这篇做路由;也是给问答 agent 的导航总图 - 关键词: 导航 / 索引 / 目录 / 怎么查 / 问题分类 / 去哪找 / navigator / sitemap / 文档结构 / 检索建议 - 最后更新: 2026-07-09 # AI 导航索引 本知识库分 7 个主段。下面给出每段职责、关键文件,以及"问题类型 → 去哪查"的路由建议。 检索策略:先按关键词全文搜索(各文档关键词行已优化);不确定再按本索引定位段,再进段内文件。 ## 各段职责与关键文件 ### 01-架构原理/ —— 平台是什么、怎么设计的 - `项目简介.md`、`基础组件介绍.md`(命名空间/各开源组件版本与依赖)、`商业版与开源版功能清单.md` - `平台架构-Kubernetes基础.md` / `平台架构-ML任务流.md` / `平台架构-推理服务.md` / `平台架构-分布式训练与加速.md` - `算力统筹与分布式存储.md`、`流量代理与网关.md`、`RDMA网络与分布式训练.md`、`监控体系/` ### 02-部署安装/ —— 怎么把平台装起来 - 入口:`README.md`(部署方式选择)、`部署方式/部署总览与前置要求.md`、`部署方式/单机部署-docker-compose/`、`部署方式/多机多集群多资源组.md` - 集群:`部署方式/`(k3s/kubeadm/RKE2/KubeKey/KubeSphere/Rancher/serverless/边缘 kubeedge/Windows) - 硬件:`GPU与异构算力/`(昇腾/海光DCU/寒武纪/沐曦/昆仑/摩尔/壁仞/vGPU/节点接入)、`网络/`(RDMA/FRP) - 存储:`存储准备/`(NFS/Ceph/JuiceFS/MinIO/Alluxio)、`部署验证.md`、`版本升级.md` ### 03-平台使用/ —— 怎么用各功能 - 入门:`01-入门与权限/`(新人指南、项目空间、用户和角色、资源配置) - 开发:`03-在线开发/`(在线 IDE、SDK、本地 Jupyter 对接 Hadoop)、`04-镜像构建与仓库/` - 数据:`SQLLab/库表/指标/维表/数据集/数据ETL`、`08-数据标注/`(含内置 LLM 自动标注后端) - 训练:`任务流.md`、`超参搜索.md`;服务化:`07-服务化与推理/`(ml/tfserving/torchserve/triton/**大模型LLM**/模型服务/服务网关/内部服务) - 其他:`AIHub模型市场.md`、`私有知识库.md`、`计量计费.md`、`02-资源与存储/机器租赁.md`(算力租赁) ### 04-运维管理/ —— 日常运维、配置、登录、排障 - 必读:`运维注意事项.md`、`管理员操作指南.md`、`常见问题FAQ.md` - 配置/登录:`配置文件管理.md`、`认证与单点登录配置.md`(LDAP/OAuth2/CAS/飞书/企微/钉钉/微信)、`定时任务与自动清理.md`(平台自动清理/资源/账单任务)、`多租户隔离.md`(按组织 org 隔离数据) - 组件:`元数据库配置.md`、`达梦数据库部署与迁移.md`、`Redis哨兵部署.md`、`私有镜像仓库Harbor.md`、`监控部署与看板.md`、`平台HTTPS配置.md`、`端口使用情况.md`、`加密与安全加固.md` ### 05-任务模板/ —— pipeline 算子/模板及参数 - `00-模板总览.md`(全部算子与所属家族);家族文档:数据导入导出/数据处理/机器学习/深度学习/**大模型**/模型服务化/多媒体CV语音/超参搜索 - `模板使用/`(使用视角的命令与参数)、`开发任务模板.md` ### 06-二次开发/ —— 改代码、调 API、表结构 - `代码结构与模块地图.md`、`FAB后端开发框架.md`、`新增视图页面与数据库升级.md` - API:`API参考/`(接口总览 / 标准化接口 / 标准化接口参数详情 / 特殊接口详情 / 菜单 / 血缘 / 数据集预览) - 数据库:`数据库结构/`(按域分篇);扩展:`登录认证与消息推送扩展.md`、`镜像构建/`、`AIHub算法应用开发.md`、`GPT知识库实现原理.md` ### 07-参考速查/ —— 快速定位代码/接口/表/配置/模板 - `模块地图.md`、`核心API速查.md`、`核心数据模型速查.md` - `配置项速查.md`(config.py 常用项默认值/含义)、`任务模板注册速查.md`(102 个算子镜像/参数) ## 问题类型 → 去哪查 | 用户问的 | 先查 | |---|---| | 怎么用 XX 功能 | `03-平台使用/` | | 怎么部署/安装/集群准备/装 GPU | `02-部署安装/` | | XX 组件是什么 / 为什么这么设计 | `01-架构原理/` | | 报错了 / 出问题了 | `04-运维管理/常见问题FAQ.md`、`运维注意事项.md`、`管理员操作指南.md` | | 登录/SSO/认证 配置 | `04-运维管理/认证与单点登录配置.md` | | 某个算子/模板参数 | `05-任务模板/`(先看 `00-模板总览.md`) | | 怎么二开 / 改代码 / 调 API / 表结构 | `06-二次开发/` | | 大模型推理(vllm/ollama/mindie/triton-llm) | `03-平台使用/07-服务化与推理/推理服务-大模型LLM.md` | | 平台有哪些定时任务 / 为什么 pod/数据被自动清理 | `04-运维管理/定时任务与自动清理.md` | | 某配置项默认值/含义 | `07-参考速查/配置项速查.md` | | 某算子/模板用什么镜像/参数 | `07-参考速查/任务模板注册速查.md`(或 `05-任务模板/`) | | 某端口/接口/表 在哪 | `07-参考速查/`、`04-运维管理/端口使用情况.md`,必要时直接检索源码 | | 多租户 / 按组织隔离数据 | `04-运维管理/多租户隔离.md` | | 机器/算力租赁(按量/按天、单卡/整机) | `03-平台使用/02-资源与存储/机器租赁.md` | | 人大金仓 KingBase 作元数据库 | `04-运维管理/元数据库配置.md` | | 用了同义词没搜到 | `00-索引/术语表.md` | > 文档未覆盖的细粒度字段/参数,可直接检索对应源码(如 `myapp/views/`、`myapp/models/`、`myapp/config.py`、`job-template/job/`)。 --- ### 全文目录(知识库完整文件清单) - 链接: https://www.cubestudio.vip/docs/00-%E7%B4%A2%E5%BC%95/%E5%85%A8%E6%96%87%E7%9B%AE%E5%BD%95 - 分类: 索引 / 目录 - 适用场景: 想快速看到知识库有哪些文档、按段浏览全部文件时读这篇 - 关键词: 全文目录 / 文件清单 / 目录 / sitemap / 索引 / toc / 知识库结构 - 最后更新: 2026-07-09 # 全文目录 本知识库分 7 个主段(外加本索引段)。下列为各段全部文档。 ## 01-架构原理 - [CubeStudio 平台简介与整体架构](../01-架构原理/项目简介.md) - [商业版与开源版功能清单](../01-架构原理/商业版与开源版功能清单.md) - [平台架构 - Kubernetes 基础与 CRD](../01-架构原理/平台架构-Kubernetes基础.md) - [基础组件介绍(命名空间、开源软件版本与依赖)](../01-架构原理/基础组件介绍.md) - [平台架构 - ML 任务流(Pipeline 编排)](../01-架构原理/平台架构-ML任务流.md) - [平台架构 - 分布式训练与加速](../01-架构原理/平台架构-分布式训练与加速.md) - [平台架构 - 推理服务](../01-架构原理/平台架构-推理服务.md) - [算力统筹与分布式存储](../01-架构原理/算力统筹与分布式存储.md) - [流量代理与网关](../01-架构原理/流量代理与网关.md) - [RDMA 网络与分布式训练](../01-架构原理/RDMA网络与分布式训练.md) - [Prometheus 与 Operator 架构](../01-架构原理/监控体系/01-Prometheus与Operator架构.md) - [机器与容器监控(node-exporter / kubelet / dashboard)](../01-架构原理/监控体系/02-机器与容器监控.md) - [入口流量与三方中间件监控](../01-架构原理/监控体系/03-入口流量与中间件监控.md) - [自定义指标与自研 pushgateway](../01-架构原理/监控体系/04-自定义指标与pushgateway.md) - [ServiceMonitor 配置与调试](../01-架构原理/监控体系/05-ServiceMonitor配置与调试.md) - [告警(Alertmanager)与 Grafana 可视化](../01-架构原理/监控体系/06-告警与Grafana.md) - [监控体系总览(Prometheus + Grafana)](../01-架构原理/监控体系/README.md) ## 02-部署安装 - [部署安装总览(部署方式选择指南)](../02-部署安装/README.md) - [部署后初步验证(pipeline/notebook/推理/超参/AIHUB/数据智能/标注)](../02-部署安装/部署验证.md) - [平台版本升级(老版本升级到新版本)](../02-部署安装/版本升级.md) - [NVIDIA vGPU 切分虚拟化(HAMi)](../02-部署安装/GPU与异构算力/vGPU虚拟化.md) - [昇腾 NPU 基础部署(驱动 / 运行时 / k8s 插件 / 监控)](../02-部署安装/GPU与异构算力/华为昇腾NPU/01-基础部署.md) - [昇腾 vNPU 虚拟化(静态切分)](../02-部署安装/GPU与异构算力/华为昇腾NPU/02-vNPU虚拟化.md) - [昇腾 MindIE 多机分布式推理](../02-部署安装/GPU与异构算力/华为昇腾NPU/03-MindIE分布式推理.md) - [华为昇腾 NPU 适配总览](../02-部署安装/GPU与异构算力/华为昇腾NPU/README.md) - [国产GPU/NPU 与 ARM64 适配总览](../02-部署安装/GPU与异构算力/国产GPU与ARM64适配总览.md) - [壁仞 GPU 适配(biren:驱动 + k8s 组件 + 占用测试)](../02-部署安装/GPU与异构算力/壁仞GPU.md) - [寒武纪 MLU 适配(Cambricon)](../02-部署安装/GPU与异构算力/寒武纪MLU.md) - [摩尔线程 GPU 适配(mthreads / MUSA)](../02-部署安装/GPU与异构算力/摩尔线程GPU.md) - [昆仑芯 XPU 适配(百度昆仑芯)](../02-部署安装/GPU与异构算力/昆仑芯GPU.md) - [沐曦 GPU 适配(C500:驱动 + device plugin + mx-exporter)](../02-部署安装/GPU与异构算力/沐曦GPU.md) - [海光 DCU 适配(驱动 + k8s device plugin + vDCU 虚拟化)](../02-部署安装/GPU与异构算力/海光DCU.md)- [NFS 共享存储部署](../02-部署安装/存储准备/NFS共享存储.md)- [替换基础组件与镜像(对接自有 istio/prometheus/minio/mysql 等)](../02-部署安装/组件与运维衔接/替换基础组件.md) - [FRP 内网穿透(把内网 CubeStudio 暴露到公网)](../02-部署安装/网络/FRP内网穿透.md) - [RDMA 高速网络部署(InfiniBand / RoCE / Mellanox)](../02-部署安装/网络/RDMA高速网络.md) - [GPU 节点接入与初始化](../02-部署安装/节点准备/GPU节点接入与初始化.md) - [Jetson 边缘 GPU 节点初始化](../02-部署安装/节点准备/Jetson节点初始化.md) - [节点安装 Containerd 容器运行时](../02-部署安装/节点准备/安装Containerd.md) - [节点安装 Docker](../02-部署安装/节点准备/安装Docker.md) - [RKE2 + Rancher 方式部署 K8s 集群](../02-部署安装/部署方式/RKE2部署.md) - [Windows 部署 CubeStudio(WSL2)](../02-部署安装/部署方式/Windows部署.md) - [k3s 单机部署 CubeStudio](../02-部署安装/部署方式/k3s单机部署.md) - [kubeadm 安装 k8s 组件](../02-部署安装/部署方式/kubeadm部署.md) - [KubeKey 环境准备与安装 k8s](../02-部署安装/部署方式/kubekey部署/01-环境准备与安装k8s.md) - [在 KubeKey k8s 上部署 cube-studio](../02-部署安装/部署方式/kubekey部署/02-部署cube-studio.md) - [KubeKey 离线部署 k8s](../02-部署安装/部署方式/kubekey部署/03-离线部署.md) - [KubeKey 节点扩缩容、高可用与卸载](../02-部署安装/部署方式/kubekey部署/04-节点扩缩容与高可用.md) - [KubeKey 部署 CubeStudio 总览](../02-部署安装/部署方式/kubekey部署/README.md) - [KubeSphere 多机部署(一)主机环境初始化与系统优化](../02-部署安装/部署方式/kubesphere多机部署/01-主机环境与系统优化.md) - [KubeSphere 多机部署(二)安装 KubeSphere 与 K8s 集群](../02-部署安装/部署方式/kubesphere多机部署/02-安装KubeSphere与K8s集群.md) - [KubeSphere 多机部署(三)在集群上部署 cube-studio](../02-部署安装/部署方式/kubesphere多机部署/03-部署cube-studio.md) - [KubeSphere 多机部署 CubeStudio(概览)](../02-部署安装/部署方式/kubesphere多机部署/README.md) - [Rancher RKE 机器初始化与镜像准备](../02-部署安装/部署方式/rancher-RKE部署/01-机器初始化与镜像准备.md) - [部署 Rancher Server 与 K8s 集群](../02-部署安装/部署方式/rancher-RKE部署/02-部署RancherServer与K8s集群.md) - [Rancher 运维与故障处理](../02-部署安装/部署方式/rancher-RKE部署/03-Rancher运维与故障处理.md) - [Rancher 扩容、多用户、节点清理与重建迁移](../02-部署安装/部署方式/rancher-RKE部署/04-扩容多用户与重建迁移.md) - [Rancher + RKE 部署 K8s 集群总览](../02-部署安装/部署方式/rancher-RKE部署/README.md)- [单机 k8s 部署(rancher / 已有 k8s / 隔离内网)](../02-部署安装/部署方式/单机部署-docker-compose/01-单机k8s部署.md) - [docker-compose 本地部署(前后端 + mysql + redis)](../02-部署安装/部署方式/单机部署-docker-compose/02-docker-compose本地部署.md) - [本地开发与调试(IDE 断点 / 前端构建 / 镜像升级 / Q&A)](../02-部署安装/部署方式/单机部署-docker-compose/03-本地开发与调试.md) - [单机部署与 docker-compose 部署(概览)](../02-部署安装/部署方式/单机部署-docker-compose/README.md) - [多机/多集群/多资源组部署](../02-部署安装/部署方式/多机多集群多资源组.md) - [离线/内网部署](../02-部署安装/部署方式/离线部署.md) - [边缘集群部署 - 原理与适用场景](../02-部署安装/部署方式/边缘集群部署-KubeEdge/01-原理与适用场景.md) - [边缘集群部署 - 一键脚本(install/kubernetes/kubeedge)](../02-部署安装/部署方式/边缘集群部署-KubeEdge/02-一键脚本部署.md) - [边缘集群部署 - 云端环境准备(K8s + NFS)](../02-部署安装/部署方式/边缘集群部署-KubeEdge/03-云端环境准备-K8s与NFS.md) - [边缘集群部署 - 云端部署 CubeStudio 与 CloudCore](../02-部署安装/部署方式/边缘集群部署-KubeEdge/04-云端cube-studio与CloudCore.md) - [边缘集群部署 - 边缘节点接入与项目组配置](../02-部署安装/部署方式/边缘集群部署-KubeEdge/05-边缘节点接入与项目组配置.md) - [边缘集群部署 - 端到端验证与最大坑(label 硬编码)](../02-部署安装/部署方式/边缘集群部署-KubeEdge/06-验证与最大坑-label硬编码.md) - [边缘集群部署 - 踩坑速查与版本命令](../02-部署安装/部署方式/边缘集群部署-KubeEdge/07-踩坑速查.md) - [边缘集群部署(KubeEdge 云-边)概览](../02-部署安装/部署方式/边缘集群部署-KubeEdge/README.md) - [部署总览与前置要求](../02-部署安装/部署方式/部署总览与前置要求.md) ## 03-平台使用 - [新人指南-基础认识与视频教程](../03-平台使用/01-入门与权限/新人用户使用指南/01-基础认识与视频教程.md) - [新人指南-加入项目组与权限](../03-平台使用/01-入门与权限/新人用户使用指南/02-加入项目组与权限.md) - [新人指南-在线 notebook 开发](../03-平台使用/01-入门与权限/新人用户使用指南/03-在线notebook开发.md) - [新人指南-在线构建镜像](../03-平台使用/01-入门与权限/新人用户使用指南/04-在线构建镜像.md) - [新人指南-pipeline 配置/调试/定时运行](../03-平台使用/01-入门与权限/新人用户使用指南/05-pipeline配置调试定时.md) - [新人指南-NNI 超参搜索](../03-平台使用/01-入门与权限/新人用户使用指南/06-nni超参搜索.md) - [新人指南-内部服务](../03-平台使用/01-入门与权限/新人用户使用指南/07-内部服务.md) - [新人指南-推理服务](../03-平台使用/01-入门与权限/新人用户使用指南/08-推理服务.md) - [新人用户使用指南(总览与目录)](../03-平台使用/01-入门与权限/新人用户使用指南/README.md) - [用户和角色(权限体系)](../03-平台使用/01-入门与权限/用户和角色.md) - [项目空间(项目组)使用与权限](../03-平台使用/01-入门与权限/项目空间.md) - [存储资源配置](../03-平台使用/02-资源与存储/存储资源配置.md) - [整体资源(全局资源视角与 Pod 管理)](../03-平台使用/02-资源与存储/整体资源.md) - [机器/算力租赁(rental)](../03-平台使用/02-资源与存储/机器租赁.md) - [机器资源配置](../03-平台使用/02-资源与存储/机器资源配置.md) - [cube-studio Python SDK 使用](../03-平台使用/03-在线开发/SDK使用.md) - [在 Notebook 镜像中部署本地大模型版 Claude Code](../03-平台使用/03-在线开发/notebook部署ClaudeCode.md) - [在线 IDE(Notebook / VSCode / RStudio / Matlab)](../03-平台使用/03-在线开发/在线IDE.md) - [手动安装 Hadoop 生态:Spark 配置与测试](../03-平台使用/03-在线开发/本地Jupyter对接Hadoop生态/01-手动安装-Spark配置与测试.md) - [手动安装 Hadoop 生态:Flink 配置与测试](../03-平台使用/03-在线开发/本地Jupyter对接Hadoop生态/02-手动安装-Flink配置与测试.md) - [基于 Dockerfile 的 Hadoop 生态集成镜像(bigdata)](../03-平台使用/03-在线开发/本地Jupyter对接Hadoop生态/03-基于Dockerfile集成镜像.md) - [Hadoop 生态对接:其他辅助文档](../03-平台使用/03-在线开发/本地Jupyter对接Hadoop生态/04-其他辅助文档.md) - [本地 Jupyter 对接 Hadoop 生态(总览)](../03-平台使用/03-在线开发/本地Jupyter对接Hadoop生态/README.md) - [镜像仓库(凭据管理与拉取/推送策略)](../03-平台使用/04-镜像构建与仓库/镜像仓库.md) - [镜像在线构建和管理](../03-平台使用/04-镜像构建与仓库/镜像在线构建和管理.md) - [SQLLab 在线数据库查询](../03-平台使用/05-数据资产与处理/SQLLab.md) - [库表(离线元数据库表管理)](../03-平台使用/05-数据资产与处理/库表.md) - [指标(数据资产指标管理)](../03-平台使用/05-数据资产与处理/指标.md) - [数据 ETL 任务流](../03-平台使用/05-数据资产与处理/数据ETL.md) - [数据集导入与管理](../03-平台使用/05-数据资产与处理/数据集.md) - [维表(维度表资产)使用](../03-平台使用/05-数据资产与处理/维表.md) - [任务可视化 echart 数据格式说明](../03-平台使用/06-任务流与训练/任务可视化echart数据格式.md) - [任务流(Pipeline)编排与调度](../03-平台使用/06-任务流与训练/任务流.md) - [NNI 超参搜索](../03-平台使用/06-任务流与训练/超参搜索.md) - [内部服务(数据库 Web 管理端 / 桌面等)](../03-平台使用/07-服务化与推理/内部服务.md) - [推理服务 ml-server(sklearn / xgboost / R-pmml)](../03-平台使用/07-服务化与推理/推理服务-ml.md) - [推理服务 TFServing(TensorFlow Serving)](../03-平台使用/07-服务化与推理/推理服务-tfserving.md) - [TorchServe 推理服务](../03-平台使用/07-服务化与推理/推理服务-torchserve.md) - [Triton 推理服务](../03-平台使用/07-服务化与推理/推理服务-triton.md) - [推理服务 - 大模型(LLM)推理(vllm / ollama / mindie / triton-llm)](../03-平台使用/07-服务化与推理/推理服务-大模型LLM.md) - [大模型 OpenAI 服务网关](../03-平台使用/07-服务化与推理/服务网关.md) - [模型管理与推理服务](../03-平台使用/07-服务化与推理/模型服务.md) - [标注平台功能介绍与操作流程](../03-平台使用/08-数据标注/标注平台/01-功能与操作流程.md) - [标注平台数据导入格式说明](../03-平台使用/08-数据标注/标注平台/02-数据导入格式说明.md) - [标注平台 - 内置 LLM 自动标注后端接入](../03-平台使用/08-数据标注/标注平台/03-内置LLM自动标注后端.md) - [标注平台总览](../03-平台使用/08-数据标注/标注平台/README.md) - [AIHUB 模型市场使用指南](../03-平台使用/09-数据智能与市场/AIHub模型市场.md) - [私有知识库使用说明](../03-平台使用/09-数据智能与市场/私有知识库.md) - [计量计费与资源账单](../03-平台使用/10-计量计费/计量计费.md) - [03-平台使用 段导航(按上手路径)](../03-平台使用/README.md) ## 04-运维管理 - [运维注意事项与通用约定](../04-运维管理/运维注意事项.md) - [管理员操作指南](../04-运维管理/管理员操作指南.md) - [平台配置文件管理(config.py / entrypoint.sh / project.py / kubeconfig)](../04-运维管理/配置文件管理.md) - [CubeStudio 端口使用情况](../04-运维管理/端口使用情况.md) - [平台元数据库配置(MySQL / PostgreSQL)](../04-运维管理/元数据库配置.md) - [分布式存储目录结构(/data/k8s)](../04-运维管理/分布式存储目录.md) - [私有镜像仓库 Harbor 安装](../04-运维管理/私有镜像仓库Harbor.md) - [Redis 哨兵模式部署与故障切换验证](../04-运维管理/Redis哨兵部署.md) - [达梦数据库(DM8)部署与 MySQL 迁移](../04-运维管理/达梦数据库部署与迁移.md) - [认证与单点登录(SSO)配置](../04-运维管理/认证与单点登录配置.md) - [平台 HTTPS 配置(istio gateway / nginx 代理 / 自签证书)](../04-运维管理/平台HTTPS配置.md) - [加密与安全加固(交付加固清单 + containerd 镜像加密)](../04-运维管理/加密与安全加固.md) - [多租户隔离(ENABLE_MULTI_TENANT)](../04-运维管理/多租户隔离.md) - [平台定时任务与自动清理(Celery beat)](../04-运维管理/定时任务与自动清理.md) - [监控部署与看板(Prometheus + Grafana)](../04-运维管理/监控部署与看板.md) - [监控指标推送与报警代理(cloud-pushgateway)](../04-运维管理/监控指标推送-pushgateway.md) - [故障恢复 - Rancher RKE 集群时间回拨](../04-运维管理/故障恢复-集群时间回拨.md) - [常见问题 FAQ](../04-运维管理/常见问题FAQ.md) ## 05-任务模板 - [任务模板/算子总览索引](../05-任务模板/00-模板总览.md) - [数据导入导出类任务模板(datax / dataset / model-download / label-studio-import)](../05-任务模板/01-数据导入导出.md) - [数据处理类任务模板(data-process / hadoop / spark / ray / volcano / nlp-process / feature-process)](../05-任务模板/02-数据处理.md) - [机器学习任务模板(sklearn 算法族 / ray-sklearn 分布式)](../05-任务模板/03-机器学习.md) - [深度学习分布式训练任务模板(TF / PyTorch / 多框架)](../05-任务模板/04-深度学习.md) - [大模型任务模板(训练 / 蒸馏 / 剪枝 / 量化 / 评测)](../05-任务模板/05-大模型.md) - [模型服务化任务模板(转换/注册/部署/评估/离线推理)](../05-任务模板/06-模型服务化.md) - [多媒体/CV/语音任务模板(视频音频/图像/语音/YOLO/OCR)](../05-任务模板/07-多媒体CV语音.md) - [超参搜索任务模板(NNI / Ray Tune)](../05-任务模板/08-超参搜索.md) - [开发并注册新任务模板](../05-任务模板/开发任务模板.md) - [基础命令模板(自定义镜像/逻辑节点/python 节点)](../05-任务模板/模板使用/00-基础命令.md) - [数据导入导出模板(datax/dataset/label-studio/model-download)](../05-任务模板/模板使用/01-数据导入导出.md) - [数据处理模板(hadoop/volcanojob/ray/sparkjob)](../05-任务模板/模板使用/02-数据处理.md) - [数据预处理模板(去重/缺失/单一值/填充/统计量/异常值)](../05-任务模板/模板使用/03-数据预处理.md) - [特征处理模板(离散化/标准化/采样/降维/拆分/转换/编码/索引/排序/SQL/合并/特征重要性/特征组合/相关性)](../05-任务模板/模板使用/04-特征处理.md) - [机器学习算法模板(RF/LR/LightGBM/KNN/KMeans/GBDT/决策树/贝叶斯/XGB/AdaBoost/超参搜索/AR/ARIMA/回归)](../05-任务模板/模板使用/05-机器学习算法.md) - [深度学习分布式训练模板(tfjob/pytorchjob/mxnet/paddlejob/mindspore)](../05-任务模板/模板使用/06-深度学习.md) - [模型处理模板(model-evaluation 模型评估 / model-convert 模型转换)](../05-任务模板/模板使用/07-模型处理.md) - [模型服务化模板(离线推理/服务部署/模型注册)](../05-任务模板/模板使用/08-模型服务化.md) - [多媒体类模板(媒体下载/视频抽帧/视频提音频)](../05-任务模板/模板使用/09-多媒体类模板.md) - [分布式加速模板(horovod)](../05-任务模板/模板使用/10-分布式加速.md) - [任务模板使用手册(总览)](../05-任务模板/模板使用/README.md) ## 06-二次开发 - [代码结构与模块地图](../06-二次开发/代码结构与模块地图.md) - [FAB 后端开发框架(Flask-AppBuilder)](../06-二次开发/FAB后端开发框架.md) - [新增视图页面与数据库升级](../06-二次开发/新增视图页面与数据库升级.md) - [更换 Logo 与水印](../06-二次开发/更换Logo与水印.md) - [弹窗报警与提醒格式(前端协议)](../06-二次开发/弹窗报警与提醒格式.md) - [登录认证与消息推送扩展](../06-二次开发/登录认证与消息推送扩展.md) - [推理服务 JWT 认证(统一鉴权)](../06-二次开发/推理服务JWT认证.md) - [AIHub 算法应用开发](../06-二次开发/AIHub算法应用开发.md) - [LabelStudio 标注平台二次开发](../06-二次开发/LabelStudio标注开发.md) - [GPT 知识库实现原理(RAG / llama_index)](../06-二次开发/GPT知识库实现原理.md) - [SQLLab 计算引擎对接(二次开发)](../06-二次开发/SQLLab计算引擎对接.md) - [数据 ETL 调度引擎对接(二次开发)](../06-二次开发/数据ETL调度引擎对接.md) - [API 接口总览(路由前缀 + 特殊接口索引)](../06-二次开发/API参考/接口总览.md) - [数据集预览/详情渲染协议](../06-二次开发/API参考/数据集预览接口.md) - [标准化接口-通用约定与 $view 路径对照表](../06-二次开发/API参考/标准化接口/01-通用约定与路径对照.md) - [标准化接口-标准 CRUD(_info/list/show/add/edit/delete)](../06-二次开发/API参考/标准化接口/02-标准CRUD接口.md) - [标准化接口-操作/图表/收藏(action/multi_action/echart/favorite)](../06-二次开发/API参考/标准化接口/03-操作图表收藏.md) - [标准化接口-文件上传下载(download_template/upload/download/upload_files)](../06-二次开发/API参考/标准化接口/04-文件上传下载.md) - [标准化接口-Python 客户端调用示例](../06-二次开发/API参考/标准化接口/05-Python客户端示例.md) - [标准化接口(MyappModelRestApi 基类)概览](../06-二次开发/API参考/标准化接口/README.md) - [标准化接口参数详情-项目与权限](../06-二次开发/API参考/标准化接口参数详情/01-项目与权限.md) - [标准化接口参数详情-资源计费与日志](../06-二次开发/API参考/标准化接口参数详情/02-资源计费与日志.md) - [标准化接口参数详情-数据治理](../06-二次开发/API参考/标准化接口参数详情/03-数据治理.md) - [标准化接口参数详情-镜像与 notebook](../06-二次开发/API参考/标准化接口参数详情/04-镜像与notebook.md) - [标准化接口参数详情-数据开发](../06-二次开发/API参考/标准化接口参数详情/05-数据开发.md) - [标准化接口参数详情-训练](../06-二次开发/API参考/标准化接口参数详情/06-训练.md) - [标准化接口参数详情-模型与服务](../06-二次开发/API参考/标准化接口参数详情/07-模型与服务.md) - [标准化接口参数详情-aihub 与智能体](../06-二次开发/API参考/标准化接口参数详情/08-aihub与智能体.md) - [标准化接口参数详情(各模型字段)概览](../06-二次开发/API参考/标准化接口参数详情/README.md) - [特殊接口 - 平台基础(导航/用户/项目组/审批)](../06-二次开发/API参考/特殊接口详情/01-平台基础.md) - [特殊接口 - 镜像与开发环境(镜像构建/Notebook/Docker)](../06-二次开发/API参考/特殊接口详情/02-镜像与开发环境.md) - [特殊接口 - 训练任务流(Pipeline/固化/Task/Workflow/NNI)](../06-二次开发/API参考/特殊接口详情/03-训练任务流.md) - [特殊接口 - 数据开发任务流(ETL/运行实例/服务化任务流)](../06-二次开发/API参考/特殊接口详情/04-数据开发任务流.md) - [特殊接口 - 模型与服务(模型定义/训练模型/推理服务/内部服务/AIHub)](../06-二次开发/API参考/特殊接口详情/05-模型与服务.md) - [特殊接口 - 智能体与对话(aitalk/钉钉/微信/企业微信/LLM网关)](../06-二次开发/API参考/特殊接口详情/06-智能体与对话.md) - [特殊接口 - 数据治理(数据集/维表/血缘/LabelStudio/SQL查询)](../06-二次开发/API参考/特殊接口详情/07-数据治理.md) - [特殊接口 - 运维系统(消息/K8s/仪表盘/账单/整体资源)](../06-二次开发/API参考/特殊接口详情/08-运维系统.md) - [特殊接口详情(非标准 CRUD)总览](../06-二次开发/API参考/特殊接口详情/README.md) - [菜单与导航接口(/myapp/menu 与 navbar)](../06-二次开发/API参考/菜单与导航接口.md) - [通用血缘链路接口(通用关系图 commonRelation 与 /blood 数据血缘)](../06-二次开发/API参考/通用血缘链路接口.md) - [数据库结构 - 权限与用户](../06-二次开发/数据库结构/01-权限与用户.md) - [数据库结构 - 项目计费与账户](../06-二次开发/数据库结构/02-项目计费与账户.md) - [数据库结构 - 数据治理](../06-二次开发/数据库结构/03-数据治理.md) - [数据库结构 - 镜像与开发环境](../06-二次开发/数据库结构/04-镜像与开发环境.md) - [数据库结构 - 数据开发 ETL](../06-二次开发/数据库结构/05-数据开发ETL.md) - [数据库结构 - 训练任务流与分布式训练](../06-二次开发/数据库结构/06-训练任务流.md) - [数据库结构 - 模型与服务](../06-二次开发/数据库结构/07-模型与服务.md) - [数据库结构 - 智能体与系统](../06-二次开发/数据库结构/08-智能体与系统.md) - [数据库结构总览](../06-二次开发/数据库结构/README.md) - [Windows 桌面容器镜像(KVM)](../06-二次开发/镜像构建/Windows桌面容器镜像.md) - [数据分析运行镜像与算子开发(data-analysis runner)](../06-二次开发/镜像构建/数据分析运行镜像与算子开发.md) - [自定义 Notebook 镜像构建](../06-二次开发/镜像构建/自定义Notebook镜像.md) - [镜像构建总览](../06-二次开发/镜像构建/镜像构建总览.md) ## 07-参考速查 - [模块地图(后端 myapp / 前端 frontend 总览)](../07-参考速查/模块地图.md) - [核心数据模型速查(ORM / 数据库表)](../07-参考速查/核心数据模型速查.md) - [核心 API 速查(REST 端点 / route_base)](../07-参考速查/核心API速查.md) - [config.py 配置项速查(常用项)](../07-参考速查/配置项速查.md) - [任务模板注册速查(全部算子:镜像 / 启动命令 / 参数)](../07-参考速查/任务模板注册速查.md) --- ### 术语表(别名 / 同义词 → 规范说法与文档) - 链接: https://www.cubestudio.vip/docs/00-%E7%B4%A2%E5%BC%95/%E6%9C%AF%E8%AF%AD%E8%A1%A8 - 分类: 索引 / 术语 - 适用场景: 用户用了某个叫法/缩写没搜到对应文档时,用这张表把别名映射到规范说法与所在文档 - 关键词: 术语表 / 别名 / 同义词 / 缩写 / glossary / 名词解释 / 叫法 / 对照 - 最后更新: 2026-07-05 # 术语表 平台不同叫法/缩写很多。下表把常见别名映射到规范说法及主要文档,辅助按关键词命中。 | 别名 / 同义词 / 缩写 | 规范说法 | 主要文档 | |---|---|---| | pipeline、工作流、DAG、编排 | 任务流 | `03-平台使用/任务流.md`、`01-架构原理/平台架构-ML任务流.md` | | notebook、jupyter、在线 IDE、VSCode、开发环境 | 在线开发 / 在线 IDE | `03-平台使用/03-在线开发/在线IDE.md` | | inference、serving、模型上线、模型部署 | 推理服务 | `03-平台使用/07-服务化与推理/` | | LLM、大模型推理、vllm、ollama、mindie、triton-llm | 大模型推理服务 | `03-平台使用/07-服务化与推理/推理服务-大模型LLM.md` | | 算子、job-template、组件、节点 | 任务模板 | `05-任务模板/` | | aihub、模型市场、模型仓库 | AIHub 模型市场 | `03-平台使用/AIHub模型市场.md` | | RAG、GPT 知识库、数据智能、知识问答 | 私有知识库 | `03-平台使用/私有知识库.md`、`06-二次开发/GPT知识库实现原理.md` | | team、项目组、空间、租户 | 项目空间 / 项目组 | `03-平台使用/01-入门与权限/项目空间.md` | | HPO、NNI、自动调参 | 超参搜索 | `03-平台使用/超参搜索.md` | | docker build、在线构建镜像、镜像调试 | 镜像构建 | `03-平台使用/04-镜像构建与仓库/` | | registry、hubsecret、镜像凭据 | 镜像仓库 | `03-平台使用/04-镜像构建与仓库/镜像仓库.md` | | billing、账单、计费、配额、quota、额度 | 计量计费 / 资源额度 | `03-平台使用/计量计费.md`、`03-平台使用/01-入门与权限/项目空间.md` | | 数据集、标注、库表、指标、维表 | 数据资产 | `03-平台使用/`(各对应文档)、`03-平台使用/08-数据标注/` | | OpenAI 网关、LLM 网关、大模型代理 | 服务网关 | `03-平台使用/07-服务化与推理/服务网关.md` | | 内网服务、工具服务 | 内部服务 | `03-平台使用/07-服务化与推理/内部服务.md` | | SSO、单点登录、OAuth2、CAS、飞书/企微/钉钉/微信登录、LDAP | 认证与单点登录 | `04-运维管理/认证与单点登录配置.md` | | 元数据库、MySQL/PostgreSQL/达梦/金仓 | 元数据库 | `04-运维管理/元数据库配置.md`、`04-运维管理/达梦数据库部署与迁移.md` | | Harbor、私有仓库 | 私有镜像仓库 | `04-运维管理/私有镜像仓库Harbor.md` | | NPU、昇腾、海光 DCU、寒武纪、沐曦、昆仑、摩尔线程、壁仞、国产卡 | 异构算力/国产 GPU 适配 | `02-部署安装/GPU与异构算力/` | | NFS、共享存储 | 分布式/共享存储 | `02-部署安装/存储准备/` | | 监控、Prometheus、Grafana、告警 | 监控体系 | `01-架构原理/监控体系/`、`04-运维管理/监控部署与看板.md` | | API、接口、CRUD、token 认证 | REST 接口 / 二次开发 | `06-二次开发/API参考/`、`07-参考速查/核心API速查.md` | | 表结构、ORM、数据库表 | 数据库结构 | `06-二次开发/数据库结构/`、`07-参考速查/核心数据模型速查.md` | | 边缘集群、kubeedge | 边缘集群部署 | `02-部署安装/部署方式/边缘集群部署/` | --- ## 架构原理(17 篇) ### CubeStudio 平台简介与整体架构 - 链接: https://www.cubestudio.vip/docs/01-%E6%9E%B6%E6%9E%84%E5%8E%9F%E7%90%86/%E9%A1%B9%E7%9B%AE%E7%AE%80%E4%BB%8B - 分类: 01-架构原理 / 总览 - 适用场景: 想快速了解 CubeStudio 是什么、有哪些功能模块、整体架构如何组成、与各专题篇的关系时读这篇(本段总览首篇) - 关键词: cube-studio / 平台简介 / 项目简介 / overview / 机器学习平台 / MLOps / AI平台 / 一站式 / 整体架构 / architecture / 功能清单 / 商业版 / pipeline / notebook / 推理服务 / AIHub / 大模型 / 多集群 / 算力 / 存储 / 多租户 / 项目组 - 最后更新: 2026-07-09 # CubeStudio 平台简介 > 本篇为「01-架构原理」段总览首篇。功能清单、整体架构、各模块概述在此汇总,更细节的 Kubernetes 基础、基础组件版本与依赖见同段的 > [平台架构-Kubernetes基础](平台架构-Kubernetes基础.md) 与 [基础组件介绍](基础组件介绍.md)。 ## 背景 传统算法落地流程:从申请机器、配置环境、拉取数据、处理数据、算法训练、调试、模型测试,到服务化上线全流程,算法工程师在每个环节都浪费了很多时间,而不是把精力集中在算法模型的构建上。 CubeStudio 一站式机器学习平台,从平台架构上对以下几个问题做了更贴近用户实用化的考虑。 ![平台定位](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/beijing.png) 主要问题场景: ![问题场景](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/problems.jpeg) ## CubeStudio 是什么 CubeStudio 是开源云原生一站式机器学习/深度学习 AI 平台,支持 SSO 登录、多租户/多项目组、数据资产对接、notebook 在线开发、拖拉拽任务流 pipeline 编排、多机多卡分布式算法训练、超参搜索、推理服务 VGPU、多集群调度、边缘计算、serverless、标注平台自动化标注、数据集管理、大模型一键微调、私有知识库、AI 应用商店;支持模型一键开发/推理/微调、私有化部署,支持国产 CPU/GPU/NPU 芯片,支持 RDMA。 ## 功能清单(商业版) | 模块分组 | 功能 | 说明 | |:----|:---|:----| | 基础能力 | 项目组管理 | 通过项目划分配置项目组用户权限,任务/服务的挂载、资源组、集群、服务代理、项目组内角色控制 | | 基础能力 | 网络 | 支持非 80 端口,支持公网/域名,支持反向代理和内网穿透方式访问,支持 https | | 基础能力 | 用户管理/角色管理/权限管理 | 管理平台用户基本信息、组织架构,支持账号密码、RBAC 权限体系 | | 基础能力 | SSO 单点登录 | 支持对接公司账号体系 AUTH_OID/AUTH_LDAP/AUTH_REMOTE_USER 等登录注册方式,支持消息推送 | | 基础能力 | 支持多种算力 | 多规格资源支持不同使用场景,cpu/gpu 等;支持 T4/V100/A100 等多种卡型,支持 arm64 芯片、vgpu 等模式;支持国产 gpu、海光 gpu、海飞科 dcu、华为 npu,支持 rdma 调度 | | 基础能力 | 多资源组/多集群 | 支持划分多资源组,支持多 k8s 集群 | | 基础能力 | 边缘集群 | 支持边缘集群模式,支持边缘节点开发、训练、推理 | | 基础能力 | serverless 集群模式 | 支持腾讯云、阿里云 serverless 集群模式(notebook、pipeline、推理服务模块支持) | | 基础能力 | 数据库存储 | 支持外部 mysql/postgres 作为元数据库 | | 基础能力 | 存储盘管理 | 支持 web 界面添加存储盘,支持项目组绑定,notebook/pipeline/推理服务直接在 pod 中挂载外部分布式存储,支持 nfs、cfs | | 基础能力 | 国际化能力 | 支持配置多语言,目前支持中英文 | | 数据管理 | 数据地图 | 元数据库表管理、指标、维表 | | 数据管理 | 数据计算 | sqllab 交互查询,支持 mysql、postgresql 等计算引擎 | | 数据管理 | ETL 编排 | 数据 ETL 任务流编排、任务管理等,对接公司数据中台相应计算/调度引擎 | | 数据管理 | 数据集管理 | 允许用户随时上传样本集(图片、音频、文本等),支持 sdk 进行数据集对接 | | 数据管理 | 数据标注 | 支持开源标注平台,图/文/音/多模态各类型标注能力,对接一站式机器学习平台,支持自动化标注 | | 开发环境 | 镜像功能 | 镜像仓库/镜像管理/在线构建镜像;提供平台所有镜像(模板镜像/服务镜像/notebook 镜像/gpu 基础环境)的构建方法和构建后镜像,支持 dockerfile 在线构建 | | 开发环境 | notebook | 基于开源 Jupyterlab/vscode 的在线交互式开发调试工具;多种可选 ide 与开发示例,支持资源类型选择;支持大数据/机器学习/深度学习版本;支持 ssh remote 与 notebook 远程开发;支持 matlab、Rstudio 等在线 ide;支持 gpu/cpu/内存监控、git 交互;支持自定义 notebook 镜像;多内核(R/julia/python2.7~3.10 及 CubeStudio 专有环境);支持 tensorboard 可视化、环境镜像保存、密码保护、整卡/虚拟卡/gpu 共享占用、启动自动初始化 | | 开发环境 | 拖拉拽任务流编排调试 | 拖拽式交互开发 pipeline;单任务调试,训练支持多种资源规格与卡型选择、超时重试,任务支持虚拟化 gpu 独占/共享占用;pipeline 支持定时调度、补录、并发限制、超时、实例依赖、任务管理、workflow 实例管理、资源监控、任务输入输出、全局变量、文本/图片/echart 结果可视化;支持运行中任务监听端口提供运行中服务 | | 开发环境 | 主流功能算子 | 基础算子(自定义镜像/逻辑节点/python)、数据同步(数据集导入/datax/模型导入)、数据预处理、特征处理、数据处理(hadoop/spark/volcanojob/ray/sparkjob)、传统机器学习(ray-sklearn/xgb 等及超参搜索)、分布式深度学习(tf/pytorch/mxnet/horovod/paddlejob/mindspore)、分布式加速(colossalai/deepspeed/horovod)、模型处理(评估/格式转换)、模型服务化(注册/离线处理/部署)、媒体分布式处理 | | 开发环境 | 算子自定义 | 通过 web 界面将自定义算法代码镜像注册为可被复用的 pipeline 算子 | | 开发环境 | 自动学习 | 面向非 AI 背景用户的自动学习,选择场景并上传数据即可自动训练与部署,支持示例 automl 任务流导入导出 | | 开发环境 | 自定义镜像 | 面向高级 AI 开发者,提供自定义训练作业(执行环境 + 代码) | | 开发环境 | 自动调参 | 基于单机/分布式自动超参搜索 | | 开发环境 | TensorBoard 作业 | 实时/离线观察模型训练过程中的参数和指标变化 | | 模型服务化 | 内部服务 | 快捷部署 mysql-web、postgresql web、mongo web、redis web、neo4j、rstudio 等开源工具 | | 模型服务化 | 模型管理 | 模型多版本管理,支持模型发布为推理服务 | | 模型服务化 | 推理服务 | 支持 ml/tf/pytorch/tensorrt/onnx 常规模型多版本 0 代码发布;gpu 卡型选择、vgpu、独占/共享、cpu/mem/gpu 弹性伸缩、服务优先级、流量分流/复制、sidecar、泛域名、配置文件挂载、启动目录/命令/环境变量/端口/指标/健康检查;调试/测试/生产环境;域名/ip 代理;负载指标监控;多版本滚动升级回滚、单 pod 滚动发布;可禁用 k8s service 负载均衡器;远程模型路径;提供常规模型推理镜像并支持自定义推理镜像 | | 监控 | 整体资源 | 所有集群/机器使用情况(集群、资源组、机器 ip、cpu/gpu 类型卡型、cpu/内存/gpu 使用率);所有计算 pod 使用情况(集群、资源组、命名空间、调度 ip、pod 名、启动用户、cpu/gpu/内存申请使用率) | | 监控 | 监控体系 | 机器 gpu 资源、内存/cpu/网络 io/磁盘 io 负载;pod 的内存/cpu/gpu/网络 io 负载;推理服务的内存/cpu/gpu/qps/吞吐/vgpu 负载 | | AIHUB | 模型应用管理方案 | 提供 cube-studio sdk,提供模型开发与使用规范;提供 web 端模型应用体验,支持同步/异步推理;提供多个 python cuda 版本基础镜像 | | AIHUB | 预训练模型 | 提供视觉、听觉、nlp、多模态等 400+ 预训练模型,提供模型加载和推理能力,可一键部署服务并提供 api | | AIHUB | 模型市场 | aihub 应用对接 CubeStudio 平台卡片式展示 | | AIHUB | 模型一键开发 | 一键转 notebook 开发,提供符合该模型环境的 jupyter | | AIHUB | 模型一键微调 | 一键转 pipeline 微调链路(示例数据集下载、微调、模型注册、模型部署),支持微调后模型部署 | | AIHUB | 模型一键部署 web | 一键部署手机端/pc 端 web 界面和 api,提供 demo 示例弹窗演示 | | AIHUB | 模型自动化标注 | 支持部署对接 labelstudio 自动化标注 | | AIHUB | SDK | 数据集 sdk(搜索/上传/下载、加解密/解压缩/基础信息查看)、notebook sdk、pipeline 训练 sdk、推理服务 sdk | | 大模型 | 分布式多机多卡 | 支持 mpi/deepspeed/Colossal-AI 等分布式多机多卡训练 | | 大模型 | 大模型推理 | 支持 deepseek/chatglm/llama/qwen 部署 | | 大模型 | 大模型微调 | 支持 deepseek/chatglm/llama/qwen 微调 | | 大模型 | 智能对话 | 多场景对话,支持提示词构建、推理接口配置、llm 问答、问询中模型切换/清理/历史上下文 | | 大模型 | 私有知识库 | 私有知识库配置与召回,支持召回列表模式、aigc 模式,支持微信公众号服务号、企业微信群聊机器人、钉钉群聊机器人对接 | ## 平台部署 部署说明见 [02-部署安装](../02-部署安装/) 段。Kubernetes 部署相关说明散落在 `install/kubernetes/` 下各组件子目录的 readme(如 `rancher/readme.md`、`prometheus/readme.md` 等)以及 `install/README.md`(仓库中无 `install/kubernetes/README.md`)。 平台完成部署之后的界面如下: ![部署完成界面](https://foruda.gitee.com/images/1700638826074173896/8ee56db3_13742231.png) ## 支持的任务模板 提示: - 能单机运行没必要多机运行; - 开发自定义模板更符合自己业务线下的需求。 > 下表「实现位置」为模板在仓库源码中的相对目录(供检索定位);模板的使用文档统一见 [05-任务模板](../05-任务模板/) 段。 > 注意:传统机器学习算法模板已合并到 `job-template/job/sklearn/`(各算法对应一个 `launcher-*.py`);分布式深度学习框架模板已合并到 `job-template/job/deep-learning-framework/`(各框架对应一个 `README-*.md`)。 | 模块 | 模板 | 类型 | 实现位置(仓库源码) | |:----|:----|:----|:----| | 数据导入导出 | datax | 单机 | job-template/job/datax/ | | 数据导入导出 | 数据集导入 | 单机 | job-template/job/dataset/ | | 数据导入导出 | 模型导入 | 单机 | job-template/job/model_download/ | | 数据预处理 | data-process | 单机 | job-template/job/data-process/ | | 数据处理工具 | hadoop | 单机 | job-template/job/hadoop/ | | 数据处理工具 | spark | 分布式 | job-template/job/spark/ | | 数据处理工具 | ray | 分布式 | job-template/job/ray/ | | 数据处理工具 | volcanojob | 分布式 | job-template/job/volcano/ | | 特征处理 | feature-process | 单机 | job-template/job/feature-process/ | | 机器学习框架 | ray-sklearn | 分布式 | job-template/job/ray-sklearn/ | | 机器学习算法 | random_forest | 单机 | job-template/job/sklearn/ (launcher-random-forest.py) | | 机器学习算法 | lr | 单机 | job-template/job/sklearn/ (launcher-lr.py) | | 机器学习算法 | lightgbm | 单机 | job-template/job/sklearn/ (launcher-lightgbm.py) | | 机器学习算法 | knn | 单机 | job-template/job/sklearn/ (launcher-knn.py) | | 机器学习算法 | kmeans | 单机 | job-template/job/sklearn/ (launcher-kmeans.py) | | 机器学习算法 | nni | 单机 | job-template/job/hyperparameter-search-nni/ | | 机器学习算法 | xgb | 单机 | job-template/job/sklearn/ (launcher-xgb.py) | | 机器学习算法 | gbdt | 单机 | job-template/job/sklearn/ (launcher-gbdt.py) | | 机器学习算法 | decision-tree | 单机 | job-template/job/sklearn/ (launcher-decision-tree.py) | | 机器学习算法 | bayesian | 单机 | job-template/job/sklearn/ (launcher-bayesian.py) | | 机器学习算法 | adaboost | 单机 | job-template/job/sklearn/ (launcher-adaboost.py) | | 深度学习 | tfjob | 分布式 | job-template/job/tf/ | | 深度学习 | pytorchjob | 分布式 | job-template/job/pytorch/ | | 深度学习 | paddle | 分布式 | job-template/job/deep-learning-framework/ (README-paddle.md) | | 深度学习 | mxnet | 分布式 | job-template/job/deep-learning-framework/ (README-mxnet.md) | | 深度学习 | mindspore | 分布式 | job-template/job/deep-learning-framework/ (README-mindspore.md) | | 深度学习 | horovod | 分布式 | job-template/job/deep-learning-framework/ (README-horovod.md) | | 深度学习 | mpi | 分布式 | job-template/job/deep-learning-framework/ (README-mpi.md) | | 深度学习 | colossalai | 分布式 | job-template/job/deep-learning-framework/ (README-colossalai.md) | | 深度学习 | deepspeed | 分布式 | job-template/job/deep-learning-framework/ (README-deepspeed.md) | | 深度学习 | megatron | 分布式 | job-template/job/deep-learning-framework/ (README-megatron.md) | | 模型处理 | model-evaluation | 单机 | job-template/job/model_evaluation/ | | 模型服务化 | model-convert | 单机 | job-template/job/model-convert/ | | 模型服务化 | model-register | 单机 | job-template/job/model_register/ | | 模型服务化 | deploy-service | 单机 | job-template/job/deploy-service/ | | 模型服务化 | model-offline-predict | 分布式 | job-template/job/offline-predict/ | | 多媒体类 | media-download | 分布式 | job-template/job/video-audio/ | | 多媒体类 | video-img | 分布式 | job-template/job/video-audio/ | | 多媒体类 | video-audio | 分布式 | job-template/job/video-audio/ | | 大模型 | llama | 单机多卡 | job-template/job/llama-factory/ | | 大模型 | chatglm | 单机多卡 | job-template/job/llama-factory/ | | 大模型 | deepseek | 单机多卡 | job-template/job/llama-factory/ | | 大模型 | qwen | 单机多卡 | job-template/job/llama-factory/ | ## 整体架构 完整的平台包含: 1. 机器的标准化; 2. 分布式存储(单机可忽略)、k8s 集群、监控体系(prometheus/efk/zipkin); 3. 基础能力(tf/pytorch/mxnet/volcano/ray 等分布式,nni/ray 超参搜索); 4. 平台 web 部分(oa/权限/项目组、在线构建镜像、在线开发、pipeline 拖拉拽、超参搜索、推理服务管理等)。 ![整体架构](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/infra.png) ## 算力 / 存储 / 用户管理 算力: - 云原生统筹平台 cpu/gpu 等算力; - 支持划分多资源组,支持多 k8s 集群、多地部署; - 支持 T4/V100/A100/昇腾/dcu/VGPU 等异构 GPU/NPU 环境; - 支持边缘集群模式,支持边缘节点上开发/训练/推理; - 支持鲲鹏芯片 arm64 架构、RDMA。 存储: - 自带分布式存储,支持多机分布式下文件处理; - 支持外部存储挂载,支持项目组挂载绑定; - 支持个人存储空间/组空间等多种形式; - 平台内存储空间不需要迁移。 用户权限: - 支持 sso 登录,对接公司账号体系; - 支持项目组划分,支持配置相应项目组用户权限; - 管理平台用户基本信息、组织架构,rbac 权限体系。 ## 多集群管控 单个 k8s 集群的部署拓扑图: ![单集群拓扑](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/one-k8s-infra.png) CubeStudio 支持多集群调度,可同时管控多个训练或推理集群。在单个集群内,不仅能做到一个项目组内对在线开发、训练、推理的隔离,还可以做到一个 k8s 集群下多个项目组算力的隔离。不同项目组下的算力间具有动态均衡能力,能够在多项目间共享公共算力池和私有化算力池,做到成本最低化。 ![多集群管控](https://foruda.gitee.com/images/1700638883899604064/594984a3_13742231.png) ## 分布式存储 CubeStudio 会自动为用户挂载用户的个人目录,同一个用户在平台任何地方启动的容器,其用户个人子目录均为 `/mnt/$username`。可以将 pvc/hostpath/memory/configmap 等挂载成容器目录。同时可以在项目组中配置项目组的默认挂载,进而实现一个项目组共享同一个目录等功能。 ![分布式存储](https://foruda.gitee.com/images/1700638909994130903/21509b52_13742231.png) ## 在线开发 - 系统多租户/多实例管理,在线交互开发调试,无需安装三方控件,只需浏览器就能完成开发; - 支持 vscode、jupyter、Matlab、Rstudio 等多种在线 IDE 类型; - Jupyter 支持 cube-studio sdk,Julia、R、python、pyspark 多内核版本; - 支持 c++、java、conda 等多种开发语言,以及 tensorboard/git/gpu 监控等多种插件; - 支持 ssh remote 与 notebook 互通,本地进行代码开发; - 在线镜像构建,通过 Web Shell 在浏览器中完成构建;并提供各种版本 notebook、inference、gpu、python 等基础镜像。 ![在线开发](https://foruda.gitee.com/images/1700638934409882911/6fd39f42_13742231.png) ## 标注平台 - 支持图/文/音/多模态/大模型多种类型标注功能、用户管理、工作任务分发; - 对接 aihub 模型市场,支持自动化标注;对接数据集,支持标注数据导入;对接 pipeline,支持标注结果自动化训练。 ![标注平台](https://foruda.gitee.com/images/1700638984355648038/dd364128_13742231.png) ## 拖拉拽 pipeline 编排 1. ML 全流程:数据导入、数据预处理、超参搜索、模型训练、模型评估、模型压缩、模型注册、服务上线,ML 算法全流程; 2. 灵活开放:支持单任务调试、分布式任务日志聚合查看、pipeline 调试跟踪、任务运行资源监控,以及定时调度功能(补录、忽略、重试、依赖、并发限制、过期淘汰等)。 ![pipeline编排](https://foruda.gitee.com/images/1700639014115951983/143617d0_13742231.png) ## 分布式框架 1. 训练框架支持分布式(协议和策略); 2. 代码识别分布式角色(有状态); 3. 控制器部署分布式训练集群(operator); 4. 配置分布式训练集群的部署(CRD)。 CRD 与 operator 的关系详见 [平台架构-Kubernetes基础](平台架构-Kubernetes基础.md)。 ## 多层次多类型算子 以 k8s 为核心: 1. 支持 tf 分布式训练、pytorch 分布式训练、spark 分布式数据处理、ray 分布式超参搜索、mpi 分布式训练、horovod 分布式训练、nni 分布式超参搜索、mxnet 分布式训练、volcano 分布式数据处理等; 2. 以及衍生的分布式数据下载、hdfs 拉取、cos 上传下载、视频采帧、音频抽取等。 ![多类型算子](https://foruda.gitee.com/images/1700639039508595862/305a7ea0_13742231.png) ## 功能模板化 - 与非模板开发相比,使用模板建立应用成本更低,无需开发平台; - 迁移更容易,模板标准化后,后续应用迭代只需迁移配置模板; - 配置复用,简单配置即可复用能力,算法与工程分离避免重复开发。 平台对 pipeline 中的 task 功能进行模板化开发,平台开发者或用户可自行开发模板镜像并注册到平台,供其他用户复用。平台自带模板在 `job-template/` 目录下(详见 [05-任务模板](../05-任务模板/))。 ![功能模板化](https://foruda.gitee.com/images/1700639064997200785/d29bd416_13742231.png) ## 流水线调试 - Pipeline 调试支持定时执行、补录、并发限制、超时、实例依赖等; - 运行支持变量在任务间输入输出、全局变量、流向控制、模板变量、数据时间等; - 运行支持任务结果可视化:图片、csv/json、echart 源码可视化。 ![流水线调试](https://foruda.gitee.com/images/1700639114920102568/8f00a285_13742231.png) ## NNI 超参搜索 界面化呈现训练各组数据,通过图形界面直观呈现,降低调参过程的枯燥感,无需丰富经验即可实现更精准的参数控制调节。 ```python # 上报当前迭代目标值 nni.report_intermediate_result(test_acc) # 上报最终目标值 nni.report_final_result(test_acc) # 接收超参数为输入参数 parser.add_argument('--batch_size', type=int) ``` ![nni超参搜索](https://foruda.gitee.com/images/1700639143626105768/e2a43750_13742231.png) ## 推理服务 0 代码发布推理服务从底层到上层,包含服务网格、serverless、pipeline、http 框架、模型计算: - 服务网格阶段:代理流量的中转和管控,例如分流、镜像、限流、黑白名单; - serverless 阶段:服务的智能化运维,例如服务的激活、伸缩容、版本管理、蓝绿发布; - pipeline 阶段:请求在各数据处理/推理之间的流动,推理的前后置处理逻辑; - http/grpc 框架:处理客户端请求、准备推理样本、推理后响应; - 模型计算:模型在 cpu/gpu 上对输入样本做前向计算。 主要功能: - 支持模型管理注册、灰度发布、版本回退、模型指标可视化,以及在 pipeline 中进行模型注册; - 推理服务支持多集群、多资源组、异构 gpu 环境、平台资源统筹监控、VGPU、服务流量分流/复制、sidecar; - 支持 0 代码模型发布、gpu 推理加速、训练推理混部、服务优先级、自定义指标弹性伸缩。 ![推理服务](https://foruda.gitee.com/images/1700639370208099263/bd89615d_13742376.png) ## 监控和推送 - 监控:CubeStudio 集成 prometheus 生态,可监控主机、进程、服务流量、gpu 等相关负载,并配套 grafana 进行可视化; - 推送:CubeStudio 开放推送接口,可自定义推送给企业 oa 系统。 ![监控和推送](https://foruda.gitee.com/images/1700639395119577791/cd1ac2aa_13742376.png) ## AIHub - 系统自带通用模型数量 400+,覆盖绝大多数行业场景,可按需扩充; - 模型开源、按需定制,方便快速集成; - 模型标准化开发管理,大幅降低使用门槛; - AIHub 模型可一键部署为 WEB 端应用(手机端/PC 端),实时查看效果;点击模型开发即可进入 notebook 二次开发;点击训练即可加入数据一键微调。 ![AIHub](https://foruda.gitee.com/images/1700639434869953948/2bace2c0_13742376.png) ## GPT 训练微调 - CubeStudio 支持 deepspeed/colossalai 等分布式加速框架,可一键实现大模型多机多卡分布式训练; - AIHub 包含 gpt/AIGC 大模型,可一键转为微调 pipeline,修改为自己的数据后即可微调并部署。 ![GPT训练微调](https://foruda.gitee.com/images/1700639481624506769/044da76f_13742376.png) ## GPT-RDMA rdma 插件部署后,k8s 机器可用资源: ```yaml capacity: cpu: '128' memory: 1056469320Ki nvidia.com/gpu: '8' rdma/hca: '500' ``` 代码分布式训练中使用 IB 设备: ```bash export NCCL_IB_HCA=mlx5 export MLP_WORKER_GPU=$GPU_NUM export MLP_WORKER_NUM=$WORLD_SIZE export MLP_ROLE_INDEX=$RANK export MLP_WORKER_0_HOST=$MASTER_ADDR export MLP_WORKER_0_PORT=$MASTER_PORT ``` ![GPT-RDMA](https://foruda.gitee.com/images/1700639514746995383/b1ac0777_13742376.png) ## GPT 私有知识库 - 数据智能模块可配置专业领域智能对话,快速敏捷使用 llm; - 可为某个聊天场景配置私有知识库文件,支持主题分割、语义 embedding、意图识别、概要提取、多路召回、排序、多种功能融合。 ![私有知识库](https://foruda.gitee.com/images/1700639535204668937/39511fd5_13742376.png) ## GPT 智能聊天 - 可将智能会话与 AIHub 结合,例如 AIGC 模型与聊天会话; - 可使用 Autogpt 方式串联所有 aihub 模型,进行图文音智能化处理; - 智能会话与公众号打通,可在微信公众号中进行图文音对话。 ![智能聊天](https://foruda.gitee.com/images/1700639561296900661/7ea529a8_13742376.png) ## 数据中台对接 为了加速 AI 算法平台的使用,CubeStudio 支持对接公司原有数据中台,包括数据计算引擎 sqllab、元数据管理、指标管理、维表管理、数据 ETL、数据集管理。 ![数据中台对接](https://foruda.gitee.com/images/1700639585820739093/b36e8cf9_13742376.png) ## 三种部署方式 针对企业需求,根据不同场景对计算实时性的不同需求,可以提供三种建设模式: - 模式一:私有化部署——对数据安全要求高、预算充足、自己有开发能力; - 模式二:边缘集群部署——算力分散、多个子网环境的场景,或边缘设备场景; - 模式三:serverless 集群——成本有限、按需申请算力的场景。 具体部署见 [02-部署安装](../02-部署安装/) 段。 ### 边缘计算 通过边缘集群的形式,在中心节点部署平台,并将边缘节点加入调度,每个私有网用户通过项目组将 notebook、pipeline、service 部署在边缘节点: 1. 避免数据到中心节点的带宽传输; 2. 避免中心节点的算力成本,充分利用边缘节点算力; 3. 避免边缘节点的运维成本。 ![边缘计算](https://foruda.gitee.com/images/1700639624949363049/c6109834_13742376.png) --- ### 平台架构 - Kubernetes 基础与 CRD - 链接: https://www.cubestudio.vip/docs/01-%E6%9E%B6%E6%9E%84%E5%8E%9F%E7%90%86/%E5%B9%B3%E5%8F%B0%E6%9E%B6%E6%9E%84-Kubernetes%E5%9F%BA%E7%A1%80 - 分类: 01-架构原理 / 平台架构 - 适用场景: 想了解 CubeStudio 为什么用 k8s/rancher、平台用到哪些 CRD(分布式训练/工作流/监控/网关/批调度)、调度打分策略与内网 DNS 配置时读这篇 - 关键词: kubernetes / k8s / rancher / CRD / CustomResourceDefinition / operator / 自定义资源 / pytorchjob / tfjob / mpijob / mxjob / mxnet / sparkjob / sparkapplication / workflow / argo / prometheus / servicemonitor / istio / gateway / virtualservice / volcano / vcjob / queue / scheduler / 调度 / 过滤打分 / coredns / dns / 内网域名 - 最后更新: 2026-07-04 # 平台架构 - Kubernetes 基础 ## rancher / kubernetes CubeStudio 利用 Kubernetes 的优势: - 原生的环境隔离; - 集群化自动化管理; - 计算资源(CPU/GPU)自动调度; - 成熟的生态体系; - crd/operator 便捷的 api 方式管理。 机器环境配置好以后,就可以来部署 k8s 机器了。下面是 k8s 的一个架构: ![k8s架构](https://foruda.gitee.com/images/1700637106463511748/8edc8404_1019082.png) ## CRD(自定义资源) 除了需要了解 k8s 官方资源(pod、service、sa、rbac、sts、deployment 等),还需要特别了解 k8s 的自定义资源 CustomResourceDefinition(简称 CRD)。CRD 在机器学习平台中使用非常频繁。下面列举平台用到的常用 CRD。 > 表中 group / version / plural / kind 已对照后端代码 `myapp/config.py` 的 `CRD_INFO`(约 `config.py:1148`)核实。平台实际通过该配置直接对接 k8s 集群创建/监听这些自定义资源。 ### Kubeflow 系(分布式训练) | 资源类型(plural) | group | version | kind | 说明 | |:----|:----|:----|:----|:----| | pytorchjobs | kubeflow.org | v1 | PyTorchJob | pytorch 分布式训练 | | tfjobs | kubeflow.org | v1 | TFJob | tf 分布式训练 | | mpijobs | kubeflow.org | v1 | MPIJob | mpi 分布式训练 | | mxjobs | kubeflow.org | v1 | MXJob | mxnet 分布式训练 | | paddlejobs | kubeflow.org | v1 | PaddleJob | paddle 分布式训练 | | xgboostjobs | xgboostjob.kubeflow.org | v1alpha1 | (未在 CRD_INFO 显式声明 kind) | xgboost 分布式训练 | > ⚠️ 已按代码纠正:原文将 mxnet 资源写为 `mxnetjobs` / kind `MxnetJob`,但 `config.py:1211-1216` 中实际为 plural `mxjobs`、kind `MXJob`、group `kubeflow.org`。 > 补充:`config.py` 的 `CRD_INFO` 还定义了 `paddlejobs`(kind `PaddleJob`)与 `xgboostjobs`(group `xgboostjob.kubeflow.org`,`config.py:1170-1175`),原文表中未列出。 ### Spark 系 | 资源类型(plural) | group | version | kind | 说明 | |:----|:----|:----|:----|:----| | sparkapplications | sparkoperator.k8s.io | v1beta2 | SparkApplication | spark 分布式任务 | ### Argo 系(工作流) | 资源类型(plural) | group | version | kind | 说明 | |:----|:----|:----|:----|:----| | workflows | argoproj.io | v1alpha1 | Workflow | argo 的 workflow(pipeline 底层) | ### Prometheus 系(监控) > 以下为 prometheus-operator 上游标准 CRD,未在 `CRD_INFO` 中声明(平台不直接创建);kind 按 prometheus-operator 标准命名。 | 资源类型(plural) | group | kind | 说明 | |:----|:----|:----|:----| | alertmanagers | monitoring.coreos.com | Alertmanager | prometheus 监控 k8s 的报警机制 | | prometheuses | monitoring.coreos.com | Prometheus | prometheus 部署实例 | | prometheusrules | monitoring.coreos.com | PrometheusRule | prometheus 拉取/告警规则配置 | | servicemonitors | monitoring.coreos.com | ServiceMonitor | prometheus 拉取某个服务下所有 pod 的指标 | ### Istio 系(流量代理) | 资源类型(plural) | group | version | kind | 说明 | |:----|:----|:----|:----|:----| | gateways | networking.istio.io | - | Gateway | istio 网关 | | virtualservices | networking.istio.io | v1alpha3 | VirtualService | istio 虚拟服务(`config.py:1183`) | ### Volcano 系(批调度) | 资源类型(plural) | group | version | kind | 说明 | |:----|:----|:----|:----|:----| | jobs | batch.volcano.sh | v1alpha1 | Job | volcano 批处理任务(vcjob) | | queues | scheduling.volcano.sh | v1beta1 | Queue | 批优先级队列 | > ⚠️ 已按代码纠正:原文将 volcano `jobs` 的 kind 误写为 `Gateway`,实际 kind 为 `Job`(见 `config.py:1190-1196` 的 `vcjob` 与 `install/kubernetes/volcano/demo.yaml:1-2`:`apiVersion: batch.volcano.sh/v1alpha1` / `kind: Job`)。podgroup/queue 使用 `scheduling.volcano.sh/v1beta1`(`install/kubernetes/volcano/volcano-podgroup.yaml`)。 ## scheduler(调度过滤打分) k8s 的调度包含很多方面:节点选择、亲和度、污点,还有过滤打分的环节。CubeStudio 中使用到的调度机制如下: ![调度机制](https://foruda.gitee.com/images/1700637139449024803/13242426_1019082.png) 调度策略配置文件为仓库中的 `install/kubernetes/scheduler-policy-config.json`(部署相关说明见 [02-部署安装](../02-部署安装/))。其核心是一组打分插件(priorities),关键项包括: - `SelectorSpreadPriority`、`InterPodAffinityPriority`、`NodeAffinityPriority`、`TaintTolerationPriority`、`ImageLocalityPriority`、`BalancedResourceAllocation`(各权重 1); - `RequestedToCapacityRatioPriority`(权重 1,按 cpu/memory 的利用率打分,利用率 0 得 10 分、100 得 0 分,鼓励均匀分散); - `NodePreferAvoidPodsPriority`(权重 10000)。 主要使用场景:在不同 pipeline 的任务同时发起时,希望每台机器都能被均匀使用,而不是过度集中在其中数台服务器上。 如果在 rancher 中使用,还需要将该文件挂载到调度器中。 ## coredns(内网 DNS) 内网部署时,pod 中常会用到内网域名,往往需要在 pod 配置内网的 dns 解析服务器。配置方式:修改 `kube-system` 命名空间的对应 configmap(coredns),然后重启 coredns。参考配置文件为仓库中的 `install/kubernetes/rancher/coredns.yaml`(部署相关说明见 [02-部署安装](../02-部署安装/))。 该配置通过 coredns 的 `hosts` 插件把镜像仓库、apt/pip 源、modelscope 等域名指向内网镜像地址,并可为 `oa.com` 等结尾的域名单独配置 dns 代理(`forward`)。 --- ### 基础组件介绍(命名空间、开源软件版本与依赖) - 链接: https://www.cubestudio.vip/docs/01-%E6%9E%B6%E6%9E%84%E5%8E%9F%E7%90%86/%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6%E4%BB%8B%E7%BB%8D - 分类: 01-架构原理 / 基础组件 - 适用场景: 想知道平台由哪些基础组件构成、各组件在哪个命名空间、用的哪个版本/开源协议、依赖关系与配置位置时读这篇 - 关键词: 基础组件 / 命名空间 / namespace / 组件清单 / 开源软件版本 / 开源协议 / license / redis / mysql / postgresql / kubernetes-dashboard / metrics-scraper / nvidia-device-plugin / hami / vgpu / rdma / dcgm-exporter / node-exporter / prometheus / grafana / prometheus-adapter / training-operator / workflow-controller / argo / minio / volcano / istio / ingressgateway / istiod / labelstudio / 标注平台 - 最后更新: 2026-07-09 # 基础组件介绍 ## 平台基础架构 ![基础架构](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/infra-small.png) 完整的平台包含: 1. 机器的标准化; 2. 分布式存储(单机可忽略)、k8s 集群、监控体系(prometheus/grafana); 3. 基础能力(tf/pytorch/mxnet/volcano/ray 等分布式,nni/ray 超参搜索); 4. 平台 web 部分(oa/权限/项目组、在线构建镜像、在线开发、pipeline 拖拉拽、超参搜索、推理服务管理等)。 ## 组件说明(命名空间 - 组件对照) | 命名空间 | 组件名 | 组件说明 | |:----|:----|:----| | infra | kubeflow-dashboard-frontend | CubeStudio 平台的 web 前端,提供静态文件的访问 | | infra | kubeflow-dashboard | CubeStudio 平台的 web 后端,提供后端 api 的访问 | | infra | kubeflow-dashboard-schedule | 调度 CubeStudio 系统自带的调度任务,比如定时清理 | | infra | kubeflow-dashboard-worker | 执行 CubeStudio 系统自带的调度任务,比如定时清理 | | infra | kubeflow-watch | 监控 CubeStudio 平台中的任务,发起通知和信息更新 | | infra | mysql | 平台元数据的存储 | | infra | redis | 平台缓存,和异步任务对接 | | kube-system | kubernetes-dashboard-cluster | k8s 中 pod 的管理界面 | | kube-system | dashboard-cluster-metrics-scraper | k8s pod 管理界面上的 pod 资源使用情况插件 | | kube-system | nvidia-device-plugin-daemonset | k8s 中使用机器 gpu 驱动和设备的插件 | | kube-system | hami-daemonset | k8s 中使用机器 gpu 虚拟化驱动和设备的插件 | | kube-system | rdma-shared-dp-ds | k8s 中使用机器 rdma 网络和设备的插件 | | kube-system | metrics-server | 集群资源使用情况的指标采集,用于 hpa | | kube-system | kubeflow-prometheus-adapter | 将 prometheus 采集的指标转化为可用于 hpa 的指标 | | kubeflow | labelstudio | 标注平台 | | kubeflow | postgres | postgres 数据库,labelstudio 平台的元数据存储 | | kubeflow | train-operator | tf/pytorch/xgb/mxnet/mpi 等分布式训练 operator | | kubeflow | workflow-controller | argo 云原生调度 | | kubeflow | minio | 对象存储 | | kubeflow | volcano-* | volcano 分布式和批调度 | | istio-system | istio-ingressgateway | 入口网关,代理所有外部访问 | | istio-system | 其他 | istio 基础组件 | | monitoring | dcgm-exporter | gpu 机器资源监控 | | monitoring | node-exporter | cpu 机器资源监控 | | monitoring | prometheus-k8s | 监控数据存储服务 | | monitoring | grafana | 监控数据可视化 | | jupyter | docker-* | 用户创建的在线构建镜像的 pod | | jupyter | 其他 | 用户创建的在线 notebook | | service | 全部 | 用户创建的内部服务和推理服务 | | pipeline | 全部 | 用户创建的 pipeline 任务 | | automl | 全部 | 用户创建的超参数搜索任务 | > 说明:volcano 在本仓库的 `install/kubernetes/volcano/volcano-development.yaml` 中部署到 `kubeflow` 命名空间;另有 `install/README.md` 中将其标注为 `volcano-system`,以实际部署清单为准。 ## 对开源软件的修改情况(版本与协议) > 下表版本已对照 `install/kubernetes/all_image.py` 与各组件部署 yaml 核实,并标注纠正项。 | 序号 | 名称 | 版本 | 软件类型 | 是否修改 | 开源协议 | 协议地址 | |------|------|------|------|------|------|------| | 1 | Redis | 7.4 | 开源软件 | 未修改,官方镜像商用 | BSD-3-Clause | https://github.com/redis/redis | | 2 | Kubernetes Dashboard | v2.6.1 | 开源软件 | 未修改,官方镜像商用 | Apache-2.0 | https://github.com/kubernetes/dashboard | | 3 | NVIDIA Device Plugin | v0.17.1 | 开源软件 | 未修改,官方镜像商用 | Apache-2.0 | https://github.com/NVIDIA/k8s-device-plugin | | 4 | Hami | v2.8.0 | 开源软件 | 未修改,官方镜像商用 | Apache-2.0 | https://github.com/Project-HAMi/HAMi | | 5 | RDMA Shared DP DS | v1.5.1 | 开源软件 | 未修改,官方镜像商用 | Apache-2.0 | https://github.com/Mellanox/k8s-rdma-shared-dev-plugin | | 6 | Prometheus Adapter | v0.9.1 | 开源软件 | 未修改,官方镜像商用 | Apache-2.0 | https://github.com/kubernetes-sigs/prometheus-adapter | | 7 | Training Operator | v1-8a066f9 | 开源软件 | 未修改,官方镜像商用 | Apache-2.0 | https://github.com/kubeflow/training-operator | | 8 | Workflow Controller | v3.4.3 | 开源软件 | 未修改,官方镜像商用 | Apache-2.0 | https://github.com/argoproj/argo-workflows | | 9 | MinIO | RELEASE.2023-04-20T17-56-55Z | 开源软件 | 未修改,官方镜像商用 | AGPL-3.0 | https://github.com/minio/minio | | 10 | Volcano | v1.14.0 | 开源软件 | 未修改,官方镜像商用 | Apache-2.0 | https://github.com/volcano-sh/volcano | | 11 | Istio | 1.15.0 | 开源软件 | 未修改,官方镜像商用 | Apache-2.0 | https://github.com/istio/istio | | 12 | DCGM Exporter | 3.1.7-3.1.4 | 开源软件 | 未修改,官方镜像商用 | Apache-2.0 | https://github.com/NVIDIA/dcgm-exporter | | 13 | Node Exporter | v1.5.0 | 开源软件 | 未修改,官方镜像商用 | Apache-2.0 | https://github.com/prometheus/node_exporter | | 14 | Prometheus | v2.27.1 | 开源软件 | 未修改,官方镜像商用 | Apache-2.0 | https://github.com/prometheus/prometheus | | 15 | Grafana | 9.5.20 | 开源软件 | 未修改,官方镜像商用 | AGPL-3.0 | https://github.com/grafana/grafana | | 16 | PostgreSQL | 11.5 | 开源软件 | 未修改,官方镜像商用 | PostgreSQL | https://www.postgresql.org/about/licence/ | | 17 | Label Studio | 见下方待核实 | 开源软件 | 部分修改 | Apache-2.0 | https://github.com/HumanSignal/label-studio | > ⚠️ 已按代码纠正: > - Grafana:原文写 9.1.5,实际镜像为 `grafana/grafana:9.5.20`(`install/kubernetes/all_image.py`、`install/kubernetes/prometheus/grafana/grafana-dp.yml`)。 > - Volcano:原文「基础组件依赖」小节写 1.7.0,实际镜像为 `volcanosh/vc-webhook-manager:v1.14.0`(`install/kubernetes/volcano/volcano-development.yaml`),与本表 1.14.0 一致,已统一为 v1.14.0。 > > ⚠️ 待核实:Label Studio 版本。原文表与依赖小节均写 1.13.2,但 `install/kubernetes/labelstudio/labelstudio.yaml:40` 实际使用自定义镜像 tag `ccr.ccs.tencentyun.com/cube-studio/label-studio:20260701`,行内注释为 `heartexlabs/label-studio:1.10.1`。具体基线版本请确认。 ## 基础组件依赖 ### mysql / postgresql - 版本:mysql `8.0.32`(`install/kubernetes/mysql/deploy.yaml`)、postgres `11.5`; - 功能:CubeStudio 的基础元数据存储; - 依赖关系:CubeStudio 自研 pod(infra/kubeflow-dashboard-* 的 pod)依赖数据库;企业自己准备 mysql/postgresql,并不作为商业版交付,可自行配置地址; - 配置位置:infra/kubeflow-dashboard-* pod 的环境变量,可修改 mysql 地址,默认为 infra/mysql 的 service; - 注意:开发者需自主完成 mysql 的高可用和按日备份。 ### redis - 版本:redis `7.4`(`install/kubernetes/redis/redis.yaml`); - 功能:CubeStudio 的缓存数据存储、异步任务的中间队列和结果存储; - 依赖关系:CubeStudio 自研 pod(infra/kubeflow-dashboard-*)依赖 redis,企业可自己准备 redis; - 配置位置:infra/kubeflow-dashboard-* pod 的环境变量,可修改 redis 地址,默认为 infra/redis 的 service; - 注意:redis 版本太低可能无法支持依赖的功能,建议按依赖版本准备。 ### kubernetes-dashboard / metrics-scraper - 版本:kubernetes-dashboard `v2.6.1`、metrics-scraper `v1.0.8`; - 功能:CubeStudio 查看 pod 日志、搜索 pod、查看 service 和 node 基础信息等;metrics-scraper 用于在 k8s dashboard 中查看 pod 的资源使用情况; - 依赖关系:CubeStudio 自研 pod(infra/kubeflow-dashboard-*)依赖 k8s dashboard; - 配置位置:infra/kubeflow-dashboard-config 的 configmap,即 CubeStudio 的 config.py 配置文件; - 注意:包含 user 版本和 cluster 版本的 k8s dashboard,可自行控制不同用户权限。 ### nvidia-device-plugin / dcgm-exporter / rdma-shared-dp-ds - 版本:nvidia-device-plugin `v0.17.1`、dcgm-exporter `3.1.7-3.1.4`、rdma-shared-dp-ds `v1.5.1`; - 功能:device-plugin 为 k8s 中调度 gpu 机器的 gpu 设备(cpu 机器不使用);dcgm-exporter 为 gpu 监控;rdma-shared-dp-ds 为 ib 交换机或 roce 网络对应的 k8s 插件; - 依赖关系:gpu 机器初始化的必备条件;不同 gpu 厂商使用的插件和监控组件不同,需要厂商提供; - 配置位置:infra/kubeflow-dashboard-config 的 configmap,即 CubeStudio 的配置文件; - 注意:对于不同厂商的 AI 加速卡,需要不同的 gpu 插件、虚拟化插件和监控插件。 > ⚠️ 待核实:rdma-shared-dp-ds 版本。镜像为自定义 tag `ccr.ccs.tencentyun.com/cube-studio/k8s-rdma-shared-dev-plugin:mellanox`(`install/kubernetes/rdma/mellanox/daemonset.yaml`),无法直接确认是否对应上游 v1.5.1。 ### hami - 版本:`2.8.0`(默认 `install/kubernetes/gpu/vgpu/vgpu.yaml` 使用 `projecthami/hami:v2.8.0`;旧 k8s 版本变体 vgpu-k8s1.21.yaml / vgpu-k8s1.25.yaml 使用 2.3.x); - 功能:k8s 中以虚拟化方式调度 gpu 机器的 gpu 设备,目前支持英伟达 gpu(cpu 机器不使用); - 依赖关系:虚拟化调用 gpu 的一种方式,也可在驱动层面做虚拟化;不同 gpu 厂商使用的插件不同,需要厂商提供虚拟化方法; - 配置位置:infra/kubeflow-dashboard-config 的 configmap,即 CubeStudio 的配置文件; - 注意:该组件是 cuda 层面做虚拟化的一种方式,最好每次只新建一个 pod。 ### labelstudio - 版本:见上方「待核实」(原文标 1.13.2); - 功能:标注平台; - 依赖关系:CubeStudio 中仅做跳转链接; - 配置位置:`myapp/views/home.py` 中的菜单配置(约 `home.py:251-255`,菜单标题「标注平台」,`menu_type: out_link`,url `/labelstudio/user/login/`); - 注意:label studio 标注平台可配置账号密码及注册登录方式,可自行设置。 > ⚠️ 已按代码纠正:原文写「myapp/home.py 中的菜单配置」,当前仓库无 `myapp/home.py`;标注平台菜单实际定义在 `myapp/views/home.py`(`home.py:251-255`)。 ### postgresql(labelstudio 元数据) - 版本:`11.5`(`install/kubernetes/labelstudio/postgresql.yaml`); - 功能:标注平台的元数据存储; - 依赖关系:labelstudio 依赖 postgresql,CubeStudio 未直接依赖; - 配置位置:kubeflow/label-studio 的 pod 环境变量中指定 postgresql 地址;后端读取标注库地址的配置项为 `LABEL_STUDIO_DAT`(`myapp/config.py:1119`,默认 `postgresql+psycopg2://postgres:postgres@postgresql.kubeflow:5432/labelstudio`)。 ### training-operator - 版本:`v1-8a066f9`(`install/kubernetes/all_image.py`); - 功能:tf/pytorch/xgb/mxnet/mpi 等分布式训练; - 依赖关系:相关分布式任务模板都依赖这个组件;CubeStudio 并没有直接依赖; - 配置位置:`job-template/job/` 下 tf、pytorch、mxnet(deep-learning-framework)、mpi 等相关任务模板(详见 [05-任务模板](../05-任务模板/))。 ### volcano - 版本:`v1.14.0`(`install/kubernetes/volcano/volcano-development.yaml`,`volcanosh/vc-webhook-manager:v1.14.0`); - 功能:volcano 相关任务、nni 超参搜索、deepspeed 等分布式训练所依赖的底层分布式/批调度框架; - 依赖关系:volcano 分布式任务、媒体分布式数据处理任务模板依赖该组件,nni 超参搜索也依赖它进行分布式集群部署; - 配置位置:CubeStudio 代码中使用 vcjob 的 yaml 直接对接 k8s 集群,再由 volcano 解析和运行(CRD 见 [平台架构-Kubernetes基础](平台架构-Kubernetes基础.md)); - 注意:多个地方使用(代码、模板任务等)。 ### workflow-controller、minio - 版本:workflow-controller `v3.4.3`、minio `RELEASE.2023-04-20T17-56-55Z`; - 功能:pipeline 的云原生调度; - 依赖关系:CubeStudio 使用 workflow 运行 pipeline,workflow 使用 minio 作为中间日志和数据的存储;CubeStudio 也有定时任务清理过期 worker 和 minio 中过期文件; - 配置位置:CubeStudio 代码中直接创建 workflow 的 yaml 并提交到目标 k8s 集群,然后监听 workflow 状态。 ### istio-ingressgateway / istiod - 版本:`1.15.0`; - 功能:ingressgateway 负责服务流量代理,istiod 为 istio 的控制面; - 依赖关系:所有 notebook、nni 超参搜索使用 istio 做前缀代理;grafana/k8s-dashboard/CubeStudio 前后端、所有推理服务和内部服务都使用 istio-ingressgateway 做前缀处理;推理服务在 prometheus 中的统计也由 istio ingressgateway 提供; - 配置位置:`install/kubernetes/virtual.yaml` 配置了基础组件的代理,其他在代码中直接对接 virtualservice 的 yaml; - 注意:全局流量入口均在 istio ingressgateway。 ### prometheus / node-exporter / grafana / prometheus-adapter - 版本:prometheus `v2.27.1`、node-exporter `v1.5.0`、grafana `9.5.20`、prometheus-adapter `v0.9.1`; - 功能:监控的生态组件;在 pipeline 拖拉拽界面可快速查看任务资源使用情况,在推理服务界面查看服务负载和 gpu 监控,在整体资源查看机器/pod 监控以及集群整体使用情况; - 依赖关系:CubeStudio 只依赖 grafana 进行监控数据的显示,需要包含指定的几个页面; - 配置位置:infra/kubeflow-dashboard-config 的 configmap,即 CubeStudio 的配置文件; - 注意:如果是多 k8s 集群,注意每个集群的 prometheus 存储数据不要用同一个目录。 --- ### 平台架构 - ML 任务流(Pipeline 编排) - 链接: https://www.cubestudio.vip/docs/01-%E6%9E%B6%E6%9E%84%E5%8E%9F%E7%90%86/%E5%B9%B3%E5%8F%B0%E6%9E%B6%E6%9E%84-ML%E4%BB%BB%E5%8A%A1%E6%B5%81 - 分类: 01-架构原理 / 平台架构 - 适用场景: 想了解 CubeStudio 如何用 argo 做可视化任务流编排、模板变量怎么用、单 task 调试与日志聚合、断点重训/重试/超时、定时调度补录与并发控制、以及如何自定义注册插件模板时读这篇。 - 关键词: pipeline / 任务流 / workflow / argo / 拖拉拽 / 编排 / 模板变量 / template variable / creator / runner / pipeline_id / execution_date / stern / 日志聚合 / 断点重训 / 重试 / 超时 / retry / timeout / 定时调度 / crontab / cronjob / celery / make_timerun_config / 补录 / 并发 / 过期淘汰 / depends_on_past / max_active_runs / expired_limit / 开放式插件 / 任务模板 / job template - 最后更新: 2026-07-04 # 平台架构 - ML 任务流(Pipeline 编排) ## 拖拉拽的 pipeline 编排 CubeStudio 使用 argo 作为任务流 workflow,为了能降低用户的学习成本,开发了一套拖拉拽的任务流编排能力。并且在其中加入了很多分布式的任务模板,基本上的分布式框架都可以得到解决。各类分布式框架在分布式任务加速中也有介绍,详见 [平台架构-分布式训练与加速.md](平台架构-分布式训练与加速.md)。 ![拖拉拽 pipeline 编排](https://foruda.gitee.com/images/1700637377744474805/78809965_1019082.png "屏幕截图") ## 模板变量 有些任务希望在任务实例运行时再产生某些变量的值,目前平台支持以下模板变量: ``` creator = pipeline.created_by.username 字符串:pipeline 的创建者 datetime = datetime 包 runner = g.user.username 字符串:实例的运行者 uuid = uuid 包 pipeline_id = pipeline.id 字符串 pipeline_name = pipeline.name 字符串:pipeline 的名称 cluster_name = pipeline.project.cluster['NAME'] 字符串:当前所属 k8s 集群 execution_date = eta.strftime('%Y-%m-%d %H:%M:%S') 字符串:实例的周期时间 ``` > ℹ️ 核实:模板变量的注入逻辑见 `myapp/views/view_pipeline.py:427`(pipeline 级渲染)与 `myapp/views/view_task.py:602`(单 task 级渲染)。代码中 `runner` 兜底逻辑为:若无登录用户则回退为 pipeline 创建者(`g.user.username if g and g.user and g.user.username else pipeline.created_by.username`)。除上述变量外,pipeline 级渲染还额外注入了 `run_id=pipeline.run_id`。`execution_date` 若未通过调度传入,则默认取当前时间(`myapp/views/view_pipeline.py:420-421`)。 使用示例: ``` {{uuid.uuid4().hex[:4]}} {{datetime.datetime.now().strftime("%Y%m%d-%H%M%S.%f")}} {{pipeline_id}} {{pipeline_name}} {{cluster_name}} {{runner}} {{execution_date}} ``` ## 单个 task 调试 通过 notebook 我们可以进行代码的编辑,通过镜像调试可以构建自己的镜像,然后就可以编排 pipeline 了。pipeline 运行前需要独立运行调试单个 task,所以 CubeStudio 添加了单 task 独立调试的功能。 ![单 task 调试](https://foruda.gitee.com/images/1700637190728886599/496b6f8d_1019082.png "屏幕截图") 每个 task 都可以独立 debug 和独立运行,这样就不用每次都运行整体 pipeline 才能进行调试。并且对于分布式任务的 task,CubeStudio 在模板中借用 stern 实现了多个容器 log 聚合查看,这样就不用每个 worker 的日志都单独去看了。 ![任务查看](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/mlrenwuchakan.png) ### 单个任务为分布式任务 往往某个任务需要是分布式任务,所以需要启动分布式任务。云原生分布式任务需要 k8s 对应的 operator。分布式算法模板的实现方法,主要在模板中实现 launcher:创建对应分布式任务的 job yaml,提交到 k8s,对应的 job operator 创建每个 worker 的 pod 和 service,然后运行业务代码。launcher 端启动 stern 组件,监听该分布式任务的所有 pod 的日志并进行输出,这样就可以在当前任务中查看到所有 worker 的日志。 > ℹ️ 核实:stern 日志聚合在各分布式框架的 launcher 中使用,例如 `job-template/job/pytorch/launcher.py`、`job-template/job/volcano/launcher.py`、`job-template/job/deep-learning-framework/launcher-*.py`。分布式框架的具体实现见 [平台架构-分布式训练与加速.md](平台架构-分布式训练与加速.md)。 ![分布式任务日志](https://foruda.gitee.com/images/1700637224958642565/2182a43e_1019082.png "屏幕截图") 并且每个任务启动后都可以看到相应的资源情况,这样可以边调试边配置资源的申请量。在 gpu 上也可以及时知道是否还有优化的空间、目前任务的主要瓶颈在哪里,这样能更加直观地确定优化的方向。 ![资源查看](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/mlziyuanchakan.png) ## 断点重训 / 重试 / 超时 对于某些情况,一个任务流运行后,可能在某些任务开始出现偶发性错误。CubeStudio 提供了在结束 pipeline 后从失败点继续训练的功能,这样就不用重复训练某些耗时的任务。同时 CubeStudio 也为每个任务提供了重试次数和超时时长的配置,并且提供了任务的实时和离线日志查询两种功能。 ## pod 运行 pod 调度情况可以最真实地反映每个任务或分布式任务的状态,还有资源使用情况。 ![pod 运行](https://foruda.gitee.com/images/1700637313354539288/75f322d6_1019082.png "屏幕截图") ## 定时调度 任务编排调试好以后,还要进行定时调度。CubeStudio 支持了定时调度任务的补录、忽略、重试、依赖、并发限制、过期淘汰等功能,能应对任务堆积、平台故障等可能问题。 ![定时调度](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/mldingshidiaodu.png) 并且对同一个 pipeline,区分对待手动运行和定时调度两种实例。 注意(定时调度细节偏使用/运维,可与 [03-平台使用/](../03-平台使用/) 互链): - 定时调度由 celery 定时任务 `make_timerun_config` 进行控制。 > ℹ️ 核实:任务名 `task.make_timerun_config` 注册于 `myapp/config.py:612` 与 `myapp/config.py:696-697`(beat 调度),实现见 `myapp/tasks/schedules.py`。 - pipeline 扩展参数中 `cronjob_start_time` 用来控制历史任务的补录时间起点(修改 pipeline 调度类型和 crontab 会重置 `cronjob_start_time` 为当前时间)。 - pipeline 参数中需要使用 `execution_date` 才能在补录时保留实例时间点状态。 - pipeline 的 `depends_on_past` 参数控制新的实例运行是否要关注上一次实例是否完成。 - pipeline 的 `expired_limit` 参数控制过往未调度实例只保留多少个最新实例运行,更久远实例过期。 > ℹ️ 核实:表字段注释为"过期保留个数,此数值有效时,会优先使用,覆盖 max_active_runs 的功能",见 `myapp/migrations/versions-mysql/3471634cbb23_.py:619`。 - pipeline 的 `max_active_runs` 参数控制最多同时并行多少个调度实例运行。 - 最大并发周期为全局变量 `PIPELINE_TASK_CRON_RESOLUTION`,默认 10(分钟一次)。 > ℹ️ 核实:`PIPELINE_TASK_CRON_RESOLUTION = 10`,见 `myapp/config.py:387`,注释为"任务的最小执行间隔 min"。 ### 定时调度记录 查看路径:训练 - 定时调度记录 字段说明:执行时间为这个 pipeline 本次调度该发起的时间点。 状态:`comed` 为调度配置已经产生,`created` 为调度已经发起。 操作说明: 1. 平台会根据 pipeline 的配置决定是否发起调度。 2. 状态链接中可以看到本次调度发起的 workflow 的运行情况。 3. 日志链接中可以看到本次调度发起的日志。 ## 开放式插件 平台自带的任务模板并不一定能完全满足所有需求。除了用户可以使用自定义镜像、自定义命令的方式外,平台还将插件的注册功能开放给用户。 ![自定义模板](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/mlmubanzidingyi.png) 这样用户就可以自己定义模板,然后开放给全平台的用户使用。用户只需要自己构建好功能镜像,然后将其他用户使用此镜像需要填写的参数注册进来就可以了。其中也包含模板特定功能,例如固定的挂载、固定的环境变量、k8s 账号等。 > 任务模板的具体使用与编写规范见 [05-任务模板/](../05-任务模板/)。 --- ### 平台架构 - 分布式训练与加速 - 链接: https://www.cubestudio.vip/docs/01-%E6%9E%B6%E6%9E%84%E5%8E%9F%E7%90%86/%E5%B9%B3%E5%8F%B0%E6%9E%B6%E6%9E%84-%E5%88%86%E5%B8%83%E5%BC%8F%E8%AE%AD%E7%BB%83%E4%B8%8E%E5%8A%A0%E9%80%9F - 分类: 01-架构原理 / 平台架构 - 适用场景: 想了解 CubeStudio 如何用 CRD+operator 自动建分布式集群、如何选分布式框架、worker 均衡与亲和/反亲和、kube-scheduler 打分策略修正、gang/volcano 批调度、单 worker 与 gpu 利用率优化、vgpu/共享 gpu、任务资源动态调整与资源池均衡时读这篇。 - 关键词: 分布式训练 / distributed training / CRD / operator / train-operator / tf / pytorch / horovod / mpi / ray / spark / mxnet / volcano / nni / 框架选型 / 无状态 / 有状态 / ring allreduce / ps / worker / 均衡 / 亲和 / 反亲和 / affinity / anti-affinity / kube-scheduler / 打分策略 / RequestedToCapacityRatioPriority / scheduler-policy-config / gang调度 / kube-batch / 批调度 / 优先级调度 / gpu利用率 / GPU utilization / dcgm / vgpu / 共享gpu / DALI / num_workers / prefetch / pin_memory / 资源动态调整 / TASK_RESOURCE_CPU / TASK_RESOURCE_MEMORY / TASK_RESOURCE_GPU / NO_RESOURCE_CHECK / 资源池均衡 - 最后更新: 2026-07-04 # 平台架构 - 分布式训练与加速 ## 分布式集群 要做分布式处理/训练,首先要有分布式集群。在数据处理/训练前,先根据用户的需求创建需要的分布式集群,例如: - tf 分布式训练集群 - pytorch 分布式训练集群 - spark 分布式数据处理集群 - ray 分布式超参搜索集群 - mpi 分布式训练集群 - horovod 分布式训练集群 - nni 分布式超参搜索集群 - mxnet 分布式集群 - volcano 分布式集群 - …… 以及在此衍生出来的分布式的数据下载、hdfs 拉取、cos 上传下载、视频采帧、音频抽取。 要实现这些分布式数据处理/训练,在云原生中定义对应的 crd,然后部署相应的 operator,来解析我们提交的 crd yaml。例如下面我们要实现一个 tf 的 ps 分布式训练集群的结构。 ![tf ps 分布式集群结构](https://foruda.gitee.com/images/1700637408221890910/a9ec0b84_1019082.png "屏幕截图") 实现自动创建这样的分布式集群,需要四个层面的支持。 **1、配置分布式训练集群的部署(CRD)** 用户每次任务使用的集群框架和集群规模都是不一样的,需要一个简单的方式能够描述用户本次所需要的集群。在 k8s 中通过 crd 来实现这样的集群定义,可以理解为一个 yaml 文件。 **2、控制器部署分布式训练集群(operator)** 有了 crd 定义的这样一个集群,还需要一个 operator 来监听、解析、创建、监控 yaml 文件中定义的集群。对于没法直接搬移到 k8s 之上的分布式,要开发对应的 crd+operator:例如分布式多机多卡训练在 train-operator 框架上做开发,horovod 分布式训练在 mpi 的分布式上做开发。tf/pytorch/mxnet/ray 官方都有对应的 k8s 分布式解决方案,可以直接使用对应的方式加入到 k8s 中来。 **3、代码识别分布式角色(有状态)** 在 k8s 中分布式集群创建好以后,对于有状态的分布式集群,需要用户的代码能识别自己是哪个角色。如果单独为每个角色都写一份代码是很不友好的,所以用户代码需要按照分布式策略识别自己在集群中的角色和身份,进而加入集群、协调工作内容。对于无状态集群,代码只需要接收自己要处理的任务、处理返回即可。在 k8s 中,大部分场景是通过环境变量来识别身份的。 **4、训练框架支持分布式(协议和策略)** 当每个 pod 都进入各自的工作岗位以后,还需要该用户所使用的算法框架必须支持分布式的训练模式,支持分布式集群通信的协议和协商方法,以及不同角色的节点之间的分工,这样才能协调一致工作,不然就要用户自己手动编写分工逻辑。 在 k8s 中角色(pod)之间的区别主要通过环境变量或者名称来识别,例如 `role:ps`、`role:worker`;通信的方式主要通过域名:端口,或者挂载相同的分布式存储、使用文件来沟通。 通过上面的方法,我们就可以实现一个分布式任务在集群中的创建运行。 ## 选对分布式框架 k8s 中分布式框架按照角色形式主要分为下面几种: ![分布式框架角色形式](https://foruda.gitee.com/images/1700637618993393626/65978c8a_1019082.png "屏幕截图") **1、无状态的框架**:优势在于任务 worker 可以横向扩展,任务的完成没有数据倾斜的问题。在集群启动前并不定义 worker 要做哪些数据的处理任务,运行起来以后才开始决定处理哪些任务(比如 kafka 的消费者、ray 的分布式)。这类分布式任务不会因为某个 worker 而严重拖慢整体任务的进度,但一定程度上受限于任务分发机制:比如 kafka 需要将任务发送到队列,ray 只能传输可序列化的函数、无法传递大内存变量。比较适合无状态的任务函数,每次处理之间不存在依赖或者不依赖基础对象。 **2、有序分布式任务**:提前告诉每个 worker 在集群中的角色和位置,但并不定义它们之间的通信逻辑。比如 volcano 分布式训练,这类任务可以在数据处理前先定义好每个 worker 要处理的任务,这种就不需要任务分发器;但这样用户的任务容易存在数据倾斜的问题(比如某个 worker 所要处理的数据因为某些原因被拖慢,那么整个 pipeline 的结束时间会因为这一个 worker 而拖慢,例如 volcano-job)。也可以在运行中有专门的角色 worker 来分发任务,这种任务如果官方没有分发器的话需要自己写一个专门的分发器。 **3、分角色有序分布式任务**:在上面的基础上,同时定义好了角色之间的通信逻辑。这种一般是因为除了做分工还要做协同,比如 ring allreduce 的分布式训练方案。这样每个 worker 不仅要知道自己是什么角色(ps-worker),还要知道访问其他 worker 的方法。这种分布式一般来源于特定分布式任务的框架,例如 tf/pytorch。 对于同一个分布式框架,也有多种分布式的方式。比如对于 tf 分布式,有 ps 模式和 ring allreduce 的方式。在单机模型可承受的情况下,ring allreduce 的效率一般比 ps 的方式高;对于单机无法承受模型大小的情况下,选择 ps 模式进行模型并行优化。同时还有 cpu/gpu 方式的选择、稀疏 embedding 大模型和稠密大模型的选择等。 ![分布式方式选择](https://foruda.gitee.com/images/1700637644279379271/96da39f1_1019082.png "屏幕截图") ## 分布式 worker 的均衡度 有了分布式的能力,在机器学习平台中 CubeStudio 加入了通过拖拉拽制作分布式 ml 任务流的能力(见 [平台架构-ML任务流.md](平台架构-ML任务流.md)),每个 task 可能都是一个分布式任务,也可能是单机的任务。不同的用户会有很多分布式的任务流。 ![分布式任务流](https://foruda.gitee.com/images/1700637674740372317/d6da4f96_1019082.png "屏幕截图") 如果不做均衡,分布式任务很容易无法更好地利用多机的算力,会更早受到机器的性能瓶颈,进而影响任务运行的效率。为了更好地利用多机的能力、加快整体任务流的运行效率,平台在三个层次做优化。 ## 亲和度 + 反亲和度 ### 一个分布式任务的不同 worker 在一个分布式框架启动了一个分布式集群进行训练时,这些 worker 应该根据实际需求确定尽量分布在哪里,就像 impala 尽量分布在 hdfs datanode 所在的节点上。因为分布式集群中除了分工协作,还有沟通的过程,相当于既独立又合作,所以分布式的方式要能利于这两种操作。例如在 tf ring allreduce 的方式进行分布式训练时,不同 worker 节点之间需要通信传递参数,所以通信的时延也不可忽略:对于在 gpu 上训练时,如果训练中其他过程耗时很小(io、gpu 计算等耗时小),那么通信时延的性能影响就会比较突出,这个时候我们可能更偏向于将 gpu 的任务分布在相同的机器上;如果是 cpu 的训练任务,前向计算的时长比较大、通信时延可以忽略,我们为了能更多地利用 cpu 资源,可能会选择将 cpu 的任务分布在不同的机器上。 ### 同一个 pipeline,不同的 task 在同一个 pipeline 下,我们有时候会并行很多 task,它们并不是完全串行的。比如我们同时跑 7 个 hdfs 数据拉取的任务,分别拉取最近 7 天的数据,后面用这 7 天的数据同时跑 3 个分布式的多机多卡训练。在 k8s 中内存、cpu 等资源是相互隔离的,但是对于部分资源无法做到很好的隔离,比如机器的网络 io、磁盘 io、三方平台的黑白名单限制限速等。对于这种作用相同的任务,我们倾向于将同一个 pipeline 下不同的 task 区分到不同的机器上。如果某个 task 是一个分布式任务,那么 task 下面的 worker 再由 task launcher 自行决定如何调度。 ## kube-scheduler 打分策略 不同的 pipeline 可能归属于不同的用户,可能会运行在同一个资源组。在 k8s 中 pod 调度依赖于算法和策略,策略部分主要由过滤和打分两个阶段组成,就像推荐中的召回和排序一样:过滤会将满足必备条件的机器筛选出来,打分阶段则选择其中最适合部署当前 pod 的机器。 ![调度过滤与打分](https://foruda.gitee.com/images/1700637696514556872/501da068_1019082.png "屏幕截图") 过滤段主要是: - PodFitsHostPorts:检查 Pod 请求的端口(网络协议类型)在节点上是否可用。 - PodFitsHost:检查 Pod 是否通过主机名指定了 Node。 - PodFitsResources:检查节点的空闲资源(例如 CPU 和内存)是否满足 Pod 的要求。 - MatchNodeSelector:检查 Pod 的节点选择算符和节点的标签是否匹配。 - NoVolumeZoneConflict:给定该存储的故障区域限制,评估 Pod 请求的卷在节点上是否可用。 - NoDiskConflict:根据 Pod 请求的卷是否在节点上已经挂载,评估 Pod 和节点是否匹配。 - MaxCSIVolumeCount:决定附加 CSI 卷的数量,判断是否超过配置的限制。 - PodToleratesNodeTaints:检查 Pod 的容忍是否能容忍节点的污点。 - CheckVolumeBinding:基于 Pod 的卷请求,评估 Pod 是否适合节点(包括绑定的和未绑定的 PVC)。 打分段主要包含如下接口: - SelectorSpreadPriority:属于同一 Service、StatefulSet、ReplicaSet 的 Pod 跨主机部署。 - InterPodAffinityPriority:实现了 Pod 亲和性和反亲和性的优先级。 - LeastRequestedPriority:偏向最少请求资源的节点。换句话说,节点上的 Pod 越多、使用的资源就越多,此策略给出的排名就越低。 - MostRequestedPriority:支持最多请求资源的节点。该策略将 Pod 调度到整体工作负载所需的最少的一组节点上。 - RequestedToCapacityRatioPriority:使用默认的打分方法模型,创建基于 ResourceAllocationPriority 的 requestedToCapacity。 - BalancedResourceAllocation:偏向平衡资源使用的节点。 - NodePreferAvoidPodsPriority:根据节点的注解 `scheduler.alpha.kubernetes.io/preferAvoidPods` 对节点进行优先级排序。 - NodeAffinityPriority:根据节点亲和中 PreferredDuringSchedulingIgnoredDuringExecution 字段对节点进行优先级排序。 - TaintTolerationPriority:根据节点上无法忍受的污点数量,给所有节点进行优先级排序。 - ImageLocalityPriority:偏向已在本地缓存 Pod 所需容器镜像的节点。 - ServiceSpreadingPriority:对于给定的 Service,确保该 Service 关联的 Pod 在不同节点上运行,偏向把 Pod 调度到没有该服务的节点。 - EqualPriority:给予所有节点相等的权重。 - EvenPodsSpreadPriority:实现了 Pod 拓扑扩展约束的优先级排序。 其中在 RequestedToCapacityRatioPriority 打分阶段,k8s 默认的方式是在之前运行成功过的机器上调度任务,这个策略不太适用于分布式训练——我们需要在资源申请率(注意不是申请量)最小的机器上调度新的 pod,所以可以创建修正后的调度打分策略。 > ℹ️ 核实:配置文件 `scheduler-policy-config.json` 真实存在于 `install/kubernetes/scheduler-policy-config.json`,其 `RequestedToCapacityRatioPriority` 的 `shape` 设为 `utilization:0 -> score:10`、`utilization:100 -> score:0`,即资源利用率越低分数越高,从而优先调度到申请率最低的机器,与上文描述一致。该文件的部署位置与用法见 [02-部署安装/](../02-部署安装/)。 ## gang 调度 在一个算力资源池中运行多个分布式任务时,会存在资源死锁的问题。例如下图所示的 3 台 4 卡的 gpu 机器,如果每个分布式任务有 4 个 worker、每个 worker 占 1 张卡,那么最多能同时启动 3 个这样的分布式任务;但如果同时启动了 4 个这样的分布式任务,就有可能存在每个分布式任务只成功启动了 3 个 worker,而另一个 worker 因为占不到卡而启动不了的情况,进而所有分布式任务都在等待新的卡释放出来。这种情况经常出现在剩余资源不足够多的场景下。 ![资源死锁](https://foruda.gitee.com/images/1700637718437620318/637bdc29_1019082.png "屏幕截图") 应对这种情况,CubeStudio 加入了 kube-batch 工具,使用 gang 调度算法,配置新的 scheduler 组件,为分布式任务配置批量调度的能力:在调度队列中,先计算剩余资源是否满足所有 worker 的算力要求,完全满足并且全部占用以后,整个集群才算调度成功。 同时引入 volcano 实现批调度的同时,加入优先级调度的能力,在 scheduler 层面统筹批调度的能力。 ![volcano 批调度](https://foruda.gitee.com/images/1700637737990857252/f1e997d2_1019082.png "屏幕截图") ## 分布式任务单 worker 的性能加速 通过分布式框架是为了能使用更多的算力帮助用户尽快完成任务,但能尽快完成的前提也是分布式任务中每个 worker 也能尽快完成自己所属的任务。 ### 对于均匀式的任务分配 即每个 worker 所做的工作时长基本一致,那么就需要每个 worker 尽快完成自己所属的数据处理工作,并尽快完成不同 worker 之间的交流,尽快进入下一个迭代。 对于独立的单 worker 任务加速,我们可以像单机优化方案一样,使用多进程多线程的并发方案,或者使用 ray、异步 io 等并发方案,让单 worker 申请的资源能尽可能使用起来。虽然用户申请的 cpu/内存资源如果没有使用起来会被 CubeStudio 的智能算法自动调整到合理的范围,但这些方案只是提高了整体利用率,并没有加速任务的运行,所以一定程度上还是需要用户加速单 worker 的运行。 当然还有尽快完成每个 worker 之间的协商,例如 ring allreduce 之间的通信时长。对于不同 worker 之间的通信,在 k8s 中均是通过内部服务域名解析、在 pod 之间进行通信,主要优化点是在内核方面优化容器 tcp 通信时的效率:使用更高版本的内核,从 linux3 升级到 linux4 后,压测 pod 之间的通信效率从 1.3Gi 升级到 18Gi(主机带宽 25Gi)。还有 nvlink 等解决方案。 ### 对于非均匀式任务分配 尽量减少数据倾斜,或者对未完成任务进行重分配、重新均衡。这种方式的不足是需要用户手动进行再均衡,优势是用户可以自由决定角色的定义,比如用户自行决定 rank=0 的 worker 进行最后结果数据的合并操作。 ## gpu 利用率提高 gpu 相对于内存和 cpu 比较特殊:内存和 cpu 可以通过算法进行智能修改,可以通过增大 worker 数量替代单 worker 性能不高的问题;但对于 gpu,因为在训练中是独占的形式(可以使用 vgpu 的方式,但并不推荐在训练中使用 vgpu,而是将 vgpu 的能力应用到推理中,详见 [平台架构-推理服务.md](平台架构-推理服务.md)),所以 gpu 使用率不高的话非常影响训练任务的效率。 因为 gpu 的计算能力比 cpu 强很多,所以之前在 cpu 下不凸显的问题在 gpu 下都变得非常明显。 ### gpu 利用率监控 通过监控按钮,可以进入查看任务运行的资源使用率,对于资源使用超标可以手动配置增加资源。 > ℹ️ 核实:gpu 利用率采集自 NVIDIA dcgm-exporter 的指标 `DCGM_FI_DEV_GPU_UTIL`,平台侧查询见 `myapp/utils/py/py_prometheus.py:104/202/333/458`。 ![gpu 利用率监控](https://foruda.gitee.com/images/1700638305328570739/7874a747_13742231.png "屏幕截图") 其中 gpu 由于是整卡占用,需要调整任务的部分参数和代码,提高 gpu 显存占用率和 gpu 使用率。 ![gpu 参数调整](https://foruda.gitee.com/images/1700638331398687479/69339422_13742231.png "屏幕截图") 注意:很多框架对 gpu 的显存占用默认是独占,所以在容器内通过 nvidia-smi 等命令查看,容易看到 gpu 显存占用 100%。 ### gpu 利用率低的原因 主要思想是 cpu 操作慢,进而阻塞了 gpu 的计算。 ![gpu 利用率低原因](https://foruda.gitee.com/images/1700638356218590332/a8ef5dd4_13742231.png "屏幕截图") 常见的 CPU 计算操作如下: - 数据加载 - 数据预处理 - 模型保存 - loss 计算 - 评估指标计算 - 日志打印 - 指标上报 - 进度上报 ## 代码层面 gpu 利用率优化 **1、数据加载相关** - 存储计算不在同一个城市:数据导入到集群存储。 - 磁盘 io 性能太差:对于临时数据可以将内存映射为磁盘。 - 小文件太多、频繁 io:合并为大文件处理。 - 未启用多进程并行读取数据:pytorch 提高 `num_workers`,tf 配置 `num_parallel_calls`/`num_parallel_reads`。 - 未启用提前加载机制来实现 CPU 和 GPU 的并行:pytorch 配置 `prefetch_factor`,tf 配置 `Dataset.prefetch()`。 - 未设置共享内存 `pin_memory`:设置为 true。 - 每次送入 gpu 的 batch_size 太少:模型固定后,调整 `batch_size` 尽量增大显存的利用率,然后再调节 `num_workers` 提高 gpu 利用率。 **2、数据预处理相关** - 数据处理和训练耦合在一起:将数据处理和训练分成两个 task,训练中需要的配置之类全部提前加载到内存,让 gpu 只做训练任务。 - 使用 Nvidia DALI,在 gpu 中做数据处理。 **3、频繁 IO 操作** - 模型保存太频繁:减少保存模型(checkpoint)的频率。 - tensorboard 文件保存太频繁。 - 日志打印太频繁、频繁 cpu/gpu 切换:不要打印训练迭代中个人日志。 - 存储 io 性能太低。 - 对于频繁使用的文件(库文件、lib 等)放入了性能不高的存储中。 ## vgpu + 共享 gpu 常规我们会先采用 gpu 利用率提高的方法,把申请的 gpu 尽量占满,但这部分优化一定程度上是代码层面的优化,需要用户的配合。但有时候用户的代码无法做到很完美,这时候就需要架构层面来解决利用率的问题。 **1、使用 vgpu 的形式** 现在有很多种方案使用 vgpu,将一张卡隔离成多张卡。但在训练中使用 vgpu 有个调度问题,如下图所示:分布式任务 t1 大量占用 1/3 卡,造成大量算力碎片化,进而对于正常的任务 t2,无法找到满足条件的机器 1 卡进行调度。这是因为 k8s 首先还是在机器上,pod 的算力申请上限无法突破单机。另外一个问题,就算通过零散化算力只是为了提高 gpu 的利用率,并没有加速任务的运行。这种 vgpu 更适合在推理阶段使用,因为推理阶段输入的流量不是训练开发者决定的,而是 C 端用户决定的。 ![训练中 vgpu 碎片化](https://foruda.gitee.com/images/1700638387191218819/7626d4e8_13742231.png "屏幕截图") 虚拟化 gpu 以及虚拟内存+gpu 利用率提高在推理端的方案,在 [平台架构-推理服务.md](平台架构-推理服务.md) 中有介绍。 **2、共享 gpu** 所以我们可以采用共享 gpu 的方式来提高 gpu 利用率,同时加速任务的训练进度。在常规的多机多卡训练中,gpu 的占用是独享的,以 ring allreduce 为例,每个 worker 独享一张 gpu 卡。 ![独享 gpu](https://foruda.gitee.com/images/1700638410795830407/7f6022f0_13742231.png "屏幕截图") 但并不是每个开发者都能将 gpu 卡的利用率使用得非常高。比如用户的代码使用 gpu 训练但 gpu 利用率只有 10%,对于这种情况,一般开发者会采用使用更多的 gpu 卡来加速训练,这样 gpu 的浪费情况就更加严重。在架构层面我们调整为用户可以配置共享同一个 gpu 的进程数目,以此让在相同 gpu 卡上跑出更多分布式 worker 的效果,直到机器的某个资源达到瓶颈。比如 3 个进程共享一张卡、一台机器 4 张卡、同时 12 个进程,此时 cpu 使用率已经接近 100%,那么就要开始从其他地方进一步加速了。 ![共享 gpu](https://foruda.gitee.com/images/1700638434351353232/225e5a1d_13742231.png "屏幕截图") 这种方式重置了每个 pod 的角色,而是角色直接传递到进程,rank 和 world_size 都被重置。 ## 任务资源配置动态调整 用户在运行任务的时候也不知道任务的资源该设置为多少。除了监控、通知用户任务的资源使用情况,还需要能够智能地调整用户的配置,因为 CubeStudio 平台是统筹算力的,一个资源池里面会有很多任务在同时运行。 ![资源动态调整](https://foruda.gitee.com/images/1700638467299787395/76bcee11_13742231.png "屏幕截图") 但对于某些特殊的任务,也支持模板里面提前设置好固定资源配置 `TASK_RESOURCE_CPU`/`TASK_RESOURCE_MEMORY`/`TASK_RESOURCE_GPU`,屏蔽用户的配置。同时对于某些不合理的资源动态修正,也允许在模板中通过环境变量 `NO_RESOURCE_CHECK` 屏蔽动态资源配置。 > 说明:模板固定资源环境变量为 `TASK_RESOURCE_CPU` / `TASK_RESOURCE_MEMORY` / `TASK_RESOURCE_GPU` / `TASK_RESOURCE_RDMA`(见 `myapp/init/init-job-template.json:72` 等多处);`NO_RESOURCE_CHECK` 屏蔽动态校验的判断见 `myapp/tools/watch_workflow.py:180`,模板侧固定资源读取见 `myapp/views/view_task.py:641`。 在动态资源配置中仅对内存、cpu 进行修正;对 gpu 资源,采用的仍然是上面 gpu 利用率提升的方法。因为大部分场景下,cpu 上的任务可以通过减少每个 worker 的 cpu 数目、增加 worker 数量来降下来,但在 gpu 训练场景我们采用独占方式,所以无法缩减配置。 ## 资源池动态均衡 分布式集群的加速能力与可以占用的资源几乎可以成线性关系,所以保障分布式任务有资源能调度起来就变得异常重要,尤其在多集群、多资源组的平台下。平台在联邦控制器下,多个集群之间不进行均衡,但在一个集群下的多个项目组之间进行均衡配置:限制保障每个项目组的最低算力以保障基本任务的运行,当有临时性任务发起时,就会从公共池中将算力加入到指定项目组,运行结束后释放资源回公共池。 ![资源池动态均衡](https://foruda.gitee.com/images/1700638508401660564/433929f6_13742231.png "屏幕截图") --- ### 平台架构 - 推理服务 - 链接: https://www.cubestudio.vip/docs/01-%E6%9E%B6%E6%9E%84%E5%8E%9F%E7%90%86/%E5%B9%B3%E5%8F%B0%E6%9E%B6%E6%9E%84-%E6%8E%A8%E7%90%86%E6%9C%8D%E5%8A%A1 - 分类: 01-架构原理 / 平台架构 - 适用场景: 想了解 CubeStudio 推理服务的五层架构、istio 网关入口适配与分流/流量复制、prometheus 服务自动发现、基于 qps/gpu 利用率的 hpa、各推理框架(tfserving/torchserve/triton/tensorrt)、gpu 推理加速、vgpu 占用方式、Transformer 前后置处理与推理 pipeline 时读这篇。 - 关键词: 推理服务 / inference / serving / 服务网格 / service mesh / istio / serverless / pipeline / http框架 / grpc / 模型计算 / ingressgateway / 网关 / 分流 / 流量复制 / mirror / VirtualService / DestinationRule / 流量分发 / prometheus / 服务发现 / kubernetes_sd_configs / ServiceMonitor / hpa / 弹性伸缩 / qps / gpu利用率 / prometheus-adapter / dcgm / DCGM_FI_DEV_GPU_UTIL / container_gpu_usage / tfserving / torchserve / torch-server / onnxruntime / triton / tensorrt / vllm / ollama / mindie / INT8 / FP16 / vgpu / vcuda / NVIDIA_VISIBLE_DEVICES / hami / Transformer / 前置处理 / 后置处理 / handler / 推理pipeline - 最后更新: 2026-07-04 # 平台架构 - 推理服务 > 说明:istio 分流与网关入口适配与"平台架构 - 流量代理与网关"有重叠;prometheus 服务发现 / hpa 与"平台架构 - 监控体系"有重叠;vgpu 与 [平台架构-分布式训练与加速.md](平台架构-分布式训练与加速.md) 有重叠。流量代理与监控的更系统介绍参见 [01-架构原理/](./) 中对应文档及 [04-运维管理/](../04-运维管理/)。 ## 推理服务各阶段 推理服务从底层到上层,包含服务网格、serverless、pipeline、http 框架、模型计算。 - **服务网格阶段**:主要工作是代理流量的中转和管控,例如分流、镜像、限流、黑白名单之类的。 - **serverless 阶段**:主要为服务的智能化运维,例如服务的激活、伸缩容、版本管理、蓝绿发布。 - **pipeline 阶段**:主要为请求在各数据处理/推理之间的流动,推理的前后置处理逻辑等。 - **http/grpc 框架**:主要为处理客户端的请求,准备推理样本,推理后作出响应。 - **模型计算**:模型在 cpu/gpu 上对输入样本做前向计算。 ## 网关入口适配 全部改为 istio ingressgateway 的网关方案。 CubeStudio 中的很多功能是通过外部镜像实现的,比如 jupyter、vscode、nni、k8s-dashboard、kfp、云原生服务用户自己定义的镜像,以及推理服务外部各框架镜像、kfserving 镜像等。它们在网关入口处基本通过 url prefix 或者 host 进行区分代理,内部再加上泛化域名的能力,这样就能部署后直接访问了。 ### 分流 + 流量复制 分流表示将一批流量按照一定规则分发到多个服务上去,每一个请求只会进入一个服务端;流量镜像则表示将原有的流量原封不动地复制一份到另一个服务。这两种功能在实际生产中都非常有用。分流比较好理解,流量复制如下图所示,发起端是不等待镜像服务的响应的。 ![流量复制](https://foruda.gitee.com/images/1700638559526922748/102567dd_13742231.png "屏幕截图") 在 istio 中是通过虚拟服务(VirtualService)和目标规则(DestinationRule)来管理流量的策略的,它们与 k8s 的关系如下图。 ![istio 与 k8s 关系](https://foruda.gitee.com/images/1700638576444477725/0da6f3ac_13742231.png "屏幕截图") 在 istio 中可以很方便地实现流量的分发和复制。CubeStudio 里面一个模型使用一个唯一的 pod,不会在一个 pod 中进行多个模型的推理服务,所以在服务网格中流量的复制和分流就更加简单。在 VirtualService 中进行流量复制的方式如下: ```yaml http: - mirror: host: service1-version1.kfserving.svc.cluster.local port: number: 8501 mirror_percent: 100 route: - destination: host: service1-version2.kfserving.svc.cluster.local port: number: 8501 timeout: 300s ``` > 说明:上述示例中的命名空间 `kfserving` 为早期 kfserving 方案的写法。当前代码中推理服务统一部署在命名空间 `service`(`SERVICE_NAMESPACE = 'service'`,见 `myapp/config.py:776`;`SERVICE_PIPELINE_NAMESPACE='service'` 见 `myapp/config.py:770`),实际 host 后缀应为 `.service.svc.cluster.local`,示例仅作流量复制语法演示。 在很多情况下,我们需要将真实的流量数据与镜像流量数据进行收集并分析,需要在其中将各个复制端的请求和结果导入到对比系统中进行比较,查看服务的好坏。 在 VirtualService 中进行流量分发的方式如下: ```yaml http: - route: - destination: host: service1-version1.kfserving.svc.cluster.local port: number: 8501 weight: 20 - destination: host: service1-version2.kfserving.svc.cluster.local port: number: 8501 weight: 80 timeout: 300s ``` ## prometheus 服务发现 在 k8s 中由于服务 pod 的 ip 是变化的,所以不能像在主机上一样固定写死 pod 的 ip,需要服务的自动发现。在原有方案中需要为服务注册 ServiceMonitor,当需要监控的服务比较多时配置起来可能会有遗忘或比较麻烦,所以可以通过 `kubernetes_sd_configs` 实现对 k8s 各种资源的自动监控。 ```yaml # 其中通过 kubernetes_sd_configs 支持监控其各种资源 - job_name: 'kubernetes-service-endpoints' kubernetes_sd_configs: - role: endpoints relabel_configs: # 仅抓取具有 "prometheus.io/scrape: true" annotation 的端点: # annotation 是键值结构,源标签设为键、regex 设为值,当值匹配 regex 时执行 keep 动作保留,其余丢弃。 - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape] action: keep regex: true # 匹配 prometheus.io/scheme annotation,若匹配到 regex 则把值替换为 __scheme__ 对应的值 - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme] action: replace target_label: __scheme__ regex: (https?) # 获取 service 的 annotation 中 "prometheus.io/path: XXX" 定义的 metrics 暴露地址, # 若不是默认的 /metrics,则赋值给 __metrics_path__ 变量,prometheus 据此拼接完整 URL 抓取。 - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path] action: replace target_label: __metrics_path__ regex: (.+) - source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port] action: replace target_label: __address__ regex: ([^:]+)(?::\d+)?;(\d+) replacement: $1:$2 # 下面主要是为了给样本添加额外信息 - action: labelmap regex: __meta_kubernetes_service_label_(.+) - source_labels: [__meta_kubernetes_namespace] action: replace target_label: kubernetes_namespace - source_labels: [__meta_kubernetes_service_name] action: replace target_label: kubernetes_name ``` 这一部分的 ScrapeConfigs 配置是主动从 service 中发现 annotations 中的下列信息: ``` "prometheus.io/scrape": "true", "prometheus.io/port": 'xxx' "prometheus.io/path": 'xxx' ``` 这样就能自动监控此类服务下所有 pod 的 metrics 接口了。 ## 基于 qps/gpu 利用率进行 hpa k8s 中 hpa 可以直接使用的弹性伸缩功能是根据 pod 的内存和 cpu 进行伸缩,但在 gpu 上的推理没有直接可以使用的伸缩指标,所以基于 qps 或者 gpu 利用率的伸缩容指标需要借助自定义指标来实现。 k8s 上可以通过注册 APIService,将外部的指标注册为 k8s 的 metric,然后再将此指标作为 deployment 伸缩容的指标。我们大部分的指标都采集到 prometheus,所以可以通过 prometheus-adapter 将 prometheus 的指标注册为伸缩容的可用指标。 ![prometheus-adapter](https://foruda.gitee.com/images/1700638610852871377/977825db_13742231.png "屏幕截图") 下面以 gpu 上的推理服务、GPU 利用率为例。首先要能采集到 pod 中的 gpu 使用率,在 k8s 中使用 nvidia 官方的监控方案 dcgm-exporter,通过此可以拿到每个在 gpu 上的 pod 的 gpu 利用率。 ![dcgm-exporter](https://foruda.gitee.com/images/1700638635772791170/ec2d69f9_13742231.png "屏幕截图") 在 prometheus 中的指标类型为: ``` DCGM_FI_DEV_GPU_UTIL{UUID="xx", container="dcgm-exporter", endpoint="metrics", exported_container="volcanojob", namespace="xx", pod="xx", gpu="0", instance="xx:9400", job="dcgm-exporter", namespace="monitoring", pod="dcgm-exporter-xx", service="dcgm-exporter"} ``` 指标名为 `DCGM_FI_DEV_GPU_UTIL`,所对应的工作 pod 为 `pod`、工作 pod 所在命名空间为 `namespace`,通过这两个就可以匹配到目标 pod。 > ℹ️ 核实:指标名 `DCGM_FI_DEV_GPU_UTIL` 在平台侧 prometheus 查询中确实使用,见 `myapp/utils/py/py_prometheus.py:104/202/333/458`;自定义伸缩指标命名为 `container_gpu_usage`,见 `myapp/utils/py/py_k8s.py:2246`。 我们通过 configmap 的形式注册 apiserver 的指标: ```yaml # gpu 利用率 - seriesQuery: '{__name__="DCGM_FI_DEV_GPU_UTIL",pod!="",namespace="service"}' seriesFilters: [] # pod 自定义指标供 hpa 查询指定命名空间指定 pod 的指标, # 需通过 resources 配置指标标签和命名空间、pod 名称的映射关系 resources: overrides: namespace: # 指标的标签 resource: namespace # k8s 的资源名 pod: # 指标的标签 resource: pod # k8s 的资源名 # 用来给指标重命名 name: matches: "^(.*)" as: "container_gpu_usage" # 获取指标的值。Series 表示指标名称,LabelMatchers 为附加标签(即 pod 名称) metricsQuery: (sum(avg_over_time(<<.Series>>{<<.LabelMatchers>>}[5m])) by (<<.GroupBy>>))/100 ``` 主要需要关注的点为指标中的 label `namespace` 为真实 pod 的 namespace、指标中的 `pod` 为真实 pod 的 pod 名(推理服务命名空间为 `service`)。并且在实际推理中请求进来 gpu 利用率才会变高,所以为了避免太过敏感,最终用于 hpa 的指标值做了 5 分钟平均。 ## 各类推理框架 不同的训练框架基本都有对应的推理框架。CubeStudio 为 tf/torch/onnx/tensorrt/lightgbm/paddle/sklearn/xgboost 等模型提供推理服务,基本仅需用户填写模型名称、版本、模型地址,会自动生成所有的配置文件、提供 api 的 demo、自动提供域名和 ip 的访问。 各类型的推理框架或多或少可以代理其他训练框架的模型进行推理服务。例如 tfserving 也可以为 onnx 模型提供推理服务,所以这些框架和模型并不是唯一绑定关系。 > ℹ️ 核实(当前框架枚举已扩展):当前代码中推理服务类型 `service_type` 已扩展为 `ml-server`(sklearn/xgboost/lightgbm 等通用 ml)、`tfserving`、`torch-server`、`triton-server`(即下文的 tensorrt/Triton)、`vllm`、`vllm-distributed`、`ollama`、`mindie`、`mindie-distributed`、`triton-llm` 等,见 `myapp/views/view_inferenceserving.py:58-94`(含各框架的模型路径、健康检查 host、configmap、启动命令)。下文的 onnxruntime/tensorrt 描述对应当前的 `triton-server`。 ### tfserving tfserving 主要是 tf 模型推理服务,虽然同时也可以为其他模型提供推理服务(比如上面说的 onnx 模型)。 tfserving 推理主要需要提供 models.config、monitoring.config、platform.config 等配置文件。推理服务提供了 Model status API、Model Metadata API、Classify and Regress API、Predict API 等类型的接口。 可以使用 Model Metadata API 作为模型的健康检查接口。monitoring.config 中配置的 metric 可以用于 prometheus 监控。 > ℹ️ 核实:tfserving 启动命令为 `/usr/bin/tf_serving_entrypoint.sh --model_config_file=/config/models.config --monitoring_config_file=/config/monitoring.config --platform_config_file=/config/platform.config ...`,健康检查 host 为 `/v1/models/$model_name/metadata`,见 `myapp/views/view_inferenceserving.py:68,87`。 ### torchserve(torch-server) torch 保存模型结构和参数完整信息后,需要先使用 torch-model-archiver 将模型压缩为可直接推理的包,主要是将 http 接口封装进去。 ``` torch-model-archiver --model-name $model_name --version $model_version --handler image_classifier --serialized-file $model_version/$model_name --export-path $model_version -f ``` 其中 `--handler` 支持 image_classifier、image_segmenter、object_detector、text_classifier 或自定义 py 函数。这个 handler 就是接口处理方式,也决定了用户客户端该如何请求。 torch server 主要配置为 config.properties 和 log4j.properties,提供的 api 包括推理(8080 端口)、管理(8081)、监控(8082)。 8080/ping 可以用于 pod 的健康检查,POST /metrics 可以用于 prometheus 的监控。 > ℹ️ 核实:torch-server 的 config.properties 中 `inference_address=http://0.0.0.0:8080`、`management_address=http://0.0.0.0:8081`、`metrics_address=http://0.0.0.0:8082`,健康检查 host 为 `:8081/models`,见 `myapp/views/view_inferenceserving.py:69,81`。 ### onnxruntime pass(当前由 triton-server 统一承载 onnx/tensorrt 等模型,见上文框架枚举核实) ## 模型压缩 pass ## gpu 推理加速 推理加速除了对模型进行处理(例如模型变小、计算量变小),还可以在 gpu 上针对 gpu 的计算进行并行和去重。 TensorRT 是 NVIDIA 推出的一款基于 CUDA 和 cudnn 的神经网络推断加速引擎,相比于一般的深度学习框架,在 CPU 或 GPU 模式下可提供 10X 乃至 100X 的加速,极大提高了深度学习模型的推断速度。 TensorRT 的加速原理一是支持 INT8 和 FP16 的计算,通过在减少计算量和保持精度之间达到一个理想的 trade-off;另一个是 TensorRT 对网络结构进行了重构和优化,减少了不必要的计算和重复的计算,包括消除无用输出层、网络的垂直整合、网络的水平组合等方案。 ![TensorRT 优化](https://foruda.gitee.com/images/1700638660640339002/772394aa_13742231.png "屏幕截图") 因为支持在 gpu 计算上的加速,并不影响 http 的推理框架,所以 tensorrt server 解耦了 http 框架和 gpu 计算部分,可以兼容多种 http 框架,同时还支持自定义的 http 框架。 tensorrt server 的主要配置为 config.pbtxt,同时还集成了一个客户端 sdk,是因为在兼容多种 http 框架的同时,每一种不同的模型、不同的 http 框架、不同的 input/output,请求的方式不一样,需要先根据实际情况判断组合该用什么样的请求流。 > ℹ️ 核实:当前平台中 tensorrt/Triton 对应 `triton-server`,启动命令 `tritonserver --model-repository=/models/ --strict-model-config=true --log-verbose=1`,健康检查 host 为 `/v2/models/$model_name`,见 `myapp/views/view_inferenceserving.py:70,89`。 ## vgpu gpu 推理时三类场景需要用到 gpu: 1. gpu 显存和 gpu 利用率低:vgpu 可以在一张 gpu 卡上放更多的推理服务,共用一个 gpu。 2. 本身 gpu 数量有限,需要更多的 gpu 数量满足需求:vgpu 可以虚化出更多的 gpu 数量。 3. 显存不充足、模型比较大,或大模型却没有较多的 qps、显存占用率和 gpu 利用率差距比较大的场景。 gpu 由于价格比较昂贵,所以使用占用方式比较谨慎。在 k8s 上原生的 gpu 占用方式如下: ```yaml limits: nvidia.com/gpu: 1 ``` 这种方式是独占 gpu 的方式,占上以后就不会被其他 pod 占用,但如果 pod 占用后不使用的话就会非常浪费。 还有一种占用方式是共享占用,可以被多个 pod 共同占用和共同使用。通过环境变量确定占用的 gpu 卡号,这种方式跳过 gpu 的资源调度器,这样就不会被 k8s 识别到 gpu 卡被占用了;但这种方式多个 pod 占用一个 gpu,pod 之间会相互影响,适合允许 pod 之间 gpu 能力相互干扰的情况(比如某些对成功率没有很高要求的场景,notebook 的 gpu 场景中就可以使用这种方式占用 gpu)。 ```yaml env: - name: NVIDIA_VISIBLE_DEVICES value: "0,1" # 写相对卡顺序,比较方便 ``` > ℹ️ 核实:CubeStudio 在训练/任务侧也是通过环境变量 `NVIDIA_VISIBLE_DEVICES` 指定卡号(同时注入 `ASCEND_RT_VISIBLE_DEVICES` 兼容昇腾),见 `myapp/views/view_pipeline.py:724-726`、`myapp/views/view_nni.py:468-470`。 如果应用在 tke 上,也可以直接部署 qgpu 组件,使用 vgpu 的功能。在 tke 上可以占用卡的一部分,显存为 vcuda-memory*256Mi,独立占用 gpu 核和显存两个资源: ```yaml limits: tencent.com/vcuda-core: 200 tencent.com/vcuda-memory: 60 ``` 如果是在自建 k8s 上,也可以使用 HAMi,这个功能已经开源到 https://github.com/Project-HAMi/HAMi 。 当然也有很多其他的 vgpu 方案,例如 https://github.com/4paradigm/k8s-device-plugin 开源的 vgpu 方案,可以直接在部署的时候就将每个卡划分为指定数量的 vgpu,占用时跟原生占用方式一样,但实际只占用 2 个 vgpu。这种方式不会更改应用的书写方式,直接在显卡插件中进行了虚拟化: ```yaml limits: nvidia.com/gpu: 2 ``` 此外此虚拟化方案还可以虚化显存,用内存代替显存存放模型。虽然这个操作对模型有一定的性能影响,但也是有意义的:比如对于平时无访问的模型,放在虚化显存中,在访问量提升时,serverless 激活服务加载到实际显存中。 ## Transformer(前置/后置处理) 在不同的 http 推理框架中都有对应的前置后置处理函数,例如 tfserving 中的 TensorFlow Transform、torch-server 中的 Custom handlers 或 torchvision.transforms、tensorrt-server 中的自定义 backend。 例如 torch-server 中的 Custom handlers,假设接口用户的输入为: ```python data = { "image_url": "http://xx.xx.xx/xx", "image_id": "xx" } ``` 我们可以使用自定义的 handler: ```python # 请求得到响应 def handle(self, data, context): # 输入输出为 list self.context = context data_preprocess = self.preprocess(data) output = self.inference(data_preprocess) output = self.postprocess(output) back = [] for index in range(len(output)): back.append({ "predict": output[index], "image_id": data[index]['body']['image_id'] }) return back # 前置处理 def preprocess(self, data): des_images = [] for row in data: image_url = row.get("body")['image_url'] image = requests.get(image_url).content image = Image.open(io.BytesIO(image)) image = self.image_processing(image) des_images.append(image) return torch.stack(des_images).to(self.device) # 后置处理 def postprocess(self, data): return data.argmax(1).tolist() ``` torch-server 的自定义方式是先编写 handler 文件,然后构建到 mar 文件中,这样推理服务就会使用这个 handler 文件。在 kfserving 中使用的是独立容器的方式,不影响原有业务的代码。 ![Transformer 独立容器](https://foruda.gitee.com/images/1700638694557019212/32e5c2c3_13742231.png "屏幕截图") ## 推理服务 pipeline 服务保持无状态模式,通过前后置逻辑兼容更多的请求方式,每个服务独立控制伸缩容、监控、熔断等管理方式,链路通过用户自定义逻辑串联。 ![推理服务 pipeline](https://foruda.gitee.com/images/1700638721761337837/f2962280_13742231.png "屏幕截图") --- ### 算力统筹与分布式存储 - 链接: https://www.cubestudio.vip/docs/01-%E6%9E%B6%E6%9E%84%E5%8E%9F%E7%90%86/%E7%AE%97%E5%8A%9B%E7%BB%9F%E7%AD%B9%E4%B8%8E%E5%88%86%E5%B8%83%E5%BC%8F%E5%AD%98%E5%82%A8 - 分类: 01-架构原理 / 算力与存储设计 - 适用场景: 想了解平台为什么/如何统筹算力、各环节(notebook/pipeline/推理)共享同一套分布式存储、以及挂载配置串(pvc/hostpath/configmap/memory)的语义时阅读。 - 关键词: 算力统筹 / 算力均衡 / 资源利用率 / 异构算力 / GPU / vGPU / 分布式存储 / 存储挂载 / volume_mount / pvc / hostpath / configmap / memory / nfs / juicefs / alluxio / 数据隔离 / 组目录 / 弹性扩缩 / /mnt / kubeflow-user-workspace / subPath - 最后更新: 2026-06-30 # 算力统筹与分布式存储 ## 算力统筹 / 均衡 ### 面临的问题 - 时间、空间维度上 GPU 资源利用率不足。 - 异构算力环境,任务需区分 CPU / GPU(T4) / GPU(V100) / vGPU 等类型。 - 超大数据量必须跑分布式,且资源要尽可能多。 - 个人代码和环境依赖固定机器,而机器的回收、损坏、裁撤、磁盘不足等事件频繁,耗费大量工程运维时间。 - GPU 训练中利用率优化的主动性不大,用户会优先考虑通过扩容来提升效率。 ### 解决方案 - 统筹底层算力,最大程度提高剩余资源的利用率。 - 项目组间算力自动均衡,基本能把任务挂起等待时长保持在 5 分钟以内。 - 支持边缘集群模式,充分利用边缘网络资源,避免数据同步。 - 智能修正任务的启动资源配置,避免不合理的资源申请。 ![算力多集群统筹](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/suanliduojiqun.png) ## 平台分布式存储挂载 ### 面临的问题 - 为减少数据导入导出链路,避免用户在开发 / 调试 / 训练 / 校验 / 上线时,数据文件在不同系统之间来回搬运。 ### 解决方案 - 平台在开发 notebook、数据处理 / 训练 pipeline、模型服务化中挂载**相同的分布式存储**,不同用户挂载各自的子目录。同一用户在平台各个环节下 `/mnt/$username` 都是其个人工作目录。 ![平台分布式存储](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/fenbushicunchu.png) - **数据隔离**:`pvc` 挂载会自动追加用户个人子目录(subPath = 用户名)。 - **组目录模式**:支持多人共用分布式存储,满足团队工作目录的需求。 - **多存储挂载**:每个项目可以添加多个 pvc 挂载,比如低性能 CFS、高性能 SSD Ceph,应用于不同的数据处理 / 训练场景。 - **解耦分布式存储实现**:只需把存储挂载或软链到主机(`/data/k8s/`),或绑定到 pvc 即可。 - **磁盘爆炸**:平台提供存储监控,会提醒用户及时删除不再使用的大文件目录。 - **磁盘不足**:存储的扩缩容是弹性的,用户无需担心存储大小问题。 - **其他类型挂载**:如 hostpath、memory、configmap。 ## 挂载的配置 平台用 `挂载源(类型):容器目录` 的字符串语法描述每条挂载,多条用逗号分隔。常见类型如下(解析逻辑见 `myapp/utils/py/py_k8s.py` 约 940-1060 行): - **pvc 挂载**,例如 `kubeflow-user-workspace(pvc):/mnt`:会自动把 pvc 下的 `$username` 子目录(subPath=username)挂载到容器目录的 `$username` 子目录下,实现按用户隔离。 > 平台默认任务挂载即为 `kubeflow-user-workspace(pvc):/mnt`(见 `myapp/init/init-inference.json`、`myapp/cli.py`)。 - **hostpath 挂载**,例如 `/data/kubeflow/k8s/kubeflow/pipeline/workspace/group1(hostpath):/mnt1`:把主机目录挂载到容器目录,一般用于多人共享编辑同一目录。 - **configmap 挂载**,例如 `kubernetes-config(configmap):/root/.kube`:把 configmap 挂载到容器目录,一般用于把特殊配置文件投递进容器。 - **内存挂载**,例如 `4G(memory):/dev/shm`:把内存(emptyDir medium=Memory)挂载到容器,一般用于解决 K8s 共享内存不足的问题。 > 平台还支持几种与上面同源的挂载类型(同见 `py_k8s.py`): > - `(pvc-share)`:把整个 pvc 挂载到目标目录、**不**追加用户子目录,用于"组目录 / 团队共享"场景。 > - `(nfs)`:直接以 `ip/path(nfs):容器目录` 方式挂载 NFS。 > - `(storage)`:外部存储盘,挂载时不追加子目录。 ## 分布式文件系统 ### NFS NFS 是最常用的共享存储方案,部署方式见 [02-部署安装](../02-部署安装/) 段中的「NFS 离线部署」文档。 ### JuiceFS 可使用 JuiceFS 作为分布式文件系统(无需挂载到每台机器即可实现多个 Pod 直接共享统一目录)。部署要点(详见 [02-部署安装](../02-部署安装/) 段中的 JuiceFS 部署文档): - 执行 `cd install/kubernetes/juicefs/ && sh start_juicefs.sh`。 - 执行前请阅读 `install/kubernetes/juicefs/README.md`。 - 记得修改 `install/kubernetes/juicefs/.env` 中的 `JUICEFS_HOST_IP` 为本节点 IP,并保证 `/data` 目录有足够空间。 - 注意配置开机自动挂载,避免机器重启后挂载失效。 ### Alluxio Alluxio 也可作为分布式存储缓存层,部署方式见 [02-部署安装](../02-部署安装/) 段中的「Alluxio 分布式存储部署」文档。 --- ### 流量代理与网关 - 链接: https://www.cubestudio.vip/docs/01-%E6%9E%B6%E6%9E%84%E5%8E%9F%E7%90%86/%E6%B5%81%E9%87%8F%E4%BB%A3%E7%90%86%E4%B8%8E%E7%BD%91%E5%85%B3 - 分类: 01-架构原理 / 网络入口 - 适用场景: 想搞清楚平台对外只有一个 istio 网关入口、各功能(前端/后端/grafana/notebook/aihub/标注/k8s dashboard)分别走哪个路径前缀、以及 /backend URL 前缀如何工作时阅读。 - 关键词: 流量代理 / 网关 / gateway / istio / ingressgateway / istio-ingressgateway / VirtualService / virtual.yaml / gateway.yaml / 路径前缀 / path prefix / /backend / /frontend / /static / grafana / labelstudio / k8s dashboard / notebook / aihub / gradio / 统一入口 / 80端口 / URL 前缀 - 最后更新: 2026-07-04 # 流量代理与网关 CubeStudio 对外统一通过 **istio ingress gateway** 暴露服务:浏览器侧所有请求都打到网关的 80 端口,再由网关按 URL 路径前缀分发到各命名空间的后端服务。 ## 流量入口(Gateway) - 网关资源 `kubeflow-gateway` 定义在 `kubeflow` 命名空间,通过 `selector: istio: ingressgateway` 绑定到 istio ingress gateway 的 Pod,开放 **80 端口(HTTP)**。源码见 `install/kubernetes/gateway.yaml`。 - `gateway.yaml` 决定**哪些流量可以进来**(监听端口、host);`virtual.yaml`(VirtualService)决定**进来的流量如何分发**到后端服务。源码见 `install/kubernetes/virtual.yaml`。 - 仓库另带一份 ingress gateway 的安装清单 `install/kubernetes/istio/istio-gateway.yaml`,把网关 Pod 部署到 `istio-ingress` 命名空间,Service 类型为 `LoadBalancer`、保留客户端源 IP(`externalTrafficPolicy: Local`)、对外暴露 80 / 443 端口。 > 注意:`gateway.yaml` 的 Gateway 选择器是 `istio: ingressgateway`(见 `install/kubernetes/gateway.yaml:9`),而 `install/kubernetes/istio/istio-gateway.yaml` 部署的网关 Pod label 是 `istio: ingress`、命名空间 `istio-ingress`(见该文件 `:86,108`)。两者 label 不一致,实际生效的入口网关 Pod 取决于集群里到底装了哪个网关,请按部署实际确认。 ## 入口白名单与 /backend URL 前缀 主入口的 VirtualService `infra-kubeflow-dashboard`(`virtual.yaml:1-27`)的 `match` 声明了 `/backend`、`/frontend`、`/static` 三个前缀,外加一条兜底 `prefix: /`(`virtual.yaml:14-22`),全部路由到前端服务 `kubeflow-dashboard-frontend.infra:80`: - `/backend` —— 所有后端接口(前端 nginx 会 strip 掉 `/backend` 前缀,再转发给根路径上的 Flask 后端)。 - `/frontend` —— 前端 SPA。 - `/static` —— 静态资源。 根路径 `/` 也被 `match` 命中:除上面三个前缀外还有一条兜底 `prefix: /`(`virtual.yaml:21-22`),会把根路径及其余未被本网关其它 VirtualService 匹配的路径都路由到前端服务 `kubeflow-dashboard-frontend.infra:80`。 > 这就是平台的「`/backend` URL 前缀」架构:浏览器侧 URL 带 `/backend` 前缀经 istio → 前端 nginx,nginx strip 掉前缀后转发给运行在根路径的后端;服务间直连后端(如 `kubeflow-dashboard.infra`)则不带前缀。后端框架细节见 [06-二次开发](../06-二次开发/) 段。 > > 注意:文件内注释(`virtual.yaml:12-13`)写的是「不放开 `/`、其余路径返回 404」,与 `match` 里实际多出的兜底 `prefix: /` 不一致——按当前配置根路径会被路由到 `kubeflow-dashboard-frontend`,再由前端 nginx 按 `/backend` 等前缀转发到后端。实际生效行为以你部署的 `virtual.yaml` 为准。 ## 路径前缀代理对照表 下表分两类:一类是 `virtual.yaml` 里静态声明的 VirtualService;另一类是后端在部署 notebook / aihub 应用时**动态创建**的 VirtualService。 | 路径前缀 | 命名空间 | 目标服务 (端口) | 来源 | 备注 | |----|----|----|----|----| | `/backend`、`/frontend`、`/static` | infra | kubeflow-dashboard-frontend (80) | `virtual.yaml` 静态 | 平台前端/后端统一入口;`/backend` 被 nginx strip | | `/grafana/` | **monitoring** | grafana (8080) | `virtual.yaml` 静态 | rewrite 到 `/`,需带 `myapp_username` cookie | | `/k8s/dashboard/cluster/` | kube-system | kubernetes-dashboard-cluster (9090) | `virtual.yaml` 静态 | 高权限 k8s dashboard,rewrite 到 `/`,需 cookie | | `/k8s/dashboard/user1/` | kube-system | kubernetes-dashboard-user1 (9090) | `virtual.yaml` 静态 | 低权限 k8s dashboard,rewrite 到 `/`,需 cookie | | `/labelstudio/` | kubeflow | labelstudio (8080) | `virtual.yaml` 静态 | 标注平台,rewrite 到 `/labelstudio/`,需 cookie | | `/notebook/jupyter/$name/` | jupyter | 对应 notebook 应用 | 后端动态创建 | 每个 notebook 部署时建一个 VirtualService(`myapp/views/view_notebook.py:497-514`) | | `/aihub/$name`(app1 为 `/aihub/`) | aihub | 对应 aihub 应用 | 后端动态创建 | aihub 应用部署时创建(`myapp/views/view_aihub.py:934-961`) | | `/gradio/aihub/$name/` | aihub | 对应 aihub gradio 应用 | 后端动态创建 | 同上,gradio 界面入口 | > 校正说明:原文档把 grafana 标在 `prometheus` 命名空间,实际为 `monitoring`(`virtual.yaml:150-170`,且 `install/kubernetes/prometheus/` 下各组件均部署在 `monitoring` 命名空间)。 > > `/grafana`、`/labelstudio`、`/k8s/dashboard/*` 这几条都额外要求请求带 `myapp_username` cookie(通过 `headers.cookie.regex` 校验),用于登录态透传。 ## 相关阅读 - 后端 `/backend` 前缀与 nginx strip 的开发细节:[06-二次开发](../06-二次开发/) 段。 - grafana / 监控相关配置:[04-运维管理](../04-运维管理/) 段。 - istio ingress gateway 作为基础组件的部署:[02-部署安装](../02-部署安装/) 段。 --- ### RDMA 网络与分布式训练 - 链接: https://www.cubestudio.vip/docs/01-%E6%9E%B6%E6%9E%84%E5%8E%9F%E7%90%86/RDMA%E7%BD%91%E7%BB%9C%E4%B8%8E%E5%88%86%E5%B8%83%E5%BC%8F%E8%AE%AD%E7%BB%83 - 分类: 01-架构原理 / 网络与分布式训练 - 适用场景: 需要在云原生 GPU 集群上用 RDMA(RoCE/IB)+NCCL 做多机多卡分布式训练,或排查 NCCL/RDMA 网络问题、确认 CubeStudio 的 RDMA 资源配置方式时阅读。 - 关键词: RDMA / RoCE / InfiniBand / IB / NCCL / NCCL_IB_HCA / NCCL_SOCKET_IFNAME / NCCL_IB_GID_INDEX / NCCL_IB_DISABLE / PyTorchJob / 分布式训练 / distributed training / ofed_info / show_gids / nvidia-smi / IPC_LOCK / rdma/hca / rdma/shared / GPU / 集合通信 / collective communication - 最后更新: 2026-07-04 # RDMA 网络与分布式训练 > ⚠️ 重要:本文正文("环境验证"到"关键参数说明")以**百度智能云 CCE** 为示例(CCE RDMA Device Plugin、`registry.baidubce.com` 镜像、PFS 并行文件存储等),属于**通用 RDMA / NCCL 参考资料**,并非 CubeStudio 平台的原生组件。请勿把 `CCE RDMA Device Plugin`、`csi-clusterfileplugin`、`baidu.com/a100_80g_cgpu` 等当成本平台自带能力。CubeStudio 自身的 RDMA 支持方式见文末「CubeStudio 中的原生 RDMA 支持」一节。 ## 概述 RDMA(Remote Direct Memory Access,远程直接内存访问)是新一代网络通信技术,允许计算机之间直接进行内存到内存的数据传输,绕过操作系统内核与 CPU 的处理开销。在大规模分布式训练中,RDMA 可有效降低网络传输的服务器端数据处理延迟,实现高吞吐、低延迟的网络通信,从而提升训练效率。 本文介绍在云原生 AI 环境下使用 RDMA 网络进行分布式训练的通用方法。 说明: 1. 由于 RDMA 网络的特殊性,以下示例在自建 K8s 集群中可能无法直接适用。 2. IB 与 RoCE 在使用上几乎无区别,如无特别说明以下均以 RoCE 为例,IB 在应用侧无需更改。 3. 业务镜像中需要包含 NCCL 依赖库,推荐使用 NVIDIA GPU Cloud(NGC)提供的基础镜像。NGC 基础镜像通常已内置 NCCL,并预先配置和优化了常用深度学习框架与工具,可简化设置过程。 ## 使用前提(通用 RDMA 参考) - 已创建集群,且集群中至少有 2 台具有 RDMA 网络的 GPU 实例。 - GPU 实例镜像中包含 OFED 和 NVIDIA 驱动(公有云一般有预装 OFED 驱动的 GPU 镜像,免去手动安装)。 - 集群已安装对应的 RDMA Device Plugin、GPU Manager、AI Job Scheduler 和深度学习框架 Operator 等组件。 > GPU 实例 / 驱动 / 设备插件等部署前置工作,可参考 [02-部署安装](../02-部署安装/) 段(GPU 与集群准备相关文档)。 ## 环境验证 登录集群内具有 RDMA 网络的 GPU 节点,运行以下命令验证主机环境。 ### 验证 OFED 驱动 ```bash $ ofed_info -s # 查看 RoCE/OFED 驱动版本 MLNX_OFED_LINUX-5.8-1.1.2.1: ``` ### 验证 NVIDIA GPU 驱动 ```bash $ nvidia-smi # 查看 NVIDIA GPU 驱动与显卡状态 +-----------------------------------------------------------------------------+ | NVIDIA-SMI 470.141.03 Driver Version: 470.141.03 CUDA Version: 11.4 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | |===============================+======================+======================| | 0 NVIDIA A100-SXM... On | 00000000:53:00.0 Off | 0 | | N/A 29C P0 64W / 400W | 0MiB / 81251MiB | 0% Default | +-------------------------------+----------------------+----------------------+ | ... (此处省略 GPU 1~7,A100-SXM 8 卡) ... | +-----------------------------------------------------------------------------+ ``` (示例为 8 卡 A100-SXM 节点,驱动版本 470.141.03、CUDA 11.4。) ### 查询 RDMA 网卡(GID) ```bash $ show_gids DEV PORT INDEX GID IPv4 VER DEV --- ---- ----- --- ------------ --- --- mlx5_0 1 0 fe80:0000:0000:0000:f820:20ff:fe28:c769 v1 eth0 mlx5_0 1 2 0000:0000:0000:0000:0000:ffff:0a00:3c03 10.0.60.3 v1 eth0 mlx5_1 1 2 0000:0000:0000:0000:0000:ffff:190b:8002 25.11.128.2 v1 eth1 mlx5_2 1 2 0000:0000:0000:0000:0000:ffff:190b:8022 25.11.128.34 v1 eth2 ... mlx5_8 1 2 0000:0000:0000:0000:0000:ffff:190b:80e2 25.11.128.226 v1 eth8 ``` `show_gids` 列出每张 RDMA 网卡(mlx5_x)的 GID 表,后续配置 `NCCL_IB_HCA` 与 `NCCL_IB_GID_INDEX` 时需参考此输出。其中 `mlx5_0` 通常是 TCP 网络的主网卡,`mlx5_1`~`mlx5_8` 为 RoCE 数据网卡。 ## 提交任务 NCCL 是 NVIDIA 的集合通信库,能实现 Collective 通信和点对点通信,内部已实现 RDMA 通信。NCCL 可根据环境中网卡类型和拓扑关系自行选择最优通信路径,目前主流分布式训练框架均已支持 NCCL。 下面介绍如何通过 YAML(或控制台)方式提交基于 NCCL 的 RDMA 分布式训练任务。 ### YAML 方式提交任务 前置:已通过 `kubectl` 连接到 Kubernetes 集群。 以下是一个 swin-transformer 基于 NCCL 的 PyTorch 分布式训练任务示例(PyTorchJob,Master + Worker 各 1 副本,每副本 8 卡): ```yaml apiVersion: "kubeflow.org/v1" kind: "PyTorchJob" metadata: name: "pytorch-swin-transformer-nccl" spec: pytorchReplicaSpecs: Master: replicas: 1 restartPolicy: OnFailure template: metadata: annotations: sidecar.istio.io/inject: "false" # 训练 Pod 不注入 istio sidecar spec: containers: - name: pytorch image: registry.baidubce.com/cce-ai-native/swin-transformer-torch:v2.0 # 示例镜像(百度云),自建集群请替换为含 NCCL 的镜像(如 NGC) imagePullPolicy: IfNotPresent command: - /bin/sh - -c - python -m torch.distributed.launch --nproc_per_node 8 --nnodes $WORLD_SIZE --node_rank $RANK --master_addr $HOSTNAME --master_port $MASTER_PORT main.py --cfg configs/swin/swin_large_patch4_window7_224_22k.yaml --pretrained swin_large_patch4_window7_224_22k.pth --data-path /imagenet --batch-size 128 --accumulation-steps 2 env: - name: NCCL_DEBUG value: "INFO" - name: NCCL_IB_DISABLE value: "0" # 0 = 启用 IB/RoCE 传输 securityContext: capabilities: add: [ "IPC_LOCK" ] # 锁页内存,RDMA 必需 resources: limits: nvidia.com/gpu: 8 rdma/hca: 1 # 申请 RDMA 资源 volumeMounts: - mountPath: /imagenet name: dataset - mountPath: /dev/shm name: cache-volume # 共享内存,供 IPC 使用 schedulerName: volcano volumes: - name: dataset persistentVolumeClaim: claimName: imagenet-22k-pvc - emptyDir: medium: Memory name: cache-volume Worker: replicas: 1 restartPolicy: OnFailure template: metadata: annotations: sidecar.istio.io/inject: "false" spec: containers: - name: pytorch image: registry.baidubce.com/cce-ai-native/swin-transformer-torch:v2.0 imagePullPolicy: IfNotPresent command: - /bin/sh - -c - python -m torch.distributed.launch --nproc_per_node 8 --nnodes $WORLD_SIZE --node_rank $RANK --master_addr $MASTER_ADDR --master_port $MASTER_PORT main.py --cfg configs/swin/swin_large_patch4_window7_224_22k.yaml --pretrained swin_large_patch4_window7_224_22k.pth --data-path /imagenet --batch-size 128 --accumulation-steps 2 env: - name: NCCL_DEBUG value: "INFO" - name: NCCL_IB_DISABLE value: "0" securityContext: capabilities: add: [ "IPC_LOCK" ] resources: limits: nvidia.com/gpu: 8 rdma/hca: 1 volumeMounts: - mountPath: /imagenet name: dataset - mountPath: /dev/shm name: cache-volume schedulerName: volcano volumes: - name: dataset persistentVolumeClaim: claimName: imagenet-22k-pvc - emptyDir: medium: Memory name: cache-volume --- # 以下 PV/PVC 使用百度云并行文件存储 PFS(csi-clusterfileplugin),属示例存储,自建集群请替换为 NFS/JuiceFS 等 apiVersion: v1 kind: PersistentVolume metadata: name: imagenet-22k-pv spec: accessModes: - ReadWriteMany storageClassName: capacity: storage: 100Gi csi: driver: csi-clusterfileplugin volumeHandle: data-id volumeAttributes: parentDir: / # 必填,自定义路径 path: "" # 必填,PFS 挂载路径(相对于 parentDir) clusterIP: "" # 必填,PFS 实例的 endpoint clusterPort: "8888" # 必填,当前端口固定为 8888 clientID: "" # 非必填,PFS 实例的 id --- kind: PersistentVolumeClaim apiVersion: v1 metadata: name: imagenet-22k-pvc namespace: default spec: accessModes: - ReadWriteMany storageClassName: resources: requests: storage: 100Gi ``` ## NCCL 关键参数说明 NCCL 通过环境变量来启用 RDMA 特性,主要变量如下表。带 `*` 号的变量在百度 CCE 等托管环境下会被平台基于内部经验自动注入推荐值,无需手动填写(自建集群通常需要自己设置)。 | 键 | 值 | 含义 | 备注 | |:--|:--|:--|:--| | `NCCL_IB_DISABLE` | 0 / 1 | 0 表示使用 IB/RoCE 传输;1 表示禁止 NCCL 使用 IB/RoCE,退回到 IP 套接字(TCP) | — | | `NCCL_IB_HCA` * | mlx5_1 ~ mlx5_8 | 指定使用哪些 RDMA 接口进行通信。按套餐/卡数填对应值:8 卡 RoCE 填 mlx5_1~mlx5_8,4 卡填 mlx5_1~mlx5_4,以此类推。注:mlx5_0 通常是 TCP 主网卡 | — | | `NCCL_SOCKET_IFNAME` * | eth0 | 指定使用哪个 IP 接口进行控制面通信。注:容器内默认是 eth0 | — | | `NCCL_IB_GID_INDEX` * | 动态值 | RoCE 模式中使用的全局 GID 索引,取值参考 `show_gids` 命令输出。注:通过容器网络使用 RoCE 时,CNI 插件会为容器创建对应数量的子网卡,GID INDEX 动态生成 | — | | `NCCL_IB_TIMEOUT` * | 22 | 网络断点重连超时时间 | — | | `NCCL_IB_QPS_PER_CONNECTION` * | 8 | 每个 IB QP 连接的连接数 | — | | `NCCL_DEBUG` | INFO | 控制 NCCL 输出的调试信息,常用于排障 | — | 托管环境(如百度 CCE)会在任务运行时自动检测容器的 RoCE 环境,为容器内 PID=1 的进程自动注入 `NCCL_IB_HCA`、`NCCL_SOCKET_IFNAME`、`NCCL_IB_GID_INDEX`、`NCCL_IB_TIMEOUT`、`NCCL_IB_QPS_PER_CONNECTION` 等环境变量。由 PID 1 创建的子进程会继承这些变量,但**通过 sh 启动的进程可能无法继承**。若用户在 YAML 中已显式声明这些变量,则平台不再自动注入。 为了在 rank 之间共享数据,NCCL 需要为 IPC 和固定(页面锁定)内存共享系统内存,需要在 YAML 中配置: ```yaml securityContext: capabilities: add: [ "IPC_LOCK" ] # 使能进程间通信(锁页内存) resources: limits: baidu.com/a100_80g_cgpu: 8 # 示例 GPU 资源名(百度云专有),通用环境为 nvidia.com/gpu rdma/hca: 1 # 使能 RDMA 资源 volumeMounts: - mountPath: /imagenet name: dataset - mountPath: /dev/shm # 用 emptyDir 提供足够共享内存供 IPC name: cache-volume volumes: - name: dataset persistentVolumeClaim: claimName: imagenet-22k-pvc - emptyDir: medium: Memory name: cache-volume ``` > 上例依赖开源数据集 ImageNet-22K,需提前将数据集拷贝到共享存储(示例用百度云 PFS)的挂载目录中。自建集群可改用 NFS / JuiceFS / Alluxio 等共享存储,详见 [算力统筹与分布式存储.md](算力统筹与分布式存储.md)。 ## CubeStudio 中的原生 RDMA 支持 CubeStudio 平台本身已内置 RDMA 资源的申请与注入能力,无需依赖某个云厂商的专有插件名。相关实现: - **RDMA 资源类型映射**:`myapp/config.py` 中 `RDMA_RESOURCE` 把 RDMA 类型映射到 K8s 扩展资源名: - `ib` → `rdma/hca`(IB 交换机实现的 RDMA) - `roce` → `rdma/shared`(RoCE 实现的 RDMA) - 默认资源名 `RDMA_RESOURCE_NAME = 'rdma/hca'`(见 `myapp/config.py:1278-1283`)。 > 这里的资源名是平台自定义约定,需与集群实际安装的 RDMA Device Plugin 暴露的扩展资源名一致。 - **资源解析**:`myapp/utils/core.py:1678` 的 `get_rdma(resource_rdma)` 解析任务的 RDMA 申请值。支持形如 `1(roce)` / `2(ib)` 的写法——括号内若是 `roce`/`ib` 等类型词,会被映射成对应的资源名;返回 `(数量, 类型, 资源名)`。 - **自动注入 IPC_LOCK 与资源限制**:`myapp/utils/py/py_k8s.py` 在 `rdma_num > 0` 时会自动给容器 securityContext 追加 `IPC_LOCK` capability(`py_k8s.py:1259-1262`),并把 RDMA 资源加入容器的 requests/limits(`py_k8s.py:1206-1208`)。这与上文示例 YAML 里手写的 `IPC_LOCK` + `rdma/hca: 1` 是等价目的,只是由平台自动完成。 - 是否启用 RDMA 一般在**项目组**配置中开启(见 `RDMA_RESOURCE_NAME` 注释)。 > 具体行为以源码为准;上述为帮助定位的导航说明。 --- ### 商业版与开源版功能清单 - 链接: https://www.cubestudio.vip/docs/01-%E6%9E%B6%E6%9E%84%E5%8E%9F%E7%90%86/%E5%95%86%E4%B8%9A%E7%89%88%E4%B8%8E%E5%BC%80%E6%BA%90%E7%89%88%E5%8A%9F%E8%83%BD%E6%B8%85%E5%8D%95 - 分类: 01-架构原理 / 版本与选型 - 适用场景: 想确认某个功能是开源版自带还是商业版特有、做版本选型或采购评估时读这篇 - 关键词: 商业版 / 开源版 / 功能对照 / 功能清单 / 版本差异 / 选型 / feature list / enterprise / opensource / mlops / cube-studio / 授权 / license - 最后更新: 2026-07-09 # 商业版与开源版功能清单 本文用于对照 CubeStudio 商业版与开源版的功能差异,作为**版本选型与采购评估**的参考。功能描述以产品维度组织,技术实现细节请以各专题文档与源码为准。 > 说明:下文功能项中标注 **【商业版】** 的为商业版特有能力(对应原始文档中的下划线 / `` 标记),未标注的为开源版与商业版均提供。由于原始文档 HTML 标记在部分单元格中存在未闭合情况,个别条目的"商业版 / 开源版"边界可能不够精确,正式采购前请以管理员提供的最新清单为准。 ## 产品特性 1. 国内开源 MLOps 第一名,上千家企业私有化部署,功能稳定和完善。 2. 功能完善,支持 SSO 登录、notebook 在线开发、拖拉拽任务流 pipeline 编排、多机多卡分布式算法训练、超参搜索、推理服务 VGPU、多集群调度、私有化部署 / 边缘集群 / serverless 集群、标注平台自动化标注、大模型一键微调、私有知识库、AI 应用商店;支持模型一键开发 / 推理 / 微调;支持国产 CPU/GPU/NPU 芯片;支持 RDMA。 3. 扩展性好,适合机器学习 / 深度学习 / 大模型各领域落地。特定算法适配不需要改造平台,企业落地适配性好。 4. 支持源码交付,授权可以改造、加工成自己的产品,没有 license 部署个数和时长限制,可对外出售。 5. 支持免费新增功能升级,保持平台先进性。 6. 仅对商业版特有功能收费,性价比高,同时支持只采购部分功能控制成本。 7. 采购前可帮助免费更换 logo 为客户做演示。 > 注意:商业版功能持续更新,建议联系管理员获取商业版最新信息。 ## 功能清单 ### 基础能力 **项目组管理** - AI 平台需要通过项目划分 - 支持配置相应项目组用户的权限 - 任务 / 服务的挂载、资源组、集群、服务代理 - 项目组内角色应用 **网络** - 支持非 80 端口 - 支持公网 / 域名 - 【商业版】支持反向代理和内网穿透方式访问 - 【商业版】支持 HTTPS **用户管理 / 角色管理 / 权限管理** - 管理平台用户的基本信息、组织架构,支持账号密码、RBAC 权限体系 - 【商业版】增加修改和删除、清理等操作的历史记录 - 【商业版】支持菜单权限控制 **SSO 单点登录** - 账号密码注册自动登录 - 【商业版】支持对接公司账号体系 AUTH_OID / AUTH_LDAP / AUTH_REMOTE_USER 等登录注册方式 - 【商业版】支持消息推送 - 【商业版】增加登录验证、强密码、远程用户、登录频率限制、密码密文传输等 **GPU 调度能力** - 提供多种规格的资源支持不同的使用场景,CPU/GPU 等,支持 T4/V100/A100 等多种卡型 - 【商业版】支持 GPU 禁用模型、共享模式、独占模式、vGPU 模式;支持 RDMA 协议;支持虚拟化占用显存设定;支持指定卡序号 **支持多种算力** - 【商业版】前后端镜像支持 ARM 架构,平台底层外部组件支持 ARM 架构,任务模板支持 ARM 架构,超参搜索支持 ARM 架构,AIHub 应用 70% 支持 ARM 架构 - 【商业版】支持调度海光 DCU、华为 NPU 算力 **多资源组 / 多集群** - 支持划分多资源组,支持 Docker 运行时 - 【商业版】支持多 K8s 集群,支持 IPVS 网络模式,支持 containerd 容器运行态 **计量计费功能(整体为【商业版】特性)** 1. 支持平台资源限制的分配和查看;项目组资源限制、租户资源限制、任务资源限制、项目组下个人的资源限制,包括开发资源、训练资源、推理资源等。额度限制在 notebook、docker 构建、pipeline、超参搜索、内部服务、推理服务中生效。限制支持单任务、并行任务总和、历史任务总和等方法。 2. 提供统一的开发、训练、推理服务资源监控,从租户、项目、任务角度分析模型资源分配及使用情况。 3. 支持自定义计费模式,通过计量结果自定义获取计费值。 4. 日结账单,产生用户每日账单费用和明细。 **边缘集群** - 【商业版】支持边缘集群模式,支持边缘节点开发、训练、推理 **serverless 集群模式** - 【商业版】支持腾讯云 serverless 集群模式(notebook / pipeline / 推理服务模块支持) - 【商业版】支持阿里云 serverless 集群模式(notebook / pipeline / 推理服务模块支持) **数据库存储** - 支持外部 MySQL 作为元数据库 - 【商业版】支持外部 PostgreSQL 作为元数据库 > 补充(与代码一致):平台元数据库支持 MySQL 8+(主)、PostgreSQL 11+、DamengDB(达梦),由 `MYSQL_SERVICE` / `POSTGRESQL_SERVICE` / `DM_SERVICE` 环境变量控制,见 `install/docker/`。 **机器资源管理** - 【商业版】Web 界面控制机器调度类型、所属资源组、是否启动 RDMA、是否启动 vGPU、可用任务场景等 **存储盘管理** - 【商业版】支持 Web 界面添加存储盘,支持项目组绑定;notebook / pipeline / 推理服务可直接在 Pod 中挂载外部分布式存储 - 【商业版】支持 NFS、CFS、OSS、NAS、COS、GlusterFS、CephFS、S3/MinIO **国际化能力** - 【商业版】MLOps 支持配置多语言,目前支持中英文(由 `LOCALE=en|zh` 控制) ### 数据管理 **数据地图** - 元数据库表管理、指标、维表 **数据计算** - SQLLab 交互查询,支持 MySQL - 【商业版】支持 PostgreSQL、ClickHouse、Hive、Presto 等计算引擎 **ETL 编排** - 数据 ETL 任务流编排、任务管理等,对接公司数据中台相应计算 / 调度引擎 **数据集管理** - 允许用户随时上传样本集(图片、音频、文本等) - 【商业版】支持 SDK 进行数据集对接 - 【商业版】支持数据集一键探索功能 **数据标注(整体为【商业版】特性)** - 支持标注平台,图 / 文 / 音 / 多模态各类型标注能力 - 支持分布式存储打通 MLOps 平台 - 支持项目组权限控制 - 中文汉化 - 对接一站式机器学习平台,支持自动化标注(需购买 AIHub):支持目标识别、目标边界识别、多目标视频跟踪、目标遮罩识别、图片分类、图片描述、OCR、关键点检测 - 支持大模型自动化标注:文本分类、文本翻译、命名实体识别、阅读理解、问答、摘要提取 ### 开发环境 **镜像功能** - 镜像仓库 / 镜像管理 / 在线构建镜像。同时提供平台所有镜像,包括模板镜像 / 服务镜像 / notebook 镜像 / GPU 基础环境的构建方法和构建后镜像 - 【商业版】支持同一仓库多个秘钥配置 **notebook** - 支持基于开源的 JupyterLab / VSCode,提供在线的交互式开发调试工具 - 提供多种可选环境 IDE 和开发示例,支持资源类型选择;支持大数据版本、机器学习版本、深度学习版本 - 【商业版】大数据版本支持用户信息、HDFS 客户端、Hive 客户端和 Spark 客户端 - 支持 SSH remote 与 notebook 对接远程开发,方便快速将本地代码提交到平台的训练环境 - 【商业版】SSH 隧道代理、单端口开放 - 【商业版】支持 MATLAB、RStudio 等在线 IDE - 【商业版】支持 GPU、CPU、内存监控,支持 Git 交互 - 【商业版】支持自定义 notebook 镜像,便于封装公司自己的 notebook - 【商业版】多环境 notebook,支持 R 语言 / Julia / Python 2.7 / 3.6 / 3.7 / 3.8 / 3.9 / 3.10 环境和 CubeStudio 专有环境 - 【商业版】支持 TensorBoard 任务可视化 - 【商业版】notebook 支持环境镜像保存 - 【商业版】Jupyter 支持密码保护 - 【商业版】notebook 支持整卡占用、虚拟卡占用、GPU 共享占用 - 支持 notebook 启动自动初始化环境 - 支持 notebook 自动清理、续期 ### 模型训练 **拖拉拽任务流编排调试** - 提供拖拽式交互开发环境,支持开发者以拖拽的方式完成业务逻辑的 PIPELINE - 支持单任务调试 - 训练支持多种资源规格(CPU、GPU 等),支持卡型的选择、超时重试等 - 【商业版】任务支持独占和共享占用 GPU - 【商业版】分布式任务模板支持单任务调试用户镜像而非模板镜像 - 【商业版】支持 RDMA 资源占用 - 【商业版】支持 GPU 不同厂商、不同卡型的占用 - 【商业版】分布式任务模板支持 GPU 型号透传、RDMA 资源透传、拉取秘钥透传 - pipeline 调试,支持定时调度、补录、并发限制、超时、实例依赖等 - 任务管理、workflow 实例管理、资源监控 - 【商业版】支持任务输入输出、任务流全局变量、文本 / 图片 / ECharts 结果可视化、workflow 暂停和恢复、任务流优先级 - 【商业版】支持单任务和 pipeline 运行中任务监听端口,提供运行中服务监听能力 - 【商业版】任务流支持任务推荐;定时调度支持最大保留实例数;pipeline 支持任务流优先级 **主流功能算子** - 基础算子:自定义镜像;【商业版】逻辑节点、python - 数据同步:数据集导入【商业版】(支持 HuggingFace / 魔搭数据集)、datax、【商业版】datax-import、模型导入【商业版】(支持 HuggingFace / 魔搭模型)、【商业版】labelstudio 标注数据导入 - 【商业版】特征处理:数据合并(union、join)、去重、数据变换(boxcox、二值化、类型转换、dct、按函数转换、ma 移动平均、多项式展开)、非数值型变量处理(hash、按统计量转换、one-hot)、异常值检测、统计量、去除值过于单一的变量、删除缺失率过高的值、填充缺失值、数据离散化(等宽 / 等频 / 聚类)、标准化 / 正则化 / 归一化、索引处理、排序、执行 SQL、hadamard 乘积、特征组合、降维(PCA / 卡方)、特征重要性(随机森林 / 逻辑回归 / xgboost,计算 IV、互信息、方差等)、特征向量相关性、数据拆分、采样(随机 / 分层 / 过采样 / 欠采样) - 数据处理工具:【商业版】Hadoop 模板支持 HDFS、Hive、Spark 命令;volcanojob / ray 分布式数据处理 - 【商业版】文本处理:清理异常数据、过滤数据、替换隐私数据 - 【商业版】图像数据处理:去噪声、缩放、标准化、裁剪、均衡化、空间转换、变换(旋转 / 平移 / 缩放 / 翻转) - 传统机器学习:ray-sklearn 分布式、xgb 单机训练推理 - 【商业版】传统机器学习算法:ar/arima 时间序列、random-forest、random-forest-regression、lr、lightgbm、knn、kmean、gbdt、decision-tree、pca、lda、catboost、xgb、超参搜索 - 分布式深度学习框架:tf / pytorch;【商业版】mxnet / horovod / paddlejob / mindspore 分布式训练 - 【商业版】分布式加速框架:mpi / colossalai / deepspeed / horovod / megatron - 【商业版】模型处理:模型评估、模型格式转换 - 模型服务化:模型注册;【商业版】模型离线推理、模型注册到 AIHub;模型部署 - 媒体分布式处理:分布式媒体下载、视频提取图片 **算子自定义** - 支持算子自定义,通过 Web 界面操作将自定义算法代码镜像注册为可被他人复用的 pipeline 算子 - 【商业版】自定义任务模板额外支持 int / float / list / bool / json 型,子类型支持 workdir 类型、image 类型,支持参数 tip 提醒 **自动学习** - 面向非 AI 背景的用户提供自动学习服务,选择场景后上传训练数据即可自动开始训练和模型部署 - 【商业版】支持示例 automl 任务流导入导出 **自定义镜像** - 面向高级 AI 开发者,提供自定义训练作业(执行环境 + 代码)功能 **自动调参** - 基于单机 / 【商业版】分布式自动超参搜索 **TensorBoard 作业** - 【商业版】实时 / 离线观察模型训练过程中的参数和指标变化情况 ### 模型管理 / 推理服务 **内部服务** - 支持快捷部署开发或运维工具,提供 mysql-web、postgresql-web、mongo-web、redis-web、neo4j、rstudio 等开源工具 - 【商业版】支持 ollama、xinference 大模型推理 **模型管理** - 模型多版本管理,支持模型发布为推理服务 - 【商业版】支持模型指标可视化 **推理服务** - 支持 【商业版】ml / tf / pytorch / tensorrt / onnx 常规模型的多版本 0 代码发布 - 支持 GPU 卡型选择;【商业版】支持 vGPU、独占、共享占用 - 支持 CPU/MEM/【商业版】GPU 等弹性伸缩;【商业版】支持服务优先级 - 支持远程模型路径、流量分流、流量复制、sidecar 配置、泛域名配置、配置文件挂载,启动目录 / 命令 / 环境变量 / 端口 / 指标 / 健康检查等;支持调试 / 测试 / 生产环境;支持域名 / IP 代理多种形式 - 支持服务负载指标监控 - 支持多版本服务滚动升级和回滚;【商业版】支持单 Pod 滚动发布、禁用 K8s service 负载均衡器、大模型分布式推理 - 提供 【商业版】ml / tf / pytorch / tensorrt / onnx 常规模型推理服务镜像,支持用户自定义模型推理镜像 - 【商业版】支持定时伸缩容、配置服务的 JWT 认证功能、推理服务在线测试 ### 监控 **整体资源** - 所有集群、所有计算机器的使用情况(所属集群、所属资源组、机器 IP、CPU/GPU 类型和卡型、当前 CPU/内存/GPU 使用率) - 所有集群、所有计算 Pod 的使用情况(所属集群、资源组、命名空间、调度 IP、Pod 名称、启动用户、CPU/GPU/内存 申请使用率) - 【商业版】整体资源页面支持管理员批量删除 **监控体系** - 所有机器的 GPU 资源使用情况 - 所有机器的内存 / CPU / 网络 IO / 磁盘 IO 负载情况 - 所有 Pod 的内存 / CPU / GPU / 网络 IO 负载情况 - 所有推理服务的内存 / CPU / GPU / QPS / 吞吐 - 【商业版】支持 IB 流量监控、vGPU 负载情况、NPU 监控 - 【商业版】支持首页消息提醒,支持企业微信、钉钉、飞书群聊消息推送 > 监控底层基于 Prometheus + Grafana + Prometheus Operator 实现,详见 [监控体系](监控体系/README.md)。 ### 模型应用市场(AIHub) 以下均为 **【商业版】** 特性: - **模型应用管理方案**:提供 cube-studio SDK,提供模型开发规范和使用规范;提供 Web 端模型应用体验,支持同步 / 异步推理;提供多个 Python CUDA 版本的基础镜像 - **预训练模型**:提供视觉、听觉、NLP、多模态等 400+ 预训练模型,提供模型加载和推理能力,可一键部署服务并提供 API - **模型市场**:AIHub 应用对接 CubeStudio 平台进行卡片式展示 - **模型一键开发**:一键转 notebook 开发,提供符合当前模型所需环境的 Jupyter - **模型一键微调**:一键转 pipeline 微调链路(示例数据集下载、微调、模型注册、模型部署),支持微调后模型部署 - **模型一键部署 Web**:提供手机端和 PC 端 Web 界面和 API,以及 demo 示例弹窗演示 - **模型自动化标注**:支持部署对接 labelstudio 自动化标注 - **数据集 SDK**:支持通过 Python SDK 搜索 / 上传 / 下载数据集,支持加解密 / 解压缩 / 基础信息查看 - **notebook SDK**:支持通过 API 对接 CubeStudio 创建 notebook 并跳转到指定目录 - **pipeline 训练 SDK**:提供 Python SDK 进行 pipeline 任务流管理、训练任务启动及任务流编排 - **推理服务 SDK**:提供 Python SDK 对接 CubeStudio 进行推理服务发布、服务升级 ### 大模型 以下均为 **【商业版】** 特性: - **大模型分布式多机多卡**:分布式多机多卡训练和加速框架 mpi / colossalai / deepspeed / horovod / megatron / mindformer / mxnet / paddlejob / mindspore 分布式训练 - **大模型推理(AIHub 形式)**:支持 openjourney / gpt3 / yuan / sd-v2 / sd-v1.5 / Stable Cascade / Stable Diffusion XL / chatglm / chatglm2 / chatglm3 / llama / qwen / baichuan2 / gemma / yi / aquilachat2 部署 - **大模型推理**:支持 vLLM 大模型推理,支持推理加速 + 流式 OpenAI 接口;支持分布式多机多卡 vLLM 推理;支持 MindIE 昇腾大模型推理服务(支持 910b 和 310p 算力);deepseek、qwen2、chatglm4 等模型推理示例;支持 LLM 大模型服务对话测试;支持 open-webui sidecar;支持 NPU 适配的 vLLM 推理 - **大模型微调**:支持 deepseek / chatglm4 / qwen2 / baichuan2 LoRA 微调、mindformers 微调,支持 llama-factory 大模型微调,支持 NPU 适配的 llama-factory - **智能对话**:多场景对话,支持提示词构建、推理接口配置、LLM 问答,支持问询中模型切换 / 清理 / 历史上下文 - **私有知识库**:私有知识库配置与召回;支持召回列表模式;支持 AIGC 模式;支持微信公众号 / 服务号对接;支持企业微信群聊机器人对接;支持钉钉群聊机器人对接 --- > 本清单为产品维度的功能对照,用于版本选型与采购评估;具体功能的技术细节、配置项与默认值请以对应专题文档与源码为准。商业版功能持续更新,最终以管理员提供的最新清单为准。 --- ### Prometheus 与 Operator 架构 - 链接: https://www.cubestudio.vip/docs/01-%E6%9E%B6%E6%9E%84%E5%8E%9F%E7%90%86/%E7%9B%91%E6%8E%A7%E4%BD%93%E7%B3%BB/01-Prometheus%E4%B8%8EOperator%E6%9E%B6%E6%9E%84 - 分类: 01-架构原理 / 监控体系 - 适用场景: 想理解 Prometheus 各组件职责,以及 Prometheus Operator 如何在 K8s 中管理监控对象时读这篇 - 关键词: Prometheus / Prometheus Operator / exporter / pushgateway / Prometheus Server / Alertmanager / Grafana / ServiceMonitor / CRD / Target / PromQL / 架构 - 最后更新: 2026-06-30 # Prometheus 与 Operator 架构 ## Prometheus 架构 ![Prometheus 架构](https://foruda.gitee.com/images/1700636611752169254/7032c748_1019082.png "屏幕截图") 各组件职责: 1. **pushgateway**:用来接收业务推送的数据,形成 metrics 接口。 2. **exporter**:用来监控组件(三方中间件)并形成 metrics 接口的组件的统称,负责收集目标对象(host、container…)的性能数据,并通过 HTTP 接口供 Prometheus Server 获取。 3. **Prometheus Server**:Prometheus 的核心,相当于时间序列数据库,负责从 Exporter 拉取和存储监控数据,并提供一套灵活的查询语言(PromQL)供用户使用。Prometheus Server 本身也提供了自己的 metrics 接口。 4. **Alertmanager**:报警装置(Prometheus 配置报警事件的采集规则,Alertmanager 配置报警信息的发送规则)。用户可以定义基于监控数据的告警规则,规则会触发告警。一旦 Alertmanager 收到告警,会通过预定义的方式发出告警通知。 5. **Grafana**:监控可视化报表组件。不仅支持 Prometheus,还支持很多三方数据库。 ## Prometheus Operator 架构 ![Prometheus Operator 架构](https://foruda.gitee.com/images/1700636630543751571/44de54fd_1019082.png "屏幕截图") 各组件职责: **Operator** Operator 即 Prometheus Operator,在 Kubernetes 中以 Deployment 运行。其职责是部署和管理 Prometheus Server,根据 ServiceMonitor 动态更新 Prometheus Server 的监控对象。 **Prometheus Server** Prometheus Server 会作为 Kubernetes 应用部署到集群中。为了更好地在 Kubernetes 中管理 Prometheus,CoreOS 的开发人员专门定义了一个命名为 Prometheus 类型的 Kubernetes 定制化资源。可以把 Prometheus 看作是一种特殊的 Deployment,它的用途就是专门部署 Prometheus Server。 **Service** 这里的 Service 就是 Cluster 中的 Service 资源,也是 Prometheus 要监控的对象,在 Prometheus 中叫做 Target。每个监控对象都有一个对应的 Service。比如要监控 Kubernetes Scheduler,就得有一个与 Scheduler 对应的 Service。Kubernetes 集群默认没有这个 Service,Prometheus Operator 会负责创建。 **ServiceMonitor** Operator 能够动态更新 Prometheus 的 Target 列表,ServiceMonitor 就是 Target 的抽象。比如想监控 Kubernetes Scheduler,用户可以创建一个与 Scheduler Service 相映射的 ServiceMonitor 对象。Operator 则会发现这个新的 ServiceMonitor,并将 Scheduler 的 Target 添加到 Prometheus 的监控列表中。 ServiceMonitor 也是 Prometheus Operator 专门开发的一种 Kubernetes 定制化资源类型。 **Alertmanager** 除了 Prometheus 和 ServiceMonitor,Alertmanager 是 Operator 开发的第三种 Kubernetes 定制化资源。可以把 Alertmanager 看作是一种特殊的 Deployment,它的用途就是专门部署 Alertmanager 组件。 > 与代码一致:本平台监控相关 CRD 与组件部署清单位于 `install/kubernetes/prometheus/`,包括 `operator/`(Operator + CRD)、`prometheus/`(Prometheus Server + rules + secret)、`alertmanater/`(Alertmanager)、`servicemonitor/`(各类 ServiceMonitor)等子目录,统一部署在 `monitoring` 命名空间。 --- ### 机器与容器监控(node-exporter / kubelet / dashboard) - 链接: https://www.cubestudio.vip/docs/01-%E6%9E%B6%E6%9E%84%E5%8E%9F%E7%90%86/%E7%9B%91%E6%8E%A7%E4%BD%93%E7%B3%BB/02-%E6%9C%BA%E5%99%A8%E4%B8%8E%E5%AE%B9%E5%99%A8%E7%9B%91%E6%8E%A7 - 分类: 01-架构原理 / 监控体系 - 适用场景: 想监控物理机 / 容器资源使用、或导入机器与容器监控看板时读这篇 - 关键词: node-exporter / 机器监控 / 容器监控 / kubelet / cAdvisor / metrics / grafana dashboard / dashboard 导入 / CPU / 内存 / 网络 / KUBELET_AUTHZ_ARGS / authentication-token-webhook - 最后更新: 2026-06-30 # 机器与容器监控 ## 监控机器使用情况(node-exporter) Node exporter 主要用于暴露 metrics 给 Prometheus,其中 metrics 包括:CPU 的负载、内存的使用情况、网络等。 在 Prometheus 自带的机器监控中,可以选中目标机器 IP 获取指标数据。 ![机器监控](https://foruda.gitee.com/images/1700636651600636519/e9cd127e_1019082.png "屏幕截图") 为了方便一次性查看所有机器,仓库里也提供了 dashboard 的 JSON 文件,自己导入即可。 ![所有机器看板](https://foruda.gitee.com/images/1700636795437831834/38b13910_1019082.png "屏幕截图") > 与代码一致:本仓库 dashboard JSON 位于 `install/kubernetes/prometheus/grafana/dashboard/`(机器相关有 `node.json`、`all-node.json`,Pod/容器相关有 `pod-info.json`,集群利用率有 `cluster-used-util.json`、`cluster-req-util.json`,GPU 有 `dcgm.json`、`npu.json` 等)。原文提到的 "prometheus/grafana-dashboard 文件夹" 在本仓库即此路径。node-exporter 的部署清单见 `install/kubernetes/prometheus/node-exporter/`。 ## 监控容器使用情况(kubelet) 容器的监控在 kubelet 中。有些部署方式 kubelet 启动时会提供 metrics 接口,有些部署方式默认没有启动。 如果你的 kubelet 没有提供 metrics 接口,需要修改启动参数: ```bash # /etc/systemd/system/kubelet.service.d/ Environment="KUBELET_AUTHZ_ARGS=--authentication-token-webhook=true --authorization-mode=Webhook --client-ca-file=/etc/kubernetes/pki/ca.crt" # 重启 kubelet service kubelet restart ``` > 与代码一致:部署 kubelet 监控前需确保每个节点的 kubelet 添加了 `authentication-token-webhook=true` 和 `authorization-mode=Webhook` 参数(见 `install/kubernetes/prometheus/readme.md`)。kubelet 的 ServiceMonitor 为 `install/kubernetes/prometheus/servicemonitor/kubelet-sm.yml`。 仓库的部署文件中已经包含了 kubelet 的 metrics 采集和看板显示,也开源了容器监控的 dashboard 对应的 JSON 文件,自己可以配置 top 榜单便于排查问题。 ![容器监控](https://foruda.gitee.com/images/1700636825731122842/3148de76_1019082.png "屏幕截图") --- 机器级别和业务(容器)级别的监控介绍完后,接下来介绍不同类型组件的监控,见 [入口流量与中间件监控](03-入口流量与中间件监控.md)。 --- ### 入口流量与三方中间件监控 - 链接: https://www.cubestudio.vip/docs/01-%E6%9E%B6%E6%9E%84%E5%8E%9F%E7%90%86/%E7%9B%91%E6%8E%A7%E4%BD%93%E7%B3%BB/03-%E5%85%A5%E5%8F%A3%E6%B5%81%E9%87%8F%E4%B8%8E%E4%B8%AD%E9%97%B4%E4%BB%B6%E7%9B%91%E6%8E%A7 - 分类: 01-架构原理 / 监控体系 - 适用场景: 想监控集群入口流量时延 / 吞吐,或监控 Kafka 等三方中间件时读这篇 - 关键词: 入口流量 / Gateway / 网关 / ingress-nginx / OpenResty / Kong / Service Mesh / 服务网格 / istio / linkerd / linkerd2 / sidecar / 中间件 / exporter / kafka / 三方中间件 - 最后更新: 2026-06-30 # 入口流量与三方中间件监控 ## 监控入口流量、时延等信息 入口流量监控有多种方式,非侵入式的主要有 **Service Mesh** 和**网关**两类: - 如果只需要监控总入口的流量吞吐和时延,或者并没有复杂的微服务调用链、不需要监控 service 之间的调用情况,可以使用网关来实现。 - 如果需要在微服务之间追踪查看调用,可以使用 Service Mesh 来实现。 ### Gateway 监控 OpenResty 是用 Lua 语言编写 nginx 插件的 Web 服务和动态网关框架。比如 K8s 的 ingress-nginx 就是 OpenResty 应用:,也可以使用另一个网关应用插件 Kong:。 ingress-nginx 新版本已经集成了指标监控。ingress-nginx 的部署、监控启用和配置可以按照 GitHub 官网操作。这里贴一下效果图。 ![ingress-nginx 监控1](https://foruda.gitee.com/images/1700636852657226254/cca59fc7_1019082.png "屏幕截图") ![ingress-nginx 监控2](https://foruda.gitee.com/images/1700636872328647096/b1a0a187_1019082.png "屏幕截图") > 与代码一致:本仓库提供 Kong 的 ServiceMonitor(`install/kubernetes/prometheus/servicemonitor/kong-sm.yml`)。 ### Service Mesh 监控 可以使用 istio 或 linkerd2 来实现。由于配置服务网格会添加 sidecar 容器到业务容器旁边,比较麻烦,所以这里只给一个 linkerd2 的监控效果图。 ![linkerd2 监控](https://foruda.gitee.com/images/1700636889830148414/188b247c_1019082.png "屏幕截图") > 与代码一致:本仓库提供 istio 的 ServiceMonitor(`install/kubernetes/prometheus/servicemonitor/istio-sm.yml`)和 istio 服务看板(`install/kubernetes/prometheus/grafana/dashboard/istio-service.json`)。 ## 监控三方中间件(exporter) 习惯上将监控中间件、形成 metrics 接口的组件称作 **exporter**。官方支持了很多三方中间件的 exporter 组件: 比如想监控 Kafka,可以直接在页面上跳转到 kafka exporter 的 GitHub。这些 exporter 仓库一般都提供了 Docker 版本,需要自己封装成 K8s 的 Deployment,并配置 K8s Service,为该 exporter 的 Service 打上 label,使用 [ServiceMonitor](05-ServiceMonitor配置与调试.md) 将监控添加到 Prometheus 中,并且将仓库中的 Grafana 看板配置到 Grafana 中。 ![中间件 exporter](https://foruda.gitee.com/images/1700636918454104879/62294129_1019082.png "屏幕截图") --- ### 自定义指标与自研 pushgateway - 链接: https://www.cubestudio.vip/docs/01-%E6%9E%B6%E6%9E%84%E5%8E%9F%E7%90%86/%E7%9B%91%E6%8E%A7%E4%BD%93%E7%B3%BB/04-%E8%87%AA%E5%AE%9A%E4%B9%89%E6%8C%87%E6%A0%87%E4%B8%8Epushgateway - 分类: 01-架构原理 / 监控体系 - 适用场景: 想用 pushgateway 推送业务指标、或自己写 /metrics 接口、或了解平台告警推送代理接口时读这篇 - 关键词: pushgateway / 自定义指标 / custom metrics / 报警代理 / webhook / prometheus_client / flask / aiohttp / Counter / Gauge / /metrics / 消息推送 / wechat / username_group / 企业微信 - 最后更新: 2026-07-09 # 自定义指标与自研 pushgateway ## 官方 pushgateway 及其弊端 官方的 pushgateway 是这样的: ![官方 pushgateway](https://foruda.gitee.com/images/1700636943171542308/5fd62765_1019082.png "屏幕截图") 在使用之前,有必要了解一下官方 pushgateway 的一些弊端: - 将多个节点数据汇总到 pushgateway,如果 pushgateway 挂了,受影响比多个 target 大。 - Prometheus 拉取状态 up 只针对 pushgateway,无法做到对每个节点有效。 - pushgateway 可以持久化推送给它的所有监控数据。当 Prometheus 把数据拉取以后,这些数据仍然留在 pushgateway,不会被自动删除,下一次拉取又会被拉取到 Prometheus 中。 - pushgateway 在接收到同一个 metric 的后一次推送时,会把前一次的内容删除掉。 - pushgateway 客户端在推送数据到 pushgateway 服务器端以后,必须将不同 label 下的数据清理或者置为 0,不然会有叠加效果。 ## 自研 pushgateway 与报警推送代理 由于 Alertmanager 在内网中消息推送有些故障,以及官方 pushgateway 的上述弊端,平台开源了一个 pushgateway,将 metric 数据收集和消息推送集成在 pushgateway 中。 > 与代码一致:自研 pushgateway 源码位于 `install/kubernetes/prometheus/pushgateway/`(`server.py` 基于 aiohttp 实现),K8s Service 名为 `cloud-pushgateway-service`,部署在 `monitoring` 命名空间,镜像 `ccr.ccs.tencentyun.com/cube-studio/prometheus:pushgateway`(见 `pushgateway/deploy.yaml` / `service.yaml`)。 ### 报警推送代理接口 POST 访问接口 `/{client}/webhook`(`{client}` 为来源标识,源码支持 `grafana` / `alertmanager` / `rancher` / `superset` 等,会按来源裁剪/格式化消息体)。 参数: | 参数 | 类型 | 说明 | |---|---|---| | `sender_type` | 字符串 | 推送类型,目前支持 `wechat` 和 `username_group` | | `sender` | 字符串 | 推送者(微信推送时如 `TME_DataInfra`;企业微信群推送时为企业微信机器人 key) | | `username` | 字符串 | 接收用户(逗号分隔多用户)。微信推送时为 username;企业微信群推送时为空 | | `message` | 字符串 | 推送字符串。如果有 message 字段,则仅推送 message 字段;否则除上面之外的所有字段会 JSON 序列化为 message 推送 | > 与代码一致(`pushgateway/server.py`): > - `sender_type=wechat` → `push_wechat()`:微信公众号告警指向个人推送,通过 `Sender`(发送者) + `Rcptto`(接收者列表) 调用内网微信接口。 > - `sender_type=username_group` → `push_username_group()`:企业微信群推送,`sender` 为企业微信群聊机器人的 key,调用企业微信群机器人 webhook。 > - 接口实参不区分大小写匹配 `username` / `sender_type` / `sender`,可放在 query 或 JSON body 中。 > 说明:与本仓库 `pushgateway/server.py` 参数语义一致——接收用户字段在源码中读取的是 `username` 键并赋给内部 `Receiver` 变量(见 `install/kubernetes/prometheus/pushgateway/server.py:119-128`)。 > 指标推送(非告警)接口为 POST `/metrics`,推送数据格式(metric 的 label/data、`exist_update_type`/`not_exist_update_type` 等处理策略)详见 `install/kubernetes/prometheus/pushgateway/README.md`。 ## 监控业务自定义数据(Python 自定义 metrics) 如果通用监控无法满足需求,可以自己编写 metrics 接口。下面以 Python 为例(flask 版本和 aiohttp 版本)。 > 说明:原文提到的 `python-metric` 目录在本商业版仓库中未找到(属于开源 CubeStudio 仓库的示例)。本仓库中可参考的 aiohttp 实现是自研 pushgateway 的 `install/kubernetes/prometheus/pushgateway/server.py`。下方为通用示例代码。 ### flask 版本 ```python pip install flask pip install prometheus_client import prometheus_client from prometheus_client import Counter from prometheus_client.core import CollectorRegistry from flask import Response, Flask #### @app.route("/metrics") def ApiResponse(): muxStatus.set(muxCode) manageStatus.set(manageCode) return Response(prometheus_client.generate_latest(REGISTRY), mimetype="text/plain") ``` ### aiohttp 版本 ```python pip install asyncio pip install aiohttp pip install prometheus_client import prometheus_client from prometheus_client import Counter, Gauge from prometheus_client.core import CollectorRegistry from aiohttp import web import aiohttp import asyncio import random, logging, time, datetime routes = web.RouteTableDef() # metrics @routes.get('/metrics') async def metrics(request): requests_total.inc() # requests_total.inc(2) data = prometheus_client.generate_latest(requests_total) return web.Response(body=data, content_type="text/plain") ``` ### 形成的 metrics 接口 ``` # HELP face_search_metric face search metrics # TYPE face_search_metric gauge face_search_metric{method="POST",path="/vesionbook/v1.0/user/feature",project="vesionbook"} 11.0 face_search_metric{method="POST",path="/vesionbook/v1.0/user/search",project="vesionbook"} 11.0 ``` 形成 metrics 接口后,再通过 [ServiceMonitor](05-ServiceMonitor配置与调试.md) 将其采集到 Prometheus 中。 --- ### ServiceMonitor 配置与调试 - 链接: https://www.cubestudio.vip/docs/01-%E6%9E%B6%E6%9E%84%E5%8E%9F%E7%90%86/%E7%9B%91%E6%8E%A7%E4%BD%93%E7%B3%BB/05-ServiceMonitor%E9%85%8D%E7%BD%AE%E4%B8%8E%E8%B0%83%E8%AF%95 - 分类: 01-架构原理 / 监控体系 - 适用场景: 想把一个已暴露 /metrics 的服务接入 Prometheus、或排查 ServiceMonitor 没采集到数据时读这篇 - 关键词: ServiceMonitor / servicemonitor / k8s-app / endpoints / selector / Target / Service Discovery / Graph / 非 k8s 应用 / prometheus.yml / configmap / recording rules / alerting rules / scrape_configs / 调试 - 最后更新: 2026-06-30 # ServiceMonitor 配置与调试 通过 exporter / pushgateway / 自定义 metric / ingress-nginx / node-exporter / kubelet,都已经形成 metrics 接口,并且有对应的 Service 提供服务。我们可以通过这个 Service 查看组件是否采集到数据。要把这些数据采集到 Prometheus 中,就需要编写 ServiceMonitor 文件。 ## ServiceMonitor 写法 ```yaml apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: labels: k8s-app: app1 # 这里必须是 k8s-app,不然 prometheus 采集不了该资源 name: app1 namespace: monitoring spec: endpoints: - interval: 30s path: /metrics port: http # 端口号只能是字符串,是 pod 中定义的端口 name jobLabel: k8s-app namespaceSelector: matchNames: - yournamespace selector: matchLabels: app: app1 # 匹配 service ``` > 与代码一致:本仓库 ServiceMonitor 集中在 `install/kubernetes/prometheus/servicemonitor/`,约定 `metadata.labels.k8s-app` 必须存在(Prometheus 按此 label 查找,否则采集不到),`spec.selector.matchLabels` 匹配目标 Service。可参考 `cloud-pushgateway-sm.yml`、`kubelet-sm.yml`、`node-exporter-sm.yml`、`istio-sm.yml`、`kong-sm.yml` 等。 ## 监控非 K8s 内应用 对于 K8s 内的应用,可以通过上面的 ServiceMonitor 采集 Service 暴露的 metrics 接口;对于非 K8s 内的应用,需要自己编写 Prometheus 的配置文件。 其实上面的监控也是通过 prometheus-operator 自动生成 Prometheus 的配置文件,类似可参考下面的 ConfigMap。需要自己熟悉 Prometheus 的记录规则(recording rules)与报警规则(alerting rules)。 ```yaml apiVersion: v1 kind: ConfigMap metadata: labels: app: prometheus-7.3.0 name: prometheus-config namespace: monitoring data: prometheus.yml: | global: evaluation_interval: 15s scrape_interval: 15s scrape_timeout: 10s alerting: alertmanagers: - static_configs: - targets: # - alertmanager:9093 rule_files: # prometheus-rules.yaml # - "first_rules.yml" # - "second_rules.yml" scrape_configs: - job_name: prometheus static_configs: - targets: - localhost:9090 ``` > 与代码一致:本仓库的记录 / 报警规则文件为 `install/kubernetes/prometheus/prometheus/prometheus-rules.yml` 和 `prometheus-rules-more.yaml`。 ## 配置 ServiceMonitor 后调试 在配置 ServiceMonitor 之前,要先通过 `curl service:port/metrics` 查看是否正常采集了数据。如果正常采集了数据,后面的监控才能正常。 1. 配置了 ServiceMonitor 以后,稍微等一两分钟,可以在 Prometheus 中查看是否配置成功。如果 Configuration 中包含了你的 ServiceMonitor 相关配置(解析成 Prometheus 配置以后的样子),才表示你的 SM 配置语法正确,并且配置同步到了 Prometheus 中。 ![Prometheus Configuration](https://foruda.gitee.com/images/1700636966472351541/af3ca33a_1019082.png "屏幕截图") 2. 进入 **Service Discovery**,可以看到你配置的 ServiceMonitor 匹配到了多少个 Pod。(注意:由于 ServiceMonitor 文件中匹配的是 Service,Prometheus 会自动获取 Service 下面绑定的 Pod,并将 Pod 作为 metrics 接口的访问地址,并且会随着 Service 下 Pod 的变更而变更。) ![Service Discovery](https://foruda.gitee.com/images/1700636986648167707/95511d2f_1019082.png "屏幕截图") 3. 进入 **Targets**,查看每个 Pod 的 metrics 接口是否能正常拿到数据。如果能拿到数据,Pod 状态为绿色。 ![Targets](https://foruda.gitee.com/images/1700637009543133614/f1a15a2d_1019082.png "屏幕截图") 4. 有了数据就可以在 **Graph** 中查看到指标数据,并配置 Grafana 了(见 [告警与 Grafana](06-告警与Grafana.md))。 --- ### 告警(Alertmanager)与 Grafana 可视化 - 链接: https://www.cubestudio.vip/docs/01-%E6%9E%B6%E6%9E%84%E5%8E%9F%E7%90%86/%E7%9B%91%E6%8E%A7%E4%BD%93%E7%B3%BB/06-%E5%91%8A%E8%AD%A6%E4%B8%8EGrafana - 分类: 01-架构原理 / 监控体系 - 适用场景: 想配置 Prometheus 告警推送、或安装 Grafana 插件 / 配置看板 / 接其他数据源时读这篇 - 关键词: Alertmanager / 告警 / 报警 / secret / base64 / route / receiver / webhook / inhibit_rules / 告警抑制 / Grafana / 插件 / plugins / dashboard / datasource / 数据源 / Alert / grafana-cli / 9.5.20 - 最后更新: 2026-06-30 # 告警(Alertmanager)与 Grafana 可视化 ## Alertmanager 配置报警 报警的配置文件在 K8s 中是通过 secret 来配置的,需要先生成配置文件的 base64 编码。 ```python import base64 # alert 报警的 secret # 换行都会变换 base64 编码后的格式 config=''' global: resolve_timeout: 5m templates: - '/etc/alertmanager/template/*.tmpl' route: group_by: ['alertname', 'cluster', 'service'] group_wait: 30s group_interval: 5m repeat_interval: 1h receiver: 'null' routes: - match: namespace: clickhouse receiver: 'di' - match: namespace: superset receiver: 'pengluan' - match: namespace: infra receiver: 'pengluan' # 告警抑制。避免重复告警。 # https://yunlzheng.gitbook.io/prometheus-book/parti-prometheus-ji-chu/alert/alert-manager-inhibit inhibit_rules: - source_match: severity: 'critical' target_match: severity: 'warning' # Apply inhibition if the alertname is the same. equal: ['alertname', 'cluster', 'service'] receivers: - name: 'di' webhook_configs: - send_resolved: true url: 'http://cloud-pushgateway-service.monitoring/alertmanager/webhook?sender_type=username_group&sender=your_key' - name: 'pengluan' webhook_configs: - send_resolved: true url: 'http://cloud-pushgateway-service.monitoring/alertmanager/webhook?sender_type=wechat&username=pengluan' - name: 'null' ''' base64str = base64.b64encode(bytes(config, encoding='utf-8')) print(str(base64str, encoding='utf-8')) ``` 由于 Alertmanager 在内网配置,报警受网络影响,所以 Alertmanager 的报警推送也接入到前面的自研 pushgateway 中(见 [自定义指标与 pushgateway](04-自定义指标与pushgateway.md))。 - `routes` 为要匹配的消息和发送的接收者; - `receivers` 为接收者的配置。这里配置了微信个人(`sender_type=wechat`)和企业微信群(`sender_type=username_group`)接收,企业微信群接收中 `your_key` 为企业微信群聊机器人的 key 值。 > 与代码一致:Alertmanager 的 secret 清单为 `install/kubernetes/prometheus/alertmanater/alertmanager-main-secret.yml`(`alertmanager.yaml` 字段为 base64 编码的上述配置)。仓库还提供 `make-alert-wechat-config.py` / `make-alert-email-config.py` 用于生成配置。Service 名 `cloud-pushgateway-service`、命名空间 `monitoring` 与告警 webhook URL 中的 `cloud-pushgateway-service.monitoring` 一致。 ## Grafana ### 安装插件 Grafana 独立于 Prometheus 之外,由于对 Prometheus 兼容得比较好,一般使用 Grafana 作为 Prometheus 的可视化看板。 Grafana 的数据源、看板都是以插件的形式安装的:。 官方镜像插件如果满足不了需求,需要自己编写 Dockerfile 来安装自己的插件,例如: ```dockerfile FROM grafana/grafana:9.5.20 USER root # clickhouse 数据源 RUN grafana-cli plugins install vertamedia-clickhouse-datasource # 时钟图 RUN grafana-cli plugins install grafana-clock-panel # 饼图 RUN grafana-cli plugins install grafana-piechart-panel # 气泡图 RUN grafana-cli plugins install digrich-bubblechart-panel # 世界地图 RUN grafana-cli plugins install raintank-worldping-app # json 数据 RUN grafana-cli plugins install grafana-simple-json-datasource # zabbix 报警 RUN grafana-cli plugins install alexanderzobnin-zabbix-app # k8s 监控应用 RUN grafana-cli plugins install grafana-kubernetes-app # WindRose 极坐标图 RUN grafana-cli plugins install fatcloud-windrose-panel # 雷达图 RUN grafana-cli plugins install snuids-radar-panel # 世界地图热力图 RUN grafana-cli plugins install ovh-warp10-datasource # 选点监控 RUN grafana-cli plugins install natel-usgs-datasource # es 数据监控 RUN grafana-cli plugins install stagemonitor-elasticsearch-app # Plotly 直角坐标系散点图 RUN grafana-cli plugins install natel-plotly-panel # 组织结构图 RUN grafana-cli plugins install digiapulssi-organisations-panel # ajax 请求更新数据 RUN grafana-cli plugins install ryantxu-ajax-panel ``` 然后重新构建镜像,并在部署 Grafana 中替换成新镜像名。 > 与代码一致:本仓库 Grafana 部署镜像即 `grafana/grafana:9.5.20`(见 `install/kubernetes/prometheus/grafana/grafana-dp.yml`)。数据源配置见 `grafana-datasources.yml` / `grafana-source.yml`,看板 JSON 通过 `all-grafana-dashboards` configmap 从 `grafana/dashboard/` 目录挂载。 ### dashboard 要想成功配置看板,需要几个步骤:1)配置数据源;2)配置 chart;3)配置 dashboard。 ![Grafana dashboard](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/grafana.png) Grafana 的配置是 chart 组成 dashboard 的结构。每个 chart 的配置需要绑定数据源、可视化报表类型、报警配置等。 ### Alert 在 Grafana 监控指标难免要配置报警。在内网部署报警受到一些限制,pushgateway 中封装了报警接口(见 04 篇),所以直接将 Grafana 的报警推送地址接入到 pushgateway 中。 ![Grafana Alert](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/grafana-alert.png) 配置 pushgateway 的接口:`http://cloud-pushgateway-service.monitoring/grafana/webhook?sender_type=wechat`,username 为个人用户名,密码可以不配置。 ### 其他数据源 除了 Prometheus 数据库,Grafana 还支持很多其他数据库。 ![Grafana 数据源](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/grafana-datasource.png) ### 监控业务指标 因为支持更多的数据库,所以也就可以监控数据库中的数据。比如可以监控 ES 中存储的日志,也可以监控 MySQL 中的业务数据。例如下面是监控 MySQL 中的数据指标。 ![Grafana 业务指标](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/grafana-metric.png) --- ### 监控体系总览(Prometheus + Grafana) - 链接: https://www.cubestudio.vip/docs/01-%E6%9E%B6%E6%9E%84%E5%8E%9F%E7%90%86/%E7%9B%91%E6%8E%A7%E4%BD%93%E7%B3%BB/README - 分类: 01-架构原理 / 监控体系 - 适用场景: 想了解平台监控整体架构、各监控组件职责、以及如何接入新监控目标时,从这里入口 - 关键词: 监控 / monitoring / Prometheus / Grafana / Prometheus Operator / ServiceMonitor / Alertmanager / pushgateway / exporter / node-exporter / kubelet / 告警 / 可视化 / 指标 / metrics / PromQL - 最后更新: 2026-07-09 # 监控体系总览(Prometheus + Grafana) CubeStudio 的监控体系基于 **Prometheus + Grafana + Prometheus Operator** 构建,部署在 K8s 的 `monitoring` 命名空间中。本目录按主题拆分为多篇,覆盖从架构原理、各类监控目标接入、自定义指标、ServiceMonitor 配置调试到告警与可视化的全链路。 > 部署清单与 `kubectl apply` 顺序见 `install/kubernetes/prometheus/`(operator → alertmanager → node-exporter → kube-state-metrics → grafana → prometheus → servicemonitor)。具体部署步骤请参考 02-部署安装 段。 ## 整体数据流 1. **采集**:各类 `exporter`(node-exporter、kube-state-metrics、kubelet、ingress-nginx、三方中间件 exporter)和业务 `pushgateway` / 自定义 `/metrics` 接口暴露指标。 2. **抓取**:`Prometheus Server` 按 `ServiceMonitor` / `prometheus.yml` 配置定时拉取(scrape)各 Target 的 metrics。 3. **存储与查询**:Prometheus 作为时序数据库存储数据,提供 PromQL 查询。 4. **管理**:`Prometheus Operator` 根据 ServiceMonitor 等 CRD 动态生成 Prometheus 配置、维护 Target 列表。 5. **告警**:`Alertmanager` 按 route/receiver 规则发送告警;本平台告警与 Grafana 报警统一接入自研 `pushgateway` 的 webhook 代理转发到微信 / 企业微信群。 6. **可视化**:`Grafana` 以 chart 组成 dashboard,绑定 Prometheus(及其他)数据源展示。 ## 子文档目录(TOC) | 序号 | 文档 | 内容 | |---|---|---| | 01 | [Prometheus 与 Operator 架构](01-Prometheus与Operator架构.md) | Prometheus 基础架构(pushgateway/exporter/server/alertmanager/grafana)、Prometheus Operator 架构(Operator / Prometheus / Service / ServiceMonitor / Alertmanager) | | 02 | [机器与容器监控](02-机器与容器监控.md) | node-exporter 机器监控、kubelet 容器监控、grafana-dashboard 导入 | | 03 | [入口流量与中间件监控](03-入口流量与中间件监控.md) | Gateway / ingress-nginx、Service Mesh / linkerd、三方中间件 exporter | | 04 | [自定义指标与 pushgateway](04-自定义指标与pushgateway.md) | 官方 pushgateway 弊端、自研 pushgateway 报警代理、Python 自定义 metrics(flask / aiohttp) | | 05 | [ServiceMonitor 配置与调试](05-ServiceMonitor配置与调试.md) | ServiceMonitor 写法、监控非 K8s 应用的 configmap、配置后调试(Targets / Service Discovery / Graph) | | 06 | [告警与 Grafana](06-告警与Grafana.md) | Alertmanager secret / route / receiver、Grafana 插件 / dashboard / Alert / 多数据源 | ## 相关阅读 - 自研 pushgateway 的报警推送接口同时服务于平台告警推送,与 04-运维管理段的监控 / 消息推送相关。 - Prometheus 服务发现、prometheus-adapter(自定义指标 HPA)与推理服务的弹性伸缩相关,见 01-架构原理段平台架构-推理服务相关文档。 --- ## 部署安装(56 篇) ### 部署安装总览(部署方式选择指南) - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/README - 分类: 02-部署安装 / 落地页 - 适用场景: 不知道该选哪种部署方式、想找部署相关文档入口时先读这篇 - 关键词: 部署 / 安装 / deploy / install / 单机部署 / docker-compose / k8s部署 / kubernetes / 私有化 / on-premise / GPU / 存储 / 集群准备 / 前置要求 - 最后更新: 2026-07-04 # 部署安装总览 本段落覆盖 CubeStudio 平台的各种部署方式,以及部署前需要准备的机器、存储、GPU、集群等基础环境。 > 完整文档索引请看 `00-索引/`,本页只做部署相关的导航与“选哪种部署方式”的决策指引。 ## 先读:部署前置要求 无论选择哪种部署方式,都建议先通读前置要求,确认机器规格、操作系统、k8s 版本、存储与网络是否满足。 - [部署总览与前置要求](部署方式/部署总览与前置要求.md) —— 基础环境依赖(docker / kubernetes 版本、机器配置、共享存储、GPU/IB 网络、操作系统),以及平台部署完成后的形态。 - 平台由哪些组件构成、各组件在哪个命名空间、用的哪个版本:见 [01-架构原理/基础组件介绍.md](../01-架构原理/基础组件介绍.md)。 - 平台整体架构与设计原理:见 [01-架构原理/项目简介.md](../01-架构原理/项目简介.md)。 ## 怎么选部署方式 | 场景 | 推荐方式 | 文档 | |---|---|---| | 个人本地体验 / 二次开发调试,仅需 web 端功能,不需要真正调度 k8s 任务 | docker-compose 本地部署 | [单机部署-docker-compose](部署方式/单机部署-docker-compose/README.md) | | 单台 / 少量机器上跑完整平台(含真实 k8s 任务调度、notebook、推理服务) | 单机 k8s 部署(rancher 起 k8s + start.sh 部署平台) | [单机 k8s 部署](部署方式/单机部署-docker-compose/01-单机k8s部署.md) | | 已有 k8s 集群,直接部署平台 | 已有 k8s 部署(start.sh) | [单机 k8s 部署 · 对于已有 k8s 的同学](部署方式/单机部署-docker-compose/01-单机k8s部署.md) | | 隔离内网 / 离线环境 | 离线部署(基于已有 k8s 部署流程 + 离线镜像) | [单机 k8s 部署 · 隔离内网](部署方式/单机部署-docker-compose/01-单机k8s部署.md) | > 说明:docker-compose 方式只起前端、后端、mysql、redis 四个容器,适合开发调试与功能体验;它**不会**在本机起一个 k8s 集群,发起真实 pipeline / notebook / 推理任务仍需连接一个 k8s 集群(见 docker-compose 文档中的“本地连接 k8s 集群”小节)。 ## 部署方式子目录 - [部署方式/部署总览与前置要求.md](部署方式/部署总览与前置要求.md) - [部署方式/单机部署-docker-compose/](部署方式/单机部署-docker-compose/README.md) - [01-单机k8s部署.md](部署方式/单机部署-docker-compose/01-单机k8s部署.md) - [02-docker-compose本地部署.md](部署方式/单机部署-docker-compose/02-docker-compose本地部署.md) - [03-本地开发与调试.md](部署方式/单机部署-docker-compose/03-本地开发与调试.md) ## 相关运维文档(部署后会用到) - 配置文件管理:[04-运维管理/配置文件管理.md](../04-运维管理/配置文件管理.md) - 私有镜像仓库 Harbor:[04-运维管理/私有镜像仓库Harbor.md](../04-运维管理/私有镜像仓库Harbor.md) - 分布式存储目录:[04-运维管理/分布式存储目录.md](../04-运维管理/分布式存储目录.md) - 平台 HTTPS 配置:[04-运维管理/平台HTTPS配置.md](../04-运维管理/平台HTTPS配置.md) - 元数据库(MySQL / PG / 达梦 / Kingbase):[04-运维管理/元数据库配置.md](../04-运维管理/元数据库配置.md) - 端口使用情况:[04-运维管理/端口使用情况.md](../04-运维管理/端口使用情况.md) > 本页为导航页,具体部署命令与参数以源码(`install/`、`install/docker/`、`install/kubernetes/`)为准,仅供导航。 --- ### 部署后初步验证(pipeline/notebook/推理/超参/AIHUB/数据智能/标注) - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/%E9%83%A8%E7%BD%B2%E9%AA%8C%E8%AF%81 - 分类: 02-部署安装 / 部署验证 - 适用场景: 平台部署完成后,想逐项确认各核心功能(流水线/在线开发/推理/AutoML/AIHUB/数据智能/标注)是否正常时按这篇逐步验证 - 关键词: 部署验证 / 初步验证 / 冒烟测试 / smoke test / 验收 / pipeline验证 / notebook验证 / 推理服务验证 / 超参搜索验证 / AIHUB验证 / 数据智能验证 / 标注平台验证 / yolo26 / DAMOYOLO / 服务代理 - 最后更新: 2026-07-09 # 部署后初步验证 平台部署完成后,按以下各项逐步验证核心功能是否可用。其中第 5 项及之后为商业版需要额外验证的内容。 ## 1. pipeline 验证 1. 登录 CubeStudio 首页,用户名密码用 `admin` / `admin`; 2. 点击首页的"深度学习:目标识别训练部署" pipeline; 3. 进入 pipeline 界面后,点击右上角的"运行",等待运行结束,查看是否能运行成功。 ## 2. notebook 验证 1. 进入菜单栏"在线开发",点击"代码开发"-"notebook"; 2. 点击示例 notebook 的"reset"按钮; 3. 刷新界面,等 notebook 状态变为"Running",点击名称进入 notebook,能打开 notebook 界面即可。 ## 3. 推理服务验证 1. pipeline 验证中的 pipeline 运行结束后,会自动在"服务化"-"模型服务"-"推理服务"中生成一个名为"yolo26"的推理服务; 2. 如果是纯内网环境,直接点击 yolo26 的"部署生产",成功后点击"ip:端口"链接,即可进入服务界面; 3. 如果是内外网环境,点击"项目空间"-"项目分组"-对应项目组的"更多"-"修改",修改"服务代理",填写"内网ip|外网ip",如 `172.16.0.2|175.178.255.97`,再"清理"推理服务,重新"部署生产",即可进入服务界面。 ## 4. 超参搜索验证 1. "模型训练"-"Automl"-"超参搜索",点击"运行",再点击"描述"对应的链接,打开界面,稍等几分钟,刷新,可出现超参搜索界面即可。 2. 商业版多验证一个分布式超参搜索,也是能打开界面即可。 --- > 以下都是商业版需要额外验证的。 ## 5. AIHUB 验证 1. AIHUB 界面,"DAMOYOLO-高性能通用检测模型-S"模型,点击"部署WEB"; 2. 部署之后,试一下弹窗及 WEB 界面是否可使用,可正确使用即为成功。 ## 6. 数据智能验证 1. "数据智能"界面,选择 GPT4 或 GPT4O,问问题能回答即可。 2. 先在 AIHUB 的"自然语言处理"中部署"gpt私有知识库"服务,然后在数据智能中选择"cube-studio",在输入框中输入 `/`,选择任一示例问题,能正确回答即可。 ## 7. 标注平台验证 1. 第 5 步的 AIHUB 验证成功后才可验证标注平台; 2. 打开 k8s dashboard,kubeflow 命名空间下的 labelstudio 的 deployment,编辑,将内网 ip 全部替换为外网 ip + 端口号; 3. "数据资产"-"标注平台",点击标注平台,登录后点击"视觉-目标识别-自动化标注"项目,点击任一图片,能够出现自动化标注的目标框即可。 --- ### 平台版本升级(老版本升级到新版本) - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/%E7%89%88%E6%9C%AC%E5%8D%87%E7%BA%A7 - 分类: 02-部署安装 / 版本升级 - 适用场景: 已部署的 CubeStudio 要升级到新版本前后端时,按这篇做数据库备份、配置对比与滚动部署 - 关键词: 版本升级 / 老版本升级 / upgrade / 升级 / 备份数据库 / kubeflow-dashboard / infra命名空间 / kustomize / kubectl apply -k / overlays / configmap / kubeflow-dashboard-config - 最后更新: 2026-07-04 # 平台版本升级 CubeStudio 前后台的组件在 infra 命名空间下: | 命名空间 | 组件名 | 组件说明 | | :--- | :--- | :--- | | infra | kubeflow-dashboard-frontend | CubeStudio 平台的 web 前端 | | infra | kubeflow-dashboard | CubeStudio 平台的 web 后端 | | infra | kubeflow-dashboard-schedule | 用来调度 CubeStudio 系统自带的调度任务,比如定时清理 | | infra | kubeflow-dashboard-worker | 用来执行 CubeStudio 系统自带的调度任务,比如定时清理 | | infra | kubeflow-watch | 用来监控 CubeStudio 平台中的任务,发起通知和信息更新 | | infra | mysql | 平台元数据的存储 | | infra | redis | 平台缓存,和异步任务对接 | CubeStudio 前后台的部署脚本在 `install/kubernetes/cube/` 下(base + overlays 的 kustomize 结构)。 ## 升级方法 1. 备份数据库,在主机 `/data/k8s/infra/mysql`(MySQL 数据的 hostPath,见 `install/kubernetes/mysql/pv-pvc-hostpath.yaml`)。 2. 配置部署后的配置文件 infra 空间 `kubeflow-dashboard-config-*` 的 configmap(该 configmap 由 kustomize 的 `configMapGenerator` 生成,名字带 hash 后缀,源文件见 `install/kubernetes/cube/overlays/kustomization.yml` 与 `overlays/config/`)。 3. 使用新版本部署 CubeStudio 前后端: ```bash cd install/kubernetes/ && kubectl apply -k cube/overlays ``` 4. 等待启动完成,对比一下老版本的配置文件和新版本的配置的变化,并根据实际情况修改新部署的配置文件(`kubeflow-dashboard-config-*` 的 configmap)。修改配置文件后,重启后台组件。 > 各组件的作用与命名空间归属,见 [01-架构原理/基础组件介绍.md](../01-架构原理/基础组件介绍.md);配置项含义与管理见 [04-运维管理/配置文件管理.md](../04-运维管理/配置文件管理.md)。 --- ### 部署总览与前置要求 - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/%E9%83%A8%E7%BD%B2%E6%96%B9%E5%BC%8F/%E9%83%A8%E7%BD%B2%E6%80%BB%E8%A7%88%E4%B8%8E%E5%89%8D%E7%BD%AE%E8%A6%81%E6%B1%82 - 分类: 02-部署安装 / 部署方式 - 适用场景: 部署平台前先确认机器规格 / 操作系统 / k8s 版本 / 存储 / 网络是否达标时读这篇 - 关键词: 前置要求 / 基础环境依赖 / prerequisites / docker / kubernetes / k8s版本 / 机器配置 / CPU / GPU / V100 / T4 / H800 / A100 / NFS / Ceph / 共享存储 / IB / RDMA / 操作系统 / ubuntu / centos / 部署流程 - 最后更新: 2026-07-04 # 部署总览与前置要求 本篇说明部署 CubeStudio 平台前需要准备的基础环境(机器、存储、网络、操作系统、k8s 版本),是动手部署前的检查清单。 > 平台整体架构、设计原理见 [01-架构原理/项目简介.md](../../01-架构原理/项目简介.md); > 平台由哪些组件构成、各组件所在命名空间与版本,见 [01-架构原理/基础组件介绍.md](../../01-架构原理/基础组件介绍.md)。本篇不再重复架构细节。 ## 平台构成(速览) 完整的平台自底向上包含四层(详见 01-架构原理): 1. 机器的标准化。 2. 分布式存储(单机可忽略)、k8s 集群、监控体系(prometheus / grafana)。 3. 基础能力:tf / pytorch / mxnet / volcano / ray 等分布式训练,nni / ray 超参搜索。 4. 平台 web 部分:OA / 权限 / 项目组、在线构建镜像、在线开发、pipeline 拖拉拽、超参搜索、推理服务管理等。 各命名空间的组件清单(infra / kube-system / kubeflow / istio-system / monitoring / volcano-system / jupyter / service / pipeline / automl 等)统一维护在 [01-架构原理/基础组件介绍.md](../../01-架构原理/基础组件介绍.md),避免与本篇重复。 ## 基础环境依赖 部署前请逐项核对下列依赖: - **docker**:>= 1.19.x,docker 存储目录 > 1T。 - **kubernetes**:1.25 ~ 1.31,建议 1.28。 > ⚠️ 待核实:`install/README.md:49` 写 `1.25~1.31`,而 `docs/部署/平台单机部署.md:4` 写 `1.25~1.32`,两份源文档不一致,请确认平台实际支持的 k8s 版本上限。 - **共享文件系统**(nfs / ceph 等):挂载到每台机器的 `/data/k8s/`,按需扩容,起步建议 SSD 5T(单机可忽略)。参见 [04-运维管理/分布式存储目录.md](../../04-运维管理/分布式存储目录.md)。 - **数据库接口地址**:mysql;没有可忽略,使用 CubeStudio 自带的(元数据库配置见 [04-运维管理/元数据库配置.md](../../04-运维管理/元数据库配置.md))。 - **控制端机器**:CPU >= 16 核,内存 >= 32G,至少 1 台。生产配置:32 核 64G × 2。 - **任务端 CPU / GPU 机器**(按需配置,机器数量按需扩容): - GPU 机器需按对应厂商要求装好驱动。 - 机器学习场景:选 CPU 机器即可,> 32 核 64G × 2。 - 深度学习镜像:训练机器选 V100,推理机器选 T4;每张 GPU 卡配 > 20 核 CPU(如 4 卡服务器建议 > 80 核 CPU)。 - 大模型镜像:训练机器选 H800,推理机器选 A100;每张 GPU 卡配 > 20 核 CPU(如 4 卡服务器建议 > 80 核 CPU)。 - 不要只有 GPU 训练机器,推荐同时配置纯 CPU 服务器。 - **所有机器磁盘**:>= 1T。单机磁盘容量要求不大,仅做镜像 / 容器的存储。 - **IB / RDMA 网络**:自动安装机器驱动和 IB 卡,若无可忽略。相关原理见 [01-架构原理/RDMA网络与分布式训练.md](../../01-架构原理/RDMA网络与分布式训练.md)。 - **操作系统**:ubuntu 20.04 / 22.04 / 24.04,或 centos 7.9 / centos 8。 ## 部署完成后的形态 平台完成部署后的形态如下图: ![单机部署效果](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/danjibushuxiaoguo.png) 平台基础架构图: ![平台基础架构](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/infra.png) ## 多 k8s 集群与本地开发 管理平台 web 端可连接多个 k8s 集群,用来在 k8s 集群上调度发起任务实例。同时管理多个 k8s 集群、或本地调试时,可以把各集群的 kubeconfig 文件存到 kubeconfig 目录中,按 `$ENVIRONMENT-kubeconfig` 的规范命名(如 `install/docker/kubeconfig/dev-kubeconfig`)。 本地开发 / docker-compose 启动 / 前后端构建等过程,见 [单机部署-docker-compose](单机部署-docker-compose/README.md)。 ## 下一步 - 本地体验 / 二次开发调试 → [docker-compose 本地部署](单机部署-docker-compose/02-docker-compose本地部署.md) - 真正在 k8s 上跑完整平台 → [单机 k8s 部署](单机部署-docker-compose/01-单机k8s部署.md) > 具体部署命令与参数以源码(`install/`)为准,本篇仅作前置检查清单。 --- ### 多机/多集群/多资源组部署 - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/%E9%83%A8%E7%BD%B2%E6%96%B9%E5%BC%8F/%E5%A4%9A%E6%9C%BA%E5%A4%9A%E9%9B%86%E7%BE%A4%E5%A4%9A%E8%B5%84%E6%BA%90%E7%BB%84 - 分类: 02-部署安装 / 部署方式 - 适用场景: 单机部署后要扩容成多机集群、对接多个 k8s 集群、或把算力按项目组/资源组划分时读这篇 - 关键词: 多机部署 / 集群扩容 / 多集群 / multi cluster / 多资源组 / resource group / org标签 / 机器label / 节点标签 / node label / CLUSTERS / kubeconfig / kubernetes-config configmap / kubeflow-watch / 算力均衡 / adjust_node_resource / share标签 / 主集群 / 远程集群 - 最后更新: 2026-07-04 # 多机/多集群/多资源组部署 [部署视频(公有云/单机/多机/多集群/分布式存储/私有仓库/GPU/功能初验)](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/tutorial/%E5%95%86%E4%B8%9A%E7%89%88%E9%83%A8%E7%BD%B2%E5%88%9D%E9%AA%8C.mp4) # 配置文件所在地 本地调试时(启动方式:在 `install/docker/` 目录下执行 `docker-compose up`): - k8s 集群的 config 文件:`install/docker/kubeconfig/` 下 - 配置文件 config.py:`install/docker/config.py` - 启动文件 entrypoint.sh:`install/docker/entrypoint.sh` 线上部署时(启动方式:在 `install/kubernetes/` 目录下执行 `kubectl apply -k cube/overlays`): - k8s 集群的 config 文件:`install/kubernetes/kubeconfig/` 下 - 配置文件 config.py:`install/kubernetes/cube/overlays/config/config.py` - 启动文件 entrypoint.sh:`install/kubernetes/cube/overlays/config/entrypoint.sh` # 机器标签管理 机器通过 label 进行管理,所有的调度机器由平台控制,不由用户直接控制。 **开发训练服务机器管理:** - 对于 cpu 的 train/notebook/service 会选择 `cpu=true` 的机器 - 对于 gpu 的 train/notebook/service 会选择 `gpu=true` 的机器 - 对于 vgpu 的 service 会选择 `vgpu=true` 的机器 - 对于 rdma 网络的 pod 会选择 `rdma=true` 的机器 - 训练任务会选择 `train=true` 的机器 - notebook 会选择 `notebook=true` 的机器 - 服务化会选择 `service=true` 的机器 - 不同资源组的任务会选择对应 `org=xx` 的机器,默认为 `org=public` - 可以通过 `gpu-type=xx` 表示 gpu 型号,比如 `gpu-type=V100` 或 `gpu-type=T4`;在配置 gpu 算力时也可同步配置型号,例如 `2(T4)` 表示 2 张 T4 卡。 **控制器机器管理:** - `mysql=true` 部署 mysql 服务的机器 - `redis=true` 部署 redis 服务的机器 - `kubeflow-dashboard=true` 部署 CubeStudio 服务的机器 - `kubeflow=true` 部署 kubeflow 的机器 - `istio=true` 部署 istio 的机器 - `monitoring=true` 部署 prometheus 的机器 > 上述 label 在 `install/kubernetes/start.sh:25` 的 `kubectl label node` 命令里可以看到完整集合(含 `logging=true`)。 --- # 单集群多机 ### 1、分布式存储 需要分布式存储的情况下,要先部署分布式存储:先在每台机器上部署分布式存储,可参考 `install/kubernetes/nfs/NFS离线部署.md` 部署 nfs(主节点部署并配置服务端,其他节点部署配置客户端)。 机器学习平台依赖强 IO 性能的分布式存储。原理参考 [算力统筹与分布式存储](../../01-架构原理/算力统筹与分布式存储.md)。 > !!!重要:分布式文件系统需要挂载到每台机器的 `/data/k8s/` 下面(也可以挂载到其他目录,再以软链形式链接到 `/data/k8s/`)。如果使用 juicefs,则不需要这一步。 需要每台机器都有目录 `/data/k8s` 作为分布式存储目录(juicefs 不需要): ```bash mkdir -p /data/k8s/kubeflow/minio mkdir -p /data/k8s/kubeflow/global mkdir -p /data/k8s/kubeflow/pipeline/workspace mkdir -p /data/k8s/kubeflow/pipeline/archives ``` ### 2、单机完成控制组件部署 在主节点上单机部署 CubeStudio,之后再扩容。参考 [单机部署](单机部署-docker-compose/README.md)。 ### 3、集群扩容 基础准备:主机 `/data/k8s` 目录下需为分布式存储。 **1)初始化机器** 先部署 docker、拉取代码文件。 在新机器上拉取 rancher 镜像: ```bash cd install/kubernetes/rancher sh pull_rancher_images.sh ``` 在新机器上拉取 CubeStudio 镜像: ```bash cd install/kubernetes/ bash init_node.sh ``` **2)添加 k8s(只需要 worker 角色)** 在主节点已部署的 rancher server web 界面,将新机器加入 rancher 集群,新机器只需为 worker,并为机器添加 label。 操作路径:左侧边栏「集群管理」-「集群」-「注册」- 只选择「Worker」角色,点击加入集群命令。在新机器上执行复制的命令 + `--node-name 新机器内网ip` 即可。 如果遇到 docker 的 bug,先 `systemctl restart docker`,再重新执行命令试一试。 **3)为机器添加标签** ```bash service=true train=true notebook=true org=public cpu=true # 按需 gpu=true # 按需 gpu-type=A100 # 按需 ``` ![多机标签](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/duojibiaoqian.png) 可以在 rancher 中加,也可以通过 kubectl 命令加。 --- # 多集群 **实现原理:** 在每个集群上都完成平台部署,但仅保留其中一个 web 端。web 端所在集群称为「主集群」,其他为「远程集群」。 先在新集群上部署 k8s 和 CubeStudio。 ### 1、远程 k8s 集群卸载非必要组件 ```bash # 删除 web kubectl delete -k cube/overlays # 删除 mysql 和 redis kubectl delete -f redis/redis.yaml kubectl delete -f mysql/deploy.yaml # 删除 labelstudio kubectl delete -f labelstudio/postgresql.yaml kubectl delete -f labelstudio/labelstudio.yaml # 删除 k8s dashboard cluster kubectl delete -f dashboard/v2.6.1-cluster.yaml ``` 去除远程 k8s 集群的 k8s dashboard user1 的 cookie 校验。 ![去除cookie校验](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/Snipaste_2025-09-11_20-31-45.png) ### 2、修改远程 k8s 集群分布式存储配置 如果想让主集群和远程集群使用相同的分布式存储,需要将同一个分布式存储挂载到主集群和从集群主机的 `/data/k8s` 目录下。 挂载相同分布式存储后,为新集群的 prometheus 创建新的存储目录: ```bash # 创建新 k8s 集群的监控存储目录 mkdir -p /data/k8s/monitoring/prometheus-cluster2 chmod -R 777 /data/k8s/monitoring/prometheus-cluster2 # 修改新 k8s 集群的 prometheus 的 pv kubectl delete -f cube-studio/install/kubernetes/prometheus/prometheus/prometheus-main.yml kubectl delete pvc -n monitoring prometheus-k8s-db-prometheus-k8s-0 kubectl delete -f cube-studio/install/kubernetes/prometheus/prometheus/pv-pvc-hostpath.yaml # 修改 pv-pvc-hostpath.yaml,将 pv 存储地址 /data/k8s/monitoring/prometheus 改为 /data/k8s/monitoring/prometheus-cluster2 # 然后重新部署新 k8s 集群的 prometheus kubectl create -f cube-studio/install/kubernetes/prometheus/prometheus/pv-pvc-hostpath.yaml kubectl create -f cube-studio/install/kubernetes/prometheus/prometheus/prometheus-main.yml ``` ### 3、添加配置文件 **3.1 粘贴远程集群 kubeconfig 并生成 configmap** 在主集群的 `install/kubernetes/kubeconfig/` 目录下粘贴远程集群的 config 文件并规范命名。比如远程集群叫 `dev1`,就把 config 文件粘贴到 `install/kubernetes/kubeconfig/dev1-kubeconfig`。 在主集群生成新的 kubeconfig configmap: ```bash cd install/kubernetes kubectl delete configmap kubernetes-config -n infra kubectl create configmap kubernetes-config --from-file=kubeconfig -n infra ``` > 补充(按代码 `install/kubernetes/start.sh:146-153`):`kubernetes-config` 这个 configmap 不止 `infra` 命名空间用到,`pipeline`、`automl` 命名空间也会挂载它(见 `cube/base/deploy-backend.yaml`、`deploy-watch.yaml`、`deploy-worker.yaml`)。新增集群更新 kubeconfig 后,建议在这三个命名空间都重建一遍: > > ```bash > for ns in infra pipeline automl; do > kubectl delete configmap kubernetes-config -n $ns > kubectl create configmap kubernetes-config --from-file=kubeconfig -n $ns > done > ``` **3.2 修改 config.py 配置文件** 在 `config.py` 的 `CLUSTERS` 中添加集群信息(结构见 `config.py:1403`,字段为 `NAME`/`KUBECONFIG`/`HOST`/可选 `SERVICE_DOMAIN`): ```python # 所有训练集群的信息 CLUSTERS={ # 和 project expand 里面的名称一致 "dev":{ "NAME":"dev", "KUBECONFIG":'/home/myapp/kubeconfig/dev-kubeconfig', "HOST": 'xx.xx.xx.xx', # "SERVICE_DOMAIN": 'service.svc.cluster.local' # 泛域名 }, "dev1":{ "NAME": "dev1", "KUBECONFIG": '/home/myapp/kubeconfig/dev1-kubeconfig', "HOST": 'xx.xx.xx.xx', # "SERVICE_DOMAIN": 'service.svc.cluster.local' # 泛域名 } } ``` config.py 更新到 k8s 生效: ```bash kubectl delete -k cube/overlays kubectl apply -k cube/overlays ``` 或者直接线上修改 `infra/kubeflow-dashboard-config-xx` 这个 configmap,修改后再重启 `infra/kubeflow-dashboard*` 相关的 pod。 之后就可以在「整体资源」界面看到不同集群的资源使用情况。 这样 CubeStudio 就能调度多个 k8s 集群,但还需要在项目组中指定当前项目组下的 notebook/pipeline/service 在哪个 k8s 集群调度,即在项目组的扩展参数中添加: ```json { "cluster": "dev1" } ``` ![多集群](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/duojijiqun.png) **3.3 添加新集群的 watch 组件** 复制 `infra/kubeflow-watch` 的 deployment(对应 `cube/base/deploy-watch.yaml`,deployment 名为 `kubeflow-watch`),修改名称,并把环境变量 `ENVIRONMENT` 改为新 k8s 集群的名称。 > 说明:`ENVIRONMENT` 在 `deploy-watch.yaml` 中默认来自 configmap `deploy-config` 的 `ENVIRONMENT` 键(`deploy-watch.yaml:77-81`),新集群的 watch 副本需要把它覆盖为该集群名。 **3.4 仓库秘钥重新生成** 建议重新保存一遍仓库中的秘钥,因为保存秘钥的动作会在所有 k8s 集群相关命名空间下创建对应的 hubsecret。 **3.5 将新集群的 minio 替换为主集群的地址** 先将主集群 `kubeflow` 命名空间的 service minio 改为 nodeport 方式。 再修改新集群 `kubeflow` 命名空间下的 configmap `workflow-controller-configmap`,把其中 minio 的地址改为主集群的 nodeport 地址,然后重启 workflow-controller 的 pod。 --- # 多资源组 每个 k8s 集群的算力都可以划分为多个资源组,划分通过机器 label 实现。 为机器添加标签 `org=xx`(`xx` 为资源组名称)。添加后,在项目组中把资源组配置为上面的 `xx`,保存项目组配置后,该项目组下的成员就会自动使用这一波资源组算力。 ![多资源组](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/duojiduoziyuanzu.png) --- # 单集群多项目组算力均衡 多项目组之间的算力均衡通过 `myapp/tasks/schedules.py` 中的 `adjust_node_resource` 任务实现(任务定义见 `schedules.py:1111`)。 基本原则:将「可共享的机器」从当前负载最小的项目组划分到负载最高的项目组,同时保证项目组的最小可用算力。可共享的判定为:机器 label `share` 不等于 `false`(缺省视为 `true`)且 `train=true`,并且是 cpu 或 gpu 机器(见 `schedules.py:1124-1125`)。此外,若有 pod 因资源不足挂起(Pending)超过 5 分钟,会立刻划资源过去并推送通知(`schedules.py:1144`)。 > 注意:该任务在 `CELERYBEAT_SCHEDULE` 中默认是**注释掉的(未启用)**,需要时要手动取消注释开启。启用后默认调度周期为 `crontab(minute='*/10')`,即**每 10 分钟**执行一次均衡(见 `config.py:731-734`);具体周期以你启用时的配置为准。 --- ### 离线/内网部署 - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/%E9%83%A8%E7%BD%B2%E6%96%B9%E5%BC%8F/%E7%A6%BB%E7%BA%BF%E9%83%A8%E7%BD%B2 - 分类: 02-部署安装 / 部署方式 - 适用场景: 机器无法连外网(或只有部分机器能联网),需要把镜像/模型/依赖搬进内网完成平台部署时读这篇 - 关键词: 离线部署 / 内网部署 / offline / 无外网 / 私有仓库 / harbor / 镜像导出 / image save / image load / push_harbor / pull_harbor / rancher离线 / aihub离线 / modelscope缓存 / nginx代理 / coredns自定义host / iptables转发 / apt yum pip 内网源 - 最后更新: 2026-07-04 # 离线/内网部署 前置条件:内网机器需要已安装 docker、docker-compose、iptables。 [部署视频(内网离线部署)](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/video/%E5%86%85%E7%BD%91%E7%A6%BB%E7%BA%BF%E9%83%A8%E7%BD%B2.mp4) 离线部署分两种场景: 1. **完全无法联网的内网机器**:所有镜像/数据在联网机器上下载好,再搬进内网。 2. **内网中有可以联网的机器**:用一台出口机器做代理(nginx/iptables + coredns),内网其他机器走代理拉取。 --- # 一、完全无法联网的内网机器 ## 1. 安装依赖组件和数据 在能连接外网的机器上执行下面命令,下载好后再拷贝到内网机器: ```bash mkdir offline cd offline # 下载 kubectl 和 harbor 的离线安装包 # amd64 版本 wget https://cube-studio.oss-cn-hangzhou.aliyuncs.com/install/kubectl wget https://githubfast.com/goharbor/harbor/releases/download/v2.11.1/harbor-offline-installer-v2.11.1.tgz # arm64 版本 wget https://cube-studio.oss-cn-hangzhou.aliyuncs.com/install/kubectl-arm64 && mv kubectl-arm64 kubectl wget https://githubfast.com/wise2c-devops/build-harbor-aarch64/releases/download/v2.13.0/harbor-offline-installer-aarch64-v2.13.0.tgz # 下载模型 wget https://cube-studio.oss-cn-hangzhou.aliyuncs.com/inference/resnet50.onnx wget https://cube-studio.oss-cn-hangzhou.aliyuncs.com/inference/resnet50-torchscript.pt wget https://cube-studio.oss-cn-hangzhou.aliyuncs.com/inference/resnet50.mar wget https://cube-studio.oss-cn-hangzhou.aliyuncs.com/inference/tf-mnist.tar.gz wget https://cube-studio.oss-cn-hangzhou.aliyuncs.com/inference/decisionTree_model.pkl # 训练、标注数据集 wget https://cube-studio.oss-cn-hangzhou.aliyuncs.com/pipeline/coco.zip wget https://docker-76009.sz.gfp.tencent-cloud.com/github/cube-studio/aihub/deeplearning/cv-tinynas-object-detection-damoyolo/dataset/coco2014.zip ``` > 注意:这里下载的是通用名 `kubectl`,而部署脚本 `install/kubernetes/start.sh:14-18` 下载的是带版本的 `kubectl-amd64-1.28` / `kubectl-arm64-1.28`。离线场景建议下载与 start.sh 一致的版本以避免版本不匹配,OSS 上具体文件请按实际确认。 把整个 `offline` 目录拷贝到内网机器上。 在连不上网的内网机器上: **1)安装 kubectl** ```bash cd offline chmod +x kubectl && cp kubectl /usr/bin/ && cp kubectl /usr/local/bin/ ``` **2)安装内网镜像仓库** 参考 [私有镜像仓库 Harbor](../../04-运维管理/私有镜像仓库Harbor.md)(对应源码 `install/kubernetes/harbor/readme.md`)。 并创建 `cube-studio` 和 `rancher` 两个项目,分别存放 rancher 的基础镜像和 CubeStudio 的基础镜像。 为每台机器的 docker 添加内网私有仓库到 `insecure-registries`(如果仓库是 https 可忽略此步),参考 [节点安装 Docker](../节点准备/安装Docker.md) 中「配置 docker」一节。 **3)将前面下载的数据转移到个人目录下** ```bash cp -r offline /data/k8s/kubeflow/pipeline/workspace/admin/ ``` ## 2. 镜像转移至内网 镜像导出/推送/拉取脚本由 `install/kubernetes/all_image.py`(CubeStudio 基础镜像)和 `install/kubernetes/rancher/all_image.py`(rancher 镜像)生成。运行前先修改各自脚本中的内网仓库地址 `harbor_repo`。 ### 2.1 转移 rancher 镜像 修改 `install/kubernetes/rancher/all_image.py` 中的内网仓库地址,运行后会生成下列脚本(见 `rancher/all_image.py:6-11`): - 联网机器上二选一: - 运行 `push_rancher_harbor.sh`,把镜像拉取后推送到内网 harbor 仓库; - 或运行 `rancher_image_save.sh`,把镜像压缩成 `.tar.gz` 文件,再拷贝到内网机器。 > 说明:原文此处写的是 `pull_rancher_images.sh`,但该脚本只做「从公网拉取镜像」(`rancher/all_image.py:35`),真正「推送到内网仓库」的是 `push_rancher_harbor.sh`(`rancher/all_image.py:24`),此处按代码更正。 - 不能联网机器上(每台机器都要执行)二选一: - 运行 `pull_rancher_harbor.sh`,从内网仓库拉取镜像; - 或运行 `rancher_image_load.sh`,从压缩文件中导入镜像。 ### 2.2 内网部署 k8s 使用与 rancher 相同的方法可在内网部署 k8s。 ### 2.3 转移 CubeStudio 基础镜像 修改 `install/kubernetes/all_image.py` 中的内网仓库地址,运行后生成下列脚本(见 `all_image.py:136-141`): - 联网机器上二选一: - 运行 `push_harbor.sh`,把镜像推送到内网仓库; - 或运行 `image_save.sh`,把镜像压缩成文件再导入到内网机器。 - 不能联网机器上(每台机器都要执行)二选一: - 运行 `pull_harbor.sh`,从内网仓库拉取镜像; - 或运行 `image_load.sh`,从压缩文件中导入镜像。 ## 3. 内网部署 cube-studio **1)修改镜像拉取脚本为内网拉取**(每台机器都要执行) 把节点初始化脚本 `install/kubernetes/init_node.sh` 中的镜像拉取命令改为从内网拉取。 > 说明:原文写的是「把 `pull_images.sh` 改为 `pull_harbor.sh`」,但当前 `init_node.sh` 末尾实际调用的是 `sh pull_images_mini.sh`(见 `init_node.sh` 最后一行),请把这一行改为 `sh pull_harbor.sh`。 **2)取消 start.sh 中下载 kubectl 的逻辑** 注释掉 `install/kubernetes/start.sh:13-18` 这段(因为内网无法访问 OSS,kubectl 已在前面手动安装): ```bash ARCH=$(uname -m) if [ "$ARCH" = "x86_64" ]; then wget -O kubectl https://cube-studio.oss-cn-hangzhou.aliyuncs.com/install/kubectl-amd64-1.28 && chmod +x kubectl && cp kubectl /usr/bin/ && mv kubectl /usr/local/bin/ elif [ "$ARCH" = "aarch64" ]; then wget -O kubectl https://cube-studio.oss-cn-hangzhou.aliyuncs.com/install/kubectl-arm64-1.28 && chmod +x kubectl && cp kubectl /usr/bin/ && mv kubectl /usr/local/bin/ fi ``` > 注:上面代码块已按当前 `start.sh` 更正(带版本号的 `kubectl-amd64-1.28` / `kubectl-arm64-1.28`),原文使用的是旧 URL。 **3)修改 CubeStudio 镜像为内网镜像** ```bash vi install/kubernetes/cube/overlays/kustomization.yml # 修改最底部的 newName 和 newTag ``` **4)修改 CubeStudio 的配置文件** ```bash vi install/kubernetes/cube/overlays/config/config.py ``` 下面这些镜像相关配置项改为内网仓库地址(均在 `config.py` 中,行号见括注): - `REPOSITORY_ORG`(`config.py:978`,默认 `ccr.ccs.tencentyun.com/cube-studio/`) - `PUSH_REPOSITORY_ORG`(`config.py:980`) - `USER_IMAGE`(`config.py:983`) - `NOTEBOOK_IMAGES`(`config.py:998`) - `DOCKER_IMAGES`(`config.py:1112`,默认 `docker:23.0.4`) - `NERDCTL_IMAGES`(`config.py:1113`) - `NNI_IMAGES`(`config.py:1298`) - `WAIT_POD_IMAGES`(`config.py:1300`) - `INFERNENCE_IMAGES`(`config.py:1324`,注意代码里变量名确实拼作 `INFERNENCE_IMAGES`) 其他修改: - `SERVICE_EXTERNAL_IP`(`config.py:837`)添加内网 IP,格式为 `['内网ip']` 或 `['内网ip|公网ip']`。 - `DEFAULT_GPU_RESOURCE_NAME`(`config.py:1259`,默认 `nvidia.com/gpu`)修改为默认的 k8s GPU 资源名。 **5)修改 label studio 镜像为内网镜像** ```bash vi install/kubernetes/labelstudio/labelstudio.yaml # 把其中 image 的值更换为内网镜像 ``` **6)部署 cube-studio** 复制 k8s 的 config 文件,部署方式与外网相同,参考 [单机部署](单机部署-docker-compose/README.md)。 ## 4. web 界面的内网修正 1. web 界面 hubsecret 改为内部仓库的账号密码。 2. 修改配置文件中的内网仓库信息和内外网 IP。 3. 自带的目标识别 pipeline 中,第一个数据拉取任务的启动命令改为:`cp offline/coco.zip ./ && ...`。 4. 自带的推理服务启动命令,把 `wget https://xxxx/xx.zip` 部分改为 `cp /mnt/admin/offline/xx.zip ./`。 --- # 二、aihub 模型预拉取 ### 导入所有模型 在能联网的机器上下载所有模型: ```bash cd aihub/modelscope docker run --name download --privileged -d -v $PWD:/app ccr.ccs.tencentyun.com/cube-studio/modelscope:base-cuda11.3-python3.7 python download_all_model.py ``` 将联网机器上 `aihub/modelscope/` 目录下的所有子目录,拷贝到内网服务器的 `/data/k8s/kubeflow/global/cube-studio/aihub/deep-learning/` 目录下。 ### 导入部分模型 如果只想要部分模型,可先在有网的服务器上部署启动对应的 aihub 应用,然后将服务器 `/data/k8s/kubeflow/global/cube-studio/aihub/deep-learning/` 下对应的 aihub 应用拷贝到内网同等目录下。 ### 内网启动 修改 CubeStudio 后台 `config.py` 中的: ```python AIHUB_CACHE_DIR='/mnt/workspace/.cache/modelscope/' ``` (该项在 `config.py:1358`,默认空字符串,注释中给的示例即 `/mnt/workspace/.cache/modelscope/`。) 然后重启后端 pod,再重新部署 aihub 的 web 界面。 --- # 三、内网中有可以联网的机器 如果内网里有一台机器可以出网,可让它做代理出口,内网其他机器走它拉取软件源和镜像。 ## 1. 联网机器设置代理服务器 在联网机器上用 nginx 代理软件源,配置参考 `install/kubernetes/nginx-https/apt-yum-pip-source.conf`。 启动 nginx 代理(需要监听 80 和 443 端口): ```bash docker run --name proxy-repo -d --restart=always --network=host \ -v $PWD/nginx-https/apt-yum-pip-source.conf:/etc/nginx/nginx.conf nginx ``` ## 2. 在内网机器上配置 host 在内网机器的 `/etc/hosts` 中,把需要访问的域名指向出口机器: ```bash <出口服务器的IP地址> mirrors.aliyun.com <出口服务器的IP地址> ccr.ccs.tencentyun.com <出口服务器的IP地址> registry-1.docker.io <出口服务器的IP地址> auth.docker.io <出口服务器的IP地址> hub.docker.com <出口服务器的IP地址> www.modelscope.cn <出口服务器的IP地址> modelscope.oss-cn-beijing.aliyuncs.com <出口服务器的IP地址> archive.ubuntu.com <出口服务器的IP地址> security.ubuntu.com <出口服务器的IP地址> cloud.r-project.org <出口服务器的IP地址> deb.nodesource.com <出口服务器的IP地址> docker-76009.sz.gfp.tencent-cloud.com ``` 添加新的 host 后要重启 kubelet:`docker restart kubelet`。 如果代理机器没法占用 80 和 443 端口,可用 iptables 转发: ```bash sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -d mirrors.aliyun.com -j DNAT --to-destination <出口服务器的IP地址>:<出口服务器的端口> ``` ## 3. k8s 配置域名解析 在 k8s 的 `kube-system` 命名空间,修改 coredns 的 configmap,添加自定义 host 地址映射: ```bash { "Corefile": ".:53 { errors health { lameduck 5s } ready kubernetes cluster.local in-addr.arpa ip6.arpa { pods insecure fallthrough in-addr.arpa ip6.arpa } # 自定义 host hosts { <出口服务器的IP地址> mirrors.aliyun.com <出口服务器的IP地址> ccr.ccs.tencentyun.com <出口服务器的IP地址> registry-1.docker.io <出口服务器的IP地址> auth.docker.io <出口服务器的IP地址> hub.docker.com <出口服务器的IP地址> www.modelscope.cn <出口服务器的IP地址> modelscope.oss-cn-beijing.aliyuncs.com <出口服务器的IP地址> archive.ubuntu.com <出口服务器的IP地址> security.ubuntu.com <出口服务器的IP地址> cloud.r-project.org <出口服务器的IP地址> deb.nodesource.com <出口服务器的IP地址> docker-76009.sz.gfp.tencent-cloud.com fallthrough } prometheus :9153 forward . \"/etc/resolv.conf\" cache 30 loop reload loadbalance } # STUBDOMAINS - Rancher specific change " } ``` 修改后重启 coredns 的 pod。 ## 4. 容器里面使用放开的域名 pip 配置 https 源: ```bash pip3 config set global.index-url https://mirrors.aliyun.com/pypi/simple ``` apt 配置 https 源:修改 `/etc/apt/sources.list`(ubuntu 20.04 示例): ```bash deb https://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse deb-src https://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse deb https://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse deb-src https://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse deb https://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse deb-src https://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse deb https://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse deb-src https://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse deb https://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse deb-src https://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse ``` yum 配置 https 源:下载阿里的源 ```bash wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-8.repo ``` --- ### k3s 单机部署 CubeStudio - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/%E9%83%A8%E7%BD%B2%E6%96%B9%E5%BC%8F/k3s%E5%8D%95%E6%9C%BA%E9%83%A8%E7%BD%B2 - 分类: 02-部署安装 / 部署方式 - 适用场景: 想用 k3s(轻量级 Kubernetes)在单台机器上快速搭一套 k8s 底座,再部署 CubeStudio 时读这篇 - 关键词: k3s / k3s单机 / 单机部署 / 轻量k8s / lightweight kubernetes / containerd / registries.yaml / 镜像加速 / mirror / node-token / INSTALL_K3S_EXEC / traefik / k3s-killall / k3s-uninstall / start.sh - 最后更新: 2026-07-04 # k3s 单机部署 CubeStudio 本篇说明如何用 **k3s**(Rancher 的轻量级 Kubernetes 发行版)在单台机器上快速搭一套 K8s 底座,作为 CubeStudio 的运行环境。k3s 适合资源有限、想快速体验单机部署的场景;命令里都用了国内镜像源加速。 > 关于其它 K8s 底座方式(RKE2 + Rancher、KubeSphere 多机)见同目录下对应文档。部署前的机器规格、操作系统等要求见 [部署总览与前置要求](部署总览与前置要求.md)。 --- ## 一、master 节点 单机部署时只需要这一个节点(既是 master 也跑工作负载)。 ```bash # 关闭防火墙,清空 iptables 规则(避免与 k8s/容器规则冲突) systemctl stop firewalld && systemctl disable firewalld && iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X # 下载部署脚本(指定 k3s 版本分支) git clone -b v1.24.7+k3s1 https://github.com/k3s-io/k3s.git cd k3s # 设置 k3s 版本 export INSTALL_K3S_VERSION=v1.24.7+k3s1 # 设置 k3s 启动参数: # --system-default-registry 让系统组件走阿里云镜像源 # --write-kubeconfig 把 kubeconfig 写到 ~/.kube/config # --disable=traefik 不安装自带的 traefik(CubeStudio 用 istio 做网关) # (注释行额外指定了 cluster-cidr / service-cidr,按需开启) #export INSTALL_K3S_EXEC="--system-default-registry registry.cn-hangzhou.aliyuncs.com --write-kubeconfig ~/.kube/config --disable=traefik --cluster-cidr 10.72.0.0/16 --service-cidr 10.73.0.0/16" export INSTALL_K3S_EXEC="--system-default-registry registry.cn-hangzhou.aliyuncs.com --write-kubeconfig ~/.kube/config --disable=traefik" # 使用国内源 export INSTALL_K3S_MIRROR=cn # 强制重新下载并替换软链接 export INSTALL_K3S_SYMLINK=force #export INSTALL_K3S_FORCE_RESTART=true # 国内镜像加速 URL export INSTALL_K3S_MIRROR_URL=${INSTALL_K3S_MIRROR_URL:-'rancher-mirror.rancher.cn'} # 替换 github 和 storage 为国内可访问的地址 export GITHUB_URL=https://githubfast.com/k3s-io/k3s/releases export STORAGE_URL=https://k3s-ci-builds.s3.amazonaws.com sed -i 's|^GITHUB_URL=.*|GITHUB_URL=https://githubfast.com/k3s-io/k3s/releases|' install.sh sed -i 's|^STORAGE_URL=.*|STORAGE_URL=https://k3s-ci-builds.s3.amazonaws.com|' install.sh # 执行部署 sh install.sh # 打印 master 的 token(worker 节点加入集群时需要) cat /var/lib/rancher/k3s/server/node-token ``` 部署完后给 containerd 配置镜像 mirror,加速从 docker.io 拉镜像: ```bash cat > /etc/rancher/k3s/registries.yaml < 单机部署不需要 worker 节点,本节可跳过。 如需扩展为多机集群,在每台 worker 上执行(`myserver` 换成 master 内网地址,`K3S_TOKEN` 用上一步打印的 node-token): ```bash systemctl stop firewalld && systemctl disable firewalld && iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X git clone -b v1.24.7+k3s1 https://github.com/k3s-io/k3s.git cd k3s export INSTALL_K3S_VERSION=v1.24.7 export K3S_URL=https://myserver:6443 export K3S_TOKEN=XXX sh install.sh ``` --- ## 三、配置 Containerd(非必须) 非必须,也可以使用 docker。 k3s 会在 `/var/lib/rancher/k3s/agent/etc/containerd/config.toml` 中自动生成 containerd 的配置文件。 如果要对这个文件做高级定制,可以在同一目录中创建一个名为 `config.toml.tmpl` 的文件,它会代替默认配置。`config.toml.tmpl` 是一个 Go 模板文件,渲染时 k3s 会把 `config.Node` 结构体传入模板,从而按结构字段自定义配置。具体用法(含 Linux / Windows 示例)参见 k3s 官方文档中 containerd 配置相关章节。 --- ## 四、部署 cube-studio 部署完 k3s 后,就可以按"单机部署 cube-studio"的标准流程来部署平台了,参见 [单机 k8s 部署](单机部署-docker-compose/01-单机k8s部署.md)。 将 k8s 集群的 kubeconfig 文件复制到 `install/kubernetes/config` 文件中,然后执行如下命令,其中 `xx.xx.xx.xx` 为机器**内网**的 IP(不是外网 IP): ```bash # 在 k8s worker 机器上执行(start.sh 第一个参数为内网 IP) sh start.sh xx.xx.xx.xx ``` > `start.sh xx.xx.xx.xx` 会用该内网 IP 给本节点打标签(`train/cpu/notebook/service/istio/...=true`)、部署 dashboard / mysql / redis / prometheus / istio / argo / 训练算子 / labelstudio 以及管理平台本体,并把 `SERVICE_EXTERNAL_IP` 等配置替换成该 IP。脚本细节见 `install/kubernetes/start.sh`。 --- ## 五、清理 卸载 k3s(k3s 安装时自动生成的脚本): ```bash /usr/local/bin/k3s-killall.sh /usr/local/bin/k3s-uninstall.sh ``` --- ## 六、重启 ```bash sudo systemctl stop k3s sudo systemctl start k3s # worker 节点上是 k3s-agent sudo systemctl stop k3s-agent sudo systemctl start k3s-agent ``` --- > k3s 版本、镜像加速地址等为示例值,可按需调整;CubeStudio 的部署命令与参数以源码(`install/kubernetes/`)为准,本篇仅供导航与上手。 --- ### kubeadm 安装 k8s 组件 - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/%E9%83%A8%E7%BD%B2%E6%96%B9%E5%BC%8F/kubeadm%E9%83%A8%E7%BD%B2 - 分类: 02-部署安装 / 部署方式 - 适用场景: 想用 kubeadm 在 ubuntu/centos 上手工安装 k8s 组件,或需要去掉 master 节点污点让其可调度时读这篇 - 关键词: kubeadm / kubelet / kubectl / k8s安装 / kubernetes / ubuntu / centos / apt / yum / 6443端口 / master污点 / taint / NoSchedule - 最后更新: 2026-07-04 # kubeadm 安装 k8s 组件 本篇介绍用 kubeadm 在 ubuntu/centos 上安装 k8s 组件(kubelet/kubeadm/kubectl),以及去除 master 节点污点的方法。 > 来源:`install/kubernetes/kubeadm/readme.md`。 ## 检查所需端口是否占用 apiserver 默认端口 6443,安装前可先检查是否被占用: ```bash nc 127.0.0.1 6443 ``` ## ubuntu 安装 ```bash sudo apt-get update sudo apt-get install -y apt-transport-https ca-certificates curl curl -fsSL https://dl.k8s.io/apt/doc/apt-key.gpg | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-archive-keyring.gpg echo "deb [signed-by=/etc/apt/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list sudo apt-get update sudo apt-get install -y kubelet kubeadm kubectl sudo apt-mark hold kubelet kubeadm kubectl ``` ## centos 安装 ```bash cat < /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/ enabled=1 gpgcheck=1 repo_gpgcheck=1 gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg EOF ``` ## 去除 master 节点污点(让 master 也能调度) > 原文此节标题为「使用 kubekey 来部署」,但内容是 kubeadm/kubekey 部署后通用的去污点操作。若用 KubeKey 部署,参考[《KubeKey 部署 CubeStudio 总览》](kubekey部署/README.md)。 查看 master 节点的污点: ```bash kubectl describe node | grep Taints ``` 去除 master 节点的污点,这样让 master 也能调度: ```bash kubectl taint node node-role.kubernetes.io/master:NoSchedule- ``` --- ### RKE2 + Rancher 方式部署 K8s 集群 - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/%E9%83%A8%E7%BD%B2%E6%96%B9%E5%BC%8F/RKE2%E9%83%A8%E7%BD%B2 - 分类: 02-部署安装 / 部署方式 - 适用场景: 想用 Rancher Server + RKE2 搭一套 K8s 集群作为 CubeStudio 运行底座,需要知道 RKE2 自带 containerd 的路径/配置/常用命令时读这篇 - 关键词: RKE2 / rke2 / Rancher / rancher / k3s / containerd / nerdctl / crictl / ctr / ipvs / ip_vs / kubeconfig / rke2-server / rke2-agent / 镜像加速 / mirror / CubeStudio部署底座 - 最后更新: 2026-07-05 # RKE2 + Rancher 方式部署 K8s 集群 > ⚠️ 来源 `install/kubernetes/rancher/rke2/rke2.md` 第 1 行标注「本文是测试文档,暂时未测试」。本篇按原文整理,命令与版本请在自己的环境再验证一遍,不要直接照搬到生产。 本篇说明如何用 Rancher Server 纳管、用 RKE2 部署一套 Kubernetes 集群,作为 CubeStudio 的运行底座。RKE2 自带一套 containerd 实例(与主机系统自带的 containerd 相互独立),本篇重点说明它的路径、配置改法与常用排查命令。 > RKE2 是 Rancher 的下一代 K8s 发行版,内置 containerd,由 `rke2-server` / `rke2-agent` 进程统一管理,主机本身**不需要**再单独安装 containerd。 --- ## 一、部署 Rancher Server 用 `nerdctl`(或 docker)以容器方式启动 Rancher Server。下面命令把镜像默认仓库指向阿里云加速。 ```bash # 可选:预先把 k3s 内置镜像放到 rancher 数据目录(离线/加速用) # mkdir -p /data/rancher/k3s/agent/images/ # wget https://cube-studio.oss-cn-hangzhou.aliyuncs.com/install/k3s-airgap-images.tar -O /data/rancher/k3s/agent/images/k3s-airgap-images.tar # nerdctl network create cube-studio export RANCHER_CONTAINER_TAG=v2.8.5 export PASSWORD=cube-studio nerdctl run -d --privileged --restart=unless-stopped -p 443:443 \ --name=myrancher \ -e AUDIT_LEVEL=3 \ -e CATTLE_SYSTEM_DEFAULT_REGISTRY=registry.cn-hangzhou.aliyuncs.com \ -e CATTLE_BOOTSTRAP_PASSWORD=$PASSWORD \ registry.cn-hangzhou.aliyuncs.com/rancher/rancher:$RANCHER_CONTAINER_TAG ``` 启动后: - 打开 `https://<主机IP>:443/`,等待 Web 界面就绪(预计 1~10 分钟)。 - 用 `CATTLE_BOOTSTRAP_PASSWORD` 设置的密码(这里是 `cube-studio`)登录。 > 环境变量含义:`CATTLE_SYSTEM_DEFAULT_REGISTRY` 让 Rancher 的系统组件走阿里云镜像源;`AUDIT_LEVEL=3` 开审计日志;`CATTLE_BOOTSTRAP_PASSWORD` 是首次登录的初始密码。Rancher 版本 `v2.8.5` 为示例值,可按需调整。 --- ## 二、用 Rancher 创建 RKE2 集群 在 Rancher Web 界面新建一个 RKE2 集群,注意以下要点: - **K8s 版本**:建议 `1.25`。 - **不要部署 nginx-ingress**(CubeStudio 用 istio 做网关)。 - **镜像仓库**:配置 `registry.cn-hangzhou.aliyuncs.com`,Rancher 的系统组件会走阿里云。 - **镜像加速 Mirror**:让 K8s 拉镜像走加速器: | 镜像仓库主机名 | mirror 地址 | |---|---| | `*`(所有) | `docker.m.daocloud.io` | | `docker.io` | `docker.m.daocloud.io` | - **API server 参数**(高级选项里加): ``` --service-node-port-range=1-65535 ``` > 注意:原文「高级选项-补充的」一节给过一段「kubelet 参数:使用主机的 containerd」的配置(`container-runtime=remote`、`containerd=/run/containerd/containerd.sock` 等),并自带「配置这个会出错」的标注(见 `install/kubernetes/rancher/rke2/containerd-rke2.md`)。RKE2 默认使用自带的 containerd(socket 在 `/run/k3s/containerd/containerd.sock`,见 `install/kubernetes/rancher/rke2/rke2.md:60`),**不要**把它改成主机的 `/run/containerd/containerd.sock`,否则启动异常。请勿照抄那段 kubelet 参数。 ### 部署完成后的清理 进入 Rancher Web 界面「全部命名空间 → Pod」页面,过滤 `10.4` 网段的所有 Pod 并全部删除。原因:这些不是 K8s 集群网关的 Pod,而是 nerdctl 网络残留。 --- ## 三、(可选)主机系统基线设置 如果需要开启 IPVS 模式并配置内核网络转发参数,可在每台机器执行: ```bash apt install ipset ipvsadm -y # 加载 ip_vs 系列内核模块 sudo modprobe ip_vs sudo modprobe ip_vs_rr sudo modprobe ip_vs_wrr sudo modprobe ip_vs_lc sudo modprobe ip_vs_wlc sudo modprobe ip_vs_lblc sudo modprobe ip_vs_lblcr sudo modprobe ip_vs_sh sudo modprobe ip_vs_dh sudo modprobe ip_vs_sed sudo modprobe ip_vs_nq lsmod | grep ip_vs # 网络转发 sysctl cat > /etc/sysctl.d/k8s.conf << EOF net.bridge.bridge-nf-call-iptables = 1 net.bridge.bridge-nf-call-ip6tables = 1 net.ipv4.ip_forward = 1 vm.swappiness = 0 EOF modprobe br_netfilter lsmod | grep br_netfilter ``` --- ## 四、Rancher Server 内自带的 k3s 镜像 Rancher Server 容器内自带一份 k3s air-gap 镜像包,可放到数据目录加速/离线安装: ```bash mkdir -p /data/rancher/k3s/agent/images/ wget https://cube-studio.oss-cn-hangzhou.aliyuncs.com/install/k3s-airgap-images.tar \ -O /data/rancher/k3s/agent/images/k3s-airgap-images.tar # 也可从 rancher 镜像里直接 cp 出来: # docker run --rm --entrypoint "" -v $(pwd):/output rancher/rancher:v2.8.5 \ # cp /var/lib/rancher/k3s/agent/images/k3s-airgap-images.tar /output/k3s-airgap-images.tar # cp k3s-airgap-images.tar /data/rancher/k3s/agent/images/ ``` --- ## 五、修改 RKE2 的 containerd 配置 RKE2 的 containerd 配置由 `rke2-server` 在启动时从模板 `config.toml.tmpl` 生成。要让它支持 `certs.d` 镜像 mirror,需要追加 `config_path`: ```bash # 用现有 config.toml 作为模板起点 cp /var/lib/rancher/rke2/agent/etc/containerd/config.toml \ /var/lib/rancher/rke2/agent/etc/containerd/config.toml.tmpl # 追加 registry config_path tee -a /var/lib/rancher/rke2/agent/etc/containerd/config.toml.tmpl << 'EOF' [plugins."io.containerd.grpc.v1.cri".registry] config_path = "/etc/containerd/certs.d" EOF # 改完重启 rke2-server,containerd 会随之重生成配置并重启 systemctl restart rke2-server ``` --- ## 六、RKE2 的目录与运行机制(重点) RKE2 自带 containerd 实例,**与主机系统的 containerd 完全独立**,关键路径如下: | 内容 | RKE2 自带实例 | 主机系统 containerd(如有) | |---|---|---| | 二进制目录 | `/var/lib/rancher/rke2/bin/` | 系统 PATH | | 配置文件 | `/var/lib/rancher/rke2/agent/etc/containerd/config.toml` | `/etc/containerd/config.toml` | | socket | `/run/k3s/containerd/containerd.sock` | `/run/containerd/containerd.sock` | | 由谁管理 | `rke2-server`(改配置后 `systemctl restart rke2-server`) | `containerd.service` | 要点: - RKE2 的 containerd 实例通过 `rke2-server` 管理,不要自己手动管它;改了配置就 `systemctl restart rke2-server`。 - RKE2 集群上启动的 Pod 使用 RKE2 自带的 containerd 实例,不用主机系统的,所以**主机本身不需要安装 containerd**。 --- ## 七、kubeconfig 与 kubectl RKE2 把 kubeconfig 写在 `/etc/rancher/rke2/rke2.yaml`,kubectl 在自带 bin 目录: ```bash export KUBECONFIG=/etc/rancher/rke2/rke2.yaml /var/lib/rancher/rke2/bin/kubectl get nodes # 或直接指定 kubeconfig /var/lib/rancher/rke2/bin/kubectl --kubeconfig /etc/rancher/rke2/rke2.yaml get nodes ``` --- ## 八、查看与排查 RKE2 的 containerd ```bash # 导出当前生效的 containerd 配置 /var/lib/rancher/rke2/bin/containerd config dump # 用 ctr 直连 RKE2 的 containerd socket 看容器/镜像(注意 namespace=k8s.io) /var/lib/rancher/rke2/bin/ctr --address /run/k3s/containerd/containerd.sock --namespace k8s.io container ls /var/lib/rancher/rke2/bin/ctr --address /run/k3s/containerd/containerd.sock --namespace k8s.io images ls # 让 crictl 默认走 RKE2 的配置 echo "export CRI_CONFIG_FILE=/var/lib/rancher/rke2/agent/etc/crictl.yaml" >> /etc/profile source /etc/profile cp /var/lib/rancher/rke2/bin/crictl /usr/local/bin/ crictl ps # 或显式指定配置 / runtime endpoint /var/lib/rancher/rke2/bin/crictl --config /var/lib/rancher/rke2/agent/etc/crictl.yaml ps /var/lib/rancher/rke2/bin/crictl --runtime-endpoint unix:///run/k3s/containerd/containerd.sock ps -a # 改完配置统一重启 systemctl restart rke2-server ``` --- ## 九、组件、日志与卸载 ### 组件与日志 ```bash # 控制平面节点:运行 rke2-server,含 API Server / Scheduler 等控制面组件 systemctl status rke2-server # 节点纳管 agent:运行 rke2-agent,仅工作负载相关组件(kubelet、kube-proxy) systemctl status rancher-system-agent ``` ### 卸载 ```bash rancher-system-agent-uninstall.sh ``` --- ## 部署完平台之后 RKE2 集群就绪后,把它作为 K8s 底座继续按标准流程部署 CubeStudio(执行 `install/kubernetes` 下的 `start.sh` 等)。容器 CLI 统一用 `nerdctl` 时,记得把 CubeStudio 配置 `CONTAINER_CLI` 改为 `nerdctl`(默认是 `docker`,见 `myapp/config.py:1110`)。其余部署细节参见「02-部署安装」段其它文档。 --- ### Windows 部署 CubeStudio(WSL2) - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/%E9%83%A8%E7%BD%B2%E6%96%B9%E5%BC%8F/Windows%E9%83%A8%E7%BD%B2 - 分类: 02-部署安装 / 部署方式 - 适用场景: 在 Windows 个人电脑/笔记本上通过 WSL2 准备 Linux 环境,再在其中部署 CubeStudio 体验环境时阅读。 - 关键词: Windows / WSL / WSL2 / Linux子系统 / windows subsystem for linux / Ubuntu / 虚拟化 / VT-x / AMD-V / wslconfig / 单机部署 / k3s - 最后更新: 2026-07-04 # Windows 部署 CubeStudio(WSL2) 本文介绍在 Windows 上启用 WSL2(适用于 Linux 的 Windows 子系统)并安装 Ubuntu,从而获得一个可运行 CubeStudio 的 Linux 环境。 > 说明:本文只覆盖到 **准备好 WSL2 Linux 环境** 这一步。准备完成后,进入 WSL 的 Ubuntu,按单机部署流程继续部署 CubeStudio(推荐 k3s,见文末「下一步」)。 ## 环境要求 - 控制端机器:CPU >= 16 核,内存 >= 32G,至少 1 台。 - 生产配置建议:32 核 64G × 2 台。 > WSL2 场景一般用于本地体验/开发,生产环境请使用 Linux 服务器集群部署。 --- ## 一、启用 Windows 功能(WSL) 有两种入口都可以打开「适用于 Linux 的 Windows 子系统」功能: **方式 A:通过「Windows 功能」窗口** 1. 按下 `Win + R`,输入 `optionalfeatures` 回车,打开「Windows 功能」窗口; ![启用 Windows 功能](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/d550a067d1ea4d028a29abd3f68ee978.png) 2. 勾选「适用于 Linux 的 Windows 子系统」(Windows Subsystem for Linux)及虚拟机平台相关功能后,点击窗口底部「确定」,系统会开始安装所选功能,等待安装完成(约 1~3 分钟,视电脑配置而定); 3. 安装完成后,会提示「需要重启电脑才能生效」,点击「立即重启」(**务必重启,否则后续步骤会失败**)。 **方式 B:通过「设置」开启开发者模式(旧版本系统)** 1. 开始菜单 → 设置 → 更新和安全 → 开发者选项 → 开发人员模式; 2. 开始菜单 → 设置 → 搜索「控制面板」→ 程序 → 启用或关闭 Windows 功能 → 勾选「适用于 Linux 的 Windows 子系统」; 3. 重启机器。 --- ## 二、确认虚拟化已启用 1. 按下 `Ctrl + Shift + Esc` 打开任务管理器; 2. 切换到「性能」选项卡; 3. 查看右下角「虚拟化」是否为「**已启用**」。 ![确认虚拟化已启用](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/bf977816308745a1a757b42ee4e312a8.png) 4. 如果没有启用,开机前按 `F1` / `F12` / `Del` 进入 BIOS/UEFI 设置,在 **Advanced → Intel RC Setup** 中找到: - **Intel Virtualization Technology (VT-x)**,或 - **AMD-V** 选项, 将其改为 **Enable**。 --- ## 三、安装 WSL2 及 Ubuntu ### 3.1 更新 WSL 以管理员身份运行 cmd(`Win + R` → 输入 `cmd` → 右键以管理员身份运行),执行: ```bash wsl --update ``` > 如果出现错误 `0x80070005`,请使用: > ```bash > wsl --update --web-download > ``` ### 3.2 安装 Ubuntu 发行版 ```bash # 查看可用的发行版版本 wsl --list --online # 设置默认使用 WSL2(而非 WSL1) wsl --set-default-version 2 # 安装 Ubuntu 发行版(可指定具体版本,如 Ubuntu-20.04) wsl --install -d Ubuntu ``` > 如果出现错误 `0x80072ee2`,请检查网络连通性: > ```bash > curl -I https://aka.ms/wslubuntu2204 > ``` ### 3.3 验证安装 ```bash # 查看安装是否成功(含发行版与 WSL 版本号) wsl -l -v # 仅查看已安装的发行版列表 wsl --list # 进入虚拟机 wsl -d Ubuntu ``` 显示出已安装的 Ubuntu 子系统即代表子系统启动成功。 --- ## 四、配置 WSL2 ### 4.1 修改根目录挂载传播模式 进入 WSL 后,查看 `/` 分区的传播模式: ```bash findmnt -o PROPAGATION,SOURCE,TARGET / ``` 输出示例: ``` PROPAGATION SOURCE TARGET private /dev/sdd / ``` 如果显示为 `private`,需要改为 `shared`(Kubernetes/容器挂载传播需要): ```bash sudo mount --make-shared / ``` ### 4.2 限制 WSL2 内存与 CPU 占用 WSL2 默认会占用较多内存,可通过配置文件进行限制。在 Windows 用户目录(如 `C:\Users\你的用户名\`)下创建或编辑文件 `.wslconfig`: ```ini [wsl2] # 限制内存使用,避免 WSL 吃光所有内存 memory=4GB # 限制 CPU 核心数(建议设为物理核心数的一半) processors=2 # 启用 localhost 转发(方便在 Windows 浏览器访问 WSL 服务) localhostForwarding=true ``` > 提示:上面的 `memory=4GB`、`processors=2` 是演示值;部署 CubeStudio 时请按「环境要求」放大到足够内存与核心数,否则组件可能起不来。 --- ## 五、WSL2 迁移至其他目录(可选) WSL2 默认安装在 C 盘,如需迁移至其他目录(如 D 盘),按以下步骤操作: **1. 停止正在运行的 WSL:** ```bash wsl --shutdown ``` **2. 导出目标 Linux 发行版:** ```bash wsl --export Ubuntu D:/export.tar ``` **3. 卸载原有的 Linux 发行版:** ```bash wsl --unregister Ubuntu ``` **4. 将导出文件导入到目标目录:** ```bash wsl --import Ubuntu D:\export\ D:\export.tar --version 2 ``` --- ## 下一步:在 WSL 内部署 CubeStudio WSL2 的 Ubuntu 环境准备好后,进入该 Linux 子系统,按单机部署流程继续: - 推荐使用 k3s 单机部署,参见 [k3s 单机部署](./k3s单机部署.md)。 - 也可参考本段「部署方式」下的「单机部署」文档(基于标准 Kubernetes 的单机部署)。 --- ### 边缘集群部署 - 原理与适用场景 - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/%E9%83%A8%E7%BD%B2%E6%96%B9%E5%BC%8F/%E8%BE%B9%E7%BC%98%E9%9B%86%E7%BE%A4%E9%83%A8%E7%BD%B2-KubeEdge/01-%E5%8E%9F%E7%90%86%E4%B8%8E%E9%80%82%E7%94%A8%E5%9C%BA%E6%99%AF - 分类: 02-部署安装 / 部署方式 / 边缘集群 - 适用场景: 想先搞清楚边缘集群形态适合什么场景、网络访问有什么固有限制、以及除 keadm 外还有哪些方式建边缘 k8s 集群时读这篇 - 关键词: KubeEdge / 边缘计算 / 适用场景 / 网络方向 / 单向访问 / NAT / EdgeMesh / superedge / kubesphere / 边缘k8s / edgeadm / 中心网络 / 边缘网络 / 代理IP / SERVICE_EXTERNAL_IP - 最后更新: 2026-07-04 # 边缘集群部署 - 原理与适用场景 ## 一、适用场景 通过边缘集群的形式,在中心节点部署平台,并将边缘节点加入调度。每个私有网用户通过项目组,把 notebook、pipeline、推理服务(service)部署在边缘节点。好处: 1. 避免数据到中心节点的带宽传输; 2. 避免中心节点的算力成本,充分利用边缘节点算力; 3. 避免边缘节点的运维成本(统一由中心纳管)。 ![边缘集群示意](https://foruda.gitee.com/images/1700636449934874461/6689e2f6_1019082.png) ### 支持设备 1. 边缘设备支持英伟达 ARM 盒子; 2. 独立子网的服务器或 PC,例如商城或门店的机房。 --- ## 二、网络访问方向(核心原则,决定了所有限制) 1. **边缘网络的用户可以访问边缘网络和中心网络;中心网络的用户无法访问边缘网络**。所以部署在边缘网络中的 k8s 服务都无法被中心网络访问。 2. 在中心网络和边缘网络中间也无法通过 k8s 服务名进行代理;但在中心网络或边缘网络**内部**可以通过 k8s 服务名进行代理。 3. 中心网络部署 CubeStudio 平台的控制器部分,边缘网络部署用户容器(notebook / pipeline 任务 / 服务容器)。使用时主要涉及两个操作: - 将 minio 的 host 改为中心网络的 IP(而不是服务名),因为边缘网络的任务无法通过服务名访问中心网络的 minio,但通过 IP 可以; - 为每个边缘网络配置专门的项目组,并在项目组中配置服务代理 IP(边缘网络的某台机器 IP),这样边缘网络的 notebook / service 就会自动使用代理 IP 进行访问。 ### 由此带来的 by-design 限制(不是 bug) - **Cloud → Edge pod 方向走不通**:边缘在 NAT 后面,云端 flannel 无法主动建 VXLAN 隧道到边缘,公网经 istio ingressgateway → ClusterIP → edge pod 会返回 502。 - **Edge 内网用户可用**:CubeStudio 为边缘 service 建 `-external`(`externalIPs=[边缘内网 IP]`,端口为 NodePort)。同子网用户直接 `curl http://<边缘内网IP>:/` 即可,web UI 显示的访问地址就是这个。 - **云端 pod → Edge pod**:边缘 flannel 主动建的 VXLAN 是单向的,云端节点能 curl 到 edge pod IP,但云端 service 的 iptables 规则不会自动同步到边缘,除非修了 kube-proxy(见 [05](05-边缘节点接入与项目组配置.md))。 > 要把边缘服务暴露到公网,需自己在边缘上加反向代理(nginx / frp)。 --- ## 三、搭建边缘 K8s 集群的几种方式 把边缘节点接入云端 K8s,前提是先有一套支持边缘的 K8s 集群。除了本目录主线推荐的 **kubeadm 云端 K8s + keadm 接入边缘**(见 [03](03-云端环境准备-K8s与NFS.md) ~ [05](05-边缘节点接入与项目组配置.md)),还有以下几种历史/备选方式。 ### 方式 1:直接在云厂商选择边缘 K8s 集群 各云厂商控制台一般都有"边缘容器服务"产品,开箱即用。 ![云厂商边缘集群](https://pek3b.qingstor.com/kubesphere-community/images/1621239902-395149-image.png) ### 方式 2:使用 SuperEdge(edgeadm) 每台机器先初始化环境,下载 `edgeadm`: ```bash arch=amd64 version=v0.7.0 kubernetesVersion=1.22.6 && \ rm -rf edgeadm-linux-* && \ wget https://superedge-1253687700.cos.ap-guangzhou.myqcloud.com/$version/$arch/edgeadm-linux-$arch-$version-k8s-$kubernetesVersion.tgz && \ tar -xzvf edgeadm-linux-* && \ cd edgeadm-linux-$arch-$version-k8s-$kubernetesVersion && ./edgeadm ``` 云上主节点执行 init(替换尖括号里的 IP): ```bash ./edgeadm init --kubernetes-version=1.22.6 \ --image-repository superedge.tencentcloudcr.com/superedge \ --service-cidr=10.42.0.0/16 --pod-network-cidr=10.43.0.0/16 \ --install-pkg-path ./kube-linux-*.tar.gz \ --apiserver-cert-extra-sans= \ --apiserver-advertise-address= \ --enable-edge=true ``` init 后会弹出边缘节点 join 命令,在边缘节点执行类似: ```bash ./edgeadm join 175.178.172.40:6443 --token 9hepes.rppzsjbo7hu2odkx \ --discovery-token-ca-cert-hash sha256:170ced41d33851f64c7d4f7660dc0747931f733a5d67c3b0d832b4f202ef9e85 \ --install-pkg-path ./kube-linux-*.tar.gz ``` 清理(记得删除): ```bash rm -rf /etc/docker/daemon.json ``` ### 方式 3:使用 KubeSphere + KubeEdge #### 云上用 KubeSphere 部署 K8s 集群 参考 KubeSphere 部署 CubeStudio,先在云上用 KubeSphere 部署 K8s,然后在"自定义资源"中搜索 `clusterconfiguration`,修改 `ks-installer` 的 yaml: - 把 `edgeruntime` 和 `kubeedge` 下的 `enabled` 从 `false` 改为 `true`,并配置 `advertiseAddress` 为公网 IP; - 把 `metrics_server` 改为 `true`,`openpitrix` 下 `store` 改为 `true`。 之后会出现 `kubeedge` 命名空间,在 web 界面"节点管理"下会出现边缘节点入口,按要求填写验证后会生成节点加入命令。该命令中: - `./keadm join -r docker`:`-r` 指定边缘节点运行时,这里用 docker 运行时; - `--cloudcore-ipport=<公网IP>:30000`:后面是公网地址 + `kubeedge` 命名空间 cloudcore 服务的 NodePort 端口; - `--quicport 30001 --certport 30002 --tunnelport 30004`:也全部换成 NodePort 端口。 #### 开启 cloudcore dynamicController 开启后才能直接访问边缘节点的服务,不需要可以不开。修改 `kubeedge` 命名空间下 `cloudcore` 这个 configmap: ```yaml modules: ... dynamicController: enable: true ``` 然后重启 cloudcore。 #### 添加边缘节点(配置 EdgeMesh) 边缘节点自行安装 docker,并配置 EdgeMesh: ```bash vi /etc/nsswitch.conf # hosts: 行改为: hosts: dns files mdns4_minimal [NOTFOUND=return] echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf sysctl -p | grep ip_forward ``` 执行 web 界面复制的边缘节点添加命令,类似: ```bash arch=$(uname -m); if [[ $arch != x86_64 ]]; then arch='arm64'; fi; \ curl -LO https://kubeedge.pek3b.qingstor.com/bin/v1.13.0/$arch/keadm-v1.13.0-linux-$arch.tar.gz && \ tar xvf keadm-v1.13.0-linux-$arch.tar.gz && chmod +x keadm && \ ./keadm join --kubeedge-version=1.13.0 --cloudcore-ipport=<公网IP>:30000 \ --quicport 30001 --certport 30002 --tunnelport 30004 \ --edgenode-name test100 --edgenode-ip 192.168.3.100 --token ``` 开启边缘节点上 pod 的 metric / log / exec 等操作: ```bash vi /etc/kubeedge/config/edgecore.yaml # 把 edgeStream 段的 enable 改为 true # 如果需要访问边缘节点上的服务,配置 clusterDNS: # edged: # clusterDNS: 169.254.96.16 # clusterDomain: cluster.local systemctl restart edgecore.service ``` 边缘端开启 EdgeStream,云端部署 CloudCore 后会自动开启。可能需要重启机器,之后即可在云端查看边缘节点上 pod 的日志和资源使用。 #### 卸载边缘节点 ```bash # 在边缘节点上执行 ./keadm reset # 按提示输入 y # 或强制卸载 ./keadm reset --force apt remove mosquitto # 删除相关文件 rm -rf /etc/systemd/system/edgecore.service /usr/lib/systemd/system/edgecore.service rm -rf /etc/kubeedge /var/lib/kubeedge /var/lib/edged # 在云端删除节点 kubectl delete node <边缘节点名> # 停止服务 systemctl stop edgecore.service systemctl daemon-reload ``` > 上述方式 2/3 为历史记录,命令中的版本(k8s 1.22.6 / KubeEdge v1.13.0 等)较旧。本目录主线([03](03-云端环境准备-K8s与NFS.md) 起)用的是更新的 K8s v1.28 + KubeEdge v1.23.0 + containerd 运行时。 --- ### 边缘集群部署 - 一键脚本(install/kubernetes/kubeedge) - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/%E9%83%A8%E7%BD%B2%E6%96%B9%E5%BC%8F/%E8%BE%B9%E7%BC%98%E9%9B%86%E7%BE%A4%E9%83%A8%E7%BD%B2-KubeEdge/02-%E4%B8%80%E9%94%AE%E8%84%9A%E6%9C%AC%E9%83%A8%E7%BD%B2 - 分类: 02-部署安装 / 部署方式 / 边缘集群 - 适用场景: 云端 K8s 已就绪、kubeadm init 时已加公网 SAN,想用编号脚本几条命令把边缘节点接入时读这篇 - 关键词: KubeEdge / 一键脚本 / keadm / cloudcore / 00-check-prereq / 10-cloud-cloudcore / 20-cloud-rbac / 30-edge-join / 40-edge-fix-label / 45-fix-kube-proxy / 50-verify / gettoken / 卸载 / uninstall - 最后更新: 2026-07-04 # 边缘集群部署 - 一键脚本 `install/kubernetes/kubeedge/` 下提供了一套编号脚本,用 KubeEdge 把本地/专线/独立机房的边缘节点接入云端 K8s,CubeStudio 统一调度训练(云)与推理(边)。完整原理见本目录其它子文档([03](03-云端环境准备-K8s与NFS.md) ~ [06](06-验证与最大坑-label硬编码.md))。 > 来源:`install/kubernetes/kubeedge/README.md`。脚本以仓库实际文件为准。 --- ## 脚本目录 | 文件 | 在哪执行 | 用途 | |---|---|---| | `00-check-prereq.sh` | 云端 | 检查 K8s / containerd / 端口 | | `10-cloud-cloudcore.sh ` | 云端 | 一键装 keadm + CloudCore + 开 dynamicController | | `20-cloud-rbac.yaml` | 云端 | CloudCore 需要的 ClusterRole(聚合到默认 cloudcore 角色) | | `30-edge-join.sh ` | 边缘 | keadm join + 配 edgecore + 装 CNI 插件 | | `40-edge-fix-label.sh ` | 云端 | ⭐ 修复 edge 节点 label 为空值 | | `45-fix-kube-proxy.sh ` | 云端 | ⭐ 修复 kube-proxy server 为公网 IP | | `50-verify.sh ` | 云端 | 跑一个 busybox 测试 pod,验证落到边缘并 Running | > `20-cloud-rbac.yaml` 实际定义的 ClusterRole 名为 `cloudcore-extra`,带 `rbac/aggregate-to-cloudcore: "true"` 标签,补齐 v1.23 以下 keadm 默认不全的 CRD 权限(`devices.kubeedge.io` / `apps.kubeedge.io` / `policy.kubeedge.io` 等)。见 `install/kubernetes/kubeedge/20-cloud-rbac.yaml`。 --- ## 快速流程 > 前提:K8s 集群已就绪,且 kubeadm init 时加了 `--apiserver-cert-extra-sans=<公网 IP>`(四大坑之 4)。 ### 云端(一次性) ```bash cd install/kubernetes/kubeedge # 1. 前置检查 bash 00-check-prereq.sh # 2. 装 CloudCore(传 advertise IP,必须是公网/边缘能到达的 IP) bash 10-cloud-cloudcore.sh 47.114.127.214 # 3. RBAC 补齐(keadm 装的默认 cluster role 少权限) kubectl apply -f 20-cloud-rbac.yaml # 4. 让 kube-proxy 走公网 IP(否则边缘节点永远同步不到 service 规则) bash 45-fix-kube-proxy.sh 47.114.127.214 # 5. 取 token,下面边缘要用 keadm gettoken ``` ### 边缘(每台) ```bash # 把脚本 + token 传到边缘(SSH/scp) scp 30-edge-join.sh user@edge:/tmp/ ssh user@edge "sudo bash /tmp/30-edge-join.sh <上面拿到的 token> 47.114.127.214:10000 edge-pc-01" ``` `30-edge-join.sh` 会自动:装 keadm / stop docker / 调 containerd `SystemdCgroup` / keadm join / 打开 `edgeStream`+`metaServer` / 装 CNI plugins。 ### 云端:修 label 并验证 ```bash bash 40-edge-fix-label.sh edge-pc-01 bash 50-verify.sh edge-pc-01 ``` 看到 `POD edge-verify RUNNING ON edge-pc-01 ✓` 即全通。 --- ## CubeStudio 项目组配置 - Web UI → 项目管理 → 新建"边缘项目组"; - `SERVICE_EXTERNAL_IP` 填边缘代理 IP(或云端公网 IP 做验证); - 挂到边缘项目组的 notebook / pipeline task / inference service 会自动打 `serving=true` 等 label,被 scheduler 调度到 edge 节点。 关键代码位置(节点选择器默认值与组装逻辑): - `myapp/models/model_serving.py:51,232`:推理默认 `cpu=true;serving=true` - `myapp/models/model_job.py:385,742`:训练/任务默认 `cpu=true;train=true` - `myapp/models/base.py:316`:`get_default_node_selector`(按 GPU / org 组装最终 selector) > ⚠️ 说明:`install/kubernetes/kubeedge/README.md` 原文写的是 `model_job.py:188,545`,但当前代码里 `node_selector` 默认值实际在 `model_job.py:385` 与 `:742`(值仍为 `cpu=true;train=true`),此处已按代码改正。 --- ## ⚠️ 访问边缘推理服务(by design) CubeStudio 给边缘 service 配的 `externalIPs` 是**边缘节点内网 IP**(如 `192.168.3.22`)+ NodePort(如 `20038`)。这是 KubeEdge + NAT 边缘的必然限制: - **Cloud → Edge pod 方向**:云端 flannel 没法建 VXLAN 到 NAT 后的边缘,公网经 istio ingress → ClusterIP → edge pod 走不通(502); - **Edge 内网用户**:同子网下直接 `curl http://:/xxx` 可用; - **云端 pod → Edge pod**:边缘 flannel 主动建的 VXLAN 单向,云端能 curl 到 edge pod IP,但 service iptables 规则不会在边缘生效,除非跑了 `45-fix-kube-proxy.sh`。 所以 web UI 里看到的"访问地址"默认就是 `http://<边缘内网 IP>:`,供边缘网内用户使用。 --- ## 卸载 云端: ```bash helm uninstall cloudcore -n kubeedge 2>/dev/null || true kubectl delete ns kubeedge --grace-period=0 --force kubectl get crd | grep kubeedge | awk '{print $1}' | xargs -r kubectl delete crd rm -rf /etc/kubeedge /var/lib/kubeedge ``` 边缘: ```bash sudo keadm reset --force sudo rm -rf /etc/kubeedge /var/lib/kubeedge /var/lib/edged \ /etc/systemd/system/edgecore.service \ /usr/lib/systemd/system/edgecore.service sudo systemctl daemon-reload ``` > 如果 `kubectl delete ns kubeedge` 卡在 Terminating,见 [07-踩坑速查](07-踩坑速查.md) 的"namespace 卡 Terminating"。 --- ### 边缘集群部署 - 云端环境准备(K8s + NFS) - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/%E9%83%A8%E7%BD%B2%E6%96%B9%E5%BC%8F/%E8%BE%B9%E7%BC%98%E9%9B%86%E7%BE%A4%E9%83%A8%E7%BD%B2-KubeEdge/03-%E4%BA%91%E7%AB%AF%E7%8E%AF%E5%A2%83%E5%87%86%E5%A4%87-K8s%E4%B8%8ENFS - 分类: 02-部署安装 / 部署方式 / 边缘集群 - 适用场景: 从零在公网云主机上用 kubeadm+containerd 装单节点 K8s、并搭云端 NFS 服务端作为跨端共享存储时读这篇(云-边主线 Phase A/B) - 关键词: kubeadm / containerd / containerd2.x / flannel / registry mirror / certs.d / nerdctl / crictl / NFS / nfs-kernel-server / exports / 安全组 / sandbox / SystemdCgroup / apiserver-cert-extra-sans / transfer service - 最后更新: 2026-07-09 # 边缘集群部署 - 云端环境准备(K8s + NFS) 本篇对应一次从零到可用的跨公网"云-边"部署的前两个阶段:**Phase A 云端 K8s 集群** + **Phase B 云端 NFS 服务端**。公网云主机作为云端(K8s 控制面 + cube-studio + CloudCore + NFS 服务端)。 > 来源:`docs/部署/kubeedge部署边缘集群cube-studio.md` 第 0~3 节。覆盖云厂商安全组、Ubuntu 24.04 适配、containerd 2.x 镜像 mirror、NFS 跨公网挂载。 --- ## 零、交付前必读:要替换的变量 文档里所有命令用的都是作者当时环境的示例值。正式部署前请把下列占位符换成你自己的: | 占位符 | 示例(作者的) | 说明 | 怎么查 | |---|---|---|---| | `<云端公网IP>` | `47.114.127.214` | 云端主机公网 IP,边缘节点必须能访问 | 云厂商控制台 / `curl ifconfig.me` | | `<云端内网IP>` | `172.30.159.159` | 云端 eth0 的 IP,可能 == 公网 IP(无 NAT 的云)或私网 IP(阿里云 ECS) | `ip -4 addr show eth0` | | `<云端内网CIDR>` | `172.30.0.0/16` | 云端 VPC 内网 CIDR,用于 NFS exports | 云厂商 VPC 配置 | | `<边缘节点名>` | `edge-pc` | kubectl 里的 node 名称 | 自己取,建议只有小写字母/数字/`-` | | `<边缘内网IP>` | `192.168.3.22` | 边缘节点在局域网的 IP | 边缘机 `ip -4 addr show` | | `<边缘内网CIDR>` | `192.168.3.0/24` | 边缘所在局域网 CIDR | 边缘路由器配置 | | `` / `` | `825485697` / `<你的密码>` | `ccr.ccs.tencentyun.com` 私有仓库凭证(CubeStudio 商业版镜像在那里) | 供应商提供 | > **关于边缘出口公网 IP**:本文不需要这个值。早期版本曾用边缘出口 IP 来做 NFS export 白名单和安全组放行,但家宽/4G 出口 IP 会变,每次变都要改云端 export + 安全组并强制重挂,经常凌晨断服。现在统一改成 `*` / `0.0.0.0/0`(详见 Phase B 末尾"安全权衡")。 ### 其它要自己确定的 - **云厂商**:示例是阿里云。任意厂商都行,唯一要求:云主机有固定公网 IP,能开放 `22/80/443/6443/10000-10004/2049` 端口。 - **K8s 版本**:本文用 `v1.28.15`。K8s 1.25–1.29 都 OK,KubeEdge 必须对应升到 ≥ v1.22(K8s 1.28+ 上 v1.20 有 bug)。 - **CubeStudio 商业版镜像凭证**:只有社区版镜像的话,[04](04-云端CubeStudio与CloudCore.md) 里的 `hubsecret` 部分可跳过。 --- ## 一、环境(示例) ### 角色 | 角色 | 位置 | 规格 | OS | |---|---|---|---| | 云端 `cube` | 公网 `47.114.127.214` / 内网 `172.30.159.159` | ≥ 8 vCPU / 16 GiB | Ubuntu 22.04+ | | 边缘 `edge-pc` | NAT 内网 `192.168.3.22` / 出口公网 IP 不固定 | ≥ 4 C / 8 GiB | Ubuntu 20.04+ | ### 版本栈 - K8s:**v1.28.15**(kubeadm 自装,`registry.aliyuncs.com` 镜像源) - 容器运行时:**containerd 2.2.1(云)/ 1.7.3(边)** - CNI:flannel v0.25.6 - KubeEdge:最终用 **v1.23.0**(也试过 v1.20.0 / v1.22.1) ### 云厂商安全组 / 云主机防火墙(入方向,提前在控制台配置) | 端口 | 协议 | 源 | 用途 | |---|---|---|---| | 22 | TCP | 管理员 IP | SSH | | 80、443 | TCP | 0.0.0.0/0 | cube-studio Web | | 6443 | TCP | 0.0.0.0/0 | kube-apiserver(边缘 kube-proxy 要走公网连云端 apiserver) | | 10000-10004 | TCP | 0.0.0.0/0 | CloudCore(websocket / https / stream / tunnel) | | 2049、111、20048 | TCP/UDP | `0.0.0.0/0` | NFS(详见下方"安全权衡") | | 30000-32767 | TCP | 按需 | K8s NodePort(可选) | > **NFS 公网放行的安全权衡**:NFSv4 + `sec=sys` 没有真正的客户端鉴权,源 IP 是唯一防线。把 2049 对 `0.0.0.0/0` 开等于让全网都能尝试挂载 `/data/nfs`。本场景边缘出口 IP 经常变、`/data/nfs` 里只有 CubeStudio 的 pipeline workspace(无核心数据资产),团队接受这个风险。**如果 NFS 上有敏感数据,请改用 WireGuard**:给边缘分一个固定虚拟 IP,NFS export 写虚拟 IP,安全组只对 51820/udp 开放。 --- ## 二、Phase A:云端 K8s 集群(containerd + kubeadm) ### A.1 系统基线 ```bash apt-get update -qq swapoff -a sed -i.bak '/ swap / s/^/#/' /etc/fstab cat > /etc/modules-load.d/k8s.conf < /etc/sysctl.d/k8s.conf < /etc/containerd/config.toml ``` **关键配置**(containerd 2.x 与 1.x 语法不同): ```bash # 1. SystemdCgroup 改 true sed -i 's|SystemdCgroup = false|SystemdCgroup = true|' /etc/containerd/config.toml # 2. sandbox 镜像换阿里云(2.x 字段名是 sandbox,不是 sandbox_image) sed -i "s|sandbox = 'registry.k8s.io/pause:3.10.1'|sandbox = 'registry.aliyuncs.com/google_containers/pause:3.9'|" /etc/containerd/config.toml # 3. 开启 config_path(用于 certs.d 镜像 mirror) # 位置: [plugins.'io.containerd.cri.v1.images'.registry] config_path = '/etc/containerd/certs.d' # kubeadm generate 默认已有,确认即可 ``` **关键点:containerd 2.x 的 Transfer Service 需要单独配 `config_path`**(与 CRI registry 的 config_path 并列),否则 `kubelet/crictl pull` 仍会绕过 mirror 直连原始 registry: ```toml [plugins.'io.containerd.transfer.v1.local'] config_path = '/etc/containerd/certs.d' ``` 同时设置(强制走 CRI plugin 拉镜像): ```toml use_local_image_pull = true ``` ### A.3 registry mirror ```bash mkdir -p /etc/containerd/certs.d/docker.io cat > /etc/containerd/certs.d/docker.io/hosts.toml < /etc/containerd/certs.d/registry.k8s.io/hosts.toml < /etc/crictl.yaml < /etc/apt/sources.list.d/kubernetes.list apt-get update -qq apt-get install -y -qq kubelet kubeadm kubectl apt-mark hold kubelet kubeadm kubectl ``` ### A.6 kubeadm init > ⭐ **四大坑之 4**:`--apiserver-cert-extra-sans` 必须含公网 IP,否则后面改 kube-proxy server 为公网 IP 时证书不匹配照样握手失败。 ```bash kubeadm config images pull \ --image-repository=registry.aliyuncs.com/google_containers \ --kubernetes-version=v1.28.15 kubeadm init \ --apiserver-advertise-address=172.30.159.159 \ --apiserver-cert-extra-sans=47.114.127.214,172.30.159.159 \ --pod-network-cidr=10.244.0.0/16 \ --service-cidr=10.96.0.0/12 \ --kubernetes-version=v1.28.15 \ --image-repository=registry.aliyuncs.com/google_containers \ --cri-socket=unix:///run/containerd/containerd.sock mkdir -p /root/.kube cp /etc/kubernetes/admin.conf /root/.kube/config export KUBECONFIG=/etc/kubernetes/admin.conf ``` ### A.7 CNI plugins + flannel + 单节点去污 + 节点标签 **先装 CNI plugins**(Ubuntu 24.04 apt 的 containerd 不带 `loopback`/`bridge` 等基础插件;不装会一直 `failed to find plugin "loopback"`): ```bash mkdir -p /opt/cni/bin wget -q https://gh-proxy.com/https://github.com/containernetworking/plugins/releases/download/v1.4.0/cni-plugins-linux-amd64-v1.4.0.tgz -O /tmp/cni.tgz tar -xzf /tmp/cni.tgz -C /opt/cni/bin ``` ```bash # flannel manifest(github 直连会 timeout,走代理) wget -q https://gh-proxy.com/https://raw.githubusercontent.com/flannel-io/flannel/v0.25.6/Documentation/kube-flannel.yml -O /tmp/kube-flannel.yml sed -i 's|docker.io/flannel/|docker.m.daocloud.io/flannel/|g' /tmp/kube-flannel.yml kubectl apply -f /tmp/kube-flannel.yml # 单节点集群移除 control-plane taint kubectl taint nodes --all node-role.kubernetes.io/control-plane- # 云端训练节点标签(CubeStudio 按 label 调度 pipeline) kubectl label node cube \ train=true cpu=true org=public notebook=true service=true \ node-role.kubernetes.io/master=true gpu=false --overwrite ``` **验收**:`kubectl get nodes` → Ready;`kubectl get pods -A` 全 Running。 --- ## 三、Phase B:云端 NFS 服务端 ```bash apt-get install -y -qq nfs-kernel-server mkdir -p /data/nfs/k8s chmod -R 777 /data/nfs # 让 CubeStudio 默认的 hostPath /data/k8s/... 自动落到 NFS 导出区 rm -rf /data/k8s ln -sf /data/nfs/k8s /data/k8s ``` `/etc/exports`(**对所有 IP 放行**,原因见上方"安全权衡"——边缘出口 IP 不固定,按 IP 白名单运维成本太高): > **注意**:必须用 `*` 而不是 `0.0.0.0/0`。Ubuntu 24.04 NFS server 解析 `0.0.0.0/0` 后所有非本地 IP 一律 `mount.nfs: access denied by server`(即使 `exportfs -v` 显示规则已加载)。换成 `*` 立即可挂。这是 nfs-utils 的 CIDR 匹配 bug,不是配置写错。 ```bash cat > /etc/exports < 配合云厂商安全组也要对 `0.0.0.0/0` 放行 `2049/tcp`、`111/tcp+udp`、`20048/tcp`(见 Phase A 安全组表格)。两边都改完才算生效。边缘侧的挂载方式见 [05-边缘节点接入与项目组配置](05-边缘节点接入与项目组配置.md)。 --- 下一步:在云端部署 CubeStudio 与 CloudCore,见 [04-云端CubeStudio与CloudCore](04-云端CubeStudio与CloudCore.md)。 --- ### 边缘集群部署 - 云端部署 CubeStudio 与 CloudCore - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/%E9%83%A8%E7%BD%B2%E6%96%B9%E5%BC%8F/%E8%BE%B9%E7%BC%98%E9%9B%86%E7%BE%A4%E9%83%A8%E7%BD%B2-KubeEdge/04-%E4%BA%91%E7%AB%AFcube-studio%E4%B8%8ECloudCore - 分类: 02-部署安装 / 部署方式 / 边缘集群 - 适用场景: 云端 K8s/NFS 已就绪后,在云端部署 CubeStudio 控制面并装 KubeEdge CloudCore 时读这篇(云-边主线 Phase C/D) - 关键词: cube-studio / start.sh / config.py / CONTAINER_CLI / nerdctl / hubsecret / ccr / istio-ingressgateway / externalIPs / CloudCore / keadm init / dynamicController / requireAuthorization / vgpu-hami - 最后更新: 2026-07-04 # 边缘集群部署 - 云端部署 CubeStudio 与 CloudCore 本篇对应云-边主线的 **Phase C(云端部署 CubeStudio)** 与 **Phase D(云端 CloudCore / KubeEdge)**。承接 [03-云端环境准备-K8s与NFS](03-云端环境准备-K8s与NFS.md)。 > 来源:`docs/部署/kubeedge部署边缘集群cube-studio.md` 第 4~5 节。 --- ## 四、Phase C:云端部署 cube-studio ### C.1 代码上传 ```bash # 本地(Mac)打包 install/kubernetes(含 kustomize/cube 等) tar -czf /tmp/cube-k8s.tar.gz -C install kubernetes scp /tmp/cube-k8s.tar.gz root@47.114.127.214:/root/ # 云端解压 mkdir -p /root/cube-studio && cd /root/cube-studio tar -xzf /root/cube-k8s.tar.gz ``` ### C.2 改 config.py & start.sh ```bash cd /root/cube-studio/kubernetes # config.py:CubeStudio 调用容器 CLI,统一成 nerdctl sed -i 's|^CONTAINER_CLI=.docker.|CONTAINER_CLI="nerdctl"|' cube/overlays/config/config.py # kubeconfig 给 CubeStudio 用 cp /etc/kubernetes/admin.conf config mkdir -p kubeconfig && cp /etc/kubernetes/admin.conf kubeconfig/dev-kubeconfig ``` > `CONTAINER_CLI` 默认值是 `docker`(见 `myapp/config.py:1110`,注释写明可选 `docker` / `nerdctl`)。本场景没装 docker、用 containerd+nerdctl,所以改成 `nerdctl`。 **三处 patch**(否则 start.sh 会卡住或报语法错): 1. **跳过 kubectl 重下载**(已装 v1.28):把 `start.sh` 第 15/17 行的 `wget -O kubectl ...` 注释掉。**必须同时在 if/fi 里加一行 `true`**,否则空 if 体会报 `syntax error near unexpected token 'fi'`: ```bash if [ "$ARCH" = "x86_64" ]; then # # wget -O kubectl ... # # elif [ "$ARCH" = "aarch64" ]; then # # wget -O kubectl ... true # ← 必须加,否则 bash 语法错 fi ``` > 已核实:`install/kubernetes/start.sh:15,17` 确为 `wget -O kubectl https://cube-studio.oss-cn-hangzhou.aliyuncs.com/install/kubectl-amd64-1.28`(与 arm64 版)。 2. **node 标签查找改 fallback**:原脚本 `node=$(kubectl get node -o wide | grep $1 ...)`,传入的是公网 IP,grep 匹配不到内网 IP 的节点。改为: ```bash node=$(kubectl get node -o name | head -n 1 | sed 's|node/||') ``` 3. **跳过 docker 镜像预拉**:`init_node.sh` 里 `sh pull_images_mini.sh` 用 `docker pull`(没装 docker),改成: ```bash # sh pull_images_mini.sh echo SKIP pull_images_mini # 用 containerd 懒拉 ``` ### C.3 跑 start.sh ```bash cd /root/cube-studio/kubernetes nohup bash start.sh 47.114.127.214 > /root/start.log 2>&1 & tail -f /root/start.log ``` ### C.4 修 ccr 私有镜像鉴权 `create_ns_secret.sh` 用 `xxx/xxx` 占位凭证创建 `hubsecret`,`ccr.ccs.tencentyun.com` 私有镜像会 401 拉失败。 > 已核实:`install/kubernetes/create_ns_secret.sh:7` 确为 `kubectl create secret docker-registry hubsecret --docker-server=ccr.ccs.tencentyun.com --docker-username=xxx --docker-password=xxx`,需替换成真实凭证。 获取正确凭证后(若旧环境上已有 `/root/.docker/config.json`,可解 base64 取 `username:password`),批量重建各命名空间的 `hubsecret`: ```bash for ns in infra kubeflow istio-system pipeline automl jupyter service monitoring logging kube-system aihub default; do kubectl -n $ns delete secret hubsecret 2>/dev/null kubectl -n $ns create secret docker-registry hubsecret \ --docker-server=ccr.ccs.tencentyun.com \ --docker-username=<你的账号> \ --docker-password=<你的密码> done # 触发失败 pod 重拉 kubectl get pods -A --no-headers | awk '$4 ~ /ImagePullBackOff|ErrImagePull/ {print $1, $2}' | \ while read ns pod; do kubectl delete pod -n $ns $pod --grace-period=0 --force; done ``` ### C.5 修 istio-ingressgateway Service CubeStudio 的 install YAML(`install/kubernetes/istio/install-1.15.0.yaml`)里只有 istio-ingressgateway 的 Deployment 没有 Service,需手动建 ClusterIP + externalIPs: ```bash cat > /tmp/ingress-svc.yaml < **注意**:v1.23.0 的 release tarball 解压后内层目录名其实是 `keadm-v1.20.0-linux-amd64/`(KubeEdge 上游打包失误),`keadm version` 也会显示 v1.20.0。这**不影响实际部署的 cloudcore 镜像版本**——`keadm init --kubeedge-version=v1.23.0` 才决定用哪个镜像。 ### D.2 init ```bash keadm init \ --advertise-address=47.114.127.214 \ --set iptablesManager.mode="external" \ --kubeedge-version=v1.23.0 ``` ### D.3 打开 dynamicController cloudcore configmap 的 `data` 是一个 yaml 字符串(不是顶层结构),不能直接 sed 整个 cm yaml。要先把字符串导出、改完再 apply 回去: ```bash # 导出 cloudcore.yaml 字段到临时文件 kubectl get cm -n kubeedge cloudcore -o jsonpath='{.data.cloudcore\.yaml}' > /tmp/cc.yaml # 改 dynamicController.enable: false → true sed -i '/dynamicController:/{n;s|enable: false|enable: true|;}' /tmp/cc.yaml # 写回 configmap kubectl create cm cloudcore -n kubeedge --from-file=cloudcore.yaml=/tmp/cc.yaml \ --dry-run=client -o yaml | kubectl apply -f - # Deployment 默认 RollingUpdate,但 cloudcore 用 hostNetwork 需端口独占,改 Recreate kubectl patch deployment cloudcore -n kubeedge -p '{"spec":{"strategy":{"type":"Recreate","rollingUpdate":null}}}' kubectl rollout restart deployment cloudcore -n kubeedge ``` > **注意**:`featureGates.requireAuthorization` 默认 `false`。启用会引入大量 RBAC / `serviceaccountaccesses` reconcile 逻辑,调试复杂,**建议保持 false**。 ### D.4 RBAC(仅启用 requireAuthorization 时需要) 启用 `requireAuthorization` 才需要补 ClusterRole。仓库提供了现成的 `install/kubernetes/kubeedge/20-cloud-rbac.yaml`(ClusterRole 名 `cloudcore-extra`,带 `rbac/aggregate-to-cloudcore: "true"` 标签,会自动聚合到默认 cloudcore 角色,覆盖 `devices.kubeedge.io` / `apps.kubeedge.io` / `policy.kubeedge.io` 等 CRD 权限): ```bash kubectl apply -f install/kubernetes/kubeedge/20-cloud-rbac.yaml kubectl rollout restart deployment cloudcore -n kubeedge ``` > 老环境若报 `failed to list *v1beta1.DeviceStatus forbidden`(缺 `devices.kubeedge.io` 权限),也应用这个文件补齐,见 [07-踩坑速查](07-踩坑速查.md)。 ### D.5 拿 token ```bash keadm gettoken # 输出形如:xxxxx.eyJhbGciOi... (边缘 keadm join 时用) ``` --- 下一步:边缘节点接入与 CubeStudio 项目组配置,见 [05-边缘节点接入与项目组配置](05-边缘节点接入与项目组配置.md)。 --- ### 边缘集群部署 - 边缘节点接入与项目组配置 - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/%E9%83%A8%E7%BD%B2%E6%96%B9%E5%BC%8F/%E8%BE%B9%E7%BC%98%E9%9B%86%E7%BE%A4%E9%83%A8%E7%BD%B2-KubeEdge/05-%E8%BE%B9%E7%BC%98%E8%8A%82%E7%82%B9%E6%8E%A5%E5%85%A5%E4%B8%8E%E9%A1%B9%E7%9B%AE%E7%BB%84%E9%85%8D%E7%BD%AE - 分类: 02-部署安装 / 部署方式 / 边缘集群 - 适用场景: 云端 cube-studio + CloudCore 就绪后,把 NAT 后的边缘节点 keadm join 进来、装 CNI、修 kube-proxy,并在 CubeStudio 配边缘项目组时读这篇(云-边主线 Phase E/F) - 关键词: keadm join / edgecore / containerd / CNI plugins / loopback / kube-proxy / kubeconfig / NFS mount / edgeStream / metaServer / 边缘项目组 / SERVICE_EXTERNAL_IP / node_selector / minio / NodePort / workflow-controller-configmap - 最后更新: 2026-07-04 # 边缘集群部署 - 边缘节点接入与项目组配置 本篇对应云-边主线的 **Phase E(边缘节点接入)** 与 **Phase F(CubeStudio 项目组配置)**。承接 [04-云端CubeStudio与CloudCore](04-云端CubeStudio与CloudCore.md)。 > 来源:`docs/部署/kubeedge部署边缘集群cube-studio.md` 第 6~7 节 + `docs/部署/边缘集群方式部署平台.md` 的部署流程。 --- ## 六、Phase E:边缘节点接入 ### E.1 处理存量 docker 边缘机原装 `docker-ce`,**底层已有 containerd 1.7.3**,只需停 docker.service 保留 containerd: ```bash systemctl stop docker.service docker.socket systemctl disable docker.service docker.socket ``` ### E.2 containerd 调整 ```bash # SystemdCgroup = true(v1.7.x 语法) sed -i 's|SystemdCgroup = false|SystemdCgroup = true|' /etc/containerd/config.toml # registry mirror(同云端) mkdir -p /etc/containerd/certs.d/docker.io cat > /etc/containerd/certs.d/docker.io/hosts.toml < `ccr.ccs.tencentyun.com` 的凭证文件 `/root/.docker/config.json`(docker-ce 时代留下的)nerdctl 会自动读取,无需再配。 ### E.3 挂载云端 NFS ```bash apt-get install -y -qq nfs-common mkdir -p /data/nfs mount -t nfs -o vers=4,rsize=1048576,wsize=1048576,hard,timeo=600,intr \ 47.114.127.214:/data/nfs /data/nfs # 持久化(autofs 风格,断网不阻塞开机) echo "47.114.127.214:/data/nfs /data/nfs nfs vers=4,rsize=1048576,wsize=1048576,hard,timeo=600,intr,_netdev,noauto,x-systemd.automount,x-systemd.idle-timeout=600 0 0" >> /etc/fstab # /data/k8s 软链到 NFS(与云端结构一致,cube-studio hostPath 可直接跨端共享) if [ -d /data/k8s ]; then mv /data/k8s /data/k8s.local.bak.$(date +%s); fi ln -sf /data/nfs/k8s /data/k8s ``` **验证**: ```bash echo "hello from edge $(date)" > /data/nfs/edge-test.txt # 边缘写 ssh root@47.114.127.214 cat /data/nfs/edge-test.txt # 云端读 ``` ### E.4 keadm join ```bash KEADM_VER=1.23.0 wget -q https://gh-proxy.com/https://github.com/kubeedge/kubeedge/releases/download/v${KEADM_VER}/keadm-v${KEADM_VER}-linux-amd64.tar.gz -O /tmp/keadm.tar.gz mkdir -p /tmp/keadm-extract tar -xzf /tmp/keadm.tar.gz -C /tmp/keadm-extract cp $(find /tmp/keadm-extract -name keadm -type f | head -1) /usr/local/bin/keadm TOKEN=<从云端 keadm gettoken 取> keadm join \ --token=$TOKEN \ --cloudcore-ipport=47.114.127.214:10000 \ --kubeedge-version=v1.23.0 \ --remote-runtime-endpoint=unix:///run/containerd/containerd.sock \ --cgroupdriver=systemd \ --edgenode-name=edge-pc ``` ### E.5 edgecore.yaml 开关 ```bash # edgeStream(让 kubectl logs/exec 穿透到边缘 pod) # 只改 edgeStream 段里的 enable,别用全局 sed 否则会把 websocket/quic 也误动 python3 - <<'PY' p = "/etc/kubeedge/config/edgecore.yaml" lines = open(p).readlines() out, in_es = [], False indent_es = None for L in lines: s = L.lstrip() ind = len(L) - len(s) if s.startswith("edgeStream:"): in_es = True; indent_es = ind; out.append(L); continue if in_es: if ind <= indent_es and s.strip() and not s.startswith("#"): in_es = False elif s.startswith("enable:"): L = " " * ind + "enable: true\n"; in_es = False out.append(L) open(p, "w").writelines(out) PY systemctl restart edgecore systemctl is-active edgecore ``` > metaServer(让边缘本地能 `kubectl get`)按需打开 `modules.metaManager.metaServer.enable: true`。改 edgecore.yaml 切忌全局 `sed 's/false/true/g'`,`websocket.enable` 与 `quic.enable` 互斥,详见 [07-踩坑速查](07-踩坑速查.md)。 ### E.6 装 CNI 插件(⭐ 四大坑之 2,必做) keadm join 安装的 edgecore **只放了 flannel 一个 CNI 插件**在 `/opt/cni/bin/`。pod 启动时需要 `loopback`(必需)、`bridge`、`host-local`、`portmap` 等基础插件,否则报 `failed to find plugin "loopback" in path [/opt/cni/bin]`,pod sandbox 建不起来、永远 NotReady / ContainerCreating。 ```bash mkdir -p /opt/cni/bin wget https://gh-proxy.com/https://github.com/containernetworking/plugins/releases/download/v1.4.0/cni-plugins-linux-amd64-v1.4.0.tgz -O /tmp/cni.tgz tar -xzf /tmp/cni.tgz -C /opt/cni/bin ls /opt/cni/bin # 应有 loopback、bridge、host-local、portmap、flannel 等 20 个左右 systemctl restart edgecore ``` ### E.7 修 kube-proxy kubeconfig(⭐ 四大坑之 3,必做) kubeadm init 生成的 kube-proxy configmap 里 `server: https://<私网 IP>:6443`。边缘在公网连不到私网 IP,kube-proxy 一直 `i/o timeout`,**service iptables 规则永远不会同步到边缘节点**。后果: - ClusterIP 在边缘上 curl 不通; - CubeStudio 给边缘 service 配的 `externalIPs=[<边缘内网IP>]` + NodePort 在边缘节点上也不通(依赖 edge 上 kube-proxy 建规则)。 修复(云端执行): ```bash # 前提:kubeadm init 时必须加 --apiserver-cert-extra-sans=<公网 IP>(Phase A 已有),否则证书不匹配 kubectl get cm -n kube-system kube-proxy -o yaml | \ sed 's|server: https://172.30.159.159:6443|server: https://47.114.127.214:6443|' | \ kubectl apply -f - # 删边缘节点上的 kube-proxy pod 让它拿新配置 kubectl delete pod -n kube-system -l k8s-app=kube-proxy --field-selector spec.nodeName=edge-pc --grace-period=0 --force # 验证(边缘节点上):应 > 0,说明 service 规则已同步 sudo iptables-save | grep -c KUBE-SVC ``` ### E.8 云端标签 + 验证 ```bash # ⚠️ 注意: node-role.kubernetes.io/edge 必须空值(= 后面不要跟任何东西),见 06 节最大坑 kubectl label node edge-pc \ serving=true cpu=true org=edge \ node-role.kubernetes.io/edge= \ notebook=true gpu=false --overwrite kubectl rollout restart deployment cloudcore -n kubeedge # 让 cloudcore 重读 EdgeNodes kubectl get nodes -o wide # 期望:edge-pc Ready, containerd://1.7.3, v1.32.x-kubeedge-v1.23.0 ``` --- ## 七、Phase F:CubeStudio 项目组配置 ### F.1 minio 暴露 NodePort workflow artifacts 需要 pipeline 任务跨网访问 minio: ```bash kubectl patch svc minio -n kubeflow -p \ '{"spec":{"type":"NodePort","ports":[ {"name":"http","port":9000,"targetPort":9000,"nodePort":30900,"protocol":"TCP"}, {"name":"http-console","port":9001,"targetPort":9001,"nodePort":30901,"protocol":"TCP"}]}}' # workflow-controller-configmap 里的 minio endpoint 改公网 kubectl get cm -n kubeflow workflow-controller-configmap -o yaml | \ sed "s|endpoint: minio.kubeflow:9000|endpoint: 47.114.127.214:30900|" | \ kubectl apply -f - ``` > 这一步对应旧文档 `边缘集群方式部署平台.md` 里的部署流程要点:"修改 kubeflow/workflow-controller-configmap,把 `endpoint: minio.kubeflow:9000` 改为 minio 的公网 IP 端口"——因为边缘网络的任务无法通过 k8s 服务名访问中心网络的 minio。 ### F.2 Web 配置边缘项目组 登录 `http://47.114.127.214/` → 项目管理 → 新增"边缘项目组": - `SERVICE_EXTERNAL_IP`:填**边缘节点的内网 IP**(如 `192.168.3.22`),边缘网内用户能用此 `IP:NodePort` 访问; - 挂到该组的 notebook / pipeline 任务 / 推理服务会自动打 `serving=true` 等 label,被 scheduler 调度到 edge 节点; - ⚠️ 这个 IP 是**边缘网内访问**用的,公网路径走不通(by-design,见 [01-原理与适用场景](01-原理与适用场景.md))。 按调度方向使用: - **notebook**:在边缘服务器上部署的 notebook,会自动使用边缘服务器 IP 打开,所以只有你能访问的边缘服务器才能运行; - **pipeline**:pipeline 本身不需要提供服务,可以在中心网络下查看任务的运行和日志; - **推理服务**:在边缘服务器上部署的推理服务,会自动使用边缘服务器 IP 打开,同样要求你能访问该边缘服务器。 ### F.3 代码侧节点选择器位置 - `myapp/models/model_serving.py:51,232`:推理默认 `cpu=true;serving=true` - `myapp/models/model_job.py:385,742`:训练/任务默认 `cpu=true;train=true` - `myapp/models/base.py:316`:`get_default_node_selector`(按 GPU / org 组装最终 selector) > ⚠️ 说明:原文写 `model_job.py:188,545`,当前代码里 `node_selector` 默认值实际在 `model_job.py:385` 与 `:742`(值仍为 `cpu=true;train=true`),此处已按代码改正;`base.py` 函数定义在第 `316` 行。 --- 下一步:端到端验证与"最大坑 label 硬编码",见 [06-验证与最大坑-label硬编码](06-验证与最大坑-label硬编码.md)。 --- ### 边缘集群部署 - 端到端验证与最大坑(label 硬编码) - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/%E9%83%A8%E7%BD%B2%E6%96%B9%E5%BC%8F/%E8%BE%B9%E7%BC%98%E9%9B%86%E7%BE%A4%E9%83%A8%E7%BD%B2-KubeEdge/06-%E9%AA%8C%E8%AF%81%E4%B8%8E%E6%9C%80%E5%A4%A7%E5%9D%91-label%E7%A1%AC%E7%BC%96%E7%A0%81 - 分类: 02-部署安装 / 部署方式 / 边缘集群 - 适用场景: 边缘节点接入后做端到端验证;或遇到"边缘 pod 一直 Pending、cloudcore 日志刷 0 nodes need to sync"这类调度不下发问题时读这篇 - 关键词: 端到端验证 / busybox / 边缘推理 / node-role.kubernetes.io/edge / label硬编码 / EdgeNodes / downstream.go / IsEdgeNode / EdgeNodeRoleValue / cloudcore / Pending / 调度不下发 / LocationCache - 最后更新: 2026-07-04 # 边缘集群部署 - 端到端验证与最大坑(label 硬编码) 承接 [05-边缘节点接入与项目组配置](05-边缘节点接入与项目组配置.md)。本篇是云-边主线的 **Phase G 端到端验证**,以及跨多个 KubeEdge 版本都会踩的**最大坑**。 > 来源:`docs/部署/kubeedge部署边缘集群cube-studio.md` 第 8~9 节。 --- ## 八、Phase G:端到端验证 ### G.1 Web 公网 ```bash curl -sI http://47.114.127.214/frontend/ # HTTP/1.1 200 OK ``` ### G.2 NFS 双向 ```bash # 云端 echo "cloud-$(date +%s)" > /data/nfs/cloud-write.txt # 边缘 cat /data/nfs/cloud-write.txt ``` ### G.3 云端训练 Pod ```bash kubectl run cloud-training-test \ --image=docker.m.daocloud.io/library/busybox:1.36.0 \ --restart=Never \ --overrides='{"spec":{"nodeSelector":{"train":"true"}}}' \ --command -- sh -c "echo hello; sleep 30" kubectl get pod cloud-training-test -o wide # NODE=cube ``` ### G.4 边缘推理 Pod(快速用一键脚本) ```bash cd install/kubernetes/kubeedge bash 50-verify.sh edge-pc # ✅ POD edge-verify Running on edge-pc ``` 如果一直 Pending / ContainerCreating 不前进,按严重性逐项检查: | 现象 | 对应坑 | |---|---| | `kubectl describe pod` 只有 `Scheduled` 事件 | 本页第九节(label 非空) | | edgecore log 有 `failed to find plugin "loopback"` | CNI 插件缺失,见 [05 E.6](05-边缘节点接入与项目组配置.md) / [07](07-踩坑速查.md) | | 边缘上 `iptables-save \| grep KUBE-SVC` 空 | kube-proxy kubeconfig IP,见 [05 E.7](05-边缘节点接入与项目组配置.md) / [07](07-踩坑速查.md) | | 从公网 istio 访问边缘服务 502 | by-design,不是 bug,见 [01](01-原理与适用场景.md) / [07](07-踩坑速查.md) | ### G.5 边缘推理服务访问 CubeStudio 为边缘 service 建 `-external`(`externalIPs=[边缘内网 IP]`,port=NodePort): ```bash # 在和边缘同网段的机器上(192.168.3.0/24) curl -sI http://192.168.3.22:/docs # HTTP/1.1 200 OK ``` web UI 里显示的服务访问 URL 就是这个。公网用户访问不到。 --- ## 九、【最大坑】KubeEdge edge 节点 label 硬编码 > ⭐ 四大坑之 1。跨 v1.20.0 / v1.22.1 / v1.23.0 均复现。 ### 现象 - 边缘节点 Ready,但新建的 Pod/Deployment 永远 `Pending`,`kubectl describe` 只有 `Scheduled ... to edge-pc`,无后续事件; - cloudcore 日志反复输出 `downstream.go:128] there are 0 nodes need to sync config map, operation: MODIFIED`; - cloudcore 只会 dispatch 节点**刚加入时**被 DS controller 直接设 `nodeName` 的那几个 pod(kube-proxy / kube-flannel / node-exporter / edge-eclipse-mosquitto),之后一切静默。 ### 根因(已定位到 KubeEdge 源码) `cloud/pkg/edgecontroller/controller/downstream.go`: ```go func (dc *DownstreamController) syncPod() { ... if !dc.lc.IsEdgeNode(pod.Spec.NodeName) { continue // ← 所有 edge pod 在这里被静默丢弃 } ... } ``` `LocationCache.EdgeNodes` 是通过固定 label selector 填充的: ```go // common/constants/default.go EdgeNodeRoleKey = "node-role.kubernetes.io/edge" EdgeNodeRoleValue = "" // ← 必须空字符串! ``` keadm join 时会自动打上 `node-role.kubernetes.io/edge=`(空值)。**但如果之后手动 `kubectl label node node-role.kubernetes.io/edge=true` 去"强化"这个角色标记,label 值被覆盖成 `true`,`labels.SelectorFromSet({key:""})` 就匹配不到了,所有 edge pod 从此静默丢弃**。这就是 cube-studio web 界面上在边缘项目组里看到 pod 一直 Pending 的全部原因。 > ⚠️ 待核实:上述 KubeEdge 源码路径(`cloud/pkg/edgecontroller/controller/downstream.go`、`common/constants/default.go`)来自上游 KubeEdge 项目,不在本仓库 CubeStudio 代码里,无法在本仓库核对行号。结论(edge label 必须空值)已被作者跨三个版本验证,按现象使用即可。 ### 修复 ```bash # 检查:值必须是空字符串 kubectl get node -o jsonpath='{.metadata.labels.node-role\.kubernetes\.io/edge}' # 修复(若非空) kubectl label node node-role.kubernetes.io/edge- kubectl label node node-role.kubernetes.io/edge= # 让 cloudcore 重建 LocationCache kubectl rollout restart deployment cloudcore -n kubeedge ``` 重启后 cloudcore debug 日志(`--v=4`)应立刻看到: ``` message_dispatcher.go:140] [DispatchDownstream] dispatch Message to edge: Resource:node///pod/ Operation: update / insert ``` 边缘 `crictl pods` 也会看到新 sandbox,pod 从 Pending 变 ContainerCreating → Running。 ### 对 CubeStudio 的特别提醒 CubeStudio 在项目组页面可能让你打 `node-role.kubernetes.io/edge=true`(看起来更像 K8s 风格)。**不要这样打**。要么不动(keadm join 默认就对),要么 `=` 空值。其他用于 CubeStudio 自己调度的标签(`org=edge`、`serving=true` 等)不受影响,可正常打。 --- 更多次要的坑(CNI / kube-proxy 详解、镜像大小预算、NFS stale handle、DaemonSet CrashLoop 等)见 [07-踩坑速查](07-踩坑速查.md)。 --- ### 边缘集群部署 - 踩坑速查与版本命令 - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/%E9%83%A8%E7%BD%B2%E6%96%B9%E5%BC%8F/%E8%BE%B9%E7%BC%98%E9%9B%86%E7%BE%A4%E9%83%A8%E7%BD%B2-KubeEdge/07-%E8%B8%A9%E5%9D%91%E9%80%9F%E6%9F%A5 - 分类: 02-部署安装 / 部署方式 / 边缘集群 - 适用场景: KubeEdge 云-边部署中遇到具体报错(找不到 loopback、service 不通、502、镜像撑爆磁盘、NFS 卡死、ns 删不掉等)时按症状速查 - 关键词: CNI / loopback / kube-proxy / KUBE-SVC / 502 / by-design / parse message / DeviceStatus forbidden / docker image prune / 镜像大小 / containerd root / NFS stale handle / showmount / namespace Terminating / quic websocket 互斥 / kube-flannel CrashLoopBackOff / gh-proxy / 版本速查 - 最后更新: 2026-07-04 # 边缘集群部署 - 踩坑速查与版本命令 按严重程度排序的其它坑,以及常见坑附录、版本命令速查。配合 [06-验证与最大坑-label硬编码](06-验证与最大坑-label硬编码.md) 的四大坑一起看。 > 来源:`docs/部署/kubeedge部署边缘集群cube-studio.md` 第 10 节 + 附录 A/B。 --- ## 一、其它踩过的坑(按严重程度) ### 10.1 CNI 插件只有 flannel,缺 loopback/bridge(⭐⭐⭐ 必中) - **症状**:pod 一直 `ContainerCreating`,`kubectl describe` 看到 `Events: ` 但不报错;`journalctl -u edgecore` 有 `plugin type="loopback" failed (delete): failed to find plugin "loopback" in path [/opt/cni/bin]`。 - **原因**:keadm join 只放了 `flannel` 一个 CNI 插件,kubelet 建/拆 pod sandbox 必须要 `loopback`。 - **修复**:装 `containernetworking/plugins` v1.4.0(见 [05 E.6](05-边缘节点接入与项目组配置.md))。 ### 10.2 kube-proxy kubeconfig 默认是"云端私网 IP"(⭐⭐⭐ 必中) - **症状**:边缘上 `iptables-save | grep KUBE-SVC` 空无规则;service ClusterIP / external IP / NodePort 在**边缘节点本机**都不通;但直接 pod IP 能通。 - **排查**:边缘 kube-proxy pod 日志 `failed to list *v1.Service: Get "https://172.30.159.159:6443/...": dial tcp ...: i/o timeout`。 - **原因**:kubeadm 生成的 `kube-system/kube-proxy` configmap 里 `server:` 是 apiserver 监听的**私网 IP**,边缘经公网连不通。 - **修复**:configmap 的 server 改公网 IP(见 [05 E.7](05-边缘节点接入与项目组配置.md))。前提是 `kubeadm init --apiserver-cert-extra-sans=<公网 IP>`。 ### 10.3 Cloud → Edge pod 单向不通(⭐⭐ by-design) - **症状**:云端 istio ingressgateway → Service → edge pod 路由走不通,返回 502。 - **排查**:云端 `ip route` 里看不到 edge 节点 pod CIDR(如 `10.244.1.0/24`)的路由;edge flannel 只显示它主动连 cloud 的 VXLAN,cloud flannel 没有回建。 - **原因**:边缘在 NAT 后面,cloud flannel 无法主动建 VXLAN 隧道到边缘。这是 KubeEdge+NAT 边缘的固有限制。 - **解决方式**: - **不解决**:CubeStudio 已为此设计了单独的 `-external` Service(`externalIPs=[<边缘内网 IP>]`),边缘网内用户直接访问 `http://:/` 即可; - 要公网访问的话,自己在边缘上加反向代理(nginx / frp)把流量暴出去。 ### 10.4 cloudcore `parse message ... resource type not found`(⭐ 忽略) edgecore 上行 lease/status 消息格式 warning,**与 pod-sync 无关**,忽略即可。 ### 10.5 cloudcore `failed to list *v1beta1.DeviceStatus forbidden`(⭐ 老环境需补) 旧版 keadm 生成的 ClusterRole 缺 `devices.kubeedge.io` 权限。**修复**:`kubectl apply -f install/kubernetes/kubeedge/20-cloud-rbac.yaml`(该文件 ClusterRole 名 `cloudcore-extra`,补齐相关 CRD 权限)。 ### 10.6 `docker image prune -af` 会误删正在使用的镜像(⭐ 容易踩) `docker image prune -af` 清所有"没有 running container 使用"的镜像。如果把 docker.service 停了再 prune,**所有**镜像都被认定 idle 一次性全删。 - **教训**:想从 docker 迁移镜像到 containerd `k8s.io`,要先 `docker save | ctr -n k8s.io images import -` 流式迁移,**再**停 docker。 ### 10.7 镜像大小预算(⭐ 容易撑爆 /) `docker images` 显示的是**解压后**大小(如 yolo26 25.4 GB),但拉镜像到 containerd 时经历 "download 压缩态(13.5 GB) + unpack 解压到 overlayfs(25 GB)" 两阶段,峰值磁盘需要约 `压缩 + 解压`(约 38 GB)。 - **排查**:`/var/lib/containerd` 所在分区剩余空间要有单镜像大小 × 2 的余量,`df -h /` 检查。 - **修复**:如果 / 分区小,把 containerd root dir 搬到大盘后 `systemctl restart containerd`: ```toml # /etc/containerd/config.toml root = "/data/containerd" state = "/data/containerd-state" ``` ### 10.8 edgecore.yaml 的 quic / websocket.enable 互斥 edgecore 启动验证会检查 `websocket.enable` 和 `quic.enable` 不能**同时为 true**。盲用 `sed 's/false/true/g'` 会让 edgecore 启动失败。**修复**:用 python 按 YAML 结构定向改(见 [05 E.5](05-边缘节点接入与项目组配置.md) 脚本)。 --- ## 二、常见坑附录 ### A-1 containerd 2.x 的 mirror 不生效 默认启用 **Transfer Service** 做 pull,它有独立的 `config_path`。只配 CRI plugin 的 `config_path` 对 kubelet 拉镜像不够,必须也配 transfer plugin 的 `config_path`,或者设 `use_local_image_pull = true` 强制走 CRI plugin(见 [03 A.2](03-云端环境准备-K8s与NFS.md))。 ### A-2 Ubuntu 24.04 无 iptables-legacy / firewalld `init_node.sh` 里 `systemctl stop firewalld iptables ip6tables nftables` 报 `Unit not loaded` 可忽略。 ### A-3 GitHub release 下载超时 国内直连 `github.com/releases/download/*` 几乎必 timeout。替代前缀:`gh-proxy.com`(本文到处用)、`ghproxy.net`、`mirror.ghproxy.com`。 ### A-4 NFS `showmount -e` timeout 但 `mount -t nfs` 成功 `showmount` 走 rpcbind 端口 111,mount NFSv4 只要 2049。安全组只开 2049 的话 showmount 会超时,直接 mount 没问题。 ### A-4b NFS 挂载存活但 `ls /data/nfs` 报 `d?????????`(stale handle) 老方案按"边缘出口公网 IP"做 NFS export 白名单,出口 IP 一变(家宽重拨/4G 切换),边缘 NFS 客户端会 hang 成 stale handle,所有依赖 `/data/k8s/...` 的 pod 报 `failed to prepare subPath for volumeMount "kubeflow-user-workspace"` 进入 `CreateContainerConfigError`。 现在 export 已改成 `*`(见 [03 Phase B](03-云端环境准备-K8s与NFS.md),注意必须用 `*` 不是 `0.0.0.0/0`),不会再因 IP 变化失效。若延续了老的 IP 白名单方案又遇到,临时修复: ```bash # 云端 sed -i 's|^/data/nfs <旧IP>|/data/nfs <新IP>|' /etc/exports exportfs -ra # 边缘 umount -f -l /data/nfs mount -t nfs -o vers=4,rsize=1048576,wsize=1048576,hard,timeo=600 \ <云端公网IP>:/data/nfs /data/nfs # 云端:重启所有报错的 pod kubectl get pods -A | grep CreateContainerConfigError | \ awk '{print "kubectl delete pod -n", $1, $2, "--grace-period=0 --force"}' | bash ``` ### A-5 start.sh 脚本 node 名按 IP grep 匹配不到 脚本假设传入的 `$1` 是内网 IP 且能在 `kubectl get node -o wide` 输出里匹配到。本场景传的是公网 IP(用于 SERVICE_EXTERNAL_IP),grep 匹配不到,fallback 成"取第一个节点": ```bash node=$(kubectl get node -o name | head -n 1 | sed 's|node/||') ``` ### A-6 istio-ingressgateway 没 Service `install/kubernetes/istio/install-1.15.0.yaml` 里只有 Deployment 没有 Service,要手动建 ClusterIP + externalIPs(见 [04 C.5](04-云端CubeStudio与CloudCore.md))。创建后重启 istiod + ingressgateway 让 envoy 拿到 CA + route。 ### A-7 cloudcore 升级/重装后 ns 卡 Terminating `kubectl delete ns kubeedge` 可能因残留 pod finalizer 卡住,强制 finalize: ```bash kubectl get ns kubeedge -o json | \ python3 -c 'import json,sys;d=json.load(sys.stdin);d["spec"]["finalizers"]=[];print(json.dumps(d))' | \ kubectl replace --raw /api/v1/namespaces/kubeedge/finalize -f - ``` ### A-8 edgecore.yaml 改 `enable` 别用全局 sed `edgeStream.enable`、`quic.enable`、`websocket.enable`、`metaServer.enable` 各有取值约束(`websocket.enable=true` 和 `quic.enable=true` 互斥)。用 python 按 YAML 结构局部改,不要 `sed -i 's/false/true/g'`。 ### A-9 边缘上 kube-flannel-ds / node-exporter CrashLoopBackOff(无害) - `kube-flannel`:边缘 KubeEdge 自己实现网络(不通过 flannel),但 DaemonSet `tolerations: Exists` 强制把 pod 调度到 edge 节点,pod 起来发现没 cluster CIDR、没法 watch apiserver 就 crash; - `node-exporter`:依赖 hostNetwork + 一些 kernel proc 节点,KubeEdge edge 节点 kubelet socket 路径不一致。 这两个对 CubeStudio 推理流程**完全不影响**,可忽略。要彻底干净,加 nodeAffinity 排除 edge 节点: ```bash kubectl patch ds kube-flannel-ds -n kube-flannel \ -p '{"spec":{"template":{"spec":{"affinity":{"nodeAffinity":{"requiredDuringSchedulingIgnoredDuringExecution":{"nodeSelectorTerms":[{"matchExpressions":[{"key":"node-role.kubernetes.io/edge","operator":"DoesNotExist"}]}]}}}}}}}' kubectl patch ds node-exporter -n monitoring \ -p '{"spec":{"template":{"spec":{"affinity":{"nodeAffinity":{"requiredDuringSchedulingIgnoredDuringExecution":{"nodeSelectorTerms":[{"matchExpressions":[{"key":"node-role.kubernetes.io/edge","operator":"DoesNotExist"}]}]}}}}}}}' ``` --- ## 三、版本命令速查 ```bash # 云端 kubectl version --short # v1.28.15 containerd --version # 2.2.1 nerdctl --version # 1.7.6 keadm version # v1.23.0(注意上游打包显示可能为 v1.20.0,不影响) # 边缘 containerd --version # 1.7.3 keadm version # v1.23.0 kubectl get node edge-pc # v1.32.x-kubeedge-v1.23.0 ``` > 以上版本为本次部署实录的实际栈,具体以你自己的环境与源码为准。 --- ### 边缘集群部署(KubeEdge 云-边)概览 - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/%E9%83%A8%E7%BD%B2%E6%96%B9%E5%BC%8F/%E8%BE%B9%E7%BC%98%E9%9B%86%E7%BE%A4%E9%83%A8%E7%BD%B2-KubeEdge/README - 分类: 02-部署安装 / 部署方式 / 边缘集群 - 适用场景: 想用 KubeEdge 把本地/专线/独立机房的边缘节点接入云端 K8s,由 CubeStudio 统一调度(云端训练、边缘推理)时,从这里入口选子文档 - 关键词: KubeEdge / kubeedge / 边缘集群 / 边缘计算 / 云边协同 / cloud-edge / edge / edgecore / cloudcore / keadm / 边缘节点 / NAT / 云端训练边缘推理 / superedge / kubesphere / EdgeMesh / 边缘项目组 - 最后更新: 2026-07-05 # 边缘集群部署(KubeEdge 云-边) 本目录讲如何用 **KubeEdge** 把本地 / 专线 / 独立机房的边缘节点接入云端 K8s 集群,由 CubeStudio 统一调度:**云端做训练,边缘做推理**。 适用形态:边缘设备(英伟达 ARM 盒子、商城/门店机房的独立子网服务器或 PC)算力分散、不希望把数据回传中心、又想集中管理。 > 内容来源:`docs/部署/kubeedge部署边缘集群cube-studio.md`(一次从零到可用的跨公网云-边完整实录,约 1000 行)+ `docs/部署/边缘集群方式部署平台.md`(原理与 superedge / kubesphere 等其它建集群方式)+ `install/kubernetes/kubeedge/README.md`(一键脚本说明)。 --- ## 📌 四个最大坑(任一个没处理都会失败,务必先看) | 坑 | 症状 | 解决 | |---|---|---| | **1. edge 节点 label 必须空值** | `kubectl describe pod` 只有 `Scheduled`、无后续事件;cloudcore 日志刷 `there are 0 nodes need to sync` | `node-role.kubernetes.io/edge=`(空字符串,**不能**是 `=true`),脚本 `40-edge-fix-label.sh`。详见 [06-验证与最大坑-label硬编码](06-验证与最大坑-label硬编码.md) | | **2. edge 上 /opt/cni/bin 只有 flannel**,缺 loopback/bridge | `failed to find plugin "loopback"`,pod sandbox 建不起来 | 装 containernetworking/plugins v1.4.0,脚本 `30-edge-join.sh` 会自动装。详见 [05-边缘节点接入与项目组配置](05-边缘节点接入与项目组配置.md) | | **3. kube-proxy kubeconfig 默认走云端私网 IP** | 边缘上 `iptables-save` 空无规则;service ClusterIP / NodePort / external IP 在边缘节点上都不通 | 把 `kube-system/kube-proxy` configmap 的 `server:` 改成公网 IP,脚本 `45-fix-kube-proxy.sh` | | **4. kubeadm init 时 SAN 必须含公网 IP** | 即使改了 kube-proxy server,证书不匹配照样握手失败 | 云端 K8s 初始化时加 `--apiserver-cert-extra-sans=<公网 IP>` | --- ## 两条路径 1. **一键脚本(推荐先看)**:如果云端 K8s 已就绪、且 kubeadm init 时加过公网 SAN,用 `install/kubernetes/kubeedge/` 下的编号脚本几条命令接入。见 [02-一键脚本部署](02-一键脚本部署.md)。 2. **从零手工部署**:公网云主机从裸机装 K8s + NFS + cube-studio + CloudCore,再把 NAT 后的边缘节点接进来。详见 03 ~ 06 各子文档。 --- ## 子文档目录(TOC) | 文档 | 内容 | |---|---| | [01-原理与适用场景](01-原理与适用场景.md) | 适用场景、支持设备、网络访问方向限制(中心↔边缘单向)、云-边架构;以及 superedge / kubesphere+kubeedge 等其它建边缘 K8s 集群的方式 | | [02-一键脚本部署](02-一键脚本部署.md) | `install/kubernetes/kubeedge/` 编号脚本(00~50)的用途、快速流程、卸载 | | [03-云端环境准备-K8s与NFS](03-云端环境准备-K8s与NFS.md) | 交付前要替换的变量、安全组端口、Phase A 云端 kubeadm+containerd 装 K8s、Phase B 云端 NFS 服务端 | | [04-云端CubeStudio与CloudCore](04-云端CubeStudio与CloudCore.md) | Phase C 云端部署 CubeStudio(改 config/start.sh、ccr 鉴权、istio Service)、Phase D 装 CloudCore(KubeEdge) | | [05-边缘节点接入与项目组配置](05-边缘节点接入与项目组配置.md) | Phase E 边缘 keadm join + CNI + kube-proxy 修复、Phase F CubeStudio 边缘项目组配置与调度代码位置 | | [06-验证与最大坑-label硬编码](06-验证与最大坑-label硬编码.md) | Phase G 端到端验证;**最大坑:edge 节点 label 硬编码**(KubeEdge 源码定位 + 修复) | | [07-踩坑速查](07-踩坑速查.md) | 其它踩过的坑(CNI / kube-proxy / 单向不通 / 镜像大小 / NFS stale handle 等)+ 常见坑附录 + 版本命令速查 | --- ## 访问方向(by-design,不是 bug) - **Cloud → Edge pod 方向走不通**:云端 flannel 没法建 VXLAN 到 NAT 后的边缘,公网经 istio ingress → ClusterIP → edge pod 这条路返回 502。 - **Edge 内网用户可用**:CubeStudio 给边缘 service 配的访问地址默认就是 `http://<边缘内网 IP>:`(如 `192.168.3.22:20038`),供同子网用户使用。 - 详细原理见 [01-原理与适用场景](01-原理与适用场景.md) 与 [07-踩坑速查](07-踩坑速查.md)。 > 视频教程:[边缘计算方式部署和调度(B 站)](https://www.bilibili.com/video/BV1qY4y1x7Yy/)。具体命令/镜像名/版本以源码与各子文档为准。 --- ### 单机 k8s 部署(rancher / 已有 k8s / 隔离内网) - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/%E9%83%A8%E7%BD%B2%E6%96%B9%E5%BC%8F/%E5%8D%95%E6%9C%BA%E9%83%A8%E7%BD%B2-docker-compose/01-%E5%8D%95%E6%9C%BAk8s%E9%83%A8%E7%BD%B2 - 分类: 02-部署安装 / 部署方式 / 单机与docker-compose - 适用场景: 要在单台/已有 k8s 集群上部署完整平台、或部署后打不开/排障时读这篇 - 关键词: 单机部署 / k8s部署 / kubernetes / rancher / start.sh / istio-ingressgateway / NodePort / ipvs / iptables / containerd / nerdctl / 域名访问 / virtual.yaml / SERVICE_EXTERNAL_IP / nginx反向代理 / https / 内网穿透 / frp / 部署排查 / coredns / pv / pvc / 机器标签 - 最后更新: 2026-07-09 # 单机 k8s 部署 本篇讲在机器上以 k8s 形态部署完整平台:先有一个 k8s 集群(不熟 k8s 可用 rancher 起),再用 `start.sh` 把 CubeStudio 部署到 k8s 上。部署完成后能调度真实的 pipeline / notebook / 推理任务。 > 机器规格、操作系统、k8s 版本等前置要求见 [部署总览与前置要求](../部署总览与前置要求.md)。 ## 部署提前预备内容 1. **分布式存储**:挂载到 `/data/k8s` 目录下(单机可忽略)。NFS 等分布式存储的搭建可参考仓库内 `install/kubernetes/nfs/NFS离线部署.md`;存储目录约定见 [04-运维管理/分布式存储目录.md](../../../04-运维管理/分布式存储目录.md)。 2. **私有镜像仓库**:在每台机器的 docker 配置中添加 Insecure Registries(体验可忽略)。Harbor 搭建见 [04-运维管理/私有镜像仓库Harbor.md](../../../04-运维管理/私有镜像仓库Harbor.md)(仓库内对应 `install/harbor/readme.md`)。 3. **GPU / IB 驱动**:GPU 机器要安装 nvidia-docker2,并安装对应厂商驱动;IB 设备也需安装对应驱动(CPU 机器可忽略)。可参考仓库内 `install/rancher` 目录。 ## 1、对于不熟悉 k8s 的同学 可以先用 rancher 部署 k8s,再部署 CubeStudio。 - 视频教程:[单机部署视频(bilibili)](https://www.bilibili.com/video/BV18r4y147oj/) - 文档:仓库内 `install/kubernetes/rancher/readme.md`。 ## 2、对于已有 k8s 的同学 1. **ipvs 模式的 k8s**: - (1)把 `start.sh` 脚本最后面的 `kubectl patch` 注释掉,然后手动把 istio-system 命名空间的 `istio-ingressgateway` 服务类型改为 NodePort。 - (2)把 k8s overlay 配置文件 `install/kubernetes/cube/overlays/config/config.py` 中的 `K8S_NETWORK_MODE` 改为 `ipvs`(默认 `iptables`)。 2. **containerd 运行时的 k8s**: - (1)把 `install/kubernetes/cube/overlays/config/config.py` 中的 `CONTAINER_CLI` 改为 `nerdctl`(默认 `docker`)。 3. **服务可用端口范围**要放大到 10 ~ 60000。 > 配置项含义与位置说明见 [04-运维管理/配置文件管理.md](../../../04-运维管理/配置文件管理.md)。 注意:平台入口是 istio-system 命名空间的 `istio-ingressgateway`,不是 CubeStudio 的前端部分。 **平台部署命令**:把 k8s 集群的 kubeconfig 文件复制到 `install/kubernetes/config` 文件中。对于双网卡的机器,记得 rancher 里 current-context 切换为内网的连接形式,然后执行如下命令,其中 `xx.xx.xx.xx` 为机器**内网** IP(不是外网 IP): ```bash # 在 k8s worker 机器上执行 sh start.sh xx.xx.xx.xx ``` ## 3、对于隔离内网部署的同学 参考仓库内 `install/kubernetes/offline.md`(离线部署流程 + 离线镜像)。 ## 修改为非 80 端口 修改 istio-system 命名空间下名为 `istio-ingressgateway` 的 service,将服务类型改为 NodePort。将 80 端口的 nodePort 改为其他可访问的端口,**注意不要删除 80 端口的配置**,因为 gateway 中会读取这个 80 参数。 同时商业版需修改 kubeflow 命名空间 labelstudio deployment 中环境变量 `LABEL_STUDIO_HOST` 的值,添加上暴露出来的端口号。 ## 域名访问 修改 `install/kubernetes/virtual.yaml`,将其中 hosts 参数 `*` 改为域名,然后重新部署:`kubectl apply -f virtual.yaml`。 配置文件 config.py 中修改 `SERVICE_EXTERNAL_IP`,将域名作为外网 IP,比如设置为 `['192.168.3.22|localhost.example.com']`;如果是多个集群,则修改 `CLUSTERS` 的每个集群的 `HOST` 字段。删除后重启后端 pod,使配置生效(配置文件说明见 [04-运维管理/配置文件管理.md](../../../04-运维管理/配置文件管理.md))。 然后删除所有之前创建的虚拟服务: ```bash kubectl delete vs --all -n jupyter kubectl delete vs --all -n service kubectl delete vs --all -n automl kubectl delete vs --all -n aihub ``` 修改域名后,notebook / 内部服务 / 推理服务要清理、重启才能打开。 如果没有域名但想通过域名访问,除上面的修改外,还需在本地 hosts 文件中添加域名解析: ```bash xx.xx.xx.xx your.host.com ``` > 若使用域名访问前,没有清理重启 notebook、内部服务、推理服务和 aihub 应用,那么在使用域名访问后,reset notebook 和部署服务会造成平台无法域名访问。这是因为 istio 代理中 IP 代理优于域名代理,此时要用 IP 进入平台,把 jupyter 和 service 命名空间的所有 notebook、内部服务、推理服务全部清理掉,再重新用域名访问。 ## 内部 IP 和外部 IP 1. 部署 CubeStudio 时,`start.sh` 脚本后面要填**内网 IP**,浏览器访问使用**外网 IP(公网 IP)**,并修改 config.py 中 `SERVICE_EXTERNAL_IP` 为 `['内网ip|外网ip']`(见 [04-运维管理/配置文件管理.md](../../../04-运维管理/配置文件管理.md))。 2. 标注平台:修改 kubeflow 命名空间 labelstudio 的 deployment 中前后端环境变量 `LABEL_STUDIO_HOST`,改为公网 IP 和端口。 ## nginx 反向代理 istio-ingressgateway 有时浏览器只能打开物理机 IP,而部署 CubeStudio 用的是虚拟机,需要加 nginx 代理。注意 nginx 访问超时时长要设大一些,否则 websocket 协议的 webshell 执行命令会失败。 nginx 配置参考仓库内 `install/kubernetes/nginx-https/nginx.conf`,相关说明见 [04-运维管理/平台HTTPS配置.md](../../../04-运维管理/平台HTTPS配置.md)。 ## 内网穿透形式 内网穿透参考仓库内 `install/kubernetes/frp/readme.md`。 ## https 协议 因为 `istio-ingressgateway` 只暴露 80 端口,需要通过 nginx 代理 https 协议,以 http 协议格式代理到 istio-ingressgateway。nginx 的 https 代理参考仓库内 `install/kubernetes/nginx-https/readme.md`(见 [04-运维管理/平台HTTPS配置.md](../../../04-运维管理/平台HTTPS配置.md))。 由于从 nginx 流出后均为 http 协议,后端返回某项数据或协议时可能无法识别前端是 http,所以还需要修改前端镜像构建用的 `install/docker/dockerFrontend/nginx.80.conf`,取消注释: ``` proxy_set_header X-Forwarded-Proto https; ``` 同时在 config.py 中为 `AIHUB_ENV` 增加 `"PROTOCOL":"https"` 环境变量,重启后端 pod。 ## 部署后排查 部署后打不开 / 任务起不来时,按下面顺序排查。先了解 [平台基础组件](../../../01-架构原理/基础组件介绍.md),机器标签管理可参考 [03-平台使用/02-资源与存储/机器资源配置.md](../../../03-平台使用/02-资源与存储/机器资源配置.md)。 0. 用 `kubectl version` 查看是否存在 kubectl。内网中可能 kubectl 不存在又无法下载,可改 `start.sh` 脚本手动下载 kubectl。 1. rancher 部署的是 iptables 模式,kubekey 部署是 ipvs 模式。若 k8s 采用 ipvs 网络模式,把 istio-ingressgateway 改为 nodeport 模式(而非 externalIPs),并在 config.py 中把 `K8S_NETWORK_MODE` 由 iptables 改为 ipvs。 2. 查看机器是否打了标签: ```bash kubectl get nodes --show-labels ``` 没有标签则用下面命令添加(替换 `$node` 变量): ```bash kubectl label node $node train=true cpu=true notebook=true service=true org=public istio=true knative=true kubeflow=true kubeflow-dashboard=true mysql=true redis=true monitoring=true logging=true --overwrite ``` 3. pv 和 pvc 是否绑定。有些 k8s 平台会自动为 pvc 添加 Storage Classes,需要对应 pv 也添加完成绑定。 4. infra 命名空间其他组件是否成功,它们会连接 mysql 完成数据库初始化。kubeflow 数据库由 `kubeflow-dashboard.infra` 组件完成初始化。 - 4.1 数据库如果库表不全,可把对应库删掉重启相应组件:`rm -rf /data/k8s/infra/mysql`,然后重启 infra 命名空间 mysql 的 pod,再重启 kubeflow-dashboard 相关 pod。 - 4.2 如果 kubeflow-dashboard 报 core dump,可能是 linux 系统内核版本太低,需要升级系统内核。 5. kube-system 命名空间 coredns 的 pod 是否正常,看日志是否有 timeout 报错。 - 5.1 可以放开流量代理: ``` /sbin/iptables -P FORWARD ACCEPT /sbin/iptables -P INPUT ACCEPT /sbin/iptables -P OUTPUT ACCEPT ``` 放开后重启 coredns 的 pod。 - 5.2 查看 53 端口是否被占用(比如 bind 服务),关闭主机原有 53 端口服务:`systemctl stop bind9 && systemctl disable bind9`(注意机器重启后原 53 端口服务可能被重新打开)。 - 5.3 参考 https://www.cnblogs.com/zhaichao93/p/16224163.html 修正 dns 配置。 6. istio-system 空间下,istio-ingressgateway 的 svc 是否以 externalIPs 形式暴露了内网 IP。如果有双网卡,执行 `sh start.sh xx.xx.xx.xx` 时用的是内网 IP,浏览器打开的是外网 IP。 7. istio-ingressgateway 暴露 80 后仍无法打开,可能原因:(1)80 被内网封禁(2)80 被其他服务占用(3)没有禁用 nginx-ingress(4)防火墙限制,可执行 `/sbin/iptables -P FORWARD ACCEPT`。 8. istio-ingressgateway 暴露其他端口:如果 80 被占用,可修改 `istio-system/svc/istio-ingressgateway` 类型为 NodePort,同时商业版需修改 kubeflow 命名空间 labelstudio deployment 中环境变量 `LABEL_STUDIO_HOST` 的值,加上暴露出来的端口号。 9. 镜像拉取不下来:可离线拉取一遍平台镜像(仓库内脚本 `install/kubernetes/pull_image_kubeflow.sh`);对于其他仓库镜像最好设为 public,否则更新每个命名空间 hubsecret 的账号密码。配置在“在线开发 -> 镜像仓库”中 hubsecret 的账号密码为自己的 dockerhub 账号密码。 10. 如果报错 `failed to create fsnotify watcher: too many open files`,一般由于机器算力太小,执行下面命令修复: ``` sudo sysctl -w fs.inotify.max_user_watches=2099999999 sudo sysctl -w fs.inotify.max_user_instances=2099999999 sudo sysctl -w fs.inotify.max_queued_events=2099999999 ``` > 命令、脚本路径与配置项以源码(`install/kubernetes/`、`install/docker/config.py`)为准,仅供导航。 --- ### docker-compose 本地部署(前后端 + mysql + redis) - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/%E9%83%A8%E7%BD%B2%E6%96%B9%E5%BC%8F/%E5%8D%95%E6%9C%BA%E9%83%A8%E7%BD%B2-docker-compose/02-docker-compose%E6%9C%AC%E5%9C%B0%E9%83%A8%E7%BD%B2 - 分类: 02-部署安装 / 部署方式 / 单机与docker-compose - 适用场景: 想在本机用 docker-compose 把 CubeStudio 前后端 + mysql + redis 跑起来做体验/后端调试时读这篇 - 关键词: docker-compose / 本地部署 / 本地体验 / deploy myapp / mysql / postgresql / redis / 镜像构建 / 镜像拉取 / image build / kubeflow-dashboard-enterprise / base-python3.9 / STAGE / entrypoint / minio / MINIO_HOST / 连接k8s集群 / windows / mac / linux - 最后更新: 2026-07-09 # docker-compose 本地部署 本篇讲在本机用 docker-compose 把 CubeStudio 前端、后端、mysql、redis 四个容器跑起来,适合**功能体验**和**后端二次开发调试**。 > 注意:docker-compose 方式**不会**在本机起一个 k8s 集群。发起真实的 pipeline / notebook / 推理任务仍需连接一个已部署好 CubeStudio 的 k8s 集群(见文末「本地连接 k8s 开发集群」)。要在机器上真正部署一套能调度任务的平台,请看 [01-单机 k8s 部署](01-单机k8s部署.md)。 > > 前端 / IDE 断点 / 镜像升级等更细的开发流程见 [03-本地开发与调试](03-本地开发与调试.md)。 参考视频:https://cube-studio.oss-cn-hangzhou.aliyuncs.com/video/dev.mp4 ## 本地机器环境准备 ### Windows 系统 1. 安装 Docker Desktop:下载 Docker Desktop Installer,安装最新版。Windows 10 需要启用 Hyper-V,安装配置流程可参考在线文档 https://zhuanlan.zhihu.com/p/441965046 2. 安装 PowerShell:之后的脚本需要在 PowerShell 中执行。 3. 安装 python = 3.9.16。 4. git 配置不要修改换行符:`git config --global core.autocrlf false`。 ### Mac 系统 1. 安装 Docker Desktop。 ### Linux 系统 1. 安装 docker / docker-compose。 ## docker-compose 配置说明 docker-compose 文件在 `install/docker/` 目录下(`docker-compose.yml`,仓库内同时提供 mac / linux 版本)。该 compose 文件**已内置** mysql 与 redis 服务,直接启动即可,无需另行手动 `docker run`: | 服务 | 镜像 | 端口 | 说明 | |---|---|---|---| | `frontend` | `ccr.ccs.tencentyun.com/cube-studio/kubeflow-dashboard-frontend-enterprise:2026.07.01` | `80:80` | 前端(nginx),平台入口 | | `myapp` | `ccr.ccs.tencentyun.com/cube-studio/kubeflow-dashboard-enterprise:2026.07.01` | 容器内 80 | 后端 Flask | | `mysql` | `mysql:8.0.32` | `3306:3306` | 元数据库,库名 `kubeflow`,root 密码 `admin` | | `redis` | `ccr.ccs.tencentyun.com/cube-studio/redis:7.4` | `6379:6379` | 缓存 / 异步任务队列,密码 `admin` | > 镜像名以仓库内 `install/docker/docker-compose.yml` 为准(商业版镜像带 `-enterprise` 后缀,开源版镜像名去掉该后缀)。后端 `myapp` 服务通过 `MYSQL_SERVICE` 环境变量连 `mysql:3306` 库 `kubeflow`,通过 `REDIS_HOST=redis` 连 redis。 后端 `myapp` 服务的关键环境变量(见 `install/docker/docker-compose.yml`): - `STAGE: 'dev'`:启动模式。`entrypoint.sh` 中 `dev` 跑 `python myapp/run.py`(监听 80,热更新),`build` 编译前端,`prod` 跑 gunicorn。 - `MYSQL_SERVICE: 'mysql+pymysql://root:admin@mysql:3306/kubeflow?charset=utf8mb4'` - `REDIS_HOST: 'redis'` / `REDIS_PORT: '6379'` / `REDIS_PASSWORD: admin` - `ENVIRONMENT: DEV` - 可选:`POSTGRESQL_SERVICE` / `KINGBASE_SERVICE` / `DM_SERVICE`(默认注释掉,用 mysql)。元数据库切换见 [04-运维管理/元数据库配置.md](../../../04-运维管理/元数据库配置.md)。 后端配置文件 `config.py`、`project.py` 通过挂载注入容器(`./config.py:/home/myapp/myapp/config.py`),配置项说明见 [04-运维管理/配置文件管理.md](../../../04-运维管理/配置文件管理.md)。 ## 启动 docker-compose 在 `install/docker/` 目录下执行: ```bash docker-compose -f docker-compose.yml up ``` 启动后浏览器访问 `http://<本机IP>/`(前端容器映射 80 端口)。登录首页会自动创建用户并绑定角色(Gamma),可按需为角色授权。 > `myapp` 服务的启动命令默认是 `bash -c 'sleep 100000000 && /entrypoint.sh'`,即容器起来后先 sleep。这是为了方便调试:可以 `docker-compose up -d` 起后台,再 `docker exec -it docker-myapp-1 bash` 进容器手动执行 `/entrypoint.sh`(首次,含建库初始化)或 `python myapp/run.py`(后续)。容器名 `docker-myapp-1` 来自 compose 项目目录名 `docker` + 服务名 `myapp`。 首次进入容器后的初始化由 `/entrypoint.sh` 完成,主要步骤:编译 i18n 翻译产物 → `python myapp/create_db.py` 建 schema → `myapp db upgrade` 应用迁移(`DM_SERVICE` 非空即达梦时跳过此步,改由 `create_db.py` 建表)→ `myapp fab create-admin`(用户名 / 密码均为 `admin`,邮箱 `admin@tencent.com`)→ `myapp init`(创建默认角色 / 权限 / 自定义 menu)。后续调试直接 `python myapp/run.py` 即可。 ## 使用外部数据库(可选) compose 已内置 mysql / redis。若想连**外部** mysql / postgresql,可手动起库并改 `myapp` 的环境变量: 部署 mysql: ```bash docker run -p 3306:3306 --restart always --name mysql \ -e MYSQL_ROOT_PASSWORD=admin \ -v $PWD/docker-add-file/mysqld.cnf:/etc/mysql/conf.d/mysqld.cnf \ -d mysql:8.0.32 ``` 进入 mysql 创建 `kubeflow` 库并授权: ```sql CREATE DATABASE IF NOT EXISTS kubeflow DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci; use mysql; GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION; flush privileges; ``` 部署 postgresql: ```bash docker run -p 5432:5432 --name postgres -e POSTGRES_PASSWORD=admin -d postgres:11.5 ``` 然后在 `docker-compose.yml` 的 `myapp` 服务里启用对应的 `POSTGRESQL_SERVICE` / `KINGBASE_SERVICE` / `DM_SERVICE` 环境变量(默认注释)。详见 [04-运维管理/元数据库配置.md](../../../04-运维管理/元数据库配置.md)。 ## 镜像构建(可忽略,不参与开发可直接用线上镜像) 构建命令以仓库内各 Dockerfile 头部注释为准: ```bash # 构建基础镜像(含基础环境) docker build --network=host \ -t ccr.ccs.tencentyun.com/cube-studio/kubeflow-dashboard:base-python3.9-20260601 \ -f install/docker/Dockerfile-base . # 用基础镜像构建后端生产镜像 docker build --network=host \ -t ccr.ccs.tencentyun.com/cube-studio/kubeflow-dashboard-enterprise:2026.07.01 \ -f install/docker/Dockerfile . # 构建前端镜像 docker build --network=host \ -t ccr.ccs.tencentyun.com/cube-studio/kubeflow-dashboard-frontend-enterprise:2026.07.01 \ -f install/docker/dockerFrontend/Dockerfile . ``` > 镜像名 / tag 已按 `install/docker/Dockerfile`、`install/docker/Dockerfile-base`、`install/docker/dockerFrontend/Dockerfile` 头部实际命令校正:商业版后端 / 前端镜像带 `-enterprise` 后缀,基础镜像 tag 为 `base-python3.9-20260601`。镜像构建更细的说明见 [06-二次开发/镜像构建/镜像构建总览.md](../../../06-二次开发/镜像构建/镜像构建总览.md)。 ## 镜像拉取(不参与开发可直接用线上镜像) ```bash docker pull ccr.ccs.tencentyun.com/cube-studio/kubeflow-dashboard-enterprise:2026.07.01 docker pull ccr.ccs.tencentyun.com/cube-studio/kubeflow-dashboard-frontend-enterprise:2026.07.01 ``` ## 本地连接 k8s 开发集群 docker-compose 只起前后端 + 数据库,要调度真实任务还得连一个 k8s 集群: 1. 需要先在 k8s 开发集群上部署过一遍 CubeStudio,本地才能连上去调度。 2. 把集群 kubeconfig 放到 `install/docker/kubeconfig/` 下,按 `$ENVIRONMENT-kubeconfig` 命名(仓库内已有 `dev-kubeconfig` / `prod-kubeconfig` / `cloud-kubeconfig` / `npu-kubeconfig`)。compose 已把该目录挂到容器 `/home/myapp/kubeconfig`。 ![k8s 配置](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/localk8s.jpg) ## 修改 minio 地址 把远端 k8s 上 kubeflow 命名空间下的 minio 服务改为 NodePort 类型,然后修改 `install/docker/config.py` 中的 `MINIO_HOST` 为 minio 服务的 `ip:nodeport`。 > `config.py` 中 `MINIO_HOST` 默认值为 `minio.kubeflow:9000`(见 `install/docker/config.py:1302`),是集群内访问地址;本地 docker-compose 连远端 minio 时需改为 NodePort 暴露的 `ip:nodeport`。 ## 下一步 - 在本机 IDE 里给后端打断点、前端本机开发与容器内编译、前后端镜像升级、常见问题:见 [03-本地开发与调试](03-本地开发与调试.md)。 - 在机器上真正以 k8s 形态部署完整平台:见 [01-单机 k8s 部署](01-单机k8s部署.md)。 > 镜像名 / 端口 / 环境变量 / 命令以源码(`install/docker/docker-compose.yml`、`install/docker/entrypoint.sh`、`install/docker/config.py`)为准,本篇仅供导航与上手。 --- ### 本地开发与调试(IDE 断点 / 前端构建 / 镜像升级 / Q&A) - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/%E9%83%A8%E7%BD%B2%E6%96%B9%E5%BC%8F/%E5%8D%95%E6%9C%BA%E9%83%A8%E7%BD%B2-docker-compose/03-%E6%9C%AC%E5%9C%B0%E5%BC%80%E5%8F%91%E4%B8%8E%E8%B0%83%E8%AF%95 - 分类: 02-部署安装 / 部署方式 / 单机与docker-compose - 适用场景: 想在本机 IDE 给后端打断点、做前端开发/构建、升级前后端镜像,或遇到本地开发常见报错时读这篇 - 关键词: 本地开发 / 本地调试 / conda / IDE / PyCharm / VSCode / 断点调试 / NodePort / mysql-service / redis-master / MYAPP_PORT / dmPython / 前端开发 / frontend / vision / visionPlus / npm / yarn / 容器内编译 / 镜像升级 / Q&A / 换行符 / CRLF - 最后更新: 2026-07-04 # 本地开发与调试 本篇是给开发者的进阶调试指南:在本机 IDE 给后端打断点、前端本机开发与容器内编译、前后端镜像升级、常见问题。 > 先把环境跑起来:见 [docker-compose 本地部署](02-docker-compose本地部署.md)。注意:前后端代码在生产环境均在容器中运行。 ## 后端调试方式概览 - **docker-compose 调试(推荐)**:代码通过挂载进容器,在容器里跑、看日志 debug,dev 模式自动热更新。建议学习 `pysnooper` 包。见 [02-docker-compose本地部署](02-docker-compose本地部署.md) 的「启动 docker-compose」小节(`docker exec` 进容器后跑 `/entrypoint.sh` 或 `python myapp/run.py`)。 - **PC 非 docker(conda + IDE 断点)**:在本机 IDE 直接对 myapp 打断点单步调试,不进容器。下文详述。 前端调试:大部分功能在本机 IDE 开发调试即可(热更新);完整平台前端需打包成静态文件才能验证,可在本机编译也可在容器内编译,容器内编译不支持热更新。 ## PC 非 docker(conda + IDE 断点调试) 适用场景:在本机 IDE(PyCharm / VSCode)直接对 myapp 后端打断点单步调试,不进容器。后端在本机 conda 环境跑,mysql / redis 复用集群里 infra 命名空间下已有的实例。 ### 1)准备 python 环境 ```bash conda create -y -n cube-studio-enterprise python=3.9 conda activate cube-studio-enterprise pip install --upgrade pip setuptools wheel pip install -r install/docker/requirements.txt ``` > PC 上 `dmPython==2.5.30`(达梦驱动,见 `install/docker/requirements.txt:64`)没有 wheel,装不上。不需要达梦的开发者可以跳过它: > ```bash > grep -vE "^(dmPython|dmSQLAlchemy)" install/docker/requirements.txt > /tmp/req.txt > pip install -r /tmp/req.txt > ``` ### 2)把集群里的 mysql / redis 暴露成 NodePort 后端要连 k8s infra 命名空间下的 mysql / redis,它们默认是 ClusterIP,本机连不上。一次性 patch 成 NodePort(永久生效): ```bash export KUBECONFIG=install/docker/kubeconfig/dev-kubeconfig kubectl patch svc -n infra mysql-service --type=merge \ -p '{"spec":{"type":"NodePort","ports":[{"name":"tcp","port":3306,"protocol":"TCP","targetPort":3306,"nodePort":30306}]}}' kubectl patch svc -n infra redis-master --type=merge \ -p '{"spec":{"type":"NodePort","ports":[{"name":"redis","port":6379,"protocol":"TCP","targetPort":6379,"nodePort":30379}]}}' ``` > service 名已与代码一致:mysql 为 `mysql-service`(`install/kubernetes/mysql/service.yaml`),redis 为 `redis-master`(`install/kubernetes/redis/redis.yaml`,集群中后端用 `REDIS_HOST=redis-master.infra` 连接,见 `install/kubernetes/cube/overlays/kustomization.yml:17`)。 之后从本机连 `<节点IP>:30306`(mysql)和 `<节点IP>:30379`(redis)。节点 IP 看 `kubectl get nodes -o wide` 的 INTERNAL-IP。 ### 3)准备 myapp/config.py docker 启动时靠 docker-compose 挂载 `install/docker/config.py` 覆盖容器内的 `myapp/config.py`。本地非 docker 直接跑没有挂载,把 docker 用的那份复制过来覆盖: ```bash cp install/docker/config.py myapp/config.py ``` > 注意:源文档 `install/docker/README.md` 称「仓库里 `myapp/config.py` 是空文件」,这与当前仓库不符——`myapp/config.py` 实为约 1419 行的完整默认配置(非空)。这里 `cp` 的意图是用部署用的 `install/docker/config.py` 覆盖这份默认配置;覆盖会改写已纳入版本管理的 `myapp/config.py`,之后若改了 `install/docker/config.py` 需再 `cp` 一次同步。 ### 4)配置 IDE Run/Debug 新建一个 Python 类型的 Run/Debug Configuration: | 字段 | 值 | |---|---| | Script / Module | `myapp/run.py` | | Working directory | 仓库根目录 | | Python interpreter | conda 环境 `cube-studio-enterprise` | 环境变量(与 docker-compose 里 myapp 服务的 `environment` 段对齐,节点 IP / 数据库地址改成你自己的): ```bash export FLASK_APP=myapp:app export FLASK_ENV=development export MYAPP_CONFIG=myapp.config export STAGE=dev export ENVIRONMENT=DEV export MYSQL_SERVICE=mysql+pymysql://root:admin@192.168.3.22:30306/kubeflow?charset=utf8mb4 export REDIS_HOST=192.168.3.22 export REDIS_PORT=30379 export REDIS_PASSWORD=admin export KUBECONFIG=<仓库根绝对路径>/install/docker/kubeconfig/dev-kubeconfig export MYAPP_PORT=5000 ``` > 命令行整段粘贴即可生效;IDE 的 Environment Variables 栏粘贴时去掉 `export ` 前缀。 > `myapp/run.py` 已支持读取 `MYAPP_PORT`(`app.run(..., port=int(os.environ.get("MYAPP_PORT", 80)), debug=True)`,见 `myapp/run.py:5`),不设置时仍走 80(容器原行为);本地直接监听 80 需要 sudo,所以这里设成 5000。 `export` 只对当前 shell 会话生效,开新终端要重 export。长期开发建议把上面那段存成仓库根的 `dev.env`,新开 shell 时一行加载: ```bash set -a && source dev.env && set +a ``` ### 5)准备宿主机数据目录 主机上创建 `/data/k8s/kubeflow` 目录并可读写,可软链到项目目录: ```bash ln -sfn "$(pwd)/install/docker/file" /data/k8s/kubeflow ``` ### 6)首次初始化数据库(仅 mysql 全新空库需要) 如果连的 mysql 已被其它环境初始化过(表都建好了),跳过本步。全新 mysql 按 docker `entrypoint.sh` 同样的流程跑一次: ```bash # 1. 编译 i18n 翻译产物 (.po -> .mo) pybabel compile -d myapp/translations # 2. 创建数据库 schema PYTHONPATH=. python myapp/create_db.py # 3. 应用 alembic 迁移到最新版本 PYTHONPATH=. python myapp/bin/myapp db upgrade # 4. 创建 admin 用户(用户名 / 密码都是 admin) PYTHONPATH=. python myapp/bin/myapp fab create-admin \ --username admin --firstname admin --lastname admin \ --email admin@example.com --password admin # 5. 创建默认角色 / 权限 / 自定义 menu PYTHONPATH=. python myapp/bin/myapp init ``` > 这套流程与容器 `install/docker/entrypoint.sh` 一致(容器内 create-admin 邮箱用的是 `admin@tencent.com`,邮箱可任填)。后续改了 model 想生迁移文件:`PYTHONPATH=. python myapp/bin/myapp db migrate`,再 `db upgrade`。 ### 7)启动 在仓库根目录下执行(需先 export 过上面的环境变量): ```bash PYTHONPATH=. python myapp/run.py ``` > `PYTHONPATH=.` 是因为命令行 `python myapp/run.py` 会把 `sys.path[0]` 设成 `myapp/` 而非仓库根,导致 `from myapp import app` 找不到。IDE 的 Run/Debug 默认把 working directory 加进 PYTHONPATH,所以 IDE 启动不需要这个前缀,直接 Run / Debug 即可,断点单步都生效。 浏览器访问 `http://127.0.0.1:5000/`,用 admin/admin 登录。若本地没有前端,后端接口都需认证:先打开 `http://127.0.0.1:5000/login?username=admin`,再直接访问接口(如 `http://127.0.0.1:5000/dataset_modelview/api/`)。 ### 注意事项 - 本地 myapp 和集群里部署的 myapp 共用同一份 `kubeflow` 数据库。改 model 或 `db migrate` 会影响线上 dev 环境。要隔离就单独起一个本地 mysql。 - celery worker / beat / watch 等后台进程没启动,只能调 web API。测异步任务还得靠 docker-compose。 - 后端运行仍需连 k8s,配置方法同 docker-compose(即 `KUBECONFIG` 环境变量)。 ## 前端本机开发和构建 前端代码可在本机开发调试,也可在容器内编译。不是前端开发人员建议用容器内编译,本机就不用配前端环境。 Windows 电脑前端开发视频:https://cube-studio.oss-cn-hangzhou.aliyuncs.com/video/window-frontend-dev.mp4 ### 前端代码目录 - `myapp/frontend`:主体前端项目(frontend 主项目) - `myapp/vision`:流程图(AI pipeline) - `myapp/visionPlus`:流程图(数据 ETL pipeline) 打包环境要求: ``` node: 16.15.0+ npm: 6.14.8+ yarn(建议): npm install yarn -g ``` ### 纯前端开发(本地) 注意:本地前端开发需要先用 docker-compose 在本地起好 CubeStudio 前后端。 环境准备: - 进 nodejs 官网( https://nodejs.org/en/download/ )下载 LTS 版本。 - 装 node 版本管理器:`npm install -g n`,再 `n 16.15.0` 切到 16.x。 三个前端项目都在各自 `src` 下有 `setupProxy.js` 配代理转发:把 `target` 改成已有服务地址,重启前端项目即可生效。 **frontend 主体前端**(目录 `myapp/frontend`): ```bash cd myapp/frontend npm run start # 调试模式 ``` - 首次进入 `http://localhost:3000/login?username=admin&login_url=http://localhost:3000/frontend/`,跳转后页面可关闭。 - 之后直接进 `http://localhost:3000/frontend/`。 **vision 任务流编排**(目录 `myapp/vision`): ```bash cd myapp/vision npm run dev ``` - 首页 `http://localhost:3000/#/home/`,或带 pipeline id:`http://localhost:3000/?pipeline_id=1#/`。 **visionPlus 数据 ETL 编排**(目录 `myapp/visionPlus`): ```bash cd myapp/visionPlus npm run dev ``` - 访问 `http://localhost:3000/?scenes=etl_pipeline&pipeline_id=1`。 ### 前端容器内编译 docker-compose 起前后端,进后端容器(后端容器含前端编译环境,编译命令参考 `entrypoint.sh` 中 `STAGE=build` 分支): ```bash # 构建前端主体 cd /home/myapp/myapp/frontend && npm install --force && npm run build # 构建机器学习 pipeline cd /home/myapp/myapp/vision && npm install && npm run build # 构建数据 ETL pipeline cd /home/myapp/myapp/visionPlus && yarn && npm run build ``` 输出路径:`myapp/static/appbuilder`。 > 说明:`entrypoint.sh` 的 `STAGE=build` 分支中 frontend 用 `npm install --force`(与上面命令一致),vision / visionPlus 与上面一致;以仓库内 `install/docker/entrypoint.sh` 为准。 ## 前后端镜像升级 在项目根目录执行(`xx.xx.xx/xx/` 换成你的镜像仓库地址): **前端镜像**: ```bash docker build --network=host -t xx.xx.xx/xx/kubeflow-dashboard-frontend:xx \ -f install/docker/dockerFrontend/Dockerfile . ``` 然后在线上 infra 命名空间把 `kubeflow-dashboard-frontend` 的 deployment 镜像名换成你构建的。 **后端镜像**: ```bash docker build --network=host -t xx.xx.xx/xx/kubeflow-dashboard:xx \ -f install/docker/Dockerfile . ``` 然后在线上 infra 命名空间把 `kubeflow-dashboard` 的 deployment 镜像名换成你构建的。 > 镜像构建更细的说明见 [06-二次开发/镜像构建/镜像构建总览.md](../../../06-二次开发/镜像构建/镜像构建总览.md)。 ## Q&A **1)构建镜像因网络问题失败 —— 加 pip 国内镜像** 在 `install/docker/` 下新建 `pip.conf`: ``` [global] index-url = http://mirrors.aliyun.com/pypi/simple/ extra-index-url = https://mirrors.aliyun.com/pypi/simple/ [install] trusted-host=mirrors.aliyun.com ``` 然后在 `install/docker/Dockerfile-base` 中增加: ``` RUN pip config set global.index-url https://mirrors.aliyun.com/pypi/simple ``` **2)前端装依赖失败 —— 加 npm / yarn 国内镜像** ```bash npm config set registry https://registry.npmmirror.com yarn config set registry https://registry.npmmirror.com ``` **3)Windows 下 `pip3 install -r requirements.txt` 失败** PowerShell 单独安装失败的部分,确保版本号与 `requirements.txt` 一致,再重新执行 `pip3 install -r requirements.txt`。 **4)Windows 下 docker-compose 报 `UnicodeDecodeError: 'gbk' codec`** 编码类型问题,可参考 https://cloud.tencent.com/developer/article/1530430 修改本地 `encoding.py`(大致位置:`XXX\AppData\Local\Programs\Python\Python312\Lib\site-packages\pip\_internal\utils\encoding.py`)。 **5)Windows 下 docker-compose 报 `/usr/bin/env: 'python(3)\r': No such file or directory`** Windows 行尾是 CRLF,Linux 是 LF。用 VSCode 打开项目,全文搜报错关键字(如 `/usr/bin/env`),打开对应文件,把 VSCode 右下角的 CRLF 切换为 LF 保存。 **6)Windows 下打包 visionPlus 编译报错** `myapp/visionPlus/.eslintrc` 中注释掉 `"linebreak-style": ["error", "unix"]`,取消注释 `"linebreak-style": ["error", "windows"]`。 > 命令 / 镜像名 / 配置项以源码(`install/docker/`、`myapp/run.py`、`myapp/bin/myapp`)为准,本篇仅供导航与上手。 --- ### 单机部署与 docker-compose 部署(概览) - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/%E9%83%A8%E7%BD%B2%E6%96%B9%E5%BC%8F/%E5%8D%95%E6%9C%BA%E9%83%A8%E7%BD%B2-docker-compose/README - 分类: 02-部署安装 / 部署方式 / 单机与docker-compose - 适用场景: 想在单台机器/本地把平台跑起来(生产或开发调试)时,先读这篇选子文档 - 关键词: 单机部署 / docker-compose / 本地部署 / 本地开发 / 本地调试 / k8s单机 / rancher / start.sh / istio-ingressgateway / 域名访问 / nginx代理 / https / 前端构建 / 镜像升级 - 最后更新: 2026-07-04 # 单机部署与 docker-compose 部署 本目录覆盖在“单台机器 / 本地”把 CubeStudio 跑起来的两条路径: 1. **单机 k8s 部署**(生产形态):在机器上起一个 k8s 集群(不熟 k8s 可用 rancher),再用 `start.sh` 把平台部署到 k8s 上。这种方式能跑真实的 pipeline / notebook / 推理任务。 2. **docker-compose 本地部署**(开发 / 体验形态):只起前端、后端、mysql、redis 四个容器,适合二次开发调试与功能体验;真实任务调度仍需连接一个 k8s 集群。 > 部署前请先确认机器规格、操作系统、k8s 版本等前置要求:[部署总览与前置要求](../部署总览与前置要求.md)。 ## 子文档目录(TOC) | 文档 | 内容 | |---|---| | [01-单机k8s部署.md](01-单机k8s部署.md) | 单机 / 已有 k8s / 隔离内网 三类场景;start.sh 部署;非 80 端口、域名访问、内外网 IP、nginx 反向代理、HTTPS、内网穿透;部署后排查清单 | | [02-docker-compose本地部署.md](02-docker-compose本地部署.md) | 本地机器环境准备(win/mac/linux);docker-compose 起前后端 + mysql + redis;镜像构建与拉取;连接远端 k8s 与 minio | | [03-本地开发与调试.md](03-本地开发与调试.md) | PC 非 docker(conda + IDE 断点)调试;前端(frontend / vision / visionPlus)本机开发与容器内编译;前后端镜像升级;常见问题 Q&A | ## 选哪条路径 - 只想看看平台长什么样、改后端代码做二次开发 → 走 **02 / 03**(docker-compose)。 - 要在机器上真正部署一套能调度任务的平台 → 走 **01**(单机 k8s 部署)。 > 镜像名 / 端口 / 环境变量等以源码(`install/docker/`、`install/kubernetes/`)为准,本目录文档仅供导航与上手。 --- ### KubeKey 环境准备与安装 k8s - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/%E9%83%A8%E7%BD%B2%E6%96%B9%E5%BC%8F/kubekey%E9%83%A8%E7%BD%B2/01-%E7%8E%AF%E5%A2%83%E5%87%86%E5%A4%87%E4%B8%8E%E5%AE%89%E8%A3%85k8s - 分类: 02-部署安装 / 部署方式 - 适用场景: 用 KubeKey 装 k8s 前每台机器要做哪些系统初始化、怎么下载 kk、怎么在线安装 k8s(命令行直建或配置文件多机)时读这篇 - 关键词: kubekey / kk / k8s安装 / kubernetes / 主机名 / chrony / 时间同步 / swap / firewalld / selinux / socat / conntrack / ipvsadm / KKZONE / create cluster / config-cluster.yaml / v1.25.16 / v1.28.15 / containerd / docker / sftp packet too long - 最后更新: 2026-07-04 # KubeKey 环境准备与安装 k8s 本篇覆盖 KubeKey 部署前每台机器的系统初始化,以及在线安装 k8s 的两种方式。容器运行时(docker/containerd)由 KubeKey 自动安装,节点无需手工预装。 ## 一、初始化机器环境(每台机器) > 容器运行时无需手工安装,KubeKey 会自动处理。如需了解运行时配置可参考[《节点安装 Containerd 容器运行时》](../../节点准备/安装Containerd.md)。 ### 修改主机名 主机名不要有大写,保持小写: ```bash hostnamectl set-hostname [新主机名] ``` 修改后重新进入终端,主机名才会生效。 ### 初始化安装基础组件 ```bash # 安装时间同步,启动 chronyd 服务 # yum -y install chrony # CentOS apt install -y chrony # Ubuntu systemctl start chronyd systemctl enable chronyd # 手动同步一下 timedatectl set-ntp true chronyc -a makestep date # ubuntu 安装基础依赖 apt install -y socat conntrack ebtables ipset ipvsadm # centos 安装基础依赖 yum install -y socat conntrack ebtables ipset ipvsadm tar # 关闭 firewalld 服务 systemctl stop firewalld systemctl disable firewalld # 禁用 iptables systemctl stop iptables systemctl disable iptables # 禁用 selinux echo "SELINUX=disabled" > /etc/selinux/config # 临时关闭 swap 分区 swapoff -a # 永久关闭 swap 分区:编辑 /etc/fstab 注释掉 swap 一行(修改后需重启) vim /etc/fstab # 注释掉 /dev/mapper/centos-swap swap # 检查:如果 swap 全部是 0,则代表配置完成 free -m ``` ## 二、下载 KubeKey > 机器最低规格:16C32G;之前安装过 KubeSphere(KS) 要提前清理环境。下载不成功可多执行几次。 ```bash # 在线安装 export KKZONE=cn curl -sfL https://get-kk.kubesphere.io | VERSION=v3.1.10 sh - chmod +x kk cp kk /usr/bin/ # 离线安装(提前下好二进制) # arm64 版本 # wget https://cube-studio.oss-cn-hangzhou.aliyuncs.com/install/kubekey-v3.1.10-linux-arm64 -O /usr/bin/kk # amd64 版本 # wget https://cube-studio.oss-cn-hangzhou.aliyuncs.com/install/kubekey-v3.1.10-linux-amd64 -O /usr/bin/kk # chmod +x /usr/bin/kk ``` 清理已有 kubeconfig,否则会导致其他 node 节点无法使用 kubectl: ```bash rm -rf /root/.kube/config ``` ## 三、在线安装 k8s KubeKey 安装 k8s 时会自动安装 containerd/docker、kubeadm、kubelet、kubectl、CNI、helm 等。自定义部署最好不要启用 servicemesh 和 monitoring。 ### 方式 A:命令行直接建集群(单机快速,k8s v1.28.15) ```bash # 使用 docker 作为运行时 export KKZONE=cn ./kk create cluster -y --with-kubernetes v1.28.15 --container-manager docker # 使用 containerd 作为运行时 export KKZONE=cn ./kk create cluster -y --with-kubernetes v1.28.15 --container-manager containerd ``` ### 方式 B:配置文件方式(多机,k8s v1.25.16) 适合多节点。`name` 写内网 IP,KubeKey 会用配置里的账号密码登录远程机器执行安装命令(需提前配好免密或填密码)。 ```bash # 生成配置文件 kk create config --with-kubernetes v1.25.16 ``` 编辑 `config-cluster.yaml`(示例,`name` 写内网 IP 地址): ```yaml spec: hosts: - {name: 172.16.0.2, address: 172.16.0.2, internalAddress: 172.16.0.2, user: ubuntu, password: "Qcloud@123"} - {name: 172.16.0.3, address: 172.16.0.3, internalAddress: 172.16.0.3, user: ubuntu, password: "Qcloud@123"} roleGroups: etcd: - 172.16.0.2 control-plane: - 172.16.0.2 worker: - 172.16.0.2 - 172.16.0.3 ``` 创建集群: ```bash export KKZONE=cn kk create cluster -f config-cluster.yaml # 会自动安装 containerd、kubectl、kubeadm、kubecni、helm 等 ``` > 仓库内置示例配置 `install/kubernetes/rancher/kubekey/config-cluster.yaml`:k8s 版本 `v1.25.16`、`containerManager: docker`、`controlPlaneEndpoint.domain: lb.kubesphere.local`、`registryMirrors` 预置了多个国内镜像加速地址。多机/高可用部署可在此基础上改。 ## 四、常见报错 ### sftp packet too long 报错 `new sftp client failed: packet too long`,修复方式: ```bash vim /etc/ssh/sshd_config # 注释掉 Subsystem 开头的行,并新增一行使用内部 sftp: # Subsystem sftp internal-sftp # 重启 sshd 服务 systemctl restart sshd ``` --- 装好 k8s 后,进入[《在 k8s 上部署 CubeStudio》](02-部署cube-studio.md)。离线场景见[《离线部署》](03-离线部署.md)。 --- ### 在 KubeKey k8s 上部署 cube-studio - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/%E9%83%A8%E7%BD%B2%E6%96%B9%E5%BC%8F/kubekey%E9%83%A8%E7%BD%B2/02-%E9%83%A8%E7%BD%B2cube-studio - 分类: 02-部署安装 / 部署方式 - 适用场景: k8s 已就绪,要在主节点上跑部署脚本把 CubeStudio 装上去(含 NodePort 端口范围、containerd 适配、ipvs 入口、Prometheus 切换)时读这篇 - 关键词: CubeStudio部署 / start.sh / start-with-kubesphere.sh / service-node-port-range / nodeport / nerdctl / containerd / ipvs / istio-ingressgateway / externalIPs / NodePort / kubeconfig / CONTAINER_CLI / K8S_NETWORK_MODE / PROMETHEUS / kubesphere / config.py - 最后更新: 2026-07-04 # 在 KubeKey k8s 上部署 cube-studio k8s 就绪后,在主节点上按以下步骤部署 CubeStudio。 ## 1. 放大 NodePort 可用端口范围 服务 NodePort 可用端口范围要放大到 1~65535: ```bash vim /etc/kubernetes/manifests/kube-apiserver.yaml # 修改添加 apiserver 配置 spec: containers: - command: - kube-apiserver - --service-node-port-range=1-65535 # 添加这一行 - --advertise-address=172.16.0.17 # 修改后通过 reboot 命令重启机器 ``` ## 2. containerd 运行时适配(nerdctl) 如果使用 containerd 运行时,需要把拉取脚本里的 `docker` 命令替换为 `nerdctl`: ```bash # 安装 containerd 下的 cli export TARGETARCH=amd64 curl -L https://github.com/containerd/nerdctl/releases/download/v1.7.2/nerdctl-1.7.2-linux-${TARGETARCH}.tar.gz | tar xzv -C /usr/local/bin nerdctl # 替换拉取脚本中的拉取命令 cd install/kubernetes/ sed -i 's/^docker/nerdctl/g' pull_images_mini.sh ``` > 说明:仓库提供的镜像拉取脚本是 `pull_images_mini.sh`(昇腾版为 `pull_images_mini_ascend.sh`),见 `install/kubernetes/pull_images_mini.sh`;并不存在历史文档里提到的 `pull_images.sh`。 ## 3. ipvs 模式的 istio 入口配置 对于 KubeKey 部署的 ipvs 模式 k8s: 1. externalIP 改 NodePort 这步只对 `start-with-kubesphere.sh` 适用——只有它末尾才有这两行 `kubectl patch`(`install/kubernetes/start-with-kubesphere.sh:125` 是 externalIPs 行,`:129` 是被注释的 NodePort 行)。改用 NodePort 方式时: - 注释掉 `kubectl patch svc istio-ingressgateway -n istio-system -p '{"spec":{"externalIPs":["'"$1"'"]}}'` - 取消注释 `kubectl patch svc istio-ingressgateway -n istio-system -p '{"spec":{"type":"NodePort"}}'` 纯 k8s(用 `start.sh`)没有这两行 patch——它通过 `gateway.yaml`/`virtual.yaml` + `config.py` 的 `SERVICE_EXTERNAL_IP` 暴露入口(见 `install/kubernetes/start.sh:123-124,162`),入口相关改 `config.py` 即可。 2. 将配置文件 `install/kubernetes/cube/overlays/config/config.py` 中: - `CONTAINER_CLI` 的值改为 `nerdctl`(默认 `docker`,见 `install/kubernetes/cube/overlays/config/config.py:1110`) - `K8S_NETWORK_MODE` 的值改为 `ipvs`(默认 `iptables`,见 `install/kubernetes/cube/overlays/config/config.py:820`) ## 4. 复制 kubeconfig 并执行部署脚本 将 k8s 集群的 kubeconfig 文件(默认位置 `~/.kube/config`)复制到 `install/kubernetes/config` 文件中,然后执行部署命令,其中 `xx.xx.xx.xx` 为机器内网 IP(不是外网 IP): ```bash # 在 k8s worker 机器上执行 # 如果只部署了 k8s,没有部署 kubesphere: sh start.sh xx.xx.xx.xx # 如果部署了 k8s 同时部署了 kubesphere: sh start-with-kubesphere.sh xx.xx.xx.xx ``` ## 5. 部署后排查 参考[《部署验证》](../../部署验证.md)与[《常见问题 FAQ》](../../../04-运维管理/常见问题FAQ.md)中的部署后排查环节。 ## 6. 将 Prometheus 切换为 KubeSphere 的(可选) 如果用了 KubeSphere 自带的 Prometheus,可做如下切换: - Grafana 中数据源地址替换为 `http://prometheus-k8s.kubesphere-monitoring-system.svc:9090` - 配置文件 `config.py` 中,`PROMETHEUS` 修改为 `prometheus-k8s.kubesphere-monitoring-system:9090` > `PROMETHEUS` 默认值为 `prometheus-k8s.monitoring:9090`(见 `install/kubernetes/cube/overlays/config/config.py:808`),即指向平台自带 `monitoring` 命名空间下的 Prometheus。仅当改用 KubeSphere 监控时才需要切换。监控相关详见[《监控部署与看板》](../../../04-运维管理/监控部署与看板.md)。 --- 后续的节点扩缩容、升级、高可用与卸载见[《节点扩缩容与高可用》](04-节点扩缩容与高可用.md)。 --- ### KubeKey 离线部署 k8s - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/%E9%83%A8%E7%BD%B2%E6%96%B9%E5%BC%8F/kubekey%E9%83%A8%E7%BD%B2/03-%E7%A6%BB%E7%BA%BF%E9%83%A8%E7%BD%B2 - 分类: 02-部署安装 / 部署方式 - 适用场景: 内网/无外网环境,要用 KubeKey 制作离线包并在内网机器上离线安装 k8s 时读这篇 - 关键词: kubekey离线 / 离线部署 / offline / artifact export / manifest-sample.yaml / kubesphere.tar.gz / 内网部署 / skip-pull-images / config-cluster-offline.yaml / 镜像列表 / kubesphereio / v1.25.16 - 最后更新: 2026-07-04 # KubeKey 离线部署 k8s 内网无法连接外网时,需要在联网机器上制作离线包,再复制到内网机器离线安装。 ## 一、所需镜像列表 ```text registry.cn-beijing.aliyuncs.com/kubesphereio/kube-apiserver:v1.25.16 registry.cn-beijing.aliyuncs.com/kubesphereio/kube-controller-manager:v1.25.16 registry.cn-beijing.aliyuncs.com/kubesphereio/kube-proxy:v1.25.16 registry.cn-beijing.aliyuncs.com/kubesphereio/kube-scheduler:v1.25.16 registry.cn-beijing.aliyuncs.com/kubesphereio/pause:3.8 registry.cn-beijing.aliyuncs.com/kubesphereio/coredns:1.9.3 registry.cn-beijing.aliyuncs.com/kubesphereio/cni:v3.27.3 registry.cn-beijing.aliyuncs.com/kubesphereio/kube-controllers:v3.27.3 registry.cn-beijing.aliyuncs.com/kubesphereio/node:v3.27.3 registry.cn-beijing.aliyuncs.com/kubesphereio/pod2daemon-flexvol:v3.23.2 registry.cn-beijing.aliyuncs.com/kubesphereio/k8s-dns-node-cache:1.22.20 ``` ## 二、在联网机器上制作离线包 ### 下载 KubeKey 下载不成功可多试几次: ```bash export KKZONE=cn curl -sfL https://get-kk.kubesphere.io | VERSION=v3.1.10 sh - chmod +x kk cp kk /usr/bin/ ``` ### 配置离线包内容 `manifest-sample.yaml` 详细说明见官方文档 。 ```bash vi manifest-sample.yaml # 文件夹中文档含有 ``` ### 制作离线包 ```bash export KKZONE=cn ./kk artifact export -m manifest-sample.yaml -o kubesphere.tar.gz ``` ## 三、将离线包复制到内网机器 ```bash scp -r * xx.xx.xx.xx:/root/ ``` ## 四、内网机器离线启动 ### 修改主机名 主机名不要有大写,保持小写: ```bash hostnamectl set-hostname [新主机名] ``` ### 初始化基础组件(内网机器加入前安装) ```bash # 安装时间同步 apt install -y chrony systemctl start chronyd systemctl enable chronyd # 手动同步一下 timedatectl set-ntp true chronyc -a makestep date apt update # ubuntu 安装基础依赖 apt install -y socat conntrack ebtables ipset ipvsadm # 关闭防火墙、iptables、selinux systemctl stop firewalld && systemctl disable firewalld systemctl stop iptables && systemctl disable iptables # 临时关闭 swap swapoff -a # 永久关闭 swap:编辑 /etc/fstab 注释掉 swap 一行(修改后需重启) vim /etc/fstab free -m ``` 清理已有 kubeconfig,否则会导致其他 node 节点无法使用 kubectl: ```bash rm -rf /root/.kube/config ``` ### 创建配置文件并修改参数 ```bash vi config-cluster-offline.yaml ``` > 仓库内置示例 `install/kubernetes/rancher/kubekey/config-cluster-offline.yaml`:k8s 版本 `v1.25.16`、`containerManager: containerd`。 ## 五、创建集群 ```bash export KKZONE=cn ./kk create cluster -f config-cluster-offline.yaml -a kubesphere.tar.gz --skip-pull-images ``` ## 六、卸载 KubeSphere 和 Kubernetes ```bash ./kk delete cluster -f config-cluster-offline.yaml ``` --- 平台侧(CubeStudio)的离线镜像准备另见[《离线部署》](../离线部署.md)。 --- ### KubeKey 节点扩缩容、高可用与卸载 - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/%E9%83%A8%E7%BD%B2%E6%96%B9%E5%BC%8F/kubekey%E9%83%A8%E7%BD%B2/04-%E8%8A%82%E7%82%B9%E6%89%A9%E7%BC%A9%E5%AE%B9%E4%B8%8E%E9%AB%98%E5%8F%AF%E7%94%A8 - 分类: 02-部署安装 / 部署方式 - 适用场景: 集群跑起来后要加/减节点、升级、做 master 高可用、移除 etcd 成员,或彻底卸载清理 KubeKey 部署的 k8s 时读这篇 - 关键词: kubekey / kk add nodes / kk delete node / kk upgrade / 扩缩容 / 高可用 / HA / master节点 / controlPlaneEndpoint / etcd member remove / etcdctl / 卸载 / delete cluster / 彻底清理 / kubelet / etcd - 最后更新: 2026-06-30 # KubeKey 节点扩缩容、高可用与卸载 ## 一、扩缩容节点 新机器需先执行[《环境准备与安装 k8s》](01-环境准备与安装k8s.md)中的基础环境准备,然后修改 `config-cluster.yaml` 文件: ```bash export KKZONE=cn kk add nodes -f config-cluster.yaml # 增加机器 kk delete node -f config-cluster.yaml # 释放机器 ``` ## 二、升级配置 ```bash kk upgrade -f config-cluster.yaml ``` ## 三、高可用(master 节点增删) ### 正常添加节点 需要注意 `address`: ```yaml *** 主要 address *** controlPlaneEndpoint: ## Internal loadbalancer for apiservers # internalLoadbalancer: haproxy domain: lb.kubesphere.local *** address: "172.21.106.247" *** ``` ### 节点可正常连接时删除 master 节点 ```bash ./kk delete node -f config-cluster.yaml ``` 删除后从 `config-cluster.yaml` 中再删除该节点信息,加入新的 master 节点信息。 ### 节点不可正常连接时删除 master 节点 ```bash kubectl drain nodename --ignore-daemonsets=true --grace-period=200 kubectl delete node nodename # 从 etcd 集群列出成员 exist_host_ip1=172.17.0.3 exist_host_ip2=172.17.0.252 ETCDCTL_API=3 etcdctl \ --endpoints=https://$exist_host_ip1:2379 \ --cacert=/etc/ssl/etcd/ssl/ca.pem \ --cert=/etc/ssl/etcd/ssl/admin-$exist_host_ip1.pem \ --key=/etc/ssl/etcd/ssl/admin-$exist_host_ip1-key.pem \ member list # 获取被删除节点在 etcd 中的名称,从 etcd 集群移除(替换最后面的节点 id) ETCDCTL_API=3 etcdctl \ --endpoints=https://$exist_host_ip1:2379,https://$exist_host_ip2:2379 \ --cacert=/etc/ssl/etcd/ssl/ca.pem \ --cert=/etc/ssl/etcd/ssl/admin-$exist_host_ip1.pem \ --key=/etc/ssl/etcd/ssl/admin-$exist_host_ip1-key.pem \ member remove b66918af2a6cdd2c ``` 删除旧的 master,再加入新 master 节点。 > 原文 `kubectl drain` 命令中拼写为 `--ignore-saemonsets`,已按 kubectl 实际参数名修正为 `--ignore-daemonsets`。见 `install/kubernetes/rancher/kubekey/kubekey高可用.md:22`。 ## 四、卸载 KubeSphere 和 Kubernetes ```bash # 配置文件方式 kk delete cluster -f config-cluster.yaml # 命令行直建方式(无配置文件) ./kk delete cluster ``` ## 五、彻底清理 关闭 kubelet、etcd: ```bash systemctl stop kubelet systemctl stop etcd ``` 删除 k8s 相关目录: ```bash sudo rm -rvf ~/.kube sudo rm -rvf /etc/kubernetes/ sudo rm -rvf /etc/systemd/system/kubelet.service.d sudo rm -rvf /etc/systemd/system/kubelet.service sudo rm -rvf /usr/bin/kube* sudo rm -rvf /etc/cni sudo rm -rvf /opt/cni sudo rm -rvf /var/lib/etcd sudo rm -rvf /var/etcd ``` 清除 Docker 所有相关资源: ```bash docker rm -f $(docker ps -aq) docker rmi -f $(docker images -aq) docker volume prune docker network prune ``` --- ### KubeKey 部署 CubeStudio 总览 - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/%E9%83%A8%E7%BD%B2%E6%96%B9%E5%BC%8F/kubekey%E9%83%A8%E7%BD%B2/README - 分类: 02-部署安装 / 部署方式 - 适用场景: 想用 KubeKey(kk) 一键搭建 k8s(在线/离线/多机/高可用),再在其上部署 CubeStudio 时,先读本篇了解整体流程与子文档导航 - 关键词: kubekey / kk / kubesphere / k8s部署 / kubernetes安装 / 多机部署 / 离线部署 / 高可用 / HA / ipvs / containerd / docker / CubeStudio部署 / v1.25.16 / v1.28.15 / v3.1.10 - 最后更新: 2026-07-04 # KubeKey 部署 CubeStudio 总览 本篇介绍用 [KubeKey](https://github.com/kubesphere/kubekey)(命令行工具 `kk`)搭建 Kubernetes 集群,并在其上部署 CubeStudio 平台的完整流程。KubeKey 会自动为节点安装 containerd/docker、kubeadm、kubelet、kubectl、CNI、helm 等组件,适合需要快速拉起 k8s(含多机、离线、高可用)的场景。 > 本文档由以下源文件合并整理:`docs/部署/kubekey部署cube-studio.md`、`install/kubernetes/rancher/kubekey/kubekey部署cube-studio.md`、`install/kubernetes/rancher/kubekey/kubekey离线部署k8s.md`、`install/kubernetes/rancher/kubekey/kubekey高可用.md`。 ## 适用与前置 - 机器最低规格:16C32G;之前装过 KubeSphere(KS) 的环境要先清理干净。 - 容器运行时可选 docker 或 containerd(KubeKey 自动安装,节点无需手工预装)。如需手工了解运行时配置,参考[《节点安装 Containerd 容器运行时》](../../节点准备/安装Containerd.md)。 - 部署前的机器/存储/网络检查清单见[《部署总览与前置要求》](../部署总览与前置要求.md)。 - KubeKey 版本:`v3.1.10`;可安装 k8s `v1.25.16`(配置文件方式,见仓库 `install/kubernetes/rancher/kubekey/config-cluster.yaml`)或 `v1.28.15`(命令行直建方式)。 ## 子文档目录(TOC) | 文件 | 内容 | |---|---| | [01-环境准备与安装k8s.md](01-环境准备与安装k8s.md) | 每台机器的系统初始化、下载 KubeKey、在线安装 k8s(命令行直建 / 配置文件多机两种方式)、常见报错 | | [02-部署cube-studio.md](02-部署cube-studio.md) | 在 k8s 上部署平台:NodePort 端口范围、containerd 下 nerdctl 替换、ipvs 模式 istio 入口、kubeconfig 与 `start.sh`、Prometheus 切换为 KubeSphere | | [03-离线部署.md](03-离线部署.md) | 内网离线场景:所需镜像列表、制作离线包(artifact export)、离线启动与创建集群 | | [04-节点扩缩容与高可用.md](04-节点扩缩容与高可用.md) | 增删节点、升级配置、高可用 master 增删(含 etcd 成员移除)、卸载与彻底清理 | ## 整体流程一览 1. 每台机器做系统初始化(主机名、时间同步、基础依赖、关防火墙/swap)——见 01。 2. 下载 KubeKey,安装 k8s(在线命令行或配置文件方式;离线见 03)——见 01。 3. 在 k8s 上部署 CubeStudio(端口范围、运行时适配、入口、Prometheus)——见 02。 4. 后续运维:扩缩容 / 升级 / 高可用 / 卸载——见 04。 > 部署后的排查方法可参考[《部署验证》](../../部署验证.md)与[《常见问题 FAQ》](../../../04-运维管理/常见问题FAQ.md)。 --- ### KubeSphere 多机部署(一)主机环境初始化与系统优化 - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/%E9%83%A8%E7%BD%B2%E6%96%B9%E5%BC%8F/kubesphere%E5%A4%9A%E6%9C%BA%E9%83%A8%E7%BD%B2/01-%E4%B8%BB%E6%9C%BA%E7%8E%AF%E5%A2%83%E4%B8%8E%E7%B3%BB%E7%BB%9F%E4%BC%98%E5%8C%96 - 分类: 02-部署安装 / 部署方式 / KubeSphere多机部署 - 适用场景: KubeSphere 多机部署前,对每台机器做基线初始化与系统优化时读这篇 - 关键词: 环境初始化 / 主机名 / hostname / hosts解析 / 时间同步 / chronyd / firewalld / iptables / selinux / swap / 内核参数 / br_netfilter / ipvs / ipvsadm / nf_conntrack / overlay2 / sysctl / ulimit / limits.conf / 系统优化 - 最后更新: 2026-06-30 # KubeSphere 多机部署(一)主机环境初始化与系统优化 > 这是「KubeSphere 多机部署」系列的第 1 篇,概览与目录见 [README](README.md)。 > 本篇的操作需要在**集群每台机器**上执行。 ## 步骤 1:环境初始化 ### 修改主机名 ```bash hostnamectl set-hostname [新主机名] ``` ### 1. 检查操作系统版本 ```bash # 此方式下安装 kubernetes 集群要求 CentOS 版本在 7.5 或之上 [root@master ~]# cat /etc/redhat-release CentOS Linux 7.5.1804 (Core) # 检查网络 ping www.baidu.com ping 202.108.22.5 ``` ### 2. 主机名解析 为方便集群节点间直接调用,这里配置一下主机名解析;企业中推荐使用内部 DNS 服务器。 > 如果使用 KubeSphere(KubeKey 会自动处理),可以不用手动配置该项。 ```bash # 编辑三台服务器的 /etc/hosts 文件,添加下面内容 vim /etc/hosts --- 192.168.180.110 node110 192.168.180.101 node101 192.168.180.102 node102 ``` ### 3. 时间同步 kubernetes 要求集群中各节点时间必须精确一致,这里使用 chronyd 服务从网络同步时间;企业中建议配置内部时间同步服务器。 ```bash # 启动 chronyd 服务 yum -y install chrony systemctl start chronyd systemctl enable chronyd # 手动同步一次 timedatectl set-ntp true chronyc -a makestep date ``` ### 4. 禁用 iptables 和 firewalld 服务 kubernetes 和 docker 运行中会产生大量 iptables 规则,为避免系统规则与它们混淆,直接关闭系统的规则服务。 ```bash # 1 关闭 firewalld 服务 systemctl stop firewalld systemctl disable firewalld # 2 关闭 iptables 服务 systemctl stop iptables systemctl disable iptables ``` ### 5. 禁用 selinux selinux 是 Linux 下的安全服务,如果不关闭它,安装集群时会产生各种奇怪问题。 ```bash # 编辑 /etc/selinux/config,修改 SELINUX 的值为 disabled # 注意修改完毕后需要重启 Linux vim /etc/selinux/config SELINUX=disabled ``` ### 6. 禁用 swap 分区 swap 分区即虚拟内存分区,物理内存用完后会把磁盘空间虚拟成内存使用,启用 swap 会对系统性能产生明显负面影响,因此 kubernetes 要求每个节点都禁用 swap。如确实不能关闭,需在集群安装时通过明确参数声明。 ```bash # 编辑 /etc/fstab,注释掉 swap 分区那一行(修改后需重启) vim /etc/fstab # 注释掉 /dev/mapper/centos-swap swap # /dev/mapper/centos-swap swap # 检查:free -m 中 swap 全为 0 即配置完成 free -m # 临时关闭 swap 分区 sudo swapoff -a ``` ### 7. 修改 Linux 内核参数 ```bash # 编辑 /etc/sysctl.d/kubernetes.conf,添加网桥过滤和地址转发功能 vim /etc/sysctl.d/kubernetes.conf net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 net.ipv4.ip_forward = 1 # 重新加载配置 sysctl -p # 加载网桥过滤模块 modprobe br_netfilter # 查看网桥过滤模块是否加载成功 lsmod | grep br_netfilter ``` ### 8. 配置 ipvs 功能 在 Kubernetes 中 Service 有两种代理模型:基于 iptables 和基于 ipvs。两者相比 ipvs 性能更高,但使用前需要手动载入 ipvs 模块。 ```bash # 1. 安装 ipset 和 ipvsadm yum install ipset ipvsadm -y # 2. 添加需要加载的模块写入脚本文件 mkdir -p /etc/sysconfig/modules/ cat < /etc/sysconfig/modules/ipvs.modules #!/bin/bash modprobe -- ip_vs modprobe -- ip_vs_rr modprobe -- ip_vs_wrr modprobe -- ip_vs_sh modprobe -- nf_conntrack EOF # 3. 为脚本添加执行权限 chmod +x /etc/sysconfig/modules/ipvs.modules # 4. 执行脚本 /bin/bash /etc/sysconfig/modules/ipvs.modules # 5. 查看模块是否加载成功 lsmod | grep -e ip_vs -e nf_conntrack ``` > **高内核版本注意**:低版本内核(如 3.x)用 `nf_conntrack_ipv4`,高版本内核(如 5.x)已将其替换为 `nf_conntrack`。如果执行时报 `modprobe: FATAL: Module nf_conntrack_ipv4 not found.`,把脚本里的 `modprobe -- nf_conntrack_ipv4` 改为 `modprobe -- nf_conntrack` 即可(上面的脚本已用 `nf_conntrack`)。 ### 9. 重启检查 ```bash getenforce && free -m ``` `getenforce` 显示 `Disabled`、`free -m` 中 swap 全为 0,即基线初始化完成。 --- ## 系统优化 完成基线初始化后,进一步对系统做优化(同样在每台机器上执行)。 - 更新系统: ```bash yum update ``` - 添加所需的内核引导参数: ```bash sudo /sbin/grubby --update-kernel=ALL --args='cgroup_enable=memory cgroup.memory=nokmem swapaccount=1' ``` - 启用 `overlay2` 内核模块: ```bash echo "overlay2" | sudo tee -a /etc/modules-load.d/overlay.conf ``` - 刷新动态生成的 grub2 配置: ```bash sudo grub2-set-default 0 ``` - 调整内核参数并使其生效: ```bash cat < 下一步:下载 KubeKey 并创建 K8s 集群,见 [02-安装KubeSphere与K8s集群](02-安装KubeSphere与K8s集群.md)。 --- ### KubeSphere 多机部署(二)安装 KubeSphere 与 K8s 集群 - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/%E9%83%A8%E7%BD%B2%E6%96%B9%E5%BC%8F/kubesphere%E5%A4%9A%E6%9C%BA%E9%83%A8%E7%BD%B2/02-%E5%AE%89%E8%A3%85KubeSphere%E4%B8%8EK8s%E9%9B%86%E7%BE%A4 - 分类: 02-部署安装 / 部署方式 / KubeSphere多机部署 - 适用场景: 用 KubeKey(kk)创建多节点 K8s 集群并部署 KubeSphere 控制台时读这篇 - 关键词: KubeKey / kk / KKZONE / create config / create cluster / config-sample.yaml / hosts / roleGroups / etcd / control-plane / worker / controlPlaneEndpoint / addons / OpenEBS / LocalPV / kubectl自动补全 / KubeSphere控制台 / 30880 - 最后更新: 2026-07-04 # KubeSphere 多机部署(二)安装 KubeSphere 与 K8s 集群 > 这是「KubeSphere 多机部署」系列的第 2 篇,概览与目录见 [README](README.md)。 > 开始前请先完成 [01-主机环境与系统优化](01-主机环境与系统优化.md) 的基线设置。 ## 步骤 2:下载 KubeKey 请按 KubeSphere 官方文档下载 [KubeKey](https://www.kubesphere.io/zh/docs/v3.3/installing-on-linux/introduction/kubekey)(区分「能正常访问 GitHub/Googleapis」与「访问受限」两种情况)。 先执行以下命令以确保从国内区域下载 KubeKey: ```bash export KKZONE=cn ``` 执行以下命令下载 KubeKey: ```bash curl -sfL https://get-kk.kubesphere.io | VERSION=v3.0.7 sh - ``` > 备注: > - 下载 KubeKey 后,如果把它传到另一台访问 Googleapis 同样受限的机器,请在执行后续步骤前再次执行 `export KKZONE=cn`。 > - 以上命令会下载指定版本(这里是 `v3.0.7`),可修改版本号下载其它版本。 为 `kk` 添加可执行权限: ```bash chmod +x kk ``` --- ## 步骤 3:创建集群 多节点安装需要通过指定配置文件来创建集群。 ### 1. 创建示例配置文件 ```bash ./kk create config [--with-kubernetes version] [--with-kubesphere version] [(-f | --file) path] ``` > 备注: > - 安装 KubeSphere 3.3 建议的 Kubernetes 版本:v1.20.x、v1.21.x、v1.22.x、v1.23.x、v1.24.x(带星号的版本在边缘节点上可能有部分功能不可用,如需边缘节点推荐 v1.21.x)。不指定版本时 KubeKey 默认安装 Kubernetes **v1.23.10**。 > - 命令中不加 `--with-kubesphere` 则不部署 KubeSphere(只能用配置文件中的 `addons` 字段安装,或后续 `./kk create cluster` 时再加该标志)。 > - 加 `--with-kubesphere` 但不指定版本时,会安装最新版 KubeSphere。 示例: ```bash # 使用默认配置创建示例配置文件(也可用 -f 指定文件名/目录) ./kk create config [-f ~/myfolder/abc.yaml] # 指定要安装的 KubeSphere 版本(例如 v3.3.2) ./kk create config --with-kubesphere [version] ``` ### 2. 编辑配置文件 不改名时会创建默认文件 `config-sample.yaml`。下面是「一个主节点的多节点集群」示例: ```yaml spec: hosts: - {name: master, address: 192.168.0.2, internalAddress: 192.168.0.2, user: ubuntu, password: Testing123} - {name: node1, address: 192.168.0.3, internalAddress: 192.168.0.3, user: ubuntu, password: Testing123} - {name: node2, address: 192.168.0.4, internalAddress: 192.168.0.4, user: ubuntu, password: Testing123} roleGroups: etcd: - master control-plane: - master worker: - node1 - node2 controlPlaneEndpoint: domain: lb.kubesphere.local address: "" port: 6443 ``` **hosts(主机)**:列出所有机器并填写详细信息。 - `name`:实例的主机名。 - `address`:任务机与其它实例通过 SSH 互连所用的 IP(可公网或私网,视环境而定)。 - `internalAddress`:实例的私有 IP 地址。 登录信息示例: ```yaml # 使用密码登录(端口非 22 时需显式写 port,22 为默认可省略) hosts: - {name: master, address: 192.168.0.2, internalAddress: 192.168.0.2, port: 8022, user: ubuntu, password: Testing123} # 默认 root 用户 hosts: - {name: master, address: 192.168.0.2, internalAddress: 192.168.0.2, password: Testing123} # 使用 SSH 密钥免密登录 hosts: - {name: master, address: 192.168.0.2, internalAddress: 192.168.0.2, privateKeyPath: "~/.ssh/id_rsa"} ``` > 提示: > - 安装前可用 `hosts` 里的信息通过 SSH 测试任务机与其它实例的网络连通性。 > - 安装前确保端口 `6443`(API 服务器默认端口)未被占用,否则会冲突。 **roleGroups**: - `etcd`:etcd 节点名称 - `control-plane`:主节点名称 - `worker`:工作节点名称 **controlPlaneEndpoint(仅高可用安装)**:仅当安装多个主节点时,才需要在此为高可用集群提供**外部负载均衡器**信息;`address`/`port` 需缩进两个空格,`address` 填负载均衡器地址。 **addons**:可在 `addons` 字段下指定持久化存储插件(NFS 客户端、Ceph RBD、GlusterFS 等)。KubeSphere 默认会安装 [OpenEBS](https://openebs.io/) 并为开发/测试环境配置 LocalPV;本多节点示例使用默认本地存储卷。生产环境建议用 Ceph/GlusterFS/CSI 或商业存储。 > 也可编辑配置文件启用多集群功能、选择要安装的可插拔组件。完整 `config-sample.yaml` 示例见 [KubeKey 仓库](https://github.com/kubesphere/kubekey/blob/release-2.2/docs/config-example.md)。 ### 3. 使用配置文件创建集群 ```bash ./kk create cluster -f config-sample.yaml ``` > 用了其它文件名时,把 `config-sample.yaml` 改成你的文件名。整个安装可能需要 10~20 分钟,取决于机器和网络环境。 ### 4. 验证安装 安装完成后会看到类似输出: ``` ##################################################### ### Welcome to KubeSphere! ### ##################################################### Console: http://192.168.0.2:30880 Account: admin Password: P@88w0rd ... ##################################################### ``` 之后可通过 `:30880` 用默认帐户密码(`admin` / `P@88w0rd`)访问 KubeSphere Web 控制台。 > 备注:访问控制台可能需要按环境配置端口转发规则,并确保安全组放开了端口 `30880`。登录后请尽快修改默认密码。 ### 启用 kubectl 自动补全 KubeKey 不会自动启用 kubectl 补全,按需打开(需先安装 bash-completion): ```bash # 安装 bash-completion apt-get install bash-completion # 在 ~/.bashrc 中加载补全脚本 echo 'source <(kubectl completion bash)' >>~/.bashrc # 把补全脚本放到 /etc/bash_completion.d kubectl completion bash >/etc/bash_completion.d/kubectl ``` --- > 下一步:在 KubeSphere 集群上部署 CubeStudio,见 [03-部署cube-studio](03-部署cube-studio.md)。 --- ### KubeSphere 多机部署(三)在集群上部署 cube-studio - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/%E9%83%A8%E7%BD%B2%E6%96%B9%E5%BC%8F/kubesphere%E5%A4%9A%E6%9C%BA%E9%83%A8%E7%BD%B2/03-%E9%83%A8%E7%BD%B2cube-studio - 分类: 02-部署安装 / 部署方式 / KubeSphere多机部署 - 适用场景: K8s 集群与 KubeSphere 就绪后,在其上部署 CubeStudio(含存储、网关、转发模式处理)时读这篇 - 关键词: CubeStudio部署 / kubeconfig / 节点标签 / label node / istio / gateway / virtualservice / nodeport / service-node-port-range / kube-proxy / ipvs / iptables / kube-ipvs0 / NFS / juicefs / 分布式文件系统 / start.sh / externalIP - 最后更新: 2026-07-04 # KubeSphere 多机部署(三)在集群上部署 cube-studio > 这是「KubeSphere 多机部署」系列的第 3 篇,概览与目录见 [README](README.md)。 > 开始前请先完成 K8s 集群与 KubeSphere 安装,见 [02-安装KubeSphere与K8s集群](02-安装KubeSphere与K8s集群.md)。 KubeSphere 集群就绪后,按"单机部署 cube-studio"的标准流程部署平台即可(参见 [单机 k8s 部署](../单机部署-docker-compose/01-单机k8s部署.md)),但因为 KubeSphere **已自带 Prometheus 等组件**,需要做几处适配。仓库为此提供了专门的部署脚本 `install/kubernetes/start-with-kubesphere.sh`(相比标准 `start.sh`,它**跳过了 Prometheus operator / node-exporter / servicemonitor 那一整套**,只额外部署 grafana 与 prometheus-adapter,复用 KubeSphere 自带的 Prometheus)。 ## 步骤 4:部署 CubeStudio ### 1. 下载 CubeStudio 源码 下载源码: ```bash git clone --depth=1 https://github.com/data-infra/cube-studio.git ``` #### 可选:NFS 安装 KubeSphere 没有自带分布式文件系统,可先用 NFS 提供共享存储: ```bash # 服务器端 yum -y install rpcbind nfs-utils systemctl start rpcbind systemctl enable rpcbind systemctl start nfs-server systemctl enable nfs-server echo "/data/k8s *(rw,no_root_squash)" >> /etc/exports exportfs -rv # 客户端(其它节点) yum -y install nfs-utils mount -t nfs 192.168.31.110:/data/k8s/ /data/k8s echo "192.168.31.110:/data/k8s /data/k8s nfs noatime,nodiratime 0 0" >>/etc/fstab ``` 之后应用 NFS 的 StorageClass,并为旧版 NFS 动态供应开启 `RemoveSelfLink=false`: > 说明:原始笔记此处引用了一个本地的 `nfs-sc.yaml`(NFS StorageClass 定义文件),但该文件为作者本机路径、未随仓库提供。请自行准备 NFS StorageClass 的 yaml(定义 provisioner、回收策略等)后 `kubectl apply`。NFS 离线部署的相关示例可参考 `install/kubernetes/nfs/`(含 `nfs.yaml`、`NFS离线部署.md`)与 [04-运维管理/分布式存储目录](../../../04-运维管理/分布式存储目录.md)。 ```bash kubectl apply -f nfs-sc.yaml # 旧版本 k8s 的 NFS 动态供应需要开启该特性门控 vim /etc/kubernetes/manifests/kube-apiserver.yaml # 添加 --feature-gates=RemoveSelfLink=false ``` > 注意: > - 一定要关闭 KubeSphere 的默认存储类(避免与上述 StorageClass 冲突)。 > - 建议直接在 KubeSphere 中安装 Istio 网关。 ### 2. 复制 config 将 k8s 集群的 kubeconfig 文件复制到 `install/kubernetes/config`: ```bash cp $HOME/.kube/config install/kubernetes/config ``` 然后在 worker 上用 KubeSphere 专用脚本部署,`xx.xx.xx.xx` 为机器**内网** IP: ```bash # KubeSphere 环境用这个脚本(跳过 Prometheus operator 那套,复用 KubeSphere 自带 Prometheus) sh start-with-kubesphere.sh xx.xx.xx.xx ``` 如需手动只给节点打标签(脚本内也会做这一步),标签集合如下: ```bash kubectl label node node112 train=true cpu=true notebook=true service=true org=public istio=true kubeflow=true kubeflow-dashboard=true mysql=true redis=true monitoring=true logging=true --overwrite ``` > 上面的标签集合与 `install/kubernetes/start-with-kubesphere.sh`(第 19 行)、标准 `start.sh`(第 25 行)给节点打的标签完全一致;多机时把 `node112` 换成实际节点名(或按需给多个节点打标签)。 > 注意:`start-with-kubesphere.sh` 并不会把 istio 全部注释掉——它**仍然部署 istio**(`install-1.15.0.yaml` + `gateway.yaml` + `virtual.yaml`,见 `install/kubernetes/start-with-kubesphere.sh:69-82`),只跳过了 Prometheus operator/node-exporter/servicemonitor 那套(对比纯 `start.sh:49-99` 的完整 Prometheus operator 栈)。如果你的 KubeSphere 已启用并接管 istio 网关,请按需自行注释掉脚本中 istio 部分,避免重复安装。 ### 3. istio 网关与端口映射 istio 中 `gateway` 和 `virtualservice` 两个配置注意加上 `name`,并添加 nodeport 之类的映射;也可以改 KubeSphere 的 nodeport 范围,把它映射到 80 端口(不采用 `externalIP` 指定的方式)。 建议手动确定 nodeport 范围,修改 istio gateway 的映射端口;并扩大 API server 的 nodeport 范围: ```bash vi /etc/kubernetes/manifests/kube-apiserver.yaml # 加入 --service-node-port-range=1-40000 # 或用脚本在 "- kube-apiserver" 行后插入 line=$(cat /etc/kubernetes/manifests/kube-apiserver.yaml|grep -n '\- kube-apiserver'|awk -F ":" '{print $1}') sed -i "$line a\ \ \ \ -\ --service-node-port-range=1-40000" /etc/kubernetes/manifests/kube-apiserver.yaml ``` > CubeStudio 仓库中 istio 的网关 / 路由配置见 `install/kubernetes/gateway.yaml` 与 `install/kubernetes/virtual.yaml`,`start.sh` 会 apply 这两个文件。 ### 4. kube-proxy 转发模式(IPVS → iptables) 注意:当 kube-proxy 为 **IPVS 模式**时,使用原来的 `start.sh` 脚本,**不要用本机 IP**(用 `externalIP` 指定本机 IP 会导致集群崩溃)。 KubeSphere 默认转发模式是 IPVS,如有需要可改为 iptables: ```bash kubectl edit cm kube-proxy -n kube-system # 搜索 /mode,把 mode 从 ipvs 改为 "" ``` 如果已有集群残留了 IPVS 的虚拟网卡地址,删除: ```bash # 删除已绑定到 kube-ipvs0 的地址 ip addr del 192.168.31.110/32 dev kube-ipvs0 # 删除虚拟网卡 ip link del kube-ipvs0 ``` > 关于 IPVS 模式转发失败、externalIP 导致节点故障的排查可参考: > - [kube-proxy 的 ipvs 模式转发失败,修改 iptables 模式](https://blog.csdn.net/ma726518972/article/details/125345824) > - [k8s IPVS 模式下 externalIP 导致节点故障浅析](https://blog.csdn.net/qq_41586875/article/details/124330823) ### 5. 分布式文件系统(JuiceFS) KubeSphere 没有自带分布式文件系统,官网推荐 Ceph 或 JuiceFS。使用 JuiceFS: ```bash cd install/kubernetes/juicefs/ && sh start_juicefs.sh ``` 执行前请: 1. 阅读 `install/kubernetes/juicefs/README.md`; 2. 修改 `install/kubernetes/juicefs/.env` 中的 `JUICEFS_HOST_IP` 为本节点的 IP; 3. 保证 `/data` 目录有足够空间。 --- > 部署完成后的访问入口、排查清单等可参考 [单机 k8s 部署](../单机部署-docker-compose/01-单机k8s部署.md) 中的部署后排查部分。本篇命令与版本号来自原始 KubeSphere 部署笔记,具体以源码(`install/kubernetes/`)为准,仅供导航与上手。 --- ### KubeSphere 多机部署 CubeStudio(概览) - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/%E9%83%A8%E7%BD%B2%E6%96%B9%E5%BC%8F/kubesphere%E5%A4%9A%E6%9C%BA%E9%83%A8%E7%BD%B2/README - 分类: 02-部署安装 / 部署方式 / KubeSphere多机部署 - 适用场景: 想用 KubeSphere + KubeKey 搭一套多节点 K8s 集群,再在其上部署 CubeStudio 时,先读这篇选子文档 - 关键词: KubeSphere / kubesphere / 多机部署 / 多节点 / KubeKey / kk / k8s集群 / 高可用 / HA / istio / ipvs / juicefs / nfs / CubeStudio部署 - 最后更新: 2026-07-04 # KubeSphere 多机部署 CubeStudio 本目录说明如何用 **KubeSphere**(基于 KubeKey 安装)搭建一套**多节点 Kubernetes 集群**,并在其上部署 CubeStudio。适合需要多机、希望有 KubeSphere 可视化管理界面的生产/准生产环境。 整体流程分三步: 1. **主机环境准备**:每台机器做基线初始化(主机名、时间同步、关闭 firewalld/selinux/swap、内核参数、ipvs)和系统优化。 2. **安装 KubeSphere 与 K8s 集群**:下载 KubeKey(kk),生成多节点配置文件,一键创建集群并部署 KubeSphere 控制台。 3. **部署 CubeStudio**:准备共享存储(NFS / JuiceFS),打节点标签,处理 istio 网关与 kube-proxy 转发模式,最后用 `start.sh` 部署平台。 > 部署前的机器规格、操作系统、k8s 版本等要求见 [部署总览与前置要求](../部署总览与前置要求.md)。 ## 子文档目录(TOC) | 文档 | 内容 | |---|---| | [01-主机环境与系统优化.md](01-主机环境与系统优化.md) | 步骤 1:每台机器环境初始化(主机名、主机名解析、时间同步、禁用 firewalld/iptables/selinux/swap、内核参数、ipvs 模块);以及系统优化(内核引导参数、overlay2、sysctl、文件句柄限制) | | [02-安装KubeSphere与K8s集群.md](02-安装KubeSphere与K8s集群.md) | 步骤 2-3:下载 KubeKey(kk)、创建并编辑多节点配置文件(hosts / roleGroups / controlPlaneEndpoint / addons)、创建集群、验证安装、kubectl 自动补全 | | [03-部署cube-studio.md](03-部署cube-studio.md) | 步骤 4:下载源码、复制 kubeconfig、打节点标签、istio 网关 nodeport、kube-proxy IPVS→iptables、NFS / JuiceFS 分布式存储、最后 `start.sh` 部署平台 | ## 与单机部署的区别 - 单机/k3s 部署只需一台机器,KubeSphere 多机部署需要多台并由 KubeKey 统一纳管。 - KubeSphere 会**自带 Prometheus 等组件**,所以部署 CubeStudio 用的是专门的脚本 `install/kubernetes/start-with-kubesphere.sh`(跳过 Prometheus operator 那一整套,复用 KubeSphere 自带 Prometheus;详见 03 文档)。 - 单机/k3s 路径见 [k3s 单机部署](../k3s单机部署.md) 或 [单机 k8s 部署](../单机部署-docker-compose/01-单机k8s部署.md)。 > 本目录中 KubeSphere / KubeKey 的版本号、外部命令均来自原始部署笔记,请在自己的环境再验证;CubeStudio 的部署命令与参数以源码(`install/kubernetes/`)为准,本目录仅供导航与上手。 --- ### Rancher RKE 机器初始化与镜像准备 - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/%E9%83%A8%E7%BD%B2%E6%96%B9%E5%BC%8F/rancher-RKE%E9%83%A8%E7%BD%B2/01-%E6%9C%BA%E5%99%A8%E5%88%9D%E5%A7%8B%E5%8C%96%E4%B8%8E%E9%95%9C%E5%83%8F%E5%87%86%E5%A4%87 - 分类: 02-部署安装 / 部署方式 - 适用场景: 部署 Rancher + RKE 前要做的准备:拉代码、准备镜像仓库/离线镜像、centos8 系系统初始化(内核模块与 iptables/sysctl)时读这篇 - 关键词: rancher / 机器初始化 / git clone / GnuTLS / 离线镜像 / harbor / all_image.py / pull_rancher_images.sh / centos8 / OpenCloudOS / Redhat9 / 内核模块 / br_netfilter / iptables / nftables / sysctl / bridge-nf-call-iptables - 最后更新: 2026-06-30 # Rancher RKE 机器初始化与镜像准备 ## 1. 机器初始化 容器运行时(Docker)安装参考[《节点安装 Containerd 容器运行时》](../../节点准备/安装Containerd.md)(原文指向 `install/kubernetes/rancher/install_docker.md`)。 clone 项目: ```bash git clone --depth=1 https://github.com/data-infra/cube-studio.git ``` centos 中如果没有 git,可以先 `yum install git` 安装。 ### 1.1 git clone 遇到 "GnuTLS recv error (-110)" 报错 `GnuTLS recv error (-110): The TLS connection was non-properly terminated.`,依次执行: ```bash apt-get install gnutls-bin git config --global http.sslVerify false git config --global http.postBuffer 1048576000 ``` 再执行 git clone 即可。如果还不行,直接通过国内代理拉取: ```bash git clone --depth=1 https://githubfast.com/data-infra/cube-studio.git ``` ## 2. 建设前准备 1. 自建 docker 镜像仓库或直接使用云厂商免费镜像仓库。如果内网无法连接互联网,可以使用 Harbor 自建内网仓库,并将私有仓库添加到 docker 的 `insecure-registries` 配置中。 2. 如果内网无法连接外网,需要在机器上提前拉好镜像。修改 `install/kubernetes/rancher/all_image.py` 中的内网仓库地址,运行导出/推送/拉取脚本: - 联网机器上运行 `pull_rancher_images.sh` 拉取镜像并推送到内网仓库,或 `rancher_image_save.sh` 将镜像压缩成文件再导入到内网机器。 - 内网(不能联网)机器上运行 `pull_rancher_harbor.sh` 从内网仓库中拉取镜像,或 `rancher_image_load.sh` 从压缩文件中导入镜像。 > 说明:`pull_rancher_harbor.sh`、`rancher_image_save.sh`、`rancher_image_load.sh`(以及 `push_rancher_harbor.sh`)不是仓库里的现成文件,而是**运行 `all_image.py` 时自动生成**的——先把 `all_image.py` 里的 `harbor_repo`(默认 `xx.xx.xx.xx:xx/xx/`)改成自己的内网仓库地址再运行。仓库里现成的脚本只有 `pull_rancher_images.sh` 和 `reset_docker.sh`。镜像清单来自 `rancher-images-mini.txt`。见 `install/kubernetes/rancher/all_image.py:6-11`。 ## 3. centos8 / centos8 stream / OpenCloudOS Server 8 / Redhat 9 系统初始化 ```bash # 修改 /etc/firewalld/firewalld.conf # FirewallBackend=nftables # FirewallBackend=iptables yum install -y yum-utils device-mapper-persistent-data lvm2 yum install -y iptables container-selinux iptables-services # 加载内核模块(写入开机自启) ( cat << EOF systemctl stop firewalld systemctl disable firewalld systemctl stop iptables systemctl disable iptables systemctl stop ip6tables systemctl disable ip6tables systemctl stop nftables systemctl disable nftables modprobe br_netfilter modprobe ip_tables modprobe iptable_nat modprobe iptable_filter modprobe iptable_mangle modprobe ip6_tables modprobe ip6table_nat modprobe ip6table_filter modprobe ip6table_mangle EOF )>> /etc/rc.d/rc.local chmod +x /etc/rc.d/rc.local sh /etc/rc.d/rc.local # 查看加载的内核模块 lsmod sudo echo 'ip_tables' >> /etc/modules systemctl status iptables systemctl status ip6tables systemctl status nftables systemctl status firewalld modinfo iptable_nat modinfo ip6table_nat echo "net.bridge.bridge-nf-call-ip6tables = 1" >> /etc/sysctl.conf echo "net.bridge.bridge-nf-call-iptables=1" >> /etc/sysctl.conf echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf echo "1" >/proc/sys/net/bridge/bridge-nf-call-iptables sysctl -p systemctl restart docker reboot # ipv6 相关错误可以忽略 # 查看模块:ls /lib/modules/`uname -r`/kernel/net/ipv6/netfilter/ ``` --- 系统准备好后,进入[《部署 Rancher Server 与 K8s 集群》](02-部署RancherServer与K8s集群.md)。 --- ### 部署 Rancher Server 与 K8s 集群 - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/%E9%83%A8%E7%BD%B2%E6%96%B9%E5%BC%8F/rancher-RKE%E9%83%A8%E7%BD%B2/02-%E9%83%A8%E7%BD%B2RancherServer%E4%B8%8EK8s%E9%9B%86%E7%BE%A4 - 分类: 02-部署安装 / 部署方式 - 适用场景: 单节点部署 Rancher Server,再通过 Rancher UI 添加自定义 k8s 集群(含 kubelet/kube-api/etcd 等 yaml 参数与网段配置)时读这篇 - 关键词: rancher server / RANCHER_CONTAINER_TAG / v2.10.3 / CATTLE_BOOTSTRAP_PASSWORD / 443端口 / reset_docker.sh / pull_rancher_images.sh / k8s集群 / 自定义集群 / kubelet / kube-api / etcd / service_node_port_range / service_cluster_ip_range / cluster_cidr / extra_binds / coredns - 最后更新: 2026-06-30 # 部署 Rancher Server 与 K8s 集群 ## 4. 部署 Rancher Server 单节点部署 Rancher Server: ```bash # 清理历史部署痕迹 cd cube-studio/install/kubernetes/rancher/ sh reset_docker.sh # 进程关闭会有时延。执行后用 docker ps -a 查看是否还有没清理干净的, # 如果有,重启机器,重新 sh reset_docker.sh # 提前拉取需要的镜像 sh pull_rancher_images.sh # 如果拉取失败,配置好 docker 加速器后 systemctl restart docker,再次执行拉取脚本 echo "127.0.0.1 localhost" >> /etc/hosts sudo timedatectl set-local-rtc 1 # 部署 rancher server export RANCHER_CONTAINER_TAG=v2.10.3 export PASSWORD=cube-studio sudo docker run -d --privileged --restart=unless-stopped -p 443:443 --name=myrancher -e AUDIT_LEVEL=3 -e CATTLE_BOOTSTRAP_PASSWORD=$PASSWORD rancher/rancher:$RANCHER_CONTAINER_TAG # 打开 https://xx.xx.xx.xx:443/ 等待 web 界面可以打开(预计 1~10 分钟) # 用户名 admin,密码 cube-studio ``` ### 4.1 Rancher Server 启动可能问题 - 如果是 centos 8 的配置,按 [01 文档](01-机器初始化与镜像准备.md)的方法修改配置。 - 机器 docker 存储目录要 >100G,内存 >8G。 - 要提前拉取镜像 `sh pull_rancher_images.sh`,不然会因为拉取时间过长造成失败。如果拉取不了,可配置 docker 加速器,参考[《节点安装 Containerd 容器运行时》](../../节点准备/安装Containerd.md)中的镜像加速配置(原文指向 `install/kubernetes/rancher/install_docker.md`)。 - `permission denied` 类型的报错,用 `mount` 查看所属盘是否有 `noexec` 限制。 - 查看 Rancher Server 报错:`docker logs -f myrancher`,忽略其中同步数据的错误。 - 查看 k3s 日志报错:容器刚重启后执行 `docker exec -it myrancher cat k3s.log > k3s.log`,在日志中搜索 error 相关内容: - k3s 日志报 iptables 问题:按 01 文档的 centos8 配置 iptables。 - k3s 日志报 containerd 问题:`docker exec -it myrancher mv /var/lib/rancher/k3s/agent/containerd /var/lib/rancher/k3s/agent/_containerd` - k3s 日志报系统内核没有 xx 模块:降低 linux 系统版本。 - k3s 日志报 `Failed to set sysctl: open /proc/sys/net/netfilter/nf_conntrack_max: permission denied`:执行 `echo "net.netfilter.nf_conntrack_max = 524288" | sudo tee -a /etc/sysctl.conf` 然后 `sysctl -p`。 ```bash sudo sysctl -w fs.inotify.max_user_watches=2099999999 sudo sysctl -w fs.inotify.max_user_instances=2099999999 sudo sysctl -w fs.inotify.max_queued_events=2099999999 ``` > 上面 `_containerd` 的修复命令在原文中路径有笔误(`/varllib/rancher/k3slagent/_containerd`),已按正确路径整理为 `/var/lib/rancher/k3s/agent/_containerd`。见 `install/kubernetes/rancher/readme.md:135`,请按实际路径确认。 ## 5. 部署 k8s 集群 部署完 Rancher Server 后,进入 `https://xx.xx.xx.xx/` 的 web 界面(xx 为服务器 IP)。 选择 "Set a specific password to use" 配置 Rancher 密码,不选 "Allow collection of anonymous statistics....",勾选 "I agree to the terms and conditions ...."。 ![Rancher 初始设置](https://i-blog.csdnimg.cn/img_convert/a7d56660ea7e0245f558b434dd79f78b.png) 之后选择 添加集群 -> 自定义集群 -> 填写集群名称(英文小写)。 ![添加集群](https://i-blog.csdnimg.cn/img_convert/e0beb334ab20f8d2a90a1259d3e99497.jpeg) ![自定义集群](https://i-blog.csdnimg.cn/img_convert/8bdd3a26e3df2774ae1a8b19fef3b3fe.jpeg) 然后选择 kubernetes 的版本(第一次打开可能刷新不出来,等待 1~2 分钟再刷新)。 > 注意:选择 1.28 版本的 k8s。 ![选择 k8s 版本](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/40e54f2faac34cd296a2d3780ade491f.jpeg) ![版本列表](https://i-blog.csdnimg.cn/img_convert/54178d3992b4da762afbfea90b02941d.jpeg) 修改 Advanced option,主要是禁用 nginx ingress、修改端口范围;用 `docker info` 检查服务器上的 docker 根目录是否和默认一致,不一致则需要更改。 之后选择编辑 yaml 文件,添加 kubelet 的挂载参数,需要把分布式存储的位置都加入挂载: ```yaml kube-api: ... kubelet: extra_args: # 与 apiserver 会话时的并发数,默认是 10 kube-api-burst: "30" # kubelet 默认一次拉取一个镜像,设置为 false 可同时拉取多个镜像, # 前提是存储驱动要为 overlay2,对应的 Docker 也需要增加下载并发数 serialize-image-pulls: "false" # 节点资源预留 enforce-node-allocatable: "pods" system-reserved: "cpu=0.25,memory=200Mi" kube-reserved: "cpu=0.25,memory=1500Mi" # docker 存储不能和根目录是同一个分区才生效 image-gc-high-threshold: 95 image-gc-low-threshold: 90 eviction-hard: "imagefs.available<5%,nodefs.available<5%,nodefs.inodesFree<5%" # 不限制最大并行拉取次数 registry-qps: 0 registry-burst: 10 extra_binds: - '/data:/data' ``` ![编辑 yaml](https://i-blog.csdnimg.cn/img_convert/5533c2ae063e10038fbdf3a0337ac0e5.jpeg) 这个 yaml 文件控制着 k8s 基础组件的启动方式(kubelet、api-server 等的启动参数)。 有几个需要修改的是 k8s 使用的网段,默认使用 10.xx,如果和公司网段重复,可以改为其他网段,例如 `172.16.0.0/16` 和 `172.17.0.0/16` 两个网段。 services 部分的示例(注意缩进对齐): ```yaml services: etcd: backup_config: enabled: true interval_hours: 12 retention: 6 safe_timestamp: false creation: 12h extra_args: election-timeout: '5000' heartbeat-interval: '500' gid: 0 retention: 72h snapshot: false uid: 0 kube-api: always_pull_images: false pod_security_policy: false # 服务 node port 范围 service_node_port_range: 10-32767 # 服务的 ip 范围,如果公司 ip 网段与 k8s 网段有冲突,则需要改这里 service_cluster_ip_range: 172.16.0.0/16 # 证书 https 版本 istio 需要,k8s 在 1.21 版本以下的,需要加 extra_args extra_args: service-account-issuer: kubernetes.default.svc service-account-signing-key-file: /etc/kubernetes/ssl/kube-service-account-token-key.pem kube-controller: # 集群 pod 的 ip 范围 cluster_cidr: 172.17.0.0/16 # 集群服务的 ip 范围 service_cluster_ip_range: 172.16.0.0/16 kubelet: # dns 服务的 ip cluster_dns_server: 172.16.0.10 extra_args: # 配置特殊的端口 port: 10250 image-gc-high-threshold: 90 image-gc-low-threshold: 85 resolv-conf: "/etc/resolv-src.conf" # kubelet 挂载主机目录,这样才能使用 subpath,所有情况下部署都必加,且仅此处是必须要加的 extra_binds: - '/data:/data' - '/etc/resolv-src.conf:/etc/resolv-src.conf' kubeproxy: {} scheduler: {} ``` 如果有其他参数需要后面修改,可以再在这里对 yaml 文件进行修改,然后升级集群。修改后直接进入下一步。 接着选择节点的角色: - **etcd**:k8s 的数据库,可多个节点。 - **control**:相当于 k8s 的 master(控制组件),可多节点实现高可用。 - **worker**:工作节点。 可以在部署 Rancher Server 的这台机器上添加 etcd/control 角色。(单机部署或简单尝试,可以把所有角色都选上。) ![选择角色](https://i-blog.csdnimg.cn/img_convert/8abae389555146660722367f13800e56.jpeg) 最后复制页面中显示的命令,在 Rancher Server 的终端上粘贴执行,注意在命令后面加上参数 `--node-name xx.xx.xx.xx`(服务器主机的内网 ip 地址)。 ![复制命令](https://i-blog.csdnimg.cn/img_convert/37fbfef15a62e6096e51fb925d1b46e4.jpeg) 部署完成后,集群状态会变为 "Active",之后就可以下载 kubeconfig 文件连接 k8s 集群。 ![集群 Active](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/1f0f669880ee4b3bb166bcf35ca7f6a5.png) ## 6. 部署完成后需要部分修正 由于 coredns 的资源 limits 太小,可以取消 coredns 的 limits 限制,不然 dns 会非常慢,整个集群都会缓慢。 --- 集群跑起来后的故障处理见[《Rancher 运维与故障处理》](03-Rancher运维与故障处理.md);扩容、多用户、迁移见[《扩容多用户与重建迁移》](04-扩容多用户与重建迁移.md)。 --- ### Rancher 运维与故障处理 - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/%E9%83%A8%E7%BD%B2%E6%96%B9%E5%BC%8F/rancher-RKE%E9%83%A8%E7%BD%B2/03-Rancher%E8%BF%90%E7%BB%B4%E4%B8%8E%E6%95%85%E9%9A%9C%E5%A4%84%E7%90%86 - 分类: 02-部署安装 / 部署方式 - 适用场景: Rancher Server/RKE 集群跑起来后机器重启打不开、镜像拉取超时、时间回拨、api-server/webhook 报错、证书认证过期等故障的处理方法 - 关键词: rancher故障 / k3s / registries.yaml / 镜像拉取超时 / docker hub / mirror / helm-operation / 时间回拨 / time skew / kube-apiserver / webhook / validatingwebhookconfigurations / 证书过期 / dynamic-cert.json / k3s-serving / canal - 最后更新: 2026-06-30 # Rancher 运维与故障处理 ## 机器重启后 Rancher 无法打开 ```bash docker exec -it myrancher bash kubectl get pod -A # 看 k3s 容器是否都正常,如果都正常,可以打开 rancher 平台 ``` 如果报错镜像拉取失败,可以 `describe` 查看详情。 如果报错类似: ```text Failed to pull image "rancher/shell:v0.3.1": rpc error: code = DeadlineExceeded desc = failed to pull and unpack image "docker.io/rancher/shell:v0.3.1": ... dial tcp 108.160.170.39:443: i/o timeout ``` 说明 k3s 内部 containerd 访问 Docker Hub 超时。修复方式(配置镜像加速): ```bash sudo docker exec myrancher sh -lc 'set -e cat > /etc/rancher/k3s/registries.yaml < sh -c "rm /var/lib/rancher/k3s/server/tls/dynamic-cert.json" sudo docker exec -it k3s kubectl --insecure-skip-tls-verify=true delete secret -n kube-system k3s-serving sudo docker restart # rancher server 修复后,重启每台机器的 canal 网络 pod # 之前版本的解决方法 docker stop $RANCHER_CONTAINER_NAME docker start $RANCHER_CONTAINER_NAME docker exec -it $RANCHER_CONTAINER_NAME sh -c "rm /var/lib/rancher/k3s/server/tls/dynamic-cert.json" docker logs --tail 3 $RANCHER_CONTAINER_NAME # 会出现类似: # [INFO] Waiting for server to become available: Get https://localhost:6443/version?timeout=30s: x509: certificate signed by unknown authority docker stop $RANCHER_CONTAINER_NAME docker start $RANCHER_CONTAINER_NAME # rancher server 修复后,重启每台机器的 canal 网络 pod ``` --- ### Rancher 扩容、多用户、节点清理与重建迁移 - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/%E9%83%A8%E7%BD%B2%E6%96%B9%E5%BC%8F/rancher-RKE%E9%83%A8%E7%BD%B2/04-%E6%89%A9%E5%AE%B9%E5%A4%9A%E7%94%A8%E6%88%B7%E4%B8%8E%E9%87%8D%E5%BB%BA%E8%BF%81%E7%A7%BB - 分类: 02-部署安装 / 部署方式 - 适用场景: Rancher + RKE 集群跑起来后要加机器、配多用户、用 kubectl/dashboard、清理节点,或重建/迁移 Rancher Server 时读这篇 - 关键词: rancher扩容 / node-name / rbac / 多用户 / kubectl / kubeconfig / kubernetes-dashboard / 节点清理 / reset_docker.sh / 重建rancher server / rancher迁移 / rancher-data / clusterregistrationtokens / cattle-cluster-agent / cattle-node-agent - 最后更新: 2026-06-30 # Rancher 扩容、多用户、节点清理与重建迁移 ## 7. 机器扩容 现在 k8s 集群已经有了一个 master 节点,但还没有 worker 节点;想添加更多 master/worker 节点就需要机器扩容。 在集群主机界面,点击编辑集群,选择角色为 worker(按需选择角色)。之后复制命令到目标主机上运行,注意命令后面多加一个参数 `--node-name xx.xx.xx.xx`(新加机器的 ip),等待完成即可。 ## 8. rancher/k8s 多用户 如果集群部署好了,需要添加多种权限类型的用户来管理,可以使用 Rancher 来实现 k8s 的 RBAC 多用户。 ## 9. 客户端 kubectl 如果不习惯使用 Rancher 界面,可以使用 kubectl 或 kubernetes-dashboard。 点击 Kubeconfig 文件可以看到 config 的内容,kube-apiserver 可以使用 rancher-server(端口 443)的 api 接口,或者 kube-apiserver(端口 6443)的接口控制 k8s 集群。 由于 6443 端口在 idc 网络里并不能暴露到外面,所以主要使用 rancher-server 的 443 端口代理 k8s-apiserver 的控制。提示:如果 Rancher Server 坏了,可以在内网通过 6443 端口继续控制 k8s 集群。 下载安装不同系统办公电脑对应的 kubectl,然后复制 config 到 `~/.kube/config`,就可以通过命令访问 k8s 集群了。 ## 10. kubernetes-dashboard 如果喜欢用 k8s-dashboard,可以自己安装。可参考: ## 11. 节点清理 当安装失败需要重新安装,或需要彻底清理节点时:由于清理过程比较麻烦,可以在 Rancher 界面上把 node 删除,然后再去机器上执行 `reset_docker.sh`,这样机器就恢复了部署前的状态。 如果 web 界面上删除不掉,也可以通过 kubectl 命令: ```bash kubectl delete node node12 ``` ## 12. 重新创建 Rancher Server 修改端口,或修改启动环境变量等需要重新创建 Rancher Server: ```bash export RANCHER_CONTAINER_TAG=v2.8.5 export RANCHER_CONTAINER_NAME=myrancher export PASSWORD=cube-studio docker stop $RANCHER_CONTAINER_NAME docker create --volumes-from $RANCHER_CONTAINER_NAME --name rancher-data rancher/rancher:$RANCHER_CONTAINER_TAG docker run --volumes-from rancher-data -v $PWD:/backup alpine tar zcvf /backup/rancher-data-backup-$RANCHER_VERSION-$DATE.tar.gz /var/lib/rancher docker pull rancher/rancher:$RANCHER_CONTAINER_TAG # 重新创建的命令自己按需修改 docker run -d --privileged --volumes-from rancher-data --restart=unless-stopped -p 443:443 --name=myrancher-new -e CATTLE_TLS_MIN_VERSION=1.2 -e AUDIT_LEVEL=3 -e CATTLE_BOOTSTRAP_PASSWORD=$PASSWORD rancher/rancher:$RANCHER_CONTAINER_TAG ``` 如果修改了启动端口,要在全局设置里修改 server-url,然后关闭 docker: ```bash # 停止 Docker 服务 sudo systemctl stop docker sudo systemctl stop docker.socket sudo systemctl stop containerd # 进入 share-mnt 容器的主机目录 /var/lib/docker/containers//config.v2.json, # 将其中的 server-url 改为新端口号的 # 重启 sudo systemctl start containerd sudo systemctl start docker.socket sudo systemctl start docker # 然后 docker inspect share-mnt 看该容器的启动参数变化了没 ``` 然后 k8s config 文件就可以使用了。再修改 `cattle-system` 空间下面的 secret `cattle-credentials` 中的 url,以及 deployment `cattle-cluster-agent` 和 daemonset `cattle-node-agent`,把环境变量中 server-url 地址改了。 最后 `docker ps -a | grep agent` 查看所有 agent 是否正常(share-mnt 容器正常就是会停止,看一下日志是否正常即可)。 ## 13. Rancher Server 节点迁移 可以将 Rancher Server 节点迁移到另一台机器,以防机器废弃后无法使用。 首先在原机器上把数据压缩(不要关闭源集群 Rancher Server,后面还要执行 kubectl)。`.tar.gz` 文件名以实际为准: ```bash export RANCHER_CONTAINER_TAG=v2.8.5 docker create --volumes-from myrancher-new --name rancher-data-new rancher/rancher:$RANCHER_CONTAINER_TAG docker run --volumes-from rancher-data-new -v $PWD:/backup alpine tar zcvf /backup/rancher-data-backup-20210101.tar.gz /var/lib/rancher ``` 把 tar.gz 文件复制到新的 Rancher Server 机器上: ```bash tar -zxvf rancher-data-backup-20210101.tar.gz && mv var/lib/rancher /var/lib/ ``` 接着在新机器上启动新的 Rancher Server: ```bash sudo docker run -d --restart=unless-stopped -v /var/lib/rancher:/var/lib/rancher -p 443:443 --privileged --name=myrancher -e AUDIT_LEVEL=3 rancher/rancher:$rancher_version ``` 注意以下几点: 1. 新 Rancher Server 的 web 界面上要修改 Rancher Server 的 url。 2. 打开地址 `https://新rancher的ip/v3/clusters/源集群id/clusterregistrationtokens`,例如 `https://100.116.64.86/v3/clusters/c-dfqxv/clusterregistrationtokens`。 3. 在上面的界面上找到最新时间的 `insecureCommand` 的内容,之后 curl 过去: ```bash curl --insecure -sfL https://100.108.176.29/v3/import/d9jzxfz7tmbsnbhf22jbknzlbjcck7c2lzpzknw8t8sd7f6tvz448b.yaml | kubectl apply -f - ``` 配置 kubeconfig 文件为原集群,执行上面的命令,旧 Rancher 上的应用就会连接到新的 Rancher Server。 等新集群正常后,将新机器加入到 k8s 集群的 etcd/controller 节点;将老机器踢出集群。至此完成。 --- ### Rancher + RKE 部署 K8s 集群总览 - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/%E9%83%A8%E7%BD%B2%E6%96%B9%E5%BC%8F/rancher-RKE%E9%83%A8%E7%BD%B2/README - 分类: 02-部署安装 / 部署方式 - 适用场景: 想用 Rancher Server(容器化)+ RKE 搭一套 K8s 集群作为 CubeStudio 运行底座,先读本篇了解整体流程与子文档导航 - 关键词: rancher / RKE / rke1 / k8s部署 / kubernetes / rancher server / rancher agent / etcd / control / worker / 全容器化部署 / 多机集群 / CubeStudio底座 / auth proxy / kubeconfig - 最后更新: 2026-07-04 # Rancher + RKE 部署 K8s 集群总览 Rancher 用**全部容器化**的形式来部署 k8s 集群,能大幅降低 k8s 集群部署/扩缩容的门槛。你可以用 Rancher 来扩缩容 etcd、k8s-master、k8s-worker。 > 本文档由 `install/kubernetes/rancher/readme.md`(528 行)拆分整理。 > > 这是 RKE(rke1,通过 Rancher Server UI 添加自定义集群)的部署方式。如果要用 RKE2,另见[《RKE2 + Rancher 方式部署 K8s 集群》](../RKE2部署.md)。 ## 工作原理(总结) k8s 集群(包括 etcd)的增删节点动作由 Rancher Server 节点控制、由 Rancher Agent 来执行。在新节点上通过运行 Rancher Agent 容器,访问 Rancher Server 获取要执行的部署命令,部署对应的 k8s 组件容器(包含 kubelet、api-server、scheduler、controller 等)。 Rancher 本身并不改变 k8s 的基础组件和工作原理,k8s 的架构依然不变,只不过多了一个认证代理(auth proxy),也就是 kubeconfig 文件中 Rancher Server 中的接口。 ## 子文档目录(TOC) | 文件 | 内容 | |---|---| | [01-机器初始化与镜像准备.md](01-机器初始化与镜像准备.md) | clone 项目、建设前准备(镜像仓库 / 离线镜像)、centos8 系统初始化(内核模块、iptables、sysctl) | | [02-部署RancherServer与K8s集群.md](02-部署RancherServer与K8s集群.md) | 单节点部署 Rancher Server、启动可能问题、通过 Rancher UI 添加自定义 k8s 集群(含 kubelet/kube-api/etcd 等 yaml 参数)、部署完成后修正 | | [03-Rancher运维与故障处理.md](03-Rancher运维与故障处理.md) | 机器重启 Rancher 打不开、镜像拉取超时修复、时间回拨、api-server/webhook 报错、证书认证过期 | | [04-扩容多用户与重建迁移.md](04-扩容多用户与重建迁移.md) | 机器扩容、rancher 多用户、客户端 kubectl、kubernetes-dashboard、节点清理、重建/迁移 Rancher Server | ## 整体流程一览 1. 机器初始化、准备镜像(在线/离线)——见 01。 2. 部署 Rancher Server,并通过其 UI 添加自定义 k8s 集群——见 02。 3. 集群跑起来后的故障处理与日常运维——见 03、04。 > 部署前的机器/存储/网络检查清单见[《部署总览与前置要求》](../部署总览与前置要求.md)。容器运行时(Docker/Containerd)安装见[《节点安装 Containerd 容器运行时》](../../节点准备/安装Containerd.md)。 --- ### NFS 共享存储部署 - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/%E5%AD%98%E5%82%A8%E5%87%86%E5%A4%87/NFS%E5%85%B1%E4%BA%AB%E5%AD%98%E5%82%A8 - 分类: 02-部署安装 / 存储准备 - 适用场景: 需要为 CubeStudio 准备一套可被所有 k8s 节点共享读写的存储(/data/k8s 目录)时,用 NFS 搭建最简单的共享文件系统 - 关键词: NFS / 共享存储 / 分布式存储 / nfs-kernel-server / nfs-common / nfs-utils / rpcbind / exports / showmount / 在线安装 / 离线安装 / ubuntu / centos / /data/k8s / /data/nfs / ReadWriteMany - 最后更新: 2026-07-05 # NFS 共享存储部署 CubeStudio 在多机/多节点部署时,要求每台机器的 `/data/k8s/` 目录是同一份共享存储(pipeline 工作目录、dataset、global、用户工作空间等都落在该目录下)。NFS 是搭建这份共享存储最简单的方式,适合中小规模集群或测试环境;对一致性、吞吐有更高要求的场景可改用 Ceph 或对象存储(见关联文档)。 > 共享存储在平台中的目录用途与挂载约定,见 [04-运维管理/分布式存储目录.md](../../04-运维管理/分布式存储目录.md)。 本文覆盖在线安装、离线安装、server/client 配置与性能压测。 ## 一、安装 NFS ### 在线安装(所有节点) Ubuntu: ```shell apt update apt install -y nfs-kernel-server apt install -y nfs-common ``` CentOS: ```shell yum install -y nfs-utils rpcbind ``` ### 离线安装 #### Ubuntu 使用 deb 包方式安装(所有节点) 按自己的系统版本查找对应的包: 下载 `nfs-common`、`nfs-kernel-server` 后安装: ```shell dpkg -i nfs-common dpkg -i nfs-kernel-server ``` #### CentOS 使用 rpm 包方式安装(所有节点) ```shell wget https://cube-studio.oss-cn-hangzhou.aliyuncs.com/install/nfsrpm.tar.gz tar -zxvf nfsrpm.tar.gz cd nfs rpm -ivh *.rpm --force --nodeps ``` ## 二、NFS server 配置 ```shell # 修改配置文件,增加下面这一行数据 # /data/nfs/ 代表 nfs server 本地存储目录 mkdir -p /data/nfs echo "/data/nfs/ *(rw,no_root_squash,async)" >> /etc/exports # 加载配置文件 exportfs -arv systemctl enable rpcbind.service systemctl enable nfs-server.service systemctl start rpcbind.service systemctl start nfs-server.service # 验证 [root@nfs ~]# showmount -e localhost Export list for localhost: /data/nfs * ``` server 端把存储目录软链到 CubeStudio 约定的 `/data/k8s` 目录: ```bash mkdir -p /data/nfs/k8s ln -s /data/nfs/k8s /data/ ``` > 说明:`ln -s /data/nfs/k8s /data/` 会在 `/data/` 下生成名为 `k8s` 的软链,即 `/data/k8s -> /data/nfs/k8s`。CubeStudio 默认把分布式存储挂载/软链到每台机器的 `/data/k8s/`(见 [04-运维管理/分布式存储目录.md](../../04-运维管理/分布式存储目录.md))。 如果只是单机部署 NFS,到这里就部署结束了;如果是多机部署,则还需要在客户端机器上继续部署客户端。 ## 三、NFS client 配置 客户端依据以下步骤配置。注意:**客户端和服务端的挂载不能在同一台机器上**,否则挂载会出现问题。 ```shell export server=192.168.3.100 # 查看 nfs server 信息 showmount -e $server # 结果 # Export list for xx.xx.xx.xx: # /data/nfs * # 系统层面添加挂载(写入 /etc/fstab,重启自动挂载),将服务端的 /data/nfs 挂载到客户端的 /data/nfs mkdir -p /data/nfs echo "${server}:/data/nfs /data/nfs nfs defaults 0 0" >> /etc/fstab mount -a # 或者使用命令行挂载;如果是同一台机器请注意不要用同一个地址 mount -t nfs $server:/data/nfs /data/nfs # 验证 df -h | grep nfs # 软链到 CubeStudio 的目录 mkdir -p /data/nfs/k8s ln -s /data/nfs/k8s /data/ # 输出类似下面,表示挂载成功 [root@node02 ~]# df -h /data/nfs/ Filesystem Size Used Avail Use% Mounted on 172.16.101.13:/data/nfs 3.5T 626M 3.5T 1% /data/nfs ``` ## 四、性能压测 ```bash # 写入测试 time dd if=/dev/zero of=/data/nfs/test bs=2M count=1000 # 读取测试 time dd if=/data/nfs/test of=/dev/null bs=2M ``` ## 附:在 k8s 中使用 NFS(示例 PV/PVC) `install/kubernetes/nfs/nfs.yaml` 提供了一个直接用 NFS 作为 PV 的示例(`ReadWriteMany`、`Retain` 回收策略),可作为编写自定义 PV/PVC 的参考: ```yaml apiVersion: v1 kind: PersistentVolume metadata: name: nfs-pv spec: capacity: storage: 10Gi accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Retain nfs: path: /data/nfs/test server: 9.135.95.95 # 改成你的 NFS server 地址 ``` > 同目录下还有 `cfs.yaml`(腾讯云 CFS 的 CSI 示例,driver 为 `com.tencent.cloud.csi.cfs`)可参考。具体字段以 `install/kubernetes/nfs/` 下的 yaml 源码为准。 --- ### 节点安装 Containerd 容器运行时 - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/%E8%8A%82%E7%82%B9%E5%87%86%E5%A4%87/%E5%AE%89%E8%A3%85Containerd - 分类: 部署安装 / 节点准备 - 适用场景: 在 ubuntu/centos(amd64 或 arm64)节点上安装并配置 containerd,作为 k8s 节点的容器运行时;含 nerdctl、buildkit、CNI 插件与镜像加速/私有仓库配置 - 关键词: containerd / 容器运行时 / container runtime / nerdctl / buildkit / cni / 镜像加速 / registry mirror / 私有仓库 / sandbox_image / SystemdCgroup / ubuntu / centos / arm64 / amd64 / 离线安装 - 最后更新: 2026-06-30 # 节点安装 Containerd 容器运行时 本文介绍在节点上安装并配置 containerd 作为容器运行时的完整流程,覆盖 ubuntu / centos、amd64 / arm64 在线与离线安装,以及 nerdctl、buildkit、CNI 网络插件的安装与镜像加速、私有仓库配置。 > 说明:如果节点需要接入 GPU,请在装好 containerd 后参考 [GPU 节点接入与初始化](GPU节点接入与初始化.md) 追加 NVIDIA 运行时配置。 ## 1. ubuntu 安装 containerd ### 1.1 卸载旧版本 containerd ```bash sudo apt-get remove -y docker docker-engine docker.io containerd runc sudo rm -rf /var/lib/docker /etc/docker/ sudo rm -rf /var/lib/containerd /etc/containerd/ ``` ### 1.2 ubuntu 安装 containerd ```bash # 国内使用阿里源 curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | apt-key add - # amd64机器 sudo add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable" # arm机器 sudo add-apt-repository "deb [arch=arm64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable" # 更新源 sudo apt-get update # 查看版本 apt-cache madison containerd # 安装containerd sudo apt-get install -y containerd.io # sudo apt-get install containerd= # 例如 apt-get install containerd=1.7.20-.. # 查看运行状态 systemctl start containerd systemctl enable containerd systemctl status containerd ``` ## 2. centos 安装 containerd ```bash yum update -y yum install -y yum-utils device-mapper-persistent-data lvm2 # amd64安装containerd # 使用阿里源,arm64 版本是比较老的版本 yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo yum update -y yum -y install containerd.io # 安装 1.7.20 相近版本 systemctl start containerd systemctl enable containerd systemctl status containerd ``` ## 3. arm64 和 amd64 离线下载安装 离线包包含 nerdctl、containerd、runc,但不包含 cni。建议使用 nerdctl full 包,参考:https://github.com/containerd/nerdctl/releases ```bash arch=arm64 rm -rf nerdctl-full-1.7.7-linux-${arch}.tar.gz wget https://githubfast.com/containerd/nerdctl/releases/download/v1.7.7/nerdctl-full-1.7.7-linux-${arch}.tar.gz tar xf nerdctl-full-1.7.7-linux-${arch}.tar.gz -C /usr/local cp /usr/local/lib/systemd/system/*.service /etc/systemd/system/ # 自启动 buildkit 和 containerd 服务 systemctl enable containerd buildkit systemctl start containerd buildkit # 查看状态 systemctl status buildkit containerd ``` ## 4. 配置 containerd ```bash # 生成默认配置,如果已经生成了配置文件,先删除再重新生成,因为之前自带的配置文件基本是空的 mkdir /etc/containerd containerd config default | tee /etc/containerd/config.toml vi /etc/containerd/config.toml ``` 需要在 `/etc/containerd/config.toml` 中修改/添加如下配置: **1、修改 sandbox_image 的地址** ```toml # sandbox_image = "k8s.gcr.io/pause:3.8" # 注释上面那行,添加下面这行,注意看一下后面的版本号 sandbox_image = "registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.8" ``` **2、配置 containerd 使用 systemd 管理 cgroup** ubuntu / centos 需要配置 Containerd 直接使用 systemd 去管理 cgroup,而不是直接使用 cgroupfs: ```toml [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options] # 修改下面这行 SystemdCgroup = true ``` **3、添加镜像源,拉取 dockerhub 镜像** ```toml [plugins."io.containerd.grpc.v1.cri".registry] # 此行下修改 config_path = "/etc/containerd/certs.d" # 改为此路径,并在每个路径下创建 hosts.toml 文件,存放镜像加速信息 ``` 创建 `/etc/containerd/certs.d` 下的 hosts 文件: ```bash mkdir -p /etc/containerd/certs.d/docker.io tee /etc/containerd/certs.d/docker.io/hosts.toml << 'EOF' server = "https://docker.io" [host."https://docker.1panel.live"] capabilities = ["pull", "resolve"] [host."https://hub.rat.dev/"] capabilities = ["pull", "resolve"] [host."https://docker.chenby.cn"] capabilities = ["pull", "resolve"] [host."https://docker.m.daocloud.io"] capabilities = ["pull", "resolve"] EOF ``` **4、配置私有镜像仓库** 只需给 `config_path` 添加对应的地址(注意与上一步保持一致,统一为 `/etc/containerd/certs.d`,源文件 `install/kubernetes/rancher/install_containerd.md:123` 此处误写为 `cert.d`,少了一个 `s`,两处不一致会导致镜像加速/私有仓库配置不生效): ```toml [plugins."io.containerd.grpc.v1.cri".registry] config_path = "/etc/containerd/certs.d" ``` ```bash # ip写成自己内网仓库的ip mkdir -p /etc/containerd/certs.d/172.17.0.4:88 tee /etc/containerd/certs.d/172.17.0.4:88/hosts.toml << 'EOF' server = "http://172.17.0.4:88" [host."http://172.17.0.4:88"] capabilities = ["pull", "resolve", "push"] skip_verify = true EOF ``` ```bash # 重启配置生效 systemctl daemon-reload systemctl restart containerd ``` ## 5. 安装 nerdctl 首先查看 containerd 与 nerdctl 的对应关系,下载对应的版本。查看下面地址的 “Compatible containerd versions” 部分,确认对应的 containerd 版本并获取下载地址:https://github.com/containerd/nerdctl/releases 比如这里查到适用的 nerdctl 版本是 `version=1.7.6`,那么 nerdctl 的下载地址如下: ```bash version=1.7.6 # amd64版本 wget https://githubfast.com/containerd/nerdctl/releases/download/v${version}/nerdctl-${version}-linux-amd64.tar.gz tar zxvf nerdctl-${version}-linux-amd64.tar.gz -C /usr/local/bin # arm64版本 wget https://githubfast.com/containerd/nerdctl/releases/download/v${version}/nerdctl-${version}-linux-arm64.tar.gz tar zxvf nerdctl-${version}-linux-arm64.tar.gz -C /usr/local/bin ``` 也可以直接在页面上找到相应版本,复制链接下载。 配置 nerdctl: ```bash mkdir -p /etc/nerdctl/ cat > /etc/nerdctl/nerdctl.toml << 'EOF' namespace = "k8s.io" insecure_registry = true EOF ``` ## 6. 安装构建器 buildkit 首先查看 containerd 与 buildkit 的对应关系,下载对应的版本。获取下载地址:https://github.com/moby/buildkit/releases ```bash version=v0.15.1 # amd64版本 wget https://githubfast.com/moby/buildkit/releases/download/${version}/buildkit-${version}.linux-amd64.tar.gz tar zxvf buildkit-${version}.linux-amd64.tar.gz -C /usr/local/ # arm64版本 wget https://githubfast.com/moby/buildkit/releases/download/${version}/buildkit-${version}.linux-arm64.tar.gz tar zxvf buildkit-${version}.linux-arm64.tar.gz -C /usr/local/ ``` 编辑 `/etc/systemd/system/buildkit.service`,内容如下: ```ini [Unit] Description=BuildKit Documentation=https://github.com/moby/buildkit [Service] ExecStart=/usr/local/bin/buildkitd --oci-worker=false --containerd-worker=true [Install] WantedBy=multi-user.target ``` ```bash # 启动 systemctl enable buildkit ``` ## 7. 安装 CNI 网络插件 ```bash # 创建目录 mkdir -p /opt/cni/bin /etc/cni/net.d/ # 下载 CNI 插件 amd,可能网络问题下载失败,记得删除旧文件,重新下载几次 wget https://githubfast.com/containernetworking/plugins/releases/download/v1.1.1/cni-plugins-linux-amd64-v1.1.1.tgz # wget https://cube-studio.oss-cn-hangzhou.aliyuncs.com/install/containerd/cni-plugins-linux-amd64-v1.1.1.tgz tar -C /opt/cni/bin -xzvf cni-plugins-linux-amd64-v1.1.1.tgz # 下载 CNI 插件 arm wget https://githubfast.com/containernetworking/plugins/releases/download/v1.1.1/cni-plugins-linux-arm64-v1.1.1.tgz tar -C /opt/cni/bin -xzvf cni-plugins-linux-arm64-v1.1.1.tgz ``` 修正 containerd 的配置 `vi /etc/containerd/config.toml`: ```toml [plugins."io.containerd.grpc.v1.cri".cni] # ConfDir is the directory to search CNI config files conf_dir = "/etc/cni/net.d" # BinDir is the directory to search CNI plugin binaries bin_dir = "/opt/cni/bin" ``` ```bash # 重启配置生效 systemctl daemon-reload systemctl restart containerd ``` ## 8. 注意事项 1、如果镜像源没有生效,那在拉取 dockerhub 镜像的前面加上 `docker.anyhub.us.kg/library/`。 例如: ```bash # 原本拉取 nerdctl pull nginx # 本质拉取的是 nerdctl pull docker.io/library/nginx # 替换为 nerdctl pull docker.anyhub.us.kg/library/nginx ``` > 说明:文中的 githubfast.com 镜像加速域名、各 dockerhub 加速地址、containerd/nerdctl/buildkit/cni 的具体版本号均为安装时的示例,可能随网络环境与上游发布变化,请以官方 releases 页面为准。 --- ### 节点安装 Docker - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/%E8%8A%82%E7%82%B9%E5%87%86%E5%A4%87/%E5%AE%89%E8%A3%85Docker - 分类: 02-部署安装 / 节点准备 - 适用场景: 给集群节点(ubuntu/centos/redhat)装 docker、docker-compose、kubectl 客户端,或配置 docker 镜像加速/根目录时读这篇 - 关键词: 安装docker / install docker / docker-ce / docker-compose / ubuntu docker / centos docker / redhat docker / 离线安装docker / daemon.json / registry-mirrors / 镜像加速 / insecure-registries / data-root / 切换docker根目录 / kubectl安装 / 阿里云源 - 最后更新: 2026-06-30 # 节点安装 Docker 本文覆盖 ubuntu / centos / redhat 三类系统安装 docker、docker-compose、kubectl 客户端,以及 docker 的镜像加速、根目录配置。 # 1. ubuntu 安装 docker ## 1.1 卸载旧版本 docker ```bash sudo systemctl stop docker apt-get --purge remove -y *docker* apt-get --purge remove -y docker* sudo apt-get autoremove -y dpkg -l | grep docker sudo rm -rf /var/lib/docker sudo rm -rf /data/docker sudo rm -rf /var/lib/containerd ``` ## 1.2 在线安装 docker ```bash ### 设置 docker 存储库 sudo apt-get update -y sudo apt-get install -y ca-certificates curl gnupg lsb-release vim git wget net-tools ### 添加官方秘钥 sudo mkdir -p /etc/apt/keyrings rm -rf /etc/apt/keyrings/docker.gpg rm -rf /etc/apt/sources.list.d/docker.list ### 使用 docker 官方源 #curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg #echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null ### 国内使用阿里源 curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | apt-key add - arch=amd64 # 或者 arm64 sudo add-apt-repository -y "deb [arch=${arch}] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable" ### 安装 docker sudo apt-get update ### 查看存储库中的可用版本(需要 19.03 以上的 docker) # 搜索可用版本 apt-cache madison docker-ce # 安装最新版 docker,但不建议直接使用新版本 # sudo apt install -y docker-ce # 可以提前软连 docker 根目录 # ln -s /data/docker /var/lib/ # 建议不要直接装最新版,而是安装指定版本,示例如下 apt install -y docker-ce=5:27.0.3-1~ubuntu.20.04~focal # ubuntu 2020 apt install -y docker-ce=5:27.0.3-1~ubuntu.22.04~jammy # ubuntu 2022 apt install -y docker-ce=5:27.0.3-1~ubuntu.24.04~noble # ubuntu 2024 # 安装 docker-compose apt install -y docker-compose ``` ## 1.3 离线安装 docker ```bash wget https://download.docker.com/linux/static/stable/x86_64/docker-24.0.6.tgz # arm64 下载 wget https://download.docker.com/linux/static/stable/aarch64/docker-24.0.6.tgz tar -zxvf docker-24.0.6.tgz sudo cp docker/* /usr/bin/ vim /etc/systemd/system/docker.service [Unit] Description=Docker Application Container Engine Documentation=https://docs.docker.com After=network-online.target firewalld.service Wants=network-online.target [Service] Type=notify ExecStart=/usr/bin/dockerd ExecReload=/bin/kill -s HUP $MAINPID LimitNOFILE=infinity LimitNPROC=infinity TimeoutStartSec=0 Delegate=yes KillMode=process Restart=on-failure StartLimitBurst=3 StartLimitInterval=60s [Install] WantedBy=multi-user.target chmod +x /etc/systemd/system/docker.service systemctl daemon-reload systemctl enable docker.service systemctl start docker ``` 离线安装 docker-compose: ```bash wget https://githubfast.com/docker/compose/releases/download/v5.0.2/docker-compose-linux-x86_64 #arm64 下载:wget https://githubfast.com/docker/compose/releases/download/v5.0.2/docker-compose-linux-aarch64 mv docker-compose-linux-x86_64 /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose docker-compose -v ``` > ⚠️ 待核实:docker-compose 的下载版本写的是 `v5.0.2`,但 docker compose 官方发布版本号通常是 `v2.x`(不存在 v5.0.2 的 release),原文此处可能有误。无对应代码可核实,请按实际可下载的版本(如 v2.x 最新版)替换。 # 2. ubuntu 安装 k8s 客户端(非必须) ```bash apt-get update && apt-get install -y apt-transport-https # 添加并信任 APT 证书 curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add - # 添加源地址 add-apt-repository "deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main" apt-get update -y # 搜索可用版本 apt-cache madison kubectl # 安装最新版,最好指定版本 # apt install -y kubectl # 安装指定版本 apt install -y kubectl=1.24.10-00 # 添加 completion,最好放入 .bashrc 中 apt install -y bash-completion source <(kubectl completion bash) ``` # 3. centos 安装 docker ## 3.1 安装 docker ```bash # 先卸载原有 docker service docker stop rpm -qa | grep docker | xargs yum remove -y rpm -qa | grep docker rm -rf /usr/lib/systemd/system/docker.service # 安装镜像源 yum install -y container-selinux yum-utils yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo yum update -y # 查看可用版本 yum list docker-ce --showduplicates # 安装指定版本 yum install -y docker-ce #yum install -y docker-ce-26.1.3-1.el8 #yum install -y docker-ce-26.1.3-1.el9 systemctl start docker ``` ## 3.2 yum 安装 k8s 的源 ```bash cat < /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/ enabled=1 gpgcheck=1 repo_gpgcheck=1 gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg EOF setenforce 0 yum install -y kubectl-1.24.0 source <(kubectl completion bash) ``` # 4. redhat 安装 docker ## 4.1 安装 docker ```bash dnf update -y dnf install -y yum-utils device-mapper-persistent-data lvm2 yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo dnf install -y docker-ce docker-ce-cli containerd.io systemctl start docker systemctl enable docker ``` # 5. 配置 docker ```bash mkdir -p /etc/docker/ # 添加如下配置,先把下面这个文件中的中文注释去掉,不然可能会有问题 cat > /etc/docker/daemon.json < 前置:节点应已安装容器运行时。containerd 的安装见 [安装 Containerd](安装Containerd.md)。如果是 Jetson 边缘盒子,请改用 [Jetson 节点初始化](Jetson节点初始化.md)。 --- ## 1. 安装 NVIDIA 驱动与 CUDA ### 1.1 卸载之前的驱动 ubuntu 卸载 gpu 包: ```bash sudo apt-get --purge remove -y *nvidia* sudo apt autoremove sudo apt-get --purge remove -y "*cublas*" "cuda*" sudo apt-get --purge remove -y "*nvidia*" sudo rm -rf /usr/bin/*nvidia* sudo rm -rf /usr/local/bin/*nvidia* ``` centos 卸载 gpu 包: ```bash sudo yum remove nvidia-* rpm -qa|grep -i nvid|sort yum remove kmod-nvidia-* sudo yum remove nvidia-* # sudo yum remove cublas-* cuda-* ``` 卸载后需 `reboot` 才能重新安装。 ### 1.2 安装新的驱动与 CUDA 先装依赖: ```bash # ubuntu安装依赖 sudo apt-get install -y freeglut3-dev build-essential libx11-dev libxmu-dev libxi-dev libgl1-mesa-glx libglu1-mesa libglu1-mesa-dev # centos安装依赖 sudo yum install freeglut-devel gcc gcc-c++ make kernel-devel libX11-devel libXmu-devel libXi-devel mesa-libGL mesa-libGLU mesa-libGLU-devel ``` 安装 550 的驱动(安装后重启): ```bash wget https://cn.download.nvidia.com/XFree86/Linux-x86_64/550.54.14/NVIDIA-Linux-x86_64-550.54.14.run bash ./NVIDIA-Linux-x86_64-550.54.14.run ``` 安装 cuda(安装后重启): ```bash wget https://developer.download.nvidia.com/compute/cuda/12.4.0/local_installers/cuda_12.4.0_550.54.14_linux.run bash ./cuda_12.4.0_550.54.14_linux.run ``` 如果上面安装不成功,也可以用命令推荐安装(`ubuntu-drivers devices` 查看推荐): ```bash apt install -y nvidia-driver-550-server # 或者 apt install nvidia-driver-550 # 最新稳定版 # 重启机器 ``` ### 1.3 fabricmanager(多卡 NVLink 机型) fabricmanager 必须和驱动版本一致,并且不能自动更新(一般会自动安装,不需要手动安装): ```bash # 且需在之前的版本 sudo apt-get install nvidia-fabricmanager-520 driver_version=520.61.05 driver_version_main=$(echo $driver_version | awk -F '.' '{print $1}') # wget http://mirrors.cloud.aliyuncs.com/nvidia-cuda/ubuntu2004/x86_64/nvidia-fabricmanager-${driver_version_main}_${driver_version}-1_amd64.deb wget https://developer.download.nvidia.cn/compute/cuda/repos/ubuntu2004/x86_64/nvidia-fabricmanager-${driver_version_main}_${driver_version}-1_amd64.deb dpkg -i nvidia-fabricmanager-${driver_version_main}_${driver_version}-1_amd64.deb sudo systemctl enable nvidia-fabricmanager.service sudo service nvidia-fabricmanager start systemctl status nvidia-fabricmanager ``` ### 1.4 配置系统环境变量(一般不需要) ```bash vi /etc/profile export CUDA_HOME=/usr/local/cuda export PATH=$PATH:$CUDA_HOME/bin export LD_LIBRARY_PATH=/usr/lib64:$CUDA_HOME/lib64 ``` --- ## 2. 配置容器运行时的 NVIDIA 支持 驱动装好后,需要给容器运行时安装 NVIDIA 运行时,使容器能识别 GPU。docker 运行时用 `nvidia-docker2`,containerd 运行时用 `nvidia-container-toolkit`。 ### 2.1 在线安装 #### ubuntu 在线安装 ```bash # 删除所有 NVIDIA 相关的软件源 sudo rm -f /etc/apt/sources.list.d/nvidia*.list # 删除冲突的 GPG 密钥 sudo rm -f /usr/share/keyrings/nvidia*.gpg distribution=$(. /etc/os-release;echo $ID$VERSION_ID) \ && curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \ && curl -s -L https://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.list | \ sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \ sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list apt update -y # docker 运行时安装 nvidia-docker2 apt install -y nvidia-docker2 # containerd运行时安装nvidia-container-toolkit apt install -y nvidia-container-toolkit ``` #### centos 在线安装 docker 运行时安装 `nvidia-docker2`: ```bash yum install docker-ce -y #yum install -y yum-utils #distribution=$(. /etc/os-release;echo $ID$VERSION_ID) #curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.repo | sudo tee /etc/yum.repos.d/nvidia-docker.repo cp nvidia-docker.repo /etc/yum.repos.d/nvidia-docker.repo yum makecache yum install -y nvidia-docker2 ``` containerd 运行时安装 `nvidia-container-toolkit`: ```bash yum install -y yum-utils sudo yum-config-manager --add-repo https://nvidia.github.io/libnvidia-container/stable/rpm/nvidia-container-toolkit.repo yum makecache yum install -y nvidia-container-toolkit ``` ### 2.2 离线安装 ```bash wget https://cube-studio.oss-cn-hangzhou.aliyuncs.com/install/nvidia-docker2.tar.gz && tar -zxvf nvidia-docker2.tar.gz && rm nvidia-docker2.tar.gz cd nvidia-docker2 dpkg -i ./*.deb dpkg -l | grep nvidia-docker2 ``` ### 2.3 docker 修改配置 ```bash cat > /etc/docker/daemon.json < 注意:`daemon.json` 是严格 JSON,不支持注释。上面注释仅为说明用途,实际写入文件时请删除所有 `#` 注释行。 ### 2.4 containerd 修改配置 编辑 `/etc/containerd/config.toml`: 添加 nvidia 运行时: ```toml [plugins."io.containerd.grpc.v1.cri".containerd.runtimes] # 添加下面的内容 [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.nvidia] runtime_type = "io.containerd.runc.v2" [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.nvidia.options] BinaryName = "/usr/bin/nvidia-container-runtime" ``` 修改默认运行时为 nvidia: ```toml [plugins."io.containerd.grpc.v1.cri".containerd] default_runtime_name = "nvidia" ``` 重启配置生效: ```bash systemctl daemon-reload systemctl restart containerd ``` ### 2.5 测试容器识别 GPU ```bash docker run --name test --gpus all -it nvidia/cuda:11.8.0-devel-ubuntu22.04 bash docker run --name test --gpus all -it ccr.ccs.tencentyun.com/cube-studio/ubuntu-gpu:cuda11.8.0-cudnn8-python3.9 bash ``` > 注:`ccr.ccs.tencentyun.com/cube-studio/ubuntu-gpu:cuda11.8.0-cudnn8-python3.9` 与平台默认的用户 GPU 镜像一致(`install/docker/config.py:983` 中 `USER_IMAGE`)。 --- ## 3. 将机器加入 k8s 集群并打标签 如果已经部署了 k8s 和 CubeStudio,这里只是把 GPU 机器加入到 k8s 集群;如果还没部署 k8s 和 CubeStudio,可以先参考 [单机部署](../部署方式/单机部署-docker-compose/README.md) 部署 k8s 集群和 CubeStudio。 加入 k8s 集群后为机器添加标签,标签用于管理和选择机型设备: ``` gpu=true 用于表示 gpu设备 vgpu=true 用于表示 vgpu设备 gpu-type=V100 用于表示gpu型号,或者gpu-type=T4 train=true 用于训练 service=true 用于推理 notebook=true 用于开发 org=public 用于表示属于的public资源组 ``` > 说明:这些标签会被平台用作 `node_selector` 调度 pod。例如 notebook 的节点选择器形如 `gpu=true,notebook=true,org=public`,训练任务形如 `cpu=true;train=true;org=public`(见 `myapp/views/view_aihub.py:228,437`)。`gpu-type` 主机标签值要求大写,平台据此匹配异构 GPU 机型(见 `myapp/config.py:1241`、`myapp/tasks/schedules.py:1344`)。 --- ## 4. 部署 GPU 设备插件、监控与弹性伸缩 ### 4.1 部署 k8s GPU 设备插件(平台自带) 部署文件:`install/kubernetes/gpu/nvidia-device-plugin.yml`。 它在 `kube-system` 命名空间创建名为 `nvidia-device-plugin-daemonset` 的 DaemonSet,会在每台 GPU 机器上部署 pod,用于让 scheduler 识别该机器可用的 GPU 算力。 ### 4.2 检查 k8s 机器可占用 GPU 资源 ```bash kubectl get node -o yaml ``` ```yaml status: capacity: cpu: '20' memory: 81846828Ki nvidia.com/gpu: '1' # 英伟达gpu的资源占用 ``` 如果不存在可占用 GPU,那可能是因为机器上 k8s 之外存在占用。需要先关停机器上的 GPU 占用进程,然后重启 kubelet。rancher 重启 kubelet 的方法是 `docker restart kubelet`。 ### 4.3 部署 k8s 监控组件(平台自带) 部署文件:`install/kubernetes/gpu/dcgm-exporter.yaml`。 它在 `monitoring` 命名空间创建名为 `dcgm-exporter` 的 DaemonSet,会在每台 GPU 机器上部署 pod,用于监控 GPU 的使用率(见 `install/kubernetes/gpu/dcgm-exporter.yaml:2-5`)。 ### 4.4 调度占用 GPU 直接写占用卡数目;对于异构 GPU 环境,也可以指定占用的卡型,例如 `1(T4)`、`2(V100)`、`0.1`。 ### 4.5 基于 GPU 利用率进行弹性伸缩(平台自带) 需要先将 GPU 指标采集到 prometheus,再将 prometheus 指标转换为对象指标控制 HPA。 `install/kubernetes/prometheus/prometheus_adapter/` 目录下会部署 `kubeflow-prometheus-adapter`(命名空间 `kube-system`),用于将 prometheus 指标转换为对象指标(见 `install/kubernetes/prometheus/prometheus_adapter/prometheus_adapter.yaml:12-13`)。 --- ## 5. 关于 CUDA 版本 机器安装英伟达驱动和对应版本 CUDA,比如驱动 550、CUDA 12.4。 在 k8s CubeStudio 容器中使用的 CUDA 版本要低于主机的 CUDA 版本(如 12.4)。实际 pytorch 等代码中需要适配的是**镜像中的 CUDA 版本**,不需要关心主机上的 CUDA 版本。 例如:主机 CUDA 12.4,在 k8s 中使用 CUDA 11.8 的 GPU 镜像,那就需要在镜像环境中安装兼容 CUDA 11.8 的 pytorch。 > 说明:文中驱动 550 / CUDA 12.4 / fabricmanager 520 等版本号为示例,请按实际机型与上游发布选择匹配版本。具体部署清单以 `install/kubernetes/gpu/` 与 `install/kubernetes/prometheus/prometheus_adapter/` 下源码为准。 --- ### Jetson 边缘 GPU 节点初始化 - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/%E8%8A%82%E7%82%B9%E5%87%86%E5%A4%87/Jetson%E8%8A%82%E7%82%B9%E5%88%9D%E5%A7%8B%E5%8C%96 - 分类: 部署安装 / 节点准备 - 适用场景: 把 NVIDIA Jetson 边缘盒子(Orin/Xavier 等)接入 k8s 集群前的环境初始化,按 Jetpack 版本检查环境、安装 NVIDIA 容器运行时并验证 GPU - 关键词: jetson / jetpack / l4t / orin / xavier / 边缘设备 / edge / arm64 / nvidia-container-toolkit / nvidia-container-runtime / jetson_release / jtop / tegrastats / l4t-pytorch / l4t-cuda / cuda / tensorrt / 边缘GPU / 盒子 - 最后更新: 2026-06-30 # Jetson 边缘 GPU 节点初始化 本文针对 NVIDIA Jetson 边缘盒子(如 Orin NX、Xavier)接入 k8s 集群前的环境初始化。Jetson 是 arm64 架构、基于 L4T(Linux for Tegra)的边缘 GPU 设备,与常规 x86 GPU 服务器的初始化方式不同:不需要单独装显卡驱动(随 Jetpack 刷机自带),但容器运行时与可用镜像有专门要求。 ## Jetpack 6.2 版本 刷机后,设备环境完好,可直接加入 k8s。 ## Jetpack 5.1 版本 ### 查看盒子的版本信息 ```bash # 查看盒子上有没有gpu卡 ls /dev/nvidia* # 结果类似:/dev/nvidia0 /dev/nvidiactl /dev/nvidia-uvm /dev/nvidia-modeset # 查看盒子系统相关信息 sudo swapoff -a apt-get install -y jetson-io jetson_release ``` `jetson_release` 显示信息示例: ``` Software part of jetson-stats 4.3.2 - (c) 2024, Raffaello Bonghi Model: NVIDIA Orin NX Developer Kit - Jetpack 5.1.5 [L4T 35.6.1] # 这里是jetpack的版本和L4T的版本 NV Power Mode[0]: MAXN Serial Number: [XXX Show with: jetson_release -s XXX] Hardware: - P-Number: p3767-0001 - Module: NVIDIA Jetson Orin NX (8GB ram) # 硬件型号 Platform: - Distribution: Ubuntu 20.04 focal # 平台系统 - Release: 5.10.216-tegra # 盒子上的系统版本,基于上面的ubuntu jtop: # 实时监控,等于htop,会显示jetpack的版本和L4T版本 R35对应jetpack 5.1 - Version: 4.3.2 - Service: Active Libraries: - CUDA: 11.4.315 # 这里是cuda版本 - cuDNN: 8.6.0.166 - TensorRT: 8.5.2.2 - VPI: 2.4.8 - Vulkan: 1.3.204 - OpenCV: 4.5.4 - with CUDA: NO ``` 其他监控命令: ```bash # 查看内存/cpu/gpu使用情况。实时监控,等于htop,会显示jetpack的版本和L4T版本。R35对应jetpack 5.1。GA10B(Orin)、GV10B(Xavier) jtop # 可以通过 1 2 3 替换要显示的内容 # 查看 L4T 版本号 cat /etc/nv_tegra_release # 监控 CPU/GPU/内存使用率(没有jtop那么好用) tegrastats ``` ### 安装英伟达运行时 如果之前安装错了,先强制删除之前安装的,必须卸载掉所有报错的才行: ```bash # 查看之前安装了哪些 dpkg -l | grep -E "nvidia" sudo dpkg --purge --force-all nvidia-docker2 nvidia-container-toolkit nvidia-container-runtime nvidia-container-toolkit-base libnvidia-container1 libnvidia-container0 apt purge -y nvidia-container-toolkit nvidia-container-runtime libnvidia-container-tools libnvidia-container1 libnvidia-container0 nvidia-container-toolkit-base nvidia-docker2 # 删除所有 NVIDIA 相关的软件源 sudo rm -f /etc/apt/sources.list.d/nvidia*.list # 删除冲突的 GPG 密钥 sudo rm -f /usr/share/keyrings/nvidia*.gpg ``` 5.1 版本的 jetpack 盒子原本带的源不行,太老了,重新添加源: ```bash curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \ sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \ sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list ``` 安装 NVIDIA Container Toolkit。安装一个不要太新的版本(太新的结构设计没有文档说明不清楚),这里安装 1.14 的,要求 `>= 1.11.0`,不然 k8s device plugin 部署不了: ```bash sudo apt update apt-cache madison nvidia-container-toolkit sudo apt install -y nvidia-container-toolkit=1.14.6-1 \ nvidia-container-toolkit-base=1.14.6-1 \ libnvidia-container-tools=1.14.6-1 \ libnvidia-container1=1.14.6-1 \ nvidia-container-runtime=3.14.0-1 ``` 安装后的目录结构: ```bash root@ubuntu:/# ls -l /usr/bin/nvidia-* /usr/bin/nvidia-bug-report-tegra.sh /usr/bin/nvidia-container-cli /usr/bin/nvidia-container-runtime /usr/bin/nvidia-container-runtime-hook /usr/bin/nvidia-container-toolkit -> /usr/bin/nvidia-container-runtime-hook /usr/bin/nvidia-ctk /usr/bin/nvidia-detector /usr/bin/nvidia-xconfig ``` 有些更新的版本没有 `/usr/bin/nvidia-container-runtime`,则必须新建软链 `/usr/bin/nvidia-container-runtime` 指向 `/usr/bin/nvidia-container-toolkit`。 安装后用 `dpkg -l | grep -E "nvidia"` 应能查看到这几个包: ``` ii libnvidia-container-tools 1.14.6-1 arm64 NVIDIA container runtime library (command-line tools) ii libnvidia-container1:arm64 1.14.6-1 arm64 NVIDIA container runtime library ii nvidia-container-runtime 3.14.0-1 all NVIDIA Container Toolkit meta-package ii nvidia-container-toolkit 1.14.6-1 arm64 NVIDIA Container toolkit ii nvidia-container-toolkit-base 1.14.6-1 arm64 NVIDIA Container Toolkit Base ``` ### docker 修改配置 ```bash cat > /etc/docker/daemon.json < 注意:`daemon.json` 是严格 JSON,不支持注释。上面注释仅为说明用途,实际写入文件时请删除所有 `#` 注释行。 ### 测试 docker 识别 GPU Jetson 上必须使用 L4T 的专用 pytorch 镜像,不能使用常规 pytorch / 常规 cuda 镜像。 ```bash # jetpack 5.1以前 镜像列表参考 https://catalog.ngc.nvidia.com/orgs/nvidia/containers/l4t-pytorch/tags docker run --rm --gpus all -it --runtime=nvidia --privileged nvcr.io/nvidia/l4t-pytorch:r35.1.0-pth1.13-py3 bash # jetpack 5.1以后 https://catalog.ngc.nvidia.com/orgs/nvidia/containers/l4t-cuda/tags docker run --rm --gpus all -it --runtime=nvidia --privileged nvcr.io/nvidia/l4t-cuda:12.6.11-runtime bash # 这里封装了一个包含pytorch的 docker run --rm --gpus all -it --privileged ccr.ccs.tencentyun.com/cube-studio/l4t-cuda:12.6.11-runtime bash ``` 容器内测试: ```bash ls /dev/nvidia* # 与是否启动 --privileged 有关 echo $NVIDIA_VISIBLE_DEVICES # docker run 的容器是 all,k8s 里面显示的是 tegra ``` python3 测试(安装 pytorch 包参考:https://pytorch.org/get-started/previous-versions/): ```python import torch print(torch.__version__) # 查看 PyTorch 版本 print(torch.version.cuda) # 查看编译时用的 CUDA 版本 print(torch.cuda.is_available()) # 检查 CUDA 是否可用 print(torch.cuda.device_count()) # 直接获取 GPU 数量 ``` jetpack 6.2 安装 pytorch: ```bash pip install torch==2.6.0 torchvision==0.21.0 torchaudio==2.6.0 --index-url https://download.pytorch.org/whl/cu126 ``` > 说明:文中 Jetpack / L4T / CUDA / nvidia-container-toolkit / l4t 镜像 tag 等版本号为示例,请按实际刷机版本与 NGC(catalog.ngc.nvidia.com)上的可用 tag 选择。 --- ### FRP 内网穿透(把内网 CubeStudio 暴露到公网) - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/%E7%BD%91%E7%BB%9C/FRP%E5%86%85%E7%BD%91%E7%A9%BF%E9%80%8F - 分类: 02-部署安装 / 网络 - 适用场景: 平台部署在没有公网 IP 的内网/IDC/办公室局域网,只有一台带公网 IP 的云服务器,想让公网用户访问内网 CubeStudio 时读这篇 - 关键词: FRP / frps / frpc / 内网穿透 / intranet penetration / 反向代理 / reverse proxy / 端口转发 / port forwarding / NAT穿透 / frpc.ini / frps.ini / token / range / NodePort / ingress / 公网访问 / tunnel - 最后更新: 2026-07-04 # 通过 FRP 内网穿透,把 CubeStudio 暴露到公网 本篇提供一套 **基于 [FRP](https://github.com/fatedier/frp) 的内网穿透方案**,用于在以下场景下让公网用户访问到部署在内网的 CubeStudio 平台: - 平台已部署在 **内网 / 私有 IDC / 办公室局域网**,没有公网 IP; - 仅有一台 **带公网 IP 的云服务器**(阿里云 / 腾讯云 / AWS 等任意厂商均可,最低 1C2G 即可); - 希望把 CubeStudio 的 **Web 控制台、Notebook、推理服务、内部服务端口、SSH** 等都通过这台云服务器对外暴露。 > 整个方案不需要修改 CubeStudio 任何业务代码,只是在网络层做端口转发。 > > 本文涉及的配置样例文件(`frps.ini` / `frpc.ini` / `start-server.sh` / `start-client.sh` 等)位于仓库 `install/kubernetes/frp/` 目录,docs1 知识库不再单独拷贝这些文件。 --- ## 1. 整体架构 ``` 公网用户 │ http(s)/tcp ▼ ┌──────────────────────────┐ │ 云服务器(公网 IP) │ ← frps(服务端) │ xx.xx.xx.xx:7000 │ 监听 7000 + 业务端口 └──────────────┬───────────┘ │ 反向长连接(由内网主动发起) │ token 鉴权 + (可选)TLS ▼ ┌──────────────────────────┐ │ 内网 CubeStudio 节点 │ ← frpc(客户端) │ 192.168.3.20 │ 转发到 K8s 入口 / NodePort └──────────────────────────┘ ``` 要点: - **frpc 由内网主动发起到 frps 的连接**,所以内网无需任何公网入口; - 公网用户访问 `云服务器:remote_port`,流量被 frps → frpc → 内网真实服务转发; - 配置文件中所有 `local_ip` 都应指向 **内网 CubeStudio 的 K8s 入口节点**(一般是 nginx-ingress 所在节点 / NodePort 节点)。 --- ## 2. 准备工作 ### 2.1 选一台公网云服务器 - 系统建议:Ubuntu 22.04+; - 安全组 / 防火墙:放通 `frpc.ini` 中所有 `remote_port`。其中 `7000` 用于 frpc 接入 frps,业务转发端口见下文第 4.2 节端口规划,按需放通。 ### 2.2 下载 FRP 二进制(服务端、客户端各下载一次) ```bash # amd64 服务器(GitHub) wget https://github.com/fatedier/frp/releases/download/v0.51.3/frp_0.51.3_linux_amd64.tar.gz # arm64 服务器(GitHub) wget https://github.com/fatedier/frp/releases/download/v0.51.3/frp_0.51.3_linux_arm64.tar.gz # 国内镜像(GitHub 不通时使用) # amd64 wget https://cube-studio.oss-cn-hangzhou.aliyuncs.com/install/frp_0.51.3_linux_amd64.tar.gz # arm64 wget https://cube-studio.oss-cn-hangzhou.aliyuncs.com/arm64/frp_0.51.3_linux_arm64.tar.gz ``` 解压并放到 `/root/frp/`(启动脚本默认从这里读取): ```bash tar -zxvf frp_0.51.3_linux_amd64.tar.gz mv frp_0.51.3_linux_amd64 /root/frp ``` 服务端只需要 `frps` + `frps.ini`,客户端只需要 `frpc` + `frpc.ini`。仓库提供两份示例配置(精简版 `*.ini` 与完整版 `*_full.ini`,以及 `*.toml` 新格式),直接放到 `/root/frp/` 即可。 --- ## 3. 在公网云服务器上部署 frps(服务端) ### 3.1 配置 `frps.ini` ```ini [common] bind_port = 7000 bind_addr = 0.0.0.0 token = uyennjdsahyeii677d8nedebgsdt263u # 与 frpc.ini 必须保持一致,建议改成你自己的随机串 ``` ### 3.2 启动 frps ```bash cd /root/frp sh start-server.sh # start-server.sh 内部: # nohup /root/frp/frps -c /root/frp/frps.ini > runoob.log 2>&1 & # (脚本先用 pgrep "frps" 判断进程是否已存在,避免重复拉起) ``` 建议加到 crontab 做存活守护(脚本自身已经做了 `pgrep` 判断,重复执行不会拉起多个进程): ```bash crontab -e # 每 5 分钟检查一次,挂了自动拉起 */5 * * * * sh /root/frp/start-server.sh > /dev/null 2>&1 & ``` ### 3.3 放通安全组 / 防火墙 至少放通: - `7000/tcp`:frpc 接入端口; - 业务侧所有 `remote_port`(见下一节端口规划)。 --- ## 4. 在内网 CubeStudio 节点上部署 frpc(客户端) ### 4.1 修改 `frpc.ini` 需要按你自己的环境替换 3 个变量: | 字段 | 含义 | 仓库示例值 | |---|---|-----------------------------------| | `server_addr` | 公网云服务器 IP / 域名 | `47.94.241.197`(替换成你的公网 IP) | | `server_port` | 与 `frps.ini` 中 `bind_port` 一致 | `7000` | | `token` | 与 `frps.ini` 中 `token` 一致 | `uyennjdsahyeii677d8nedebgsdt263u` | | 各 section 中的 `local_ip` | **内网 CubeStudio 的 K8s 入口节点 IP**(ingress 所在节点 / NodePort 节点) | `192.168.3.20` | ### 4.2 端口规划(重要) 仓库的 `frpc.ini` 默认把 CubeStudio 的核心端口全部映射出去(以下与 `install/kubernetes/frp/frpc.ini` 实际内容一致): | section | 用途 | 内网端口(local_port) | 公网端口(remote_port) | 说明 | |---|---|---|---|---| | `[web]` | Web 控制台 (HTTP) | 80 | **8888** | 浏览器访问 `http://公网IP:8888` 即可登录 cube-studio | | `[https]` | Web 控制台 (HTTPS) | 443 | **8443** | 启用 HTTPS 时使用 | | `[web-0]`~`[web-4]` | 预留 Web 端口 | 1080~1084 | 同号 | 备用 / 自定义服务端口 | | `[ssh]` | SSH | 22 | **8022** | 远程登录入口节点(暴露需谨慎,见安全建议) | | `[range:notebook]` | Notebook 端口段 | 10001~10227(奇数) | 同号 | JupyterLab / VSCode-Server 实例端口,每个 notebook 占一个 | | `[range:service]` | Service 端口段 | 30000~30226(偶数) | 同号 | K8s NodePort 服务端口段,模型服务 / 内部服务用 | | `[range:inference]` | Inference 端口段 | 20000~20226(偶数) | 同号 | 推理服务端口段 | | `[range:rental]` | 租用 / 弹性服务端口段 | 40000~40226(偶数) | 同号 | 资源租用类服务端口段 | > 端口段并非连续,而是分两截:notebook 为 `10001-10119` + `10201-10227`(奇数);service / inference / rental 分别为 `xx000-xx118` + `xx200-xx226`(偶数)。配置形如 `[range:notebook]`,FRP 会一次性建立大量 TCP 隧道。如果你只用其中一部分,**请删掉用不到的端口范围**,减少云服务器负载与暴露面。 ### 4.3 启动 frpc ```bash cd /root/frp sh start-client.sh # start-client.sh 内部: # nohup /root/frp/frpc -c /root/frp/frpc.ini > /runoob.log 2>&1 & # (脚本先用 pgrep "frpc" 判断进程是否已存在,避免重复拉起) ``` 同样建议加到 crontab 做存活守护: ```bash crontab -e */5 * * * * sh /root/frp/start-client.sh > /dev/null 2>&1 & ``` --- ## 5. 公网访问验证 完成上面步骤后,从公网任意客户端: ```bash # 1) Web 控制台(默认账号 admin / admin) curl -I http://公网ip:8888 ``` --- ## 6. 安全建议 公网穿透 = 把内网端口直接挂到互联网上,**务必做这几件事**: 1. **改默认 token**:`frps.ini` / `frpc.ini` 里的 `token` 必须改成你自己的强随机串; 2. **改 CubeStudio 默认密码**:登录后第一时间修改 `admin` 默认口令; 3. **最小化端口暴露**:用不到的 `[range:*]` 段全部删掉,尽量不要开放到内网的 SSH(`22` → 公网 `8022`); 4. **加防火墙**:在云服务器安全组里限制源 IP; 5. **日志监控**:关注 `runoob.log`,发现异常连接及时处置。 --- ## 7. 常见问题 | 现象 | 排查方向 | |---|---| | frpc 启动后 `runoob.log` 提示 `login to server failed` | 检查 `server_addr` / `server_port` / `token` 是否与 frps 端一致;云服务器 7000 端口安全组是否放通 | | 公网访问 `:8888` 超时 | 云服务器安全组没放通对应 `remote_port`;或者 `local_ip` 不是内网 ingress / NodePort 节点 | | 公网访问 `:8888` 拿到 502 / 连接被重置 | frpc 能连上 frps,但 `local_ip:local_port` 在内网不可达,去内网节点 `curl 192.168.3.20:80` 验证 | | Notebook 进得去但 WebSocket 断 | FRP 0.51 默认支持 WS,确认浏览器侧端口与 CubeStudio 平台分配的 notebook 端口一致 | --- ## 8. 文件清单 | 文件 | 部署位置 | 作用 | |---|---|---| | `frps.ini` / `frps_full.ini` / `frps.toml` | 公网云服务器 | frps 服务端配置(精简版 + 完整版 + toml 示例) | | `frpc.ini` / `frpc_full.ini` / `frpc.toml` | 内网入口节点 | frpc 客户端配置(精简版 + 完整版 + toml 示例) | | `start-server.sh` | 公网云服务器 | 启动 frps 的守护脚本(带 pgrep 防止重复拉起) | | `start-client.sh` | 内网入口节点 | 启动 frpc 的守护脚本(带 pgrep 防止重复拉起) | > 以上文件均在仓库 `install/kubernetes/frp/` 目录下。 --- ### RDMA 高速网络部署(InfiniBand / RoCE / Mellanox) - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/%E7%BD%91%E7%BB%9C/RDMA%E9%AB%98%E9%80%9F%E7%BD%91%E7%BB%9C - 分类: 02-部署安装 / 网络 - 适用场景: 给 k8s 节点装 RDMA/IB/RoCE 网卡驱动、在 CubeStudio 里给训练 Pod 分配 RDMA 设备、排查 InfiniBand/Mellanox 网卡问题时读这篇 - 关键词: RDMA / rdma / InfiniBand / IB / RoCE / RoCE over Converged Ethernet / Mellanox / mellanox / MLNX_OFED / ofed / mlxconfig / ib_read_bw / k8s-rdma-shared-dev-plugin / rdma/hca / device plugin / NCCL / 高速网络 / 高性能网络 / 分布式训练网络 - 最后更新: 2026-07-04 # RDMA 高速网络部署(InfiniBand / RoCE / Mellanox) RDMA(Remote Direct Memory Access)提供低延迟、高带宽、低 CPU 占用的网络传输,是多机多卡分布式训练(NCCL 通信)和高性能存储的关键。CubeStudio 通过 `k8s-rdma-shared-dev-plugin` 把宿主机的 RDMA 网卡以 `rdma/hca` 资源的形式暴露给 Pod。 本文合并自三份源码侧文档: - `install/kubernetes/rdma/readme.md`(驱动安装与验证总述) - `install/kubernetes/rdma/roce.md`(在 k8s 中使用 Mellanox RoCE 模式) - `install/kubernetes/rdma/mellanox/readme.md`(Mellanox 命令速查) 并补充了 `install/kubernetes/rdma/` 下的实际部署 YAML(device plugin DaemonSet、测试 Pod 等)。 两种链路层:`ibv_devinfo` 输出 `Link layer: InfiniBand` 表示走 IB 网络;`link_layer: Ethernet` 表示走 RoCE(以太网承载 RDMA)。 --- ## 一、节点驱动安装与验证(总述) > 先重启机器,避免以前的安装需要重启才生效。 ### 1. 查看系统内核 ```bash # centos yum update -y # ubuntu apt update -y rpm -qa | grep kernel # 查看最新的 kernel 包版本 uname -r # 查看操作系统当前运行的内核版本 ``` 对比上面两者是否一致,不一致需要重启。 ### 2. 安装依赖包 ```bash # centos yum install -y gcc-c++ dkms cmake kernel-devel kernel-headers libnl3 libnl3-devel # ubuntu apt-get install -y dkms cmake libnl-3-dev libnl-route-3-dev kernel-headers apt-get install -y python-libxml2 gfortran libgfortran3 libnl-route-3-200 dpatch quilt bison \ swig debhelper automake libltdl-dev chrpath flex autoconf m4 autotools-dev graphviz lsb-core ``` ### 3. 安装/加载驱动 ```bash /etc/init.d/openibd restart # 重新加载 RDMA 驱动 ibstat # 查看 IB 状态 ibstatus # 查询状态是否激活 ``` ### 4. 安装软件测试包并检查 RDMA 库 ```bash apt update && apt install -y infiniband-diags ``` 检查是否已安装 RDMA 相关库: ```bash dpkg -l perftest ibverbs-providers libibumad3 libibverbs1 libnl-3-200 libnl-route-3-200 librdmacm1 ``` 如有软件包未安装,执行: ```bash apt update && apt install -y perftest ibverbs-providers libibumad3 libibverbs1 \ libnl-3-200 libnl-route-3-200 librdmacm1 ``` 然后再次用 `dpkg -l ...` 确认安装结果。 ### 5. 检查设备 - `lspci`:检查本地是否有 IB 卡。 - `ibstatus`:查询状态是否激活。 - `ibv_devices`:查看本主机的 InfiniBand 设备。 - `ibnodes`:查看网络中的 InfiniBand 设备(RoCE 网络不一定有 IB 设备)。 - `ibv_devinfo`:查询设备信息。`Link layer: InfiniBand` 表示 IB 网络,`link_layer: Ethernet` 表示 RoCE。 --- ## 二、RoCE 模式(Mellanox over Ethernet) 在 Kubernetes 中使用 Mellanox 网卡的 RoCE(RDMA over Converged Ethernet)模式,需要结合硬件配置、驱动设置、Kubernetes 网络插件以及 RDMA 容器化支持。 ### 1. 确认硬件和驱动支持 - **网卡型号**:确保 Mellanox 网卡支持 RoCE(如 ConnectX-4/5/6 系列)。 - **驱动和固件**:安装最新 MLNX_OFED 驱动(Linux)或 WinOF-2(Windows)。用 `mlxconfig` 把网卡切换为 RoCE(ETH 模式): ```bash mlxconfig -d set LINK_TYPE_P1=2 # 2 = ETH 模式(RoCE) reboot # 需重启生效 ``` - **验证模式**:`ibv_devinfo` 查看网卡是否显示为 RoCE 设备。 ### 2. 配置 RoCE 网络环境 - **交换机设置**:启用 PFC(Priority Flow Control)和 ECN(Explicit Congestion Notification)以避免拥塞;若使用链路聚合(LAG),需配置 LACP(模式 4)并匹配服务器的 Bond 配置。 - **服务器端优化**:设置 MTU(通常为 4200)并开启 PFC: ```bash ifconfig mtu 4200 mlnx_qos -i --pfc=0,0,0,0,1,0,0,0 --trust=dscp ``` 关闭流控卸载(如 Flow Control)以减少 CPU 开销。 ### 3. Kubernetes 节点配置 加载 RDMA 内核模块: ```bash modprobe rdma_rxe # 可选:Soft-RoCE 支持 modprobe ib_uverbs ``` 安装 RDMA device plugin,使 Kubernetes 能识别 RDMA 设备(社区参考方案): ```bash kubectl apply -f https://raw.githubusercontent.com/Mellanox/k8s-rdma-shared-dev-plugin/master/deployment/k8s-rdma-shared-dev-plugin-daemonset.yaml ``` > CubeStudio 自带了改造后的 device plugin DaemonSet,见下文「四、CubeStudio 实际部署」,**生产部署请用仓库内的 `install/kubernetes/rdma/mellanox/daemonset.yaml`**,而非上面这条社区示例命令。 验证设备是否可见: ```bash kubectl describe node | grep rdma ``` ### 4. 容器化应用配置 在 Pod 的 `resources.limits` 中请求 RDMA 资源: ```yaml resources: limits: rdma/rdma_shared_device: "1" # 请求 1 个 RDMA 设备 ``` > 注意:这里的 `rdma/rdma_shared_device` 是通用示例,实际资源名取决于 device plugin ConfigMap 中的 `resourceName`。CubeStudio 仓库内 device plugin 的配置为 `resourceName: "hca"`(见 `install/kubernetes/rdma/mellanox/daemonset.yaml` 的 ConfigMap),对应 Pod 应请求 **`rdma/hca`**(与 `install/kubernetes/rdma/mellanox/test-hca-pod.yaml` 一致)。请以实际部署的 device plugin 配置中的 `resourceName` 为准。 也可直接把 RDMA 设备挂载到容器: ```yaml volumeMounts: - name: rdma-devices mountPath: /dev/infiniband volumes: - name: rdma-devices hostPath: path: /dev/infiniband ``` 应用兼容性:确保容器内应用支持 RDMA Verbs API(如使用 `libibverbs` 库);测试工具 `ib_write_bw` / `ib_read_bw` 可用于验证带宽。 ### 5. 网络插件选择 - **Multus**:支持多网络接口,可为 Pod 附加 RoCE 网络(需配置 RDMA CNI)。 - **Kube-OVN/Calico**:需确保不干扰 RDMA 流量(避免封装 overhead)。 - 避免使用 Service Mesh(如 Istio)或网络策略插件,可能干扰 RDMA 性能。 ### 6. 性能调优 NCCL 参数(AI 训练场景): ```yaml env: - name: NCCL_IB_TC value: "128" # 匹配 PFC 队列 - name: NCCL_IB_QPS_PER_CONNECTION value: "8" # 增加 QP 数量 ``` NUMA 亲和性:绑定 Pod 到与网卡相同的 NUMA 节点以减少延迟。 ### 常见问题 - **驱动加载失败**:检查内核版本兼容性,更新 MLNX_OFED 驱动。 - **RoCE 性能差**:确认交换机 PFC 配置,并禁用 TCP 卸载(如 `ethtool -K tso off gso off`)。 --- ## 三、Mellanox 命令速查 ### 设备/驱动信息 ```bash ofed_info # 查看 OFED 驱动信息(IB 驱动版本) ibstat # 查询 InfiniBand 设备的基本状态 ibstatus # 网卡信息 ibv_devinfo # 网卡设备信息(ibv_devinfo -d mlx5_0 -v) ibv_devices # 查看本主机的 infiniband 设备 ibnodes # 查看网络中的 infiniband 设备 show_gids # 查看网卡支持的 roce 版本 show_counters # 网卡端口统计数据(发送/接收数据大小) mlxconfig -d mlx5_1 q # 查询网卡配置信息 ``` ### 网络设备映射与链路验证 ```bash ibdev2netdev # 查看 ib 设备与网络设备(ibX/ethX)的映射 ibdev2netdev -v # 详细模式 hca_self_test.ofed # 验证 InfiniBand 链接是否已启动(Mellanox) ``` ### 配置与信息文件 ```bash /etc/infiniband/info # Mellanox OFED 安装信息 /etc/infiniband/openib.conf # 自动加载的模块列表 lspci | grep Mellanox # 检查 Mellanox 网卡是否安装及型号 modinfo mlx5_core # 查看驱动版本 ip a # 查看系统所有网卡及工作状态 ``` ### 重启 RDMA 驱动 ```bash /etc/init.d/openibd restart # 重启 RDMA 驱动 service ibacm start # 启动 ibacm(名称/地址解析服务) ``` > 注意:`service network restart` 只能启动 Ethernet 端口,并不会真正加载 RDMA 驱动。若驱动异常,`/etc/init.d/openibd restart` 会暴露很多错误,记得同时启动 `ibacm`。 信息收集脚本:`/usr/sbin/sysinfo-snapshot.py`。 参考资料: - https://blog.csdn.net/bandaoyu/article/details/115798045 - https://winddoing.github.io/post/f4fa9e36.html - 百度云 CCE RDMA 文档:https://cloud.baidu.com/doc/CCE/s/6lil1dftn - device plugin 项目:https://github.com/Mellanox/k8s-rdma-shared-dev-plugin --- ## 四、CubeStudio 实际部署(install/kubernetes/rdma/) ### 1. 节点打标 device plugin DaemonSet 通过 `nodeSelector: rdma: 'true'` 调度,只在打了标签的节点上运行。先给有 RDMA 网卡的节点打标: ```bash kubectl label node rdma=true ``` ### 2. 部署 RDMA Device Plugin(Mellanox 共享设备) `install/kubernetes/rdma/mellanox/daemonset.yaml` 包含一个 ConfigMap 和一个 DaemonSet: - ConfigMap `rdma-devices`(命名空间 `kube-system`)声明资源 `resourceName: "hca"`,按厂商 `vendors: ["15b3"]`(Mellanox)匹配网卡,`rdmaHcaMax: 500`,`periodicUpdateInterval: 300`。 - DaemonSet `rdma-shared-dp-ds`(命名空间 `kube-system`)使用镜像 `ccr.ccs.tencentyun.com/cube-studio/k8s-rdma-shared-dev-plugin:mellanox`,`hostNetwork: true`、`privileged: true`、`nodeSelector: rdma: 'true'`。 ```bash kubectl apply -f install/kubernetes/rdma/mellanox/daemonset.yaml ``` 部署后,节点会上报 `rdma/hca` 可分配资源(用 `kubectl describe node | grep rdma` 验证)。 > 如需 CDI(Container Device Interface)支持,使用 `install/kubernetes/rdma/mellanox/cdi.yaml`,它额外挂载了 `/var/run/cdi`,并演示了按 `devices: ["ib0","ib1"]` 或 `selectors`(vendor 15b3 / deviceID 1017 / ifNames)声明多个资源(`hca_shared_devices_a` / `hca_shared_devices_b`)。 ### 3. 测试 Pod `install/kubernetes/rdma/mellanox/test-hca-pod.yaml` 起一个 Deployment `rdma-test`,请求 `rdma/hca: '1'`,并加 `IPC_LOCK` capability,用 `ib_read_bw -d mlx5_0` 验证带宽: ```bash kubectl apply -f install/kubernetes/rdma/mellanox/test-hca-pod.yaml # 进入容器后: ls -l /dev/infiniband /sys/class/infiniband /sys/class/net ib_read_bw -d mlx5_0 # 服务端 ib_read_bw -d mlx5_0 # 客户端 ``` ### 4. 阿里云 eRDMA 变体(可选) `install/kubernetes/rdma/ali/` 提供阿里云环境的变体: - `erdma.yaml`:device plugin DaemonSet `rdma-device-plugin`(镜像 `registry.cn-shanghai.aliyuncs.com/acs/rdma-device-plugin`,ConfigMap 用 `{"mode":"hca"}`,`nodeSelector: rdma: "true"`,容忍 `CriticalAddonsOnly`)。 - `demo.yaml`:两个测试 Pod(`rdma-test-pod` / `rdma-test-pod-1`),镜像 `mellanox/centos_7_4_mofed_4_2_1_2_0_0_60`,请求 `rdma/hca: 1`,用 `ib_read_bw -q 30` 测试。 > 本页命令、镜像名、资源名以源码为准(`install/kubernetes/rdma/` 下 `readme.md` / `roce.md` / `mellanox/*` / `ali/*`),仅供导航与说明。 --- ### 替换基础组件与镜像(对接自有 istio/prometheus/minio/mysql 等) - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/%E7%BB%84%E4%BB%B6%E4%B8%8E%E8%BF%90%E7%BB%B4%E8%A1%94%E6%8E%A5/%E6%9B%BF%E6%8D%A2%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6 - 分类: 02-部署安装 / 组件与运维衔接 - 适用场景: 已有 istio/prometheus/minio/数据库等基础设施,想让 CubeStudio 复用而不是另起一套;或要把平台镜像换成自己私有仓库的镜像时读这篇 - 关键词: 替换组件 / replace component / 自有istio / istio / prometheus / node-exporter / grafana / kubernetes-dashboard / minio / redis / mysql / postgresql / 替换镜像 / image / 私有仓库 / NOTEBOOK_IMAGES / INFERNENCE_IMAGES / init-job-template / config.py - 最后更新: 2026-07-04 # 替换基础组件 > 适用于企业已自建了 istio / prometheus / minio(S3) / mysql / redis / postgresql / kubernetes-dashboard 等基础设施,希望 CubeStudio 直接复用而不是再部署一套的场景。 > 组件级的配置项(变量含义、默认值)参见 [04-运维管理/配置文件管理.md](../../04-运维管理/配置文件管理.md)。 ## 使用自有 istio 开源版本中使用 istio 1.15.0,可以在 `install/kubernetes/start.sh` 里注释掉"部署istio"段(约 `install/kubernetes/start.sh:114-121`,含 `kubectl apply -f istio/install-1.15.0.yaml`)来跳过 istio 部署。 注意事项: 1、istio 作为平台的统一入口,需要暴露 IP,并开放 80、8080 端口,会代理 CubeStudio 的 web 界面、notebook、pipeline、nni、内部服务、推理服务、监控服务。 2、配置 istio 的监控指标对接到 prometheus,并且默认不启动 sidecar,通过 label 启动自动注入,同时流量的复制、分流、域名代理等功能可用。 > istio 在平台中的角色与流量代理细节,见 [01-架构原理/流量代理与网关.md](../../01-架构原理/流量代理与网关.md)。 ## 兼容自有 prometheus 和 node-exporter 如果原本已经使用 prometheus-operator 部署了 prometheus,可以基于原有的 prometheus-operator 继续创建 CubeStudio 所需 prometheus,但 node-exporter 无法重复创建。 可以先修改 `install/kubernetes/prometheus/node-exporter/node-exporter-sm.yml`,其中的 `namespaceSelector` 中的命名空间,改为你已经部署了的 node-exporter 的命名空间。 然后再更新这个部署文件: ```bash kubectl apply -f node-exporter-sm.yml ``` ## 使用自有的 prometheus CubeStudio 对 prometheus 生态需求部分(不需要下面的需求可以不使用 prometheus): - pipeline 编排界面查看任务的资源使用 grafana 看板(需要配置 pod 的资源使用情况) - 整体资源界面有机器的、pod 的、gpu 的 grafana 资源采集看板,和 pod 的资源利用率(需要配置机器的、pod 的、gpu 的资源使用情况) - 推理服务界面查看 istio 服务的吞吐和使用 grafana 看板(需要配置 istio 的指标采集) - 推理服务可以配置 metric 接口(需要 prometheus 支持通过 annotations 自动发现被注册的服务入口点) - 推理服务可以配置 gpu 弹性伸缩(需要配置 prometheus_adapter 组件,将 prometheus 指标转化为弹性伸缩自定义指标) - pod 资源、node 资源、服务负载的 grafana 看板需要能接收变量,变量参考现有 CubeStudio 的 grafana 看板 修改方法: 1. 注释掉 `start.sh` 平台"部署 prometheus"部分,可以将 CubeStudio 中的 grafana 看板部署到目标 grafana 组件上。 2. 将 `config.py` 中的 `PROMETHEUS` 变量更改为目标 prometheus 服务地址(默认 `prometheus-k8s.monitoring:9090`,见 `myapp/config.py:808`)。 3. 将 `config.py` 中的 `GRAFANA_TASK_PATH`、`GRAFANA_SERVICE_PATH`、`GRAFANA_CLUSTER_PATH`、`GRAFANA_NODE_PATH`、`GRAFANA_GPU_PATH` 修改为对应的 grafana 看板地址(见 `myapp/config.py:1364-1372`)。 4. 将 `config.py` 中的 `ALL_LINKS` 中 grafana 的地址修改为真实的地址(见 `myapp/config.py:955`)。 > 监控生态的整体部署与看板说明见 [04-运维管理/监控部署与看板.md](../../04-运维管理/监控部署与看板.md);架构层面见 [01-架构原理/监控体系/README.md](../../01-架构原理/监控体系/README.md)。 ## 使用自有 kubernetes-dashboard 在 `config.py` 文件中替换 `K8S_DASHBOARD_CLUSTER` 变量(默认 `/k8s/dashboard/cluster/`,见 `myapp/config.py:817`)。 ## minio 替换 kubeflow 命名空间,`workflow-controller-configmap` 的 configmap,修改 `s3:endpoint` 为自己的 S3 服务地址,再重启 workflow 的 pod(该 configmap 定义见 `install/kubernetes/argo/workflow.yaml`,artifactRepository 中的 `s3.endpoint` 默认指向 `minio:9000`)。 在 `config.py` 文件中替换 `MINIO_HOST` 变量(默认 `minio.kubeflow:9000`,见 `myapp/config.py:1302`)。 ## redis 替换 替换 infra 命名空间 `kubeflow-dashboard-*` 的 deployment 的环境变量。 > 如需对接哨兵模式的 Redis,见 [04-运维管理/Redis哨兵部署.md](../../04-运维管理/Redis哨兵部署.md)。 ## mysql 替换 替换 infra 命名空间 `kubeflow-dashboard-*` 的 deployment 的环境变量。 > 元数据库(MySQL/PostgreSQL/达梦)配置见 [04-运维管理/元数据库配置.md](../../04-运维管理/元数据库配置.md)。 ## postgresql 替换 替换 kubeflow 命名空间 labelstudio 的 deployment 的环境变量。 --- # 替换镜像名 > 把平台默认的公共镜像(`ccr.ccs.tencentyun.com/cube-studio/...`)换成自己私有仓库的镜像。私有仓库搭建见 [04-运维管理/私有镜像仓库Harbor.md](../../04-运维管理/私有镜像仓库Harbor.md)。 ## 基础组件镜像 `install/kubernetes` 中部署的组件,可替换为源镜像名的新 tag。 ## 业务镜像 模板镜像:需要在 `myapp/init/init-job-template.json` 中的 `image_name`。 notebook 镜像:`config.py` 中的 `NOTEBOOK_IMAGES` 变量配置(见 `myapp/config.py:998`)。 超参搜索镜像:`config.py` 中 `NNI_IMAGES`、`WAIT_POD_IMAGES` 变量(见 `myapp/config.py:1298`、`1300`),`myapp/init/init-automl.json` 中的 `job_worker_image`。 内部服务镜像: - `myapp/init/init-service.json` 中 `image_name` 推理服务镜像: - `config.py` 中的 `INFERNENCE_IMAGES` 字典(含 `ml-server`、`tfserving`、`torch-server`、`triton-server`、`vllm`、`ollama`、`mindie`、`triton-llm` 等键,见 `myapp/config.py:1324` 起) - `myapp/init/init-inference.json` 中 `image_name` gpu 镜像: - `myapp/init/init-job-template.json` 中 `ccr.ccs.tencentyun.com/cube-studio` 开头的镜像 镜像管理:修改 `myapp/init/init-image.json` 中 `name`。 aihub 镜像:`myapp/init/init-aihub.json` 中的 `images`。 ## 业务代码中镜像 搜索替换 `myapp/views/` 下 `ccr.ccs.tencentyun.com/cube-studio` 开头的镜像,替换为自己的镜像,重新打包后台镜像。 --- ### 壁仞 GPU 适配(biren:驱动 + k8s 组件 + 占用测试) - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/GPU%E4%B8%8E%E5%BC%82%E6%9E%84%E7%AE%97%E5%8A%9B/%E5%A3%81%E4%BB%9EGPU - 分类: 02-部署安装 / GPU与异构算力 - 适用场景: 在 CubeStudio 上接入壁仞 GPU 算力,需要装驱动/运行时、部署 k8s 组件、确认可用卡数并占用测试时读这篇 - 关键词: 壁仞 / biren / BR / GPU / device-plugin / agent / exporter / 国产GPU / 异构算力 / GPU_RESOURCE - 最后更新: 2026-07-04 # 壁仞 GPU 适配(biren) 本文介绍如何在 k8s 中接入壁仞(biren)GPU 并在 CubeStudio 上使用。搬运自 `install/kubernetes/gpu/biren/readme.md`。壁仞相关的驱动、运行时、k8s 组件安装包均由壁仞技术人员提供,本文只描述接入步骤。 ## 1. 准备安装资料 向壁仞技术人员获取壁仞的相关安装资料(驱动、运行时、k8s 组件等安装包与文档)。 ## 2. 主机驱动和运行时 在每台壁仞节点上安装壁仞 GPU 驱动与容器运行时,并按壁仞文档校验驱动正常。 ## 3. 安装 k8s 相关组件 按壁仞提供的资料部署 k8s 侧组件,通常包含: - device plugin(向 k8s 注册壁仞 GPU 扩展资源); - agent; - exporter(GPU 监控指标采集)。 ## 4. 查询机器可用卡数 ```bash kubectl describe node <壁仞节点IP> ``` 在 node 的 `Capacity` / `Allocatable` 中查看壁仞 device plugin 注册的扩展资源名与可用卡数。 ## 5. pod 占用壁仞卡测试 按壁仞 device plugin 注册的资源名编写 pod yaml,在 `resources.limits` 中申请对应资源;pod 启动后进入容器,用壁仞自带工具确认占用到的卡。 ## 6. 平台侧资源配置(GPU_RESOURCE) > 注意:当前 `myapp/config.py:1242` 的 `GPU_RESOURCE` 字典中**没有**壁仞 biren 的预置项(已确认 `myapp/config.py`、`install/docker/config.py` 均无 biren / 壁仞条目)。接入壁仞时需要根据步骤 4 中壁仞 device plugin 实际注册的扩展资源名,在 `GPU_RESOURCE` 里手动新增一项(形如 `"biren": "<壁仞资源名>"`),再在任务里用 `gpu:1(biren)` 这种 `数量(资源简称)` 写法占用。具体资源名请以壁仞 device plugin 暴露的为准。 --- ### 国产GPU/NPU 与 ARM64 适配总览 - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/GPU%E4%B8%8E%E5%BC%82%E6%9E%84%E7%AE%97%E5%8A%9B/%E5%9B%BD%E4%BA%A7GPU%E4%B8%8EARM64%E9%80%82%E9%85%8D%E6%80%BB%E8%A7%88 - 分类: 部署安装 / GPU与异构算力 - 适用场景: 准备在国产 GPU/NPU 或 ARM64 架构机器上部署 CubeStudio,需要了解整体适配流程与各环节要点时阅读 - 关键词: 国产GPU / 国产NPU / 昇腾 / Ascend / 华为 / ARM64 / aarch64 / arm / 异构算力 / 信创 / GPU_RESOURCE / DEFAULT_GPU_RESOURCE_NAME / device-plugin / npu-exporter / 多架构镜像 / buildx / notebook镜像 - 最后更新: 2026-07-04 # 国产 GPU/NPU 与 ARM64 适配总览 本篇是 GPU 与异构算力子目录的入口,概述将 CubeStudio 适配到国产算力卡(GPU/NPU)与 ARM64 架构机器的整体流程。具体厂商的落地步骤见各子篇(如华为昇腾 NPU)。 ## 国产 GPU/NPU 适配通用流程 将任意一款国产算力卡接入 CubeStudio,一般需要完成以下 8 步: 1. **GPU/NPU 驱动**:联系运维按国产 GPU 厂商要求安装 AI 计算卡驱动。 2. **容器运行时**:使算力卡可被 docker 运行时与 containerd 运行时调用。 3. **K8s 插件**:按厂商提供的 k8s device-plugin 部署到 k8s 集群。 4. **资源占用约定**:明确 k8s 资源占用文档——占用的资源名、禁止 pod 占用的环境变量、在 k8s 中占用「指定第 n 张卡」的环境变量配置方法。 5. **监控组件**:按厂商提供的资源采集接口配置到 Prometheus,并配置相应的 Grafana 看板。 6. **平台配置**:在 `config.py` 的 `GPU_RESOURCE` 中加入该国产 GPU 对应的 k8s 资源名,并按需设置默认占用卡 `DEFAULT_GPU_RESOURCE_NAME`。 7. **环境镜像**:按厂商提供的开发环境镜像,配置为 notebook 与 pipeline 的运行镜像。 8. **框架包**:按厂商提供的 TF/PyTorch 安装方法,在业务代码中安装并尝试运行。 > 说明:上述第 6 步对应 `myapp/config.py` 中的 `GPU_RESOURCE`(约 `myapp/config.py:1242`)与 `DEFAULT_GPU_RESOURCE_NAME`(`myapp/config.py:1259`,默认值 `nvidia.com/gpu`)。`GPU_RESOURCE` 已内置多家国产卡的资源名映射,例如: > - `npu310` → `huawei.com/Ascend310`、`npu310p` → `huawei.com/Ascend310P`、`npu910` → `huawei.com/Ascend910`(华为昇腾) > - `dcu` → `hygon.com/dcu`(海光)、`mlu370` → `cambricon.com/mlu370`(寒武纪)、`mx` → `metax-tech.com/gpu`(沐曦) > - `gcu` → `enrigin.com.cn/gcu`(江原)、`xpu` → `kunlunxin.com/xpu`(昆仑芯)、`mthread` → `mthreads.com/gpu`(摩尔线程) > > 注意:`config.py` 注释明确「`GPU_RESOURCE` 的 key 必须小写;主机的 `gpu-type` 节点标签必须大写」(见 `myapp/config.py:1241`)。 ## 以华为昇腾卡为例 华为昇腾 NPU 的落地流程(详见子篇《华为昇腾 NPU》): 1. NPU 驱动安装。 2. 安装 Ascend Docker Runtime。 3. 将 docker NPU device 适配到云原生,使 k8s 可识别/使用 NPU 硬件。 4. 在配置文件中添加对 NPU k8s 资源的占用方式,并设置 CubeStudio 的机器卡型。 5. 部署 npu-exporter,配置 NPU k8s 监控看板,掌握资源使用情况。 6. 在 `config.py` 的 `GPU_RESOURCE` 中添加 `huawei.com/Ascend910`(对应 key `npu910`)。 7. 构建 NPU 基础镜像(开发/调试/推理),用于写代码、训练模型。 8. 构建昇腾 MindIE 推理镜像,使其在 k8s 中直接运行并提供 API。 详细步骤见 [华为昇腾 NPU 子目录](华为昇腾NPU/README.md)。 ## ARM64 机器部署 ### 部署 Rancher 与 x86 架构相同。 ### 部署 cube-studio 先按与 x86 架构相同的方式部署。部署完成后不一定全部功能正常,因为部分镜像没有 arm64 版本,需替换为 arm64 版本的镜像。 #### 构建 arm64 版本镜像 主机 docker 构建 arm64 镜像环境初始化: ```bash docker buildx create --use --platform=linux/arm64,linux/amd64 --name multi-platform-builder docker buildx inspect --bootstrap # 然后就可以同时构建 amd64 和 arm64 的镜像了 docker buildx build --platform=linux/arm64,linux/amd64 --push --tag project-name:latest -f ./project-name/Dockerfile . ``` 1. CubeStudio 第三方基础组件,当前版本已适配 arm64。 2. 若修改了源码,可自行在 arm64 机器上重新构建 CubeStudio 前后端镜像: ```bash docker build --network=host -t xx.xx.xx.xx/cube-studio/kubeflow-dashboard:arm64 -f install/docker/Dockerfile . docker build --network=host -t xx.xx.xx.xx/cube-studio/kubeflow-dashboard-frontend:arm64 -f install/docker/dockerFrontend/Dockerfile . ``` > 说明:`install/docker/Dockerfile` 未使用 `ARG TARGETARCH`(见 `install/docker/Dockerfile:1-4`),因此无需传 `--build-arg TARGETARCH=arm64`;在 arm64 机器上直接 `docker build` 即按本机架构构建出 arm64 镜像。如需在单台机器上同时构建 amd64/arm64,可参考 Dockerfile 顶部注释的 buildx 多架构命令:`docker buildx build --platform linux/amd64,linux/arm64 -t ...-enterprise:<日期tag> -f install/docker/Dockerfile . --push`(后端),前端对应 `install/docker/dockerFrontend/Dockerfile`。 3. notebook 镜像的 arm64 版本目前仅支持 vscode 和 jupyter,修改 `config.py` 中的 `NOTEBOOK_IMAGES`: ```python NOTEBOOK_IMAGES=[ ['ccr.ccs.tencentyun.com/cube-studio/notebook-enterprise:vscode-ubuntu-cpu-conda-arm64', 'vscode-conda(cpu)'], ['ccr.ccs.tencentyun.com/cube-studio/notebook-enterprise:vscode-ubuntu-gpu-conda-arm64', 'vscode-conda(gpu)'], ['ccr.ccs.tencentyun.com/cube-studio/notebook-enterprise:jupyter-ubuntu-cpu-conda-arm64', 'jupyter-conda(cpu)'], ['ccr.ccs.tencentyun.com/cube-studio/notebook-enterprise:jupyter-ubuntu-gpu-conda-arm64', 'jupyter-conda(gpu)'], ] ``` > 说明:以上为 arm64 部署时的示例镜像列表(带 `-arm64` 后缀)。`config.py` 默认的 `NOTEBOOK_IMAGES`(见 `myapp/config.py:998`)使用的是 amd64 / 带日期标签的镜像(如 `vscode-ubuntu-cpu-conda-20260101`),在 arm64 机器上需替换为 arm64 版本。 4. 任务模板镜像:只有部分模板包含 amd64 版本;对于没有 arm64 版本镜像的模板,需自己在 arm64 机器上重新构建模板镜像。 构建方法: ```bash cd job-template && sh build-job-arm64.sh ``` > ⚠️ 待核实:仓库中未找到 `job-template/build-job-arm64.sh`(见 `job-template/` 目录,当前仅有 `build-job-encryption.sh`)。`build-job-encryption.sh` 采用 `docker buildx build --platform linux/amd64,linux/arm64 ... --push` 进行多架构构建(见 `job-template/build-job-encryption.sh:8`)。请确认 arm64 模板镜像的实际构建脚本/方法。模板镜像的构建方式可参考二次开发段的镜像构建文档。 --- ### 海光 DCU 适配(驱动 + k8s device plugin + vDCU 虚拟化) - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/GPU%E4%B8%8E%E5%BC%82%E6%9E%84%E7%AE%97%E5%8A%9B/%E6%B5%B7%E5%85%89DCU - 分类: 02-部署安装 / GPU与异构算力 - 适用场景: 在 CubeStudio 上接入海光 DCU 算力,需要装驱动、部署 k8s device plugin、配置整卡/共享/虚拟化(vDCU)资源时读这篇 - 关键词: 海光 / DCU / hygon / hygon.com/dcu / dcu-device-plugin / vDCU / vdcu / dcunum / dcumem / dcucores / hami / MIG / hy-smi / DTK / ROCm / HIP_VISIBLE_DEVICES / 国产GPU / 异构算力 / 共享GPU / GPU虚拟化 - 最后更新: 2026-07-04 # 海光 DCU 适配 本文介绍如何在 CubeStudio 上接入海光 DCU(Hygon DCU)算力,覆盖驱动安装、k8s device plugin 部署、整卡 / 共享 / vDCU 虚拟化的资源配置,以及容器内的挂载与路径注意事项。合并自 `install/kubernetes/gpu/dcu/` 下的 `readme.md`(适配测试)、`driver.md`(驱动安装)、`vdcu.md`(设备插件与虚拟化)。 官方资料参考: - 海光开发者社区 Kubernetes 插件文档:https://cancon.hpccube.com:65024/5/main/Kubernetes%E6%8F%92%E4%BB%B6 - 海光社区下载:https://download.sourcefind.cn:65024/5/main - 光源(镜像/框架包):https://sourcefind.cn/#/service-list ## 1. 适配概述与结论 CubeStudio 已对海光 DCU 做了全流程适配,DCU 资源整体与英伟达 GPU 类似,提供了云原生领域的完整生态: - k8s device plugin(整卡、共享、禁用等占用方式); - 类似英伟达 MIG 的虚拟化方案,以及驱动层 / HAMi 两套 vDCU 虚拟化; - exporter 资源采集组件(见同目录 `dcu-exporter-v2.yaml` 与 `dcu-exporter-dashboard.json`); - Python 多种深度学习框架的替换包,无需学习新语言; - notebook 与深度学习框架的基础镜像,业务无需从头构建 DCU 专用镜像。 平台侧已适配的能力(基于海光平台 + DCU 的中科可控服务器 X7340H0,CPU 为 Hygon C86 7380 验证通过): - 平台全局算力变量配置,同时支持多厂商 GPU 卡(含 DCU)和虚拟化卡(含 vDCU); - web 界面上选择 DCU,分单卡模式与共享模式; - Notebook 在线开发; - Pipeline 分布式多机多卡训练; - 在线推理 / DeepSeek 等大模型部署。 ## 2. 平台侧资源配置(GPU_RESOURCE) 平台用 `GPU_RESOURCE` 字典把"资源简称"映射到 k8s 扩展资源名,DCU 相关项见 `myapp/config.py:1242`(生产配置同 `install/docker/config.py:1242`): ```python GPU_RESOURCE = { ... "dcu": "hygon.com/dcu", # 海光 DCU 整卡 / 共享 "vdcu": "hygon.com/dcunum", # HAMi 动态虚拟化;数量值无意义, # 需同步指定 hygon.com/dcumem、hygon.com/dcucores "vdcu1":"hygon.com/dcu-share-30c-16g", # 驱动层面的静态虚拟化 ... } ``` 禁用 DCU(复合机器上避免被共享占用)使用的环境变量见 `myapp/config.py:1264`: ```python GPU_NONE = { ... "dcu": ['HIP_VISIBLE_DEVICES', '-1'], } ``` > 在项目组 / 任务里用 `gpu:1(dcu)`、`gpu:1(vdcu)` 这种 `数量(资源简称)` 的写法占用资源,括号内的简称就是上面 `GPU_RESOURCE` 里定义的 key。 ## 3. 驱动安装 ### 3.1 驱动 / DTK 兼容列表 | 驱动版本 | 支持硬件 | 推荐 DTK 版本 | | --- | --- | --- | | rock-4.0-23-5.6.25 | Z100/Z100L | 21.04 / 21.10 / 22.04 | | rock-4.5.2-5.11.40 | Z100/Z100L | 22.04 / 22.10 / 23.04 | | rock-5.2.0-5.16.18 | Z100/Z100L | 22.10 / 23.04 | | rock-5.2.0-5.16.29 | Z100/Z100L/K100 | 23.04 / 23.10 | | rock-5.7.1-6.2.26+ | Z100/Z100L/K100/K100-AI | 24.04 / 25.04 | | rock-6.3.8+ | BW1000/K100-AI/K100/Z100L/Z100 | 25.04 | 接入 k8s device plugin(v2.3.0)时官方建议:DTK 驱动程序 ≥ 24.04、驱动版本 ≥ 6.3.15、k8s ≥ 1.18,操作系统建议 Ubuntu 20.04+ 或 CentOS 7.6+。 ### 3.2 安装依赖包 ```bash # CentOS yum install -y rpm-build gcc-c++ cmake automake elfutils-libelf-devel libdrm libdrm-devel pciutils yum install -y kernel-devel-`uname -r` kernel-modules-extra # Ubuntu apt install -y gcc g++ cmake automake libelf-dev libdrm-amdgpu1 libtinfo5 pciutils libdrm-dev apt install -y linux-headers-`uname -r` linux-modules-extra ``` ### 3.3 安装驱动 ```bash # 1) 下载驱动:https://cancon.hpccube.com:65024/6/main/latest%E9%A9%B1%E5%8A%A8 # 2) 赋可执行权限 chmod +x rock*.run # 3) 安装 ./rock*.run # 4) 重启驱动服务 systemctl restart hymgr ``` 注意事项: - 安装参数可通过 `./rock*.run -h` 查看; - 安装新驱动无需先卸载旧驱动,安装过程会自动卸载老驱动; - 安装时会询问 `Do you want to remove legacy hymgr config file? [Y/n]`,选 yes 会重新生成 `/etc/hymgr.cfg`,选 no 保留原文件; - K100/K100-AI 环境会提示 `Update vbios? [y/N]`,首次安装建议更新 vbios 并重启物理机;云计算场景对重启敏感,可不更新; - 新版本驱动要求 cmake ≥ 3.2、gcc ≥ 7.3;kernel 版本要与 kernel-devel 一致; - 6.2.* 及以前驱动的内核模块名是 `hydcu`,6.3.* 及以后是 `hycu`; - 6.3.* 驱动下 docker 调用时建议挂载 `/sys/kernel/debug`,否则容器内无法获取 DCU 进程信息。 ### 3.4 校验驱动加载 ```bash # 6.2.x 及以下 lsmod | grep -E "hydcu|hycu" # 应出现 hydcu / hydcu_sched / hyttm / hykcl 等模块 # 6.3.x 及以上 lsmod | grep -E "hydcu|hycu" # 应出现 hycu / hycu_sched / hyttm / hykcl 等模块 # 查看驱动版本 hy-smi --showdriverversion # 查看卡资源 hy-smi virtual -show-device-info ``` ## 4. k8s device plugin 部署(整卡 / 共享) ```bash # 给节点打标签(标准模式) kubectl label node hygon.com/dcu=true --overwrite # 部署 DCU device 插件 kubectl apply -f dcu-device.yaml ``` 设备插件镜像为 `image.sourcefind.cn:5000/dcu/admin/base/dcu-device-plugin:v2.3.0`(见 `install/kubernetes/gpu/dcu/dcu-device.yaml:36`)。v2.3.0 支持标准模式和 MIG;MIG 功能官方即将弃用,且开启 MIG 后 vDCU 虚拟化不可用。 > 说明:标准模式节点需打标签 `hygon.com/dcu=true`。`dcu-device.yaml` 的节点亲和要求 `hygon.com/dcu In ["true"]`(见 `install/kubernetes/gpu/dcu/dcu-device.yaml:21-34`),`dcu-exporter-v2.yaml` 也用 `nodeSelector: hygon.com/dcu: "true"`(见 `install/kubernetes/gpu/dcu/dcu-exporter-v2.yaml:32`);仓库内没有自动打标组件,故须手动打该标签,否则设备插件/exporter 不会被调度到该节点。原 `vdcu.md:15` 写的 `dcu=true` 与此 key 不同,不满足该亲和。此外该亲和还要求 `dcu-mode NotIn ["mig"]`、`dcu NotIn ["on"]`(`dcu=on` 用于区分 vDCU 虚拟化混用模式,见 5.1 节)。 部署成功后用 `kubectl describe node ` 可看到 `hygon.com/dcu` 资源。web 界面上即可按单卡模式或共享模式使用 DCU。 ## 5. vDCU 虚拟化 DCU 提供两种 vDCU 虚拟化路线:驱动层手动静态切分(与物理卡混用)和 HAMi 动态切分。 ### 5.1 驱动层手动切分(与物理卡混用) 用 `hy-smi virtual` 在驱动层手动切分 vDCU: ```bash # 均匀切分:把 0 号物理卡均分为 4 个 vDCU hy-smi virtual -d 0 --create-vdevices 4 # 不均匀切分(按算力单元与显存指定,可能失败需多调试) hy-smi virtual -d 0 --create-vdevices 4 \ --vdevice-compute-units "40,30,30,20" \ --vdevice-memory-size "25000,15000,15000,10000" # 查看 vDCU hy-smi virtual -show-vdevice-info # 销毁 vDCU hy-smi virtual -d 0 --destroy-vdevices ``` 要让手动切分的 vDCU 与物理卡混用,需把 dcu-device-plugin 的环境变量 `RESOURCE_REGISTER_STRATEGY` 设为 `mixed`(仓库内 `install/kubernetes/gpu/dcu/dcu-device.yaml:43-44` 默认即为 `mixed`)。 切分后 `kubectl describe node` 会显示 `hygon.com/dcu`、`hygon.com/dcu-share-xxc-xg` 等资源;据此在平台 `GPU_RESOURCE` 中配置对应资源名(如 `myapp/config.py:1252` 的 `"vdcu1":"hygon.com/dcu-share-30c-16g"`)。使用时写 `gpu:1(dcu)` / `gpu:1(<自定义vdcu简称>)` 即可。 ### 5.2 HAMi 动态切分 ```bash # 给节点打标签(HAMi 模式) kubectl label node dcu=on --overwrite # 依次部署 kubectl apply -f hami/vdcu-admission-webhook.yaml kubectl apply -f hami/vdcu-scheduler.yaml kubectl apply -f hami/k8s-dcu-plugin-hami.yaml ``` HAMi 版设备插件镜像同为 `image.sourcefind.cn:5000/dcu/admin/base/dcu-device-plugin:v2.3.0`,其 `RESOURCE_REGISTER_STRATEGY=hami`、`nodeSelector` 为 `dcu: "on"`(见 `install/kubernetes/gpu/dcu/hami/k8s-dcu-plugin-hami.yaml:18-30`)。 部署前需修改 `vdcu-admission-webhook.yaml`、`vdcu-scheduler.yaml`: - `nodeSelector: node-role.kubernetes.io/control-plane: ""`:高可用集群按 master 节点实际 control-plane 标签调整(`kubectl get node --show-labels` 确认); - `nodeName: master`:改成自己 control 节点的 nodename(`kubectl describe node | grep Name:`); - `volumes -> kubelet -> hostPath.path: /usr/local/bin/kubelet`:确认本地 kubelet 二进制路径,不同则替换。 删除 `vdcu-scheduler.yaml`、`k8s-dcu-plugin-hami.yaml` 时需同步清理: ```bash kubectl delete secrets -n kube-system admission-webhook-dcu-certs kubectl delete mutatingwebhookconfigurations mutating-webhook-dcu-cfg ``` 部署成功后 `kubectl describe node ` 会显示 `hygon.com/dcunum`(vDCU 资源名),据此配置 `GPU_RESOURCE` 中的 `"vdcu":"hygon.com/dcunum"`(`myapp/config.py:1251`)。使用时写 `gpu:1(vdcu)` 即可。 > 注意:HAMi 模式下 `hygon.com/dcunum` 的数量值本身无意义,须同步指定 `hygon.com/dcumem`、`hygon.com/dcucores` 来确定可分配规格;只指定 `hygon.com/dcunum:1` 而不指定显存 / 算力,则一块 vDCU 占用整张物理卡。 ## 6. 容器内挂载与路径注意事项 正常情况下 device 会自动挂载,若未自动挂载或出现库路径错误,可: - 在环境变量中添加: ``` LD_LIBRARY_PATH=/opt/dtk/lib:/opt/dtk/hipblas/lib:/opt/hyhal/lib:/usr/lib64:/lib64:/usr/lib:/lib ``` - 启动命令中添加:`bash /opt/dtk/env.sh` - 手动挂载(pvc + hostpath 形式): ``` kubeflow-user-workspace(pvc):/mnt,/opt/hyhal(hostpath):/opt/hyhal,/dev(hostpath):/dev,/dev/kfd(hostpath):/dev/kfd,/dev/dri(hostpath):/dev/dri ``` ## 7. DCU 基础镜像 平台预置/示例镜像(见 `myapp/config.py`,默认注释掉,按需启用): - Notebook / 开发:`image.sourcefind.cn:5000/dcu/admin/base/jupyterlab-pytorch:2.4.1-ubuntu22.04-dtk25.04.1-py3.10-devel`(`myapp/config.py:1019`); - 推理(vllm):`image.sourcefind.cn:5000/dcu/admin/base/vllm:0.8.5-ubuntu22.04-dtk25.04.1-py3.10`(`myapp/config.py:1332` 注释)。 更多框架包与镜像见光源:https://sourcefind.cn/#/service-list --- ### 寒武纪 MLU 适配(Cambricon) - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/GPU%E4%B8%8E%E5%BC%82%E6%9E%84%E7%AE%97%E5%8A%9B/%E5%AF%92%E6%AD%A6%E7%BA%AAMLU - 分类: 02-部署安装 / GPU与异构算力 - 适用场景: 在 CubeStudio 上接入寒武纪 MLU370 卡(驱动运行时、k8s device plugin、查可用卡数、Pod 占用测试、整体资源查看)时读这篇 - 关键词: 寒武纪 / 寒武纪370 / MLU / mlu / mlu370 / Cambricon / cambricon / cambricon.com/mlu370 / device plugin / cnmon / 国产GPU / 异构算力 / npu-share - 最后更新: 2026-07-04 # 寒武纪 MLU 适配(Cambricon) 本篇说明如何在 CubeStudio 平台上接入寒武纪 MLU(Cambricon,型号 MLU370)算力卡,覆盖主机驱动运行时、k8s device plugin、节点可用卡数查询、Pod 占用测试与整体资源查看。 > 来源:`install/kubernetes/gpu/mlu/readme.md`,原文为图文操作记录。下文保留原始操作截图(外部 OSS 链接),并补充平台侧资源名配置事实。 ## 平台资源名配置(已核实) 寒武纪在平台中对应的 GPU 资源 key 为 `mlu370`,映射到 k8s 资源名 `cambricon.com/mlu370`。 依据 `myapp/config.py:1250` 的 `GPU_RESOURCE` 配置: ```python "mlu370": "cambricon.com/mlu370", # 寒武纪370 ``` 在 Notebook / 推理服务 / 任务流的「GPU」字段中填写格式为 `数量(型号key)`,例如申请 1 张寒武纪卡填 `1(mlu370)`。括号里的 key 会被平台解析后映射到对应的 k8s 资源名(解析逻辑见 `myapp/utils/core.py:1622` 的 `get_gpu`)。 > 寒武纪推理可用镜像参考 `myapp/config.py:1333` 注释:`ccr.ccs.tencentyun.com/cube-studio/vllm:v0.11.2-mlu`。 ## 一、主机驱动和运行时 主机正常安装寒武纪驱动与运行时。 ![主机驱动和运行时](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/5dafa353589e4c45995a95d2bf852ded.png) ## 二、安装 k8s 相关组件 在 k8s 中安装寒武纪相关组件,包含 device plugin 等。 ![安装 device plugin](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/8e266b6cdfee4330a41d618c10cd92df.png) ## 三、查询机器可用卡数 通过 `kubectl describe node` 查看寒武纪节点上报的可用卡数: ```bash kubectl describe node xx.xx.xx.xx # xx.xx.xx.xx 是寒武纪节点 ip ``` ![节点可用卡数](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/7898d7896fa146128fda8247ca9a4d7f.png) ## 四、Pod 占用寒武纪卡测试 在 Pod 内部查看占用的卡。 ![Pod 内查看占用的卡](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/7f9fe6a4c1c9476da22972a3cd155505.png) ## 五、整体资源查看 在平台上查看寒武纪卡的整体资源占用情况。 ![整体资源查看](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/mlu-resource.png) --- ### 昆仑芯 XPU 适配(百度昆仑芯) - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/GPU%E4%B8%8E%E5%BC%82%E6%9E%84%E7%AE%97%E5%8A%9B/%E6%98%86%E4%BB%91%E8%8A%AFGPU - 分类: 02-部署安装 / GPU与异构算力 - 适用场景: 在 CubeStudio 上接入百度昆仑芯 XPU 卡(驱动、k8s device plugin、节点资源、Notebook、推理服务部署 DeepSeek)时读这篇 - 关键词: 昆仑芯 / kunlun / kunlunxin / XPU / xpu / xpu-smi / 百度昆仑 / kunlunxin.com/xpu / device plugin / exporter / 国产GPU / 异构算力 / DeepSeek / xtrtllm / 推理服务 - 最后更新: 2026-07-04 # 昆仑芯 XPU 适配(百度昆仑芯) 本篇说明如何在 CubeStudio 平台上接入百度昆仑芯(kunlunxin / XPU)算力卡,覆盖主机驱动、k8s device plugin、节点资源识别、Notebook 与推理服务使用。 > 来源:`install/kubernetes/gpu/kunlun/readme.md`,原文为图文操作记录。下文保留原始操作截图(外部 OSS 链接),并补充平台侧资源名配置事实。 ## 平台资源名配置(已核实) 昆仑芯在平台中对应的 GPU 资源 key 为 `xpu`,映射到 k8s 资源名 `kunlunxin.com/xpu`。 依据 `myapp/config.py:1255` 的 `GPU_RESOURCE` 配置: ```python "xpu": "kunlunxin.com/xpu", # 百度昆仑芯 ``` 在 Notebook / 推理服务 / 任务流的「GPU」字段中填写格式为 `数量(型号key)`,例如申请 1 张昆仑芯卡填 `1(xpu)`。括号里的 key 会被平台解析后映射到对应的 k8s 资源名(解析逻辑见 `myapp/utils/core.py:1622` 的 `get_gpu`)。 ## 一、主机 xpu-smi 主机驱动正常安装后,使用 `xpu-smi` 查看卡信息。 ![xpu-smi 查看卡](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/f3f588b4c2084b1cbf9f81c34ea1f0f7.png) ## 二、K8S device plugin / exporter 在 k8s 中部署昆仑芯的 device plugin 与 exporter 组件。下载地址(外部 OSS): - k8s device plugin: - k8s exporter: ![部署 device plugin](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/810f5094f0374b71989b9548ece436a7.png) ## 三、节点资源 device plugin 部署完成后,k8s 节点上会上报昆仑芯卡资源。 ![节点资源](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/201e570ab29f4ebebbe3a9238eeab6a7.png) ## 四、Notebook 使用 在 Notebook 中申请昆仑芯卡(GPU 字段填 `数量(xpu)`),进入容器后即可使用昆仑芯算力。 ![Notebook 1](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/0cc4fd7a6f0c401b8a6ccb2ad4722fac.png) ![Notebook 2](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/464018306c5a4989a3230ad6a7e83a36.png) ![Notebook 3](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/8bc507b60d494fe286fcb87bc6e92564.png) ## 五、推理服务(部署 DeepSeek) 在推理服务中使用昆仑芯卡部署 DeepSeek 模型。 ![推理服务 1](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/53c2561b6ddc490f91991bd283e7bbd7.png) ![推理服务 2](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/06f20b1f867d4e3f914db3f72f741422.png) ![推理服务 3](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/4b25f6aebff840418424e29ffcf4b3f2.png) - 镜像:`ccr.ccs.tencentyun.com/cube-studio/xtrtllm_ubuntu_2004_x86_64_deepseek-v3:v20` ![镜像与挂载](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/b3f2b8f2ce76414e871e2907a4d6c9ad.png) - 挂载目录:`kubeflow-user-workspace(pvc):/mnt`,`/mnt/model(hostpath):/workspace` - `/mnt/model` 内容放在文件夹 `model` 中 ![挂载目录](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/2f030459acea459496bc81836cce65c9.png) - 启动命令: ```bash source /home/pt201/bin/activate && export LD_LIBRARY_PATH=/usr/local/xpu/so:$LD_LIBRARY_PATH && bash /workspace/deepseek_server/run_server.sh /workspace/DeepSeek-R1-tokenizer /workspace/DeepSeek-R1-0528-BF16-engine r1 ``` ## 六、测试 部署完成后测试推理接口。 ![测试](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/e8eaabfdf4934254886e8cadd958f746.png) --- ### 摩尔线程 GPU 适配(mthreads / MUSA) - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/GPU%E4%B8%8E%E5%BC%82%E6%9E%84%E7%AE%97%E5%8A%9B/%E6%91%A9%E5%B0%94%E7%BA%BF%E7%A8%8BGPU - 分类: 02-部署安装 / GPU与异构算力 - 适用场景: 在 CubeStudio 上接入摩尔线程 GPU 卡(主机驱动、k8s device plugin、节点资源、容器占卡、平台部署 DeepSeek)时读这篇 - 关键词: 摩尔线程 / mthreads / mthreads-gmi / MUSA / musa / mthreads.com/gpu / device plugin / gpu-device / 国产GPU / 异构算力 / DeepSeek - 最后更新: 2026-07-04 # 摩尔线程 GPU 适配(mthreads / MUSA) 本篇说明如何在 CubeStudio 平台上接入摩尔线程(mthreads)GPU 算力卡,覆盖主机驱动、k8s device plugin、节点资源识别、容器占卡与平台部署 DeepSeek 模型。 > 来源:`install/kubernetes/gpu/mthreads/readme.md`,原文为图文操作记录。下文保留原始操作截图(外部 OSS 链接),并补充平台侧资源名配置事实。 ## 平台资源名配置(已核实) 摩尔线程在平台中对应的 GPU 资源 key 为 `mthread`,映射到 k8s 资源名 `mthreads.com/gpu`。 依据 `myapp/config.py:1256` 的 `GPU_RESOURCE` 配置: ```python "mthread": "mthreads.com/gpu" # 摩尔线程 ``` 在 Notebook / 推理服务 / 任务流的「GPU」字段中填写格式为 `数量(型号key)`,例如申请 2 张摩尔线程卡填 `2(mthread)`。括号里的 key 会被平台解析后映射到对应的 k8s 资源名(解析逻辑见 `myapp/utils/core.py:1622` 的 `get_gpu`)。 ## 一、主机驱动正常安装 主机正常安装摩尔线程驱动后,使用 `mthreads-gmi` 查看 GPU 卡。 ![mthreads-gmi 查看 GPU](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/e5aa4d1437f24eebaab1d6ca2aa6cd0a.png) ## 二、部署 k8s device 插件 在 k8s 中部署摩尔线程 gpu-device 插件。 ![部署 gpu-device 插件](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/fe0232fc34e541a3a9b9d84932239cc9.png) ## 三、查看 k8s 节点资源 device 插件部署完成后,查看 k8s 节点上报的摩尔线程卡资源。 ![节点资源](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/9f13dc2d03a0464bb95f973435169534.png) ## 四、容器 yaml 文件 在容器 yaml 中申请摩尔线程卡,比如这里 Pod 占用 2 张卡。 ![容器 yaml 占用 2 张卡](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/01c2c0b8a6c047d6a53881610ea4b880.png) ## 五、Pod 内查看占用卡情况 进入容器后用 `mthreads-gmi` 查看占用的卡。 ![容器内 mthreads-gmi](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/dd03bda1867c47018a2d8517e5a4b2b2.png) ## 六、CubeStudio 平台部署 DeepSeek 模型 在 CubeStudio 平台上使用摩尔线程卡部署 DeepSeek 模型。 ![平台部署 DeepSeek](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/69977dfd0fed4450beed7a2841afe649.png) ## 七、DeepSeek 接口测试 部署完成后测试 DeepSeek 推理接口。 ![DeepSeek 接口测试](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/05e07dac48b84022887f1149fc72df23.png) --- ### 沐曦 GPU 适配(C500:驱动 + device plugin + mx-exporter) - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/GPU%E4%B8%8E%E5%BC%82%E6%9E%84%E7%AE%97%E5%8A%9B/%E6%B2%90%E6%9B%A6GPU - 分类: 02-部署安装 / GPU与异构算力 - 适用场景: 在 CubeStudio 上接入沐曦 GPU(C500)算力,需要装驱动、用 helm 部署 device plugin、配置资源名、装 exporter 看监控时读这篇 - 关键词: 沐曦 / metax / MetaX / C500 / 曦云 / metax-tech.com/gpu / mx-smi / device-plugin / metax-operator / mx-exporter / npu-export / MACA / helm / 国产GPU / 异构算力 / grafana监控 - 最后更新: 2026-07-04 # 沐曦 GPU 适配(C500) 本文以沐曦曦云 C500 为例,介绍如何在 k8s 中接入沐曦 GPU 并在 CubeStudio 上做全流程适配。合并自 `install/kubernetes/gpu/metax/readme.md`(适配测试)与 `install/kubernetes/gpu/metax/部署device exporter.md`(驱动/插件/exporter 安装)。 资料与镜像地址: - 软件下载(C500 分层包):https://developer.metax-tech.com/softnova/tools?package_kind=DC&dimension=metax&chip_name=%E6%9B%A6%E4%BA%91C500%E7%B3%BB%E5%88%97&deliver_type=%E5%88%86%E5%B1%82%E5%8C%85 - 镜像下载:https://developer.metax-tech.com/softnova/docker - 安装与维护文档:https://developer.metax-tech.com/api/client/document/preview/864/split_files/%E5%AE%89%E8%A3%85%E4%B8%8E%E7%BB%B4%E6%8A%A4.html - k8s 接入文档:https://developer.metax-tech.com/api/client/document/preview/897/k8s/02_start.html ## 1. 机器环境初始化 1. 安装沐曦驱动(参考上面"安装与维护"文档); 2. 安装 docker 运行时; 3. 用 `mx-smi` 查看主机设备,确认驱动与运行时正常。 ## 2. 平台侧资源配置(GPU_RESOURCE) 沐曦 GPU 的 k8s 扩展资源名为 `metax-tech.com/gpu`,平台映射见 `myapp/config.py:1249`(生产配置同 `install/docker/config.py:1249`): ```python GPU_RESOURCE = { ... "mx": "metax-tech.com/gpu", # 沐曦 C500 GPU ... } ``` 在项目组 / 任务里用 `gpu:1(mx)` 这种 `数量(资源简称)` 写法占用沐曦卡,括号内的 `mx` 即上面定义的 key。 ## 3. 安装 device-plugin(metax-operator) 每台机器执行(以 0.13.2 版本包为例): ```bash tar xzf metax-gpu-k8s-package.0.13.2.tar.gz # 镜像加载 ./metax-k8s-images.0.13.2.run load # 加载到 docker ./metax-k8s-images.0.13.2.run nerdctl load # 加载到 containerd # 镜像推送到仓库 ./metax-k8s-images.0.13.2.run push DOMAIN/PROJECT # 默认 docker 推送 ./metax-k8s-images.0.13.2.run nerdctl push DOMAIN/PROJECT # nerdctl 推送 # 用本地镜像安装(镜像已通过 run load 加载到所有节点) helm install ./metax-operator-0.13.2.tgz \ --create-namespace -n metax-operator \ --generate-name \ --wait ``` 部署后查看 k8s node 详情,可看到 `metax-tech.com/gpu` 资源;k8s pod 即可占用沐曦 GPU,pod 内可用 `mx-smi` 查看分配到的卡。 ## 4. 安装 exporter(mx-exporter) 每台主机部署 mx-exporter(DaemonSet),用于上报 GPU 监控指标: ```bash unzip mx-exporter.zip cd mx-exporter/deployment/mx-exporter kubectl create -f mx-exporter-daemonset.yaml # 验证指标 curl :/metrics ``` Grafana 看板 json:`mx-exporter/deployment/grafana-dashboard/MetaX-GPU-C500.json`。 ## 5. CubeStudio 全流程适配能力 沐曦 C500 已在 CubeStudio 上完成大模型全流程适配,包括: - Jupyter 在线开发; - 资源占用查看 / Grafana 资源监控; - Pipeline 大模型训练; - 推理服务网关(网关名称对应推理服务中的"模型名称-模型版本"); - 预训练模型推理(服务状态为 online 表示已启动)。 ## 6. 沐曦基础镜像 平台预置/示例镜像(见 `myapp/config.py`,默认注释,按需启用): - 开发 / 训练(PyTorch,MACA):`ccr.ccs.tencentyun.com/cube-studio/maca-c500-pytorch:2.23.0.5-ubuntu22.04-x86_64`(`myapp/config.py:1021`); - 推理 / 微调(LLaMA-Factory):`ccr.ccs.tencentyun.com/cube-studio/llama-factory:20250601`(`myapp/config.py:1331` 注释,沐曦/NPU 共用)。 --- ### NVIDIA vGPU 切分虚拟化(HAMi) - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/GPU%E4%B8%8E%E5%BC%82%E6%9E%84%E7%AE%97%E5%8A%9B/vGPU%E8%99%9A%E6%8B%9F%E5%8C%96 - 分类: 部署安装 / GPU与异构算力 - 适用场景: 需要把单张 NVIDIA GPU 切分给多个 pod 共享使用(显存/算力切分)时,部署 HAMi vGPU 方案的步骤 - 关键词: vGPU / vgpu / GPU虚拟化 / GPU切分 / HAMi / 第四范式 / nvidia.com/vgpu / VGPU_RESOURCE / devicememoryscaling / hami-scheduler / device-plugin / GPU共享 / GPU分片 / prometheus监控 - 最后更新: 2026-07-04 # NVIDIA vGPU 切分虚拟化(HAMi) CubeStudio 采用第四范式开源的 [HAMi](https://github.com/Project-HAMi/HAMi) 作为 vGPU 虚拟化方案,对单张 NVIDIA GPU 做切分共享。平台侧配置见 `myapp/config.py` 的 `VGPU_RESOURCE`(`{"vgpu":"nvidia.com/vgpu"}`,约 `myapp/config.py:1270`)与 `VGPU_DRIVE_TYPE = "vgpu"`(`myapp/config.py:1276`,注释标注「第四范式解决方案」)。 ## 部署步骤 下载 HAMi chart 包: ```bash wget https://githubfast.com/Project-HAMi/HAMi/releases/download/v2.8.0/hami-2.8.0.tgz ``` 用 helm template 渲染出 `vgpu.yaml`: ```bash helm template vgpu hami \ --set resourceName=nvidia.com/vgpu \ --set scheduler.kubeScheduler.imageTag=v1.28.15 \ --set version=v2.8.0 \ --set scheduler.overwriteEnv="false" \ -n kube-system > vgpu.yaml ``` > 说明:`resourceName=nvidia.com/vgpu` 与平台 `VGPU_RESOURCE` 中的资源名保持一致。`scheduler.kubeScheduler.imageTag` 需与集群 k8s 版本匹配。仓库内已提供渲染好的样例:`install/kubernetes/gpu/vgpu/vgpu.yaml`(HAMi 2.8.0),以及按 k8s 版本区分的 `vgpu-k8s1.21.yaml`、`vgpu-k8s1.25.yaml`。 ## 修改 vgpu.yaml 对渲染出的 `vgpu.yaml` 做以下调整: 1. **关闭显存超分,只做切分**:将 `"devicememoryscaling": 1`(即不做显存虚拟化超分,仅做分隔)。该字段在仓库样例中位于 `install/kubernetes/gpu/vgpu/vgpu.yaml:50`。 2. **节点选择器**:将 `nodeSelector` 改为 `vgpu: "true"`(仅在打了该标签的节点上启用 vGPU)。 3. **命名空间**:添加 `namespace: kube-system`。 4. **服务暴露类型**:服务暴露类型改为 `type: ClusterIP`,并去掉 `nodePort`。 5. **`type: NodePort` 类型的服务**改为 ClusterIP,同时注释掉 `externalTrafficPolicy: Local`。 ### 接入 Prometheus 监控 为 `vgpu-hami-scheduler` 服务添加注释,将「调度量」等信息同步到 Prometheus: ```yaml annotations: prometheus.io/scrape: "true" prometheus.io/port: '9395' prometheus.io/path: /metrics ``` 为 `vgpu-hami-device-plugin-monitor` 服务添加注释,将「pod 实际使用情况」信息同步到 Prometheus: ```yaml annotations: prometheus.io/scrape: "true" prometheus.io/port: '9394' prometheus.io/path: /metrics ``` > 说明:上述服务名与端口与仓库样例一致——`vgpu-hami-scheduler` 暴露 9395、`vgpu-hami-device-plugin-monitor` 暴露 9394(见 `install/kubernetes/gpu/vgpu/vgpu.yaml` 中对应的 Service 定义)。 ### Bug 修复:补充 RBAC 权限 为 `vgpu-hami-scheduler` 角色添加 `volumeattachments` 权限: ```yaml # 添加 volumeattachments 权限 - apiGroups: ["storage.k8s.io"] resources: ["volumeattachments"] verbs: ["get", "list", "watch"] ``` ## 全部配置参考 所有配置项参考 HAMi 官方中文文档: --- ### 昇腾 NPU 基础部署(驱动 / 运行时 / k8s 插件 / 监控) - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/GPU%E4%B8%8E%E5%BC%82%E6%9E%84%E7%AE%97%E5%8A%9B/%E5%8D%8E%E4%B8%BA%E6%98%87%E8%85%BENPU/01-%E5%9F%BA%E7%A1%80%E9%83%A8%E7%BD%B2 - 分类: 部署安装 / GPU与异构算力 - 适用场景: 在昇腾机器上从零安装驱动/CANN、配置容器运行时、把 NPU 接入 k8s(device-plugin)并配置监控时阅读 - 关键词: 昇腾 / Ascend / NPU / 驱动 / CANN / Ascend Docker Runtime / containerd / device-plugin / npu-exporter / npu-smi / gpu-type / NPU910 / mindx-dl / ASCEND_VISIBLE_DEVICES / cgroup - 最后更新: 2026-06-30 # 昇腾 NPU 基础部署 本篇覆盖单机环境初始化(驱动 + CANN)、容器运行时配置、k8s device-plugin 与 npu-exporter 部署。 ## 机器环境初始化 安装驱动和 CANN,参考: - - 安装驱动时添加 `--install-for-all`。 查看机器设备: ```bash npu-smi info ``` ## 配置运行时 首先安装 docker 或 containerd。 配置 Ascend-docker-runtime 参考: 下载安装 Ascend-docker-runtime: ```bash chmod u+x Ascend-docker-runtime_6.0.0_linux-aarch64.run ./Ascend-docker-runtime_6.0.0_linux-aarch64.run --check # 安装 docker 运行时 ./Ascend-docker-runtime_6.0.0_linux-aarch64.run --install # docker 重启 systemctl daemon-reload && systemctl restart docker # docker info 查看默认运行时是否改为 ascend # 或者安装 containerd 运行时 ./Ascend-docker-runtime_6.0.0_linux-aarch64.run --install --install-scene=containerd # 安装 containerd 运行时,指定 containerd 地址 ./Ascend-docker-runtime_6.0.0_linux-aarch64.run --install --install-scene=containerd --config-file-path /etc/containerd/config.toml # 查看 cgroup 版本 stat -fc %T /sys/fs/cgroup/ # 若回显为 tmpfs,表示当前为 cgroup v1 版本 # 若回显为 cgroup2fs,表示当前为 cgroup v2 版本 # 按照文档中 cgroup 版本类型,修改运行时 systemctl daemon-reload && systemctl restart containerd ``` ### 测试容器使用 NPU 资源 ```bash # docker 测试 docker pull ccr.ccs.tencentyun.com/ascendhub/ascend-mindspore:24.0.RC1-A2-ubuntu20.04 docker run -it --user root --rm -e ASCEND_VISIBLE_DEVICES=0 ccr.ccs.tencentyun.com/ascendhub/ascend-mindspore:24.0.RC1-A2-ubuntu20.04 /bin/bash # 进入容器后执行 npu-smi info 看看是否只有一个 # containerd 测试 nerdctl run -it --runtime io.containerd.runtime.v1.linux --user root --rm -e ASCEND_VISIBLE_DEVICES=0 ccr.ccs.tencentyun.com/ascendhub/ascend-mindspore:24.0.RC1-A2-ubuntu20.04 /bin/bash ``` > 说明:`ASCEND_VISIBLE_DEVICES` 用于指定容器可见的 NPU 卡号;平台侧禁用占用通过 `ASCEND_VISIBLE_DEVICES=void` 实现(见 `myapp/config.py:1265-1266` 的 `GPU_NONE`)。 ## 配置 k8s 参考: ### Rancher 添加 /var/log 的 kubelet 挂载绑定 修改 rancher 集群配置,添加 kubelet 挂载,和部署时添加的挂载 `/data:/data` 类似: ```yaml kubelet: extra_args: ... extra_binds: - '/data:/data' # 部署 k8s 时就添加了的配置 - '/var/log:/var/log' # 添加这一行 fail_swap_on: false generate_serving_certificate: false ``` ### 安装 device-plugin 每台机器执行下面的命令: ```bash mkdir -p -m 750 /var/log/mindx-dl/devicePlugin chown root:root /var/log/mindx-dl/devicePlugin ``` 下载资源包: 这里以 910 为例,对应文件 `device-plugin/device-plugin-910-v6.0.0.yaml`(仓库内位于 `install/kubernetes/ascend/device-plugin/`,同目录还有 310/310P 及对应 volcano 版本的 yaml)。 操作步骤: 1. 先手动拉取镜像,然后修改 yaml 中的镜像名。 2. 修改 `nodeSelector` 为 `gpu-type: NPU910`。 3. 修改镜像拉取策略为 `IfNotPresent`。 > 说明:`gpu-type` 节点标签必须大写(如 `NPU910`),这与 `config.py` 注释「主机的 gpu-type 必须大写」一致(见 `myapp/config.py:1241`)。 然后部署: ```bash kubectl apply -f device-plugin/device-plugin-910-v6.0.0.yaml ``` ### 安装 npu-exporter 每台主机上创建目录: ```bash mkdir -p -m 755 /var/log/mindx-dl/npu-exporter chown root:root /var/log/mindx-dl/npu-exporter ``` 配置下载镜像参考: 对应文件 `npu-export/npu-exporter-v6.0.0.yaml`(仓库内位于 `install/kubernetes/ascend/npu-export/`)。 操作步骤: 1. 先手动拉取镜像,然后修改 yaml 中的镜像名。 2. 修改命名空间,创建服务使得 Prometheus 可采集到。 3. 设置 NPU 机器选择器和 hostNetwork。 然后部署: ```bash kubectl apply -f npu-export/npu-exporter-v6.0.0.yaml ``` --- ### 昇腾 vNPU 虚拟化(静态切分) - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/GPU%E4%B8%8E%E5%BC%82%E6%9E%84%E7%AE%97%E5%8A%9B/%E5%8D%8E%E4%B8%BA%E6%98%87%E8%85%BENPU/02-vNPU%E8%99%9A%E6%8B%9F%E5%8C%96 - 分类: 部署安装 / GPU与异构算力 - 适用场景: 需要把单张昇腾 NPU 静态切分成多张 vNPU 给多个 pod 使用,配置 device-plugin 并验证时阅读 - 关键词: 昇腾 / Ascend / vNPU / NPU虚拟化 / NPU切分 / 910B3 / npu-smi / create-vnpu / vir05_1c_16g / vnpu-mode / presetVirtualDevice / volcanoType / device-plugin / MindX DL / ASCEND_VNPU_SPECS / torch_npu - 最后更新: 2026-06-30 # 昇腾 vNPU 虚拟化(静态切分) 参考文档: 本文档以 NPU 910B3 卡为例。 > 平台侧:`config.py` 中 `GPU_RESOURCE` 的 `vnpu` 对应 `huawei.com/Ascend910-5c.1cpu.16g`(见 `myapp/config.py:1247`),需根据自己静态虚拟化所产生的 vNPU 规格调整该资源名。 ## 主机设置静态虚拟 NPU ### 设置虚拟化模式 > 本命令只支持在物理机执行,取值为 0 或 1(如果是在虚拟机内划分 vNPU,不需要执行本命令)。 > > - 0:虚拟化实例功能(容器模式),适用于将 vNPU 挂载到容器。 > - 1:虚拟化实例功能(虚拟机模式),适用于将 vNPU 挂载到虚拟机。 ```bash npu-smi info -t vnpu-mode # 查看当前虚拟化模式 npu-smi set -t vnpu-mode 0 # 虚拟化模式修改为容器模式 ``` ### 添加虚拟卡 创建虚拟 NPU,不同卡型号模板不同: ```bash npu-smi set -t create-vnpu -i 0 -c 0 -f --help # 查看模板 ``` 其中 `-i` 卡号、`-c` 芯片号、`-f` 模板。 ![模板列表](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/21d4fa1ad9804a0aa55cf6028d62b032.png) 可以根据名称来确定 vNPU 模板名对应的配置: ![模板配置](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/9ec5ecc5263e47e9b256f9714a7f647c.png) ```bash # 创建一张 1c16G 的 vnpu,这是 1/4 的切分颗粒度,可切分 4 张,执行 4 次此命令 npu-smi set -t create-vnpu -i 0 -c 0 -f vir05_1c_16g ``` ![创建结果](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/b967a16def3b4bc48c57c0179a9244d4.png) 设置恢复状态:配置 vNPU 恢复状态。该参数用于设备重启时保存 vNPU 配置信息,重启后 vNPU 配置依然有效: ```bash npu-smi set -t vnpu-cfg-recover -d 1 ``` 查看 vnpu 创建信息: ```bash npu-smi info -t info-vnpu -i 0 -c 0 ``` ![查看信息](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/3ef0c93ffd5247378b07d9553a4a27af.png) 销毁 vnpu: ```bash # -v 为 vnpu id,可在「查看 vnpu 创建信息」中查到 npu-smi set -t destroy-vnpu -i -c 0 -v xxx ``` ![销毁](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/5f6edc62bf6c424db74c213ab927eaed.png) > 注意:如果使用 MindX DL 动态虚拟化功能,则不需要提前创建 vNPU,MindX DL 运行任务时会自动按配置要求调用接口创建 vNPU。 > > 注意:Ascend Docker Runtime 使用 vNPU,既可以先通过 npu-smi 工具创建 vNPU 再挂载到容器;也可以在拉起容器时直接通过 `ASCEND_VISIBLE_DEVICES` 和 `ASCEND_VNPU_SPECS` 参数,从物理芯片上虚拟化出多个 vNPU 并挂载至容器。参考: ## 修改 device 插件信息 在 device-plugin 容器的 `args` 中添加 `-volcanoType=false -presetVirtualDevice=true`: ```yaml containers: - image: swr.cn-south-1.myhuaweicloud.com/ascendhub/ascend-k8sdeviceplugin:v6.0.0 name: device-plugin-01 resources: requests: memory: 500Mi cpu: 500m limits: memory: 500Mi cpu: 500m command: [ "/bin/bash", "-c", "--"] args: [ "device-plugin -useAscendDocker=true -volcanoType=false -presetVirtualDevice=true -logFile=/var/log/mindx-dl/devicePlugin/devicePlugin.log -logLevel=0" ] securityContext: privileged: true readOnlyRootFilesystem: true ``` ## 查看 node 是否有 vNPU 资源 ```bash kubectl describe node $nodename ``` ![节点资源](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/f8398223e1674f7693f156d3f60a055e.png) 查看节点是否有 `vir05_1c_16g` 的资源。 ## 启动 PyTorch 测试 使用昇腾 PyTorch 镜像测试是否可以在 pod 中看到并使用 vNPU。 > 注意:一个 pod 只能占用一张 vNPU 卡。 创建测试 pod: ![测试 pod](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/8aa70e85fa3d44a39405f42a82f9c2a8.png) ```bash kubectl apply -f pod.yaml ``` 测试占用卡是否成功: ```bash # 如果有 libgomp1 报错 apt-get update && apt-get install -y libgomp1 source /usr/local/Ascend/ascend-toolkit/set_env.sh ``` ```python import torch import torch_npu # 创建 NPU 张量 a = torch.randn(3, 3).npu() b = torch.randn(3, 3).npu() # 矩阵乘法 c = torch.matmul(a, b) print(c) # 将结果移回 CPU c_cpu = c.cpu() print(c_cpu) import torch # import torch_npu # torch_npu 2.5.1 及以后版本可以不用手动导包 x = torch.randn(2, 2).npu() y = torch.randn(2, 2).npu() z = x.mm(y) print(z) ``` ![测试结果](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/15555a2bdd0b4902bafd48975e1e65c6.png) --- ### 昇腾 MindIE 多机分布式推理 - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/GPU%E4%B8%8E%E5%BC%82%E6%9E%84%E7%AE%97%E5%8A%9B/%E5%8D%8E%E4%B8%BA%E6%98%87%E8%85%BENPU/03-MindIE%E5%88%86%E5%B8%83%E5%BC%8F%E6%8E%A8%E7%90%86 - 分类: 部署安装 / GPU与异构算力 - 适用场景: 在昇腾多机多卡环境部署 MindIE 大模型分布式推理(如 DeepSeek),配置网卡/ranktable/环境变量并启动服务时阅读 - 关键词: 昇腾 / Ascend / MindIE / 分布式推理 / 多机推理 / ranktable / RANK_TABLE_FILE / hccn_tool / HCCL / deepseek / mindieservice_daemon / worldSize / npuDeviceIds / NPU网卡 / tls校验 - 最后更新: 2026-06-30 # 昇腾 MindIE 多机分布式推理 参考: - - ## 配置网卡信息 > 注意:为 NPU 卡配置的 IP 网段要符合公司网络规划,这一部分由算力人员来做。 ```bash hccn_tool -i 0 -ip -s address 192.168.230.101 netmask 255.255.255.0 hccn_tool -i 1 -ip -s address 192.168.230.102 netmask 255.255.255.0 hccn_tool -i 2 -ip -s address 192.168.230.103 netmask 255.255.255.0 hccn_tool -i 3 -ip -s address 192.168.230.104 netmask 255.255.255.0 hccn_tool -i 4 -ip -s address 192.168.230.105 netmask 255.255.255.0 hccn_tool -i 5 -ip -s address 192.168.230.106 netmask 255.255.255.0 hccn_tool -i 6 -ip -s address 192.168.230.107 netmask 255.255.255.0 hccn_tool -i 7 -ip -s address 192.168.230.108 netmask 255.255.255.0 # 给 NPU 卡配置网关 for i in {0..7}; do hccn_tool -i $i -gateway -s gateway 192.168.230.1; done # 配置 NPU 网口检测 IP 地址,用于定期检测 NPU 网口网络状态,检测 IP 可填写 NPU 参数面 IP 网段网关地址。 for i in {0..7}; do hccn_tool -i $i -netdetect -s address 192.168.230.1; done ``` 验证 IP 配置是否生效: ```bash # 检测 NPU 卡的 ip 地址是否生效、可 ping 通,跨机器可 ping 通 hccn_tool -i 0 -ping -g address 192.168.230.101 hccn_tool -i 1 -ping -g address 192.168.230.102 hccn_tool -i 2 -ping -g address 192.168.230.103 hccn_tool -i 3 -ping -g address 192.168.230.104 hccn_tool -i 4 -ping -g address 192.168.230.105 hccn_tool -i 5 -ping -g address 192.168.230.106 hccn_tool -i 6 -ping -g address 192.168.230.107 hccn_tool -i 7 -ping -g address 192.168.230.108 # 查看卡的 ip for i in {0..7}; do hccn_tool -i $i -ip -g; done for i in {0..7}; do hccn_tool -i $i -tls -s enable 0; done ``` 关闭校验: ```bash # 检查 NPU 底层 tls 校验行为一致性,建议全 0,如果未配置会导致模型加载超时 for i in {0..7}; do hccn_tool -i $i -tls -g; done | grep switch # NPU 底层 tls 校验行为置 0 操作 for i in {0..7}; do hccn_tool -i $i -tls -s enable 0; done ``` ## 每台机器的容器内操作 设置 `/mnt/admin/../../ranktable.json`,并设置环境变量 `RANK_TABLE_FILE` 指向该地址;每台机器看到的是相同的 ranktable.json: ```json { "version": "1.0", "server_count": "2", "server_list": [ { "server_id": "10.42.0.15", "container_ip": "10.42.0.15", "device": [ { "device_id": "0", "device_ip": "192.168.230.101", "rank_id": "0" }, { "device_id": "1", "device_ip": "192.168.230.107", "rank_id": "1" }, { "device_id": "7", "device_ip": "192.168.230.108", "rank_id": "7" } ] }, { "server_id": "10.42.0.16", "container_ip": "10.42.0.16", "device": [ { "device_id": "0", "device_ip": "192.168.230.109", "rank_id": "8" }, { "device_id": "1", "device_ip": "192.168.230.110", "rank_id": "9" }, { "device_id": "7", "device_ip": "192.168.230.116", "rank_id": "15" } ] } ], "status": "completed" } ``` 修改 `/usr/local/Ascend/mindie/latest/mindie-service/conf/config.json`: ```json "ipAddress" : "0.0.0.0", "managementIpAddress" : "0.0.0.0", "allowAllZeroIpListening" : true, "httpsEnabled" : false, "interCommTLSEnabled" : false, "npuDeviceIds" : [[0,1,2,3,4,5,6,7]], "multiNodesInferEnabled" : true, "interNodeTLSEnabled" : false, "modelName" : "deepseek", "modelWeightPath" : "/mnt/admin/pipeline/example/deepseek/DeepSeek-R1-Distill-Qwen-7B", "worldSize" : 8, ``` > `modelWeightPath` 配置模型地址;`worldSize` 为单机参与卡数。 ## 设置昇腾基础环境变量 ```bash source /usr/local/Ascend/mindie/set_env.sh source /usr/local/Ascend/ascend-toolkit/set_env.sh source /usr/local/Ascend/nnal/atb/set_env.sh source /usr/local/Ascend/atb-models/set_env.sh export ATB_LLM_BENCHMARK_ENABLE=1 export ATB_LLM_ENABLE_AUTO_TRANSPOSE=0 export HCCL_CONNECT_TIMEOUT=7200 export HCCL_EXEC_TIMEOUT=0 export OMP_NUM_THREADS=1 export MINDIE_LOG_TO_STDOUT=1 export MINDIE_LLM_LOG_TO_STDOUT=1 export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True export ATB_WORKSPACE_MEM_ALLOC_ALG_TYPE=3 export ATB_WORKSPACE_MEM_ALLOC_GLOBAL=1 export NPU_MEMORY_FRACTION=0.9 export HCCL_DETERMINISTIC=false export HCCL_OP_EXPANSION_MODE="AIV" export ATB_LLM_HCCL_ENABLE=1 export ATB_LLM_COMM_BACKEND="hccl" export HCCL_CONNECT_TIMEOUT=7200 chmod 640 /usr/local/Ascend/mindie/latest/mindie-service/conf/config.json # 这里是你的模型地址 chmod -R 640 $MODEL_PATH ``` 设置多机推理环境变量: ```bash export RANK_TABLE_FILE=你上面的 ranktable.json 的绝对地址 export RANKTABLEFILE=你上面的 ranktable.json 的绝对地址 chmod 640 ${RANK_TABLE_FILE} export MIES_CONTAINER_IP=每个 pod 的容器 ip,host 模式也是主机 ip export MASTER_IP=(rank_id=0 的机器的机器 ip) export WORLD_SIZE=所有 pod 的总卡数 ``` ## 准备启动 ```bash # 重启后面的服务要先清理 find /dev/shm -name '*llm_backend_*' -type f -delete find /dev/shm -name 'llm_tokenizer_shared_memory_*' -type f -delete # 启动 mindie rm -rf ~/mindie/log/ cd /usr/local/Ascend/mindie/latest/mindie-service bin/mindieservice_daemon ``` 其他问题: ```bash # 部署模型需要信任远程代码 pip install transformers==4.46.0 ``` --- ### 华为昇腾 NPU 适配总览 - 链接: https://www.cubestudio.vip/docs/02-%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85/GPU%E4%B8%8E%E5%BC%82%E6%9E%84%E7%AE%97%E5%8A%9B/%E5%8D%8E%E4%B8%BA%E6%98%87%E8%85%BENPU/README - 分类: 部署安装 / GPU与异构算力 - 适用场景: 在华为昇腾 NPU 机器上部署 CubeStudio,了解组件架构、驱动/运行时/k8s 插件/监控的整体安装顺序时阅读 - 关键词: 华为 / 昇腾 / Ascend / NPU / 910 / 310 / 310P / MindX DL / device-plugin / npu-exporter / Ascend Docker Runtime / MindIE / vNPU / 国产算力 / npu-smi - 最后更新: 2026-07-04 # 华为昇腾 NPU 适配总览 本目录介绍如何将华为昇腾 NPU 接入 CubeStudio,涵盖驱动/运行时安装、k8s 设备插件与监控、NPU 静态/动态虚拟化(vNPU),以及 MindIE 大模型分布式推理。 平台侧配置:`config.py` 的 `GPU_RESOURCE` 已内置昇腾资源名映射(`npu310` → `huawei.com/Ascend310`、`npu310p` → `huawei.com/Ascend310P`、`npu910` → `huawei.com/Ascend910`、`vnpu` → `huawei.com/Ascend910-5c.1cpu.16g`,见 `myapp/config.py:1244-1247`),禁用占用通过 `GPU_NONE` 的 `ASCEND_VISIBLE_DEVICES=void` 实现(`myapp/config.py:1265-1266`)。 ## 工具架构(MindX DL 组件) | 组件 | 功能介绍 | |---|---| | Ascend Docker Runtime | 为训推任务提供容器化支持,自动挂载所需文件和设备依赖。 | | Ascend Device Plugin | 基于 Kubernetes 设备插件机制,提供昇腾 AI 处理器的设备发现、分配和健康状态上报功能,使 Kubernetes 能管理昇腾 AI 处理器资源。 | | NPU Exporter | 实时监测昇腾 AI 处理器的资源指标,获取利用率、温度、电压等信息。 | | Volcano | 基于开源 Volcano 调度插件机制,增加昇腾 AI 处理器的亲和性调度、故障重调度等特性。 | | ClusterD | 提供集群级别的可用资源信息。收集集群任务/资源/故障信息及影响范围,从任务、芯片和故障维度统计分析。 | | Ascend Operator | 提供训练任务生命周期管理,为不同 AI 框架的分布式训练任务提供环境变量、生成集合通讯配置。 | | HCCL Controller | 生成分布式训练任务依赖的集合通讯配置。 | | NodeD | 提供节点状态上报功能,上报节点心跳、CPU 和内存等故障信息。 | | Resilience Controller | 提供弹性缩容训练服务,硬件故障时剔除该硬件并继续训练。 | | Elastic Agent | 提供训练任务故障时刻保存临终 CheckPoint 能力。 | | MindIO ACP | 大模型训练中使用训练服务器内存作为缓存,加速 CheckPoint 的保存与加载。 | | MindIO TTP | 针对大模型训练故障,故障后即刻保存一次 CheckPoint,减少训练迭代损失。 | ![工具架构图](https://www.hiascend.com/doc_center/source/zh/mindx-dl/60rc3/clusterscheduling/clusterschedulingig/clusterschedulingig/figure/zh-cn_image_0000002090294701.png) ## 华为镜像仓库 昇腾支持的镜像(AscendHub): ## 子篇目录 - [01-基础部署](01-基础部署.md):机器环境初始化(驱动/CANN)、配置 Ascend Docker/containerd 运行时、配置 k8s(device-plugin、npu-exporter)。 - [02-vNPU 虚拟化](02-vNPU虚拟化.md):在主机上静态切分虚拟 NPU、修改 device-plugin、验证与 PyTorch 测试。 - [03-MindIE 分布式推理](03-MindIE分布式推理.md):NPU 网卡配置、ranktable.json、MindIE 多机推理环境变量与启动。 --- ## 平台使用(50 篇) ### 03-平台使用 段导航(按上手路径) - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/README - 分类: 平台使用 / 段导览 - 适用场景: 想知道"作为使用者该按什么顺序学平台、某功能的使用说明在本段哪个子目录"时,先读这页 - 关键词: 平台使用 / 使用文档 / 上手路径 / 导航 / 目录 / getting started / 新手入门 / notebook / pipeline / 推理服务 / 数据集 / 标注 / aihub / 计量计费 - 最后更新: 2026-06-30 # 03-平台使用 段导航 本页是「平台使用」段的本地导航,面向**平台使用者**(建模 / 算法 / 数据同学),按推荐上手路径与本段子目录组织各专题文档。 > 分工说明:本页只做**本段**导航。跨全段的 AI 导航索引、全文目录、术语表在 `00-索引/` 下(由专门工作流维护),本页不重复全局索引。 > 链接说明:本段按编号子目录组织(`01-入门与权限/` … `10-计量计费/`),各专题文档均以相对链接给出。其中「任务模板通用字段 / 使用约定」按知识库规划归入 `05-任务模板/` 段,本段不重复。 推荐按 `01 → 10` 的顺序学习,即一条完整的上手路径。 ## 01 入门与权限 - [新人用户使用指南](01-入门与权限/新人用户使用指南/README.md):注册 / 加入项目组 / 在线开发 / 任务流 / 推理服务一站式快速上手(已按主题拆为多页) - [用户和角色](01-入门与权限/用户和角色.md):全局角色、项目组内角色、API 认证 token 获取与使用方式 - [项目空间](01-入门与权限/项目空间.md):项目组、成员、集群 / 资源组 / 挂载 / 额度等项目组维度能力 ## 02 资源与存储(管理员 / 项目组负责人常用) - [机器资源配置](02-资源与存储/机器资源配置.md):机器资源扫描与可调度标签 - [存储资源配置](02-资源与存储/存储资源配置.md):添加存储资源、挂载为 PVC、在项目组中启用挂载 - [整体资源](02-资源与存储/整体资源.md):全局资源视角与查看方式 ## 03 在线开发(Notebook / IDE) - [在线 IDE](03-在线开发/在线IDE.md):Jupyter / Theia(VSCode) / RStudio / Matlab、端口与 SSH、tensorboard 等 - [SDK 使用](03-在线开发/SDK使用.md):平台 SDK 使用说明 - [notebook 部署 Claude Code](03-在线开发/notebook部署ClaudeCode.md):在 notebook 中配置 / 使用 Claude Code - [本地 Jupyter 对接 Hadoop 生态](03-在线开发/本地Jupyter对接Hadoop生态/README.md):本地 Jupyter 连接 Hadoop / Spark 等 ## 04 镜像构建与仓库 - [镜像在线构建和管理](04-镜像构建与仓库/镜像在线构建和管理.md):在线构建镜像(Web Shell / Dockerfile)与保存 - [镜像仓库](04-镜像构建与仓库/镜像仓库.md):镜像仓库凭据(k8s secret)与拉取 / 推送策略 ## 05 数据资产与处理 - [库表](05-数据资产与处理/库表.md):库表资产使用说明 - [指标](05-数据资产与处理/指标.md):指标资产使用说明 - [维表](05-数据资产与处理/维表.md):维表资产使用说明 - [数据集](05-数据资产与处理/数据集.md):数据集导入 / 管理 / 备份 - [数据 ETL](05-数据资产与处理/数据ETL.md):数据 ETL 任务流(对接外部数据中台时使用) - [SQLLab](05-数据资产与处理/SQLLab.md):在平台内连接数据库查询(仅支持 select 且需 limit) ## 06 任务流与训练 - [任务流(Pipeline)](06-任务流与训练/任务流.md):编排、调试、定时调度、变量与可视化结果(`/metric.json`) - [超参搜索](06-任务流与训练/超参搜索.md):NNI 超参搜索使用方式 - [任务可视化 echart 数据格式](06-任务流与训练/任务可视化echart数据格式.md):任务可视化(echart)数据格式 > 注:任务模板通用字段与使用约定(原「模板使用」)按知识库规划已移至 `05-任务模板/` 段。 ## 07 服务化与推理 - [模型服务](07-服务化与推理/模型服务.md):模型管理与推理服务发布、域名 / ip 访问方式、端口规则与灰度 / 分流 - [内部服务](07-服务化与推理/内部服务.md):内部服务(如 phpmyadmin / mongo-express / redis-ui / neo4j / jaeger 等)示例 - [推理服务-ml](07-服务化与推理/推理服务-ml.md):ml-server 标准化接口与 config.json 约定 - [推理服务-tfserving](07-服务化与推理/推理服务-tfserving.md):TFServing 模型目录 / 配置与 API - [推理服务-torchserve](07-服务化与推理/推理服务-torchserve.md):TorchServe 打包 / 配置与 API - [推理服务-triton](07-服务化与推理/推理服务-triton.md):Triton 目录 / 配置与 API - [服务网关](07-服务化与推理/服务网关.md):OpenAI 兼容网关(认证 / 限流 / 测试 / 监控) ## 08 标注与数据闭环 - [标注平台](08-数据标注/标注平台/README.md):Label Studio 使用、自动化标注、数据同步与结果保存 ## 09 数据智能与市场 - [AIHub 模型市场](09-数据智能与市场/AIHub模型市场.md):AIHub 模型市场 / 应用说明 - [私有知识库](09-数据智能与市场/私有知识库.md):私有知识库使用说明 ## 10 成本与计量(如启用) - [计量计费](10-计量计费/计量计费.md):计量计费与账单相关说明 --- ### 项目空间(项目组)使用与权限 - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/01-%E5%85%A5%E9%97%A8%E4%B8%8E%E6%9D%83%E9%99%90/%E9%A1%B9%E7%9B%AE%E7%A9%BA%E9%97%B4 - 分类: 平台使用 / 入门与权限 - 适用场景: 想了解如何加入/创建项目组、添加成员与角色、用项目组控制集群/资源组/挂载/服务代理IP/资源额度时读这篇 - 关键词: 项目空间 / 项目组 / 项目分组 / project / project group / 组成员 / member / creator / dev / ops / auditor / 角色 / role / 集群 / cluster / 资源组 / org / 挂载 / volume_mount / 服务代理ip / SERVICE_EXTERNAL_IP / 资源额度 / quota / 限额 / 命名空间 / namespace - 最后更新: 2026-06-30 # 项目空间(项目组) 项目组(数据库表 `project`,type 为 `org`)是平台划分**权限**与**资源**的核心单位。项目组既可用来控制成员能接触的资源和任务流,也可用来把任务调度到指定的集群、资源组、挂载、命名空间,并施加资源额度限制。 > 平台中“项目空间 / 项目分组 / 项目组”指的是同一概念。 ## 加入项目组 路径:项目空间 -> 项目分组 -> 更多 -> 组成员。如果自己不在需要加入的项目组成员列表中,可以联系项目组的 creator 将自己加入到项目组中。 ![image](https://foruda.gitee.com/images/1697599977554734697/9e0886cc_1019082.png) 备注: - 每个人自动都在 `public` 项目组中。 - 管理员可自行创建项目组。 ## creator 添加用户 路径:项目空间 -> 项目分组 -> 更多 -> 组成员 -> 添加组成员,则 creator 角色的组成员可以添加其他用户进组。 ![输入图片说明](https://foruda.gitee.com/images/1700037295869278624/d6b9a283_1019082.png "屏幕截图") 添加组成员时,可以选择该组成员的角色,控制组成员能接触的资源和 pipeline 等。 ![输入图片说明](https://foruda.gitee.com/images/1700037346944963204/a2dce799_1019082.png "屏幕截图") ### 成员角色 平台支持以下成员角色(见 `myapp/views/view_team.py` 中 `role` 字段的可选值 `['dev', 'ops', 'creator', 'auditor']`): - `creator`:项目组创建者/管理者,可以添加、修改、删除其他组成员(可以有多个 creator)。 - `ops`、`dev`:普通成员角色。 - `auditor`:审计角色。 权限校验逻辑:非管理员只有在自己是该项目组 creator 时,才能新增/编辑/删除组成员(`view_team.py` 的 `check_edit_permission`)。 ## 项目组控制调度集群 cluster(管理员) 平台支持多 k8s 集群调度。需要管理员先创建集群并配置到系统配置(`CLUSTERS`)后,可通过项目组扩展参数中的 `cluster` 字段控制项目组的调度集群。项目组若未配置 `cluster`,则使用配置项 `ENVIRONMENT` 对应的默认集群。 ![image](https://foruda.gitee.com/images/1697600683973018570/cb835fdc_1019082.png) > 集群准备、GPU/网络等基础设施配置参见 [02-部署安装](../../02-部署安装/) 段。 ## 项目组控制调度机器资源组(管理员) 平台支持在单集群中划分资源组。需要管理员先配置不同机器所属的资源组(机器 label `org=xxx`,见 [机器资源配置](../02-资源与存储/机器资源配置.md))后,可通过项目组扩展参数中的 `org` 字段控制项目组的调度机器。 ![输入图片说明](https://foruda.gitee.com/images/1700033741214777585/6688e5b1_1019082.png "屏幕截图") 项目组可以用来划分权限,同时也可以用来划分资源。一台调度机器只能划入一个资源组。 - 如果单纯通过项目组划分权限、不划分资源,那么一个资源组可以划入多个项目组,调度机器可以是不同项目组、不同机型、不同区域等划分方式,这种方式能提高机器利用率,避免一个项目组不使用时机器空闲。 - 如果在划分权限的同时划分资源,那么调度机器就只会属于一个项目组。 > 资源组在底层是通过机器节点的 `org` label 实现的,调度时项目组会把 `org=xxx` 加入 node_selector(见 `myapp/models/model_team.py` 的 `node_selector` 属性)。 ## 项目组控制挂载(管理员) 平台支持在单集群中划分挂载。可以配置项目组下成员将自有分布式存储挂载到平台,以及项目组内共享目录等功能,可通过项目组扩展参数中的 `volume_mount` 字段控制项目组的挂载。 挂载格式为 `$名称(类型):$容器内路径`,多个挂载用 `,` 或 `;` 分隔。支持的挂载类型有 `(pvc)`、`(pvc-share)`、`(hostpath)`、`(storage)`、`(configmap)`、`(memory)`(见 `myapp/views/view_team.py` 的 `pre_add_req` 校验): - `(pvc)`:会自动挂载该 pvc 下对应的**个人用户子目录**(以用户名为子目录)。默认挂载 `kubeflow-user-workspace` 的 pvc 到 `/mnt`。管理员可自行创建 pvc 进行挂载。 - `(pvc-share)`:挂载 pvc,但**不**自动加用户名子目录,用于多人共享。 - `(hostpath)`:挂载宿主机目录,不会自动挂载个人子目录,可用来控制多人共享同一个公共目录。 - `(storage)`:挂载[存储资源](../02-资源与存储/存储资源配置.md)中已 mount 的分布式存储(按存储名引用)。 - `(configmap)`、`(memory)`:分别挂载 configmap、内存盘。 pvc 与 hostpath 可以同时存在,实现既有个人子目录又有公共目录。 ![输入图片说明](https://foruda.gitee.com/images/1700033678049609017/e11d4b58_1019082.png "屏幕截图") 示例: ``` kubeflow-user-workspace(pvc):/mnt/;/data/aidata(hostpath):/aidata ``` > 行为细节:即使没有显式配置 `/mnt` 挂载,平台也会自动补上 `kubeflow-user-workspace(pvc):/mnt`(见 `model_team.py` 的 `volume_mount` 属性)。引用 `(pvc)` / `(storage)` 时平台会校验对应 pvc / 存储是否存在,不存在会报错。 > > 分布式存储的添加与 mount 见 [存储资源配置](../02-资源与存储/存储资源配置.md);存储底层准备参见 [02-部署安装](../../02-部署安装/) 段。 ## 项目组控制服务 service 代理 IP(管理员) 平台支持在单集群中划分服务的代理 IP,多用于边缘集群,或多网关情况下。可通过项目组扩展参数中的 `SERVICE_EXTERNAL_IP` 字段控制项目组下服务的代理 IP。 格式为 `内网ip` 或 `内网ip|公网ip`(例如 `xx.内网.xx.xx|xx.公网.xx.xx`),见 `view_team.py` 的 `SERVICE_EXTERNAL_IP` 字段说明;对应全局默认配置项为 `SERVICE_EXTERNAL_IP`(`myapp/config.py`)。 ![输入图片说明](https://foruda.gitee.com/images/1700033794762344450/c309bd8c_1019082.png "屏幕截图") ## 项目组控制资源额度 平台有三个层面的额度控制: 1. **个人额度**:在“用户列表”中可以设定某个人的额度限制,只要是这个用户启动的任务都会被纳入统计。 2. **项目组额度**:在项目组的扩展参数 `quota` 中配置,对项目组下所有用户启动的任务总和进行统计。 3. **项目组下个人额度**:在项目组成员(组成员)配置中设置,用于某个人在某个项目组下拥有的可用资源量。 ### 额度填写格式 > ⚠️ 注意:三个层面的额度填写**格式不同**。原文档只给出了 4 字段格式,实际上“个人额度(用户列表)”用的是 6 字段格式。依据 `myapp/security.py:321`、`myapp/views/view_team.py:116,402` 的表单说明,以及 `myapp/utils/core.py:2085,2147,2205` 的解析逻辑。 - **个人额度(用户列表,6 字段)**:`$集群名,$资源组名,$命名空间,$资源类型,$限制类型,$限制值` - `$集群名`:可为 `all` 或具体集群名(如 `dev`)。 - `$资源组名`:可为 `all` 或具体资源组名(如 `public`)。 - `$命名空间`:`all,jupyter,pipeline,service,automl,aihub`(`notebook` 会被等价处理为 `jupyter`)。 - `$资源类型`:`cpu,memory,gpu`。 - `$限制类型`:`single,concurrent`。 - **项目组额度 / 项目组下个人额度(4 字段)**:`$命名空间,$资源类型,$限制类型,$限制值` - `$命名空间`:`all,jupyter,pipeline,service,automl,aihub`。 - `$资源类型`:`cpu,memory,gpu`。 - `$限制类型`:`single,concurrent`。 公共说明: - `$限制类型` 中,`single` 表示单个 pod 占用的资源最大值;`concurrent` 表示可同时处于运行中的资源最大值。 - 多个限额配置之间使用**分号** `;` 分隔(也支持换行分隔)。 - 管理员不受额度限制(`core.py` 的 `meet_quota` 对 admin 直接放行)。 --- ### 用户和角色(权限体系) - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/01-%E5%85%A5%E9%97%A8%E4%B8%8E%E6%9D%83%E9%99%90/%E7%94%A8%E6%88%B7%E5%92%8C%E8%A7%92%E8%89%B2 - 分类: 平台使用 / 入门与权限 - 适用场景: 想了解全局角色(admin/gamma)、项目组内角色(creator/ops/dev)、菜单访问控制、API 调用如何带 token 认证时读这篇 - 关键词: 用户 / 角色 / 权限 / RBAC / role / permission / admin / gamma / creator / ops / dev / auditor / 项目组角色 / API token / Authorization / 认证 / ADMIN_USER / 菜单权限 - 最后更新: 2026-07-04 # 全局角色 CubeStudio 基于 Flask-AppBuilder 框架,自带了 RBAC 角色管理。不过目前此部分的角色主要为 gamma 角色(普通使用者)和 admin 角色。 ![角色管理](https://foruda.gitee.com/images/1700624729035388825/438ea0f7_1019082.png "屏幕截图") - admin 角色可以全局资源都可查看 - gamma 角色为普通使用者角色 > 说明:新注册用户默认分配的角色由配置项 `AUTH_USER_REGISTRATION_ROLE` 决定,平台默认值为 `Gamma`(见 `myapp/config.py:94`)。 # 菜单访问控制 编辑角色,可为角色添加控制对应菜单的访问权限。再将角色分配给不同的用户,以此来实现不同用户看到不同的菜单。 ![菜单访问控制](https://foruda.gitee.com/images/1739082478081767061/84722b7b_1019082.png "屏幕截图") # api 调用认证 CubeStudio 所有的后端接口访问都需要用户身份认证,api 调用时需要在添加 header。 所有 api 操作 header: ``` headers = { 'Content-Type': 'application/json', 'Authorization': '$token' } ``` 其中 token 的获取在个人详情页面。 ![获取 token](https://foruda.gitee.com/images/1739082700527233350/4f16db96_1019082.png "屏幕截图") > 实现说明(与代码核对):`Authorization` 既可以传短用户名(仅在 `AUTH_PLATFORM_ACCESS` 开启或经 K8s 内部域名 `kubeflow-dashboard.infra` 访问时放行,见 `myapp/security.py:655`-`657`),也可以传 token。token 本质是一段 JWT:payload 为 `{"sub": 用户名}`,用配置项 `JWT_PASSWORD` 以 HS256 签名,并去掉固定 header 段以缩短长度(见 `myapp/security.py:155`-`175` 生成、`myapp/security.py:649`-`676` 校验)。`JWT_PASSWORD` 在默认配置里为 `myapp`(见 `myapp/config.py:241`);代码在该配置缺失时的兜底取值才是 `cube-studio`(见 `myapp/security.py:171`、`:669`),实际部署以 `config.py` 的取值为准。 # 项目组中角色 其他对数据的权限,都是基于项目组或者个人的。 ![项目组角色](https://foruda.gitee.com/images/1700624766252977233/9125a443_1019082.png "屏幕截图") 用户在项目组内的角色主要包含 3 个:creator、ops、dev,在不同场景下,不同角色的权限是不一样的。 - 项目组场景下,creator 角色用户可以添加其他用户进入项目组 - 在线开发 / 任务 ETL,同项目组中均可见 - 模型训练 / 任务流,同项目组中均可见 - 模型训练 / 超参搜索,同项目组中均可见 - 服务化 / 内部服务,同项目组中均可见 - 服务化 / 推理服务,同项目组中均可见,项目组 creator 可以部署,其他同项目组仅可查看 > 补充(与代码核对):项目组成员角色可选值在代码中为 `['dev', 'ops', 'creator', 'auditor']`(见 `myapp/views/view_team.py:108`),默认 `dev`。即除上述 3 个角色外,较新版本还提供 `auditor`(审计)角色。 > ⚠️ 待核实:`auditor` 角色在代码其余位置未见明确的权限分支逻辑,其具体可见范围请以实际部署版本为准。 # 管理员 在有些功能地方,只允许管理员查看,管理员包括两类: - 一类是在界面上,项目空间 / 用户列表中,为用户添加了 admin 角色的,可以全局数据都可以看到,但是该类用户不是运维人员,只是平台的 boss - 一类是在配置文件 config.py 中定义的 `ADMIN_USER`,该变量定义的是平台的运维人员,用于接收系统级别的报警(默认值 `ADMIN_USER='admin'`,见 `myapp/config.py:764`) 目前仅管理员能看到的包括: - 项目空间 / 资源配置 - 项目空间 / 安全设置 - 项目空间 / 链接 - 私有知识库 # 个人权限 在有些功能地方,每个用户只允许看到自己的数据。比如: - 在线开发 / 镜像仓库 - 在线开发 / 镜像构建 - 在线开发 / 镜像管理 - 在线开发 / notebook - 模型训练 / 任务模板 - 模型训练 / 定时调度 - 模型训练 / 运行实例 - 服务化 / 模型管理 # 责任人机制 部分场景下为每个数据都配置专门的责任人,只有有权限的责任人可以看到数据,例如: - 数据资产 / 指标 - 数据资产 / 维表 - 数据资产 / 数据集 - 数据智能,只能看到自己是责任人,或者公开的私有知识库 # 完全公开 有些部分的数据是完全开放给所有人的,比如: - 数据资产 / 库表 - 服务化 / 整体资源 - aihub 模型市场 # 独立的用户权限体系 有些场景下不是用自带的账户体系,而是现场创建账户体系,主要存在于与外部人事相关的平台部分。比如: - 标注平台 --- ### 新人指南-基础认识与视频教程 - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/01-%E5%85%A5%E9%97%A8%E4%B8%8E%E6%9D%83%E9%99%90/%E6%96%B0%E4%BA%BA%E7%94%A8%E6%88%B7%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97/01-%E5%9F%BA%E7%A1%80%E8%AE%A4%E8%AF%86%E4%B8%8E%E8%A7%86%E9%A2%91%E6%95%99%E7%A8%8B - 分类: 平台使用 / 入门与权限 - 适用场景: 刚接触平台、想先看视频并搞清楚"容器/镜像/任务模板/任务流/运行实例/notebook"这些核心名词时读这篇 - 关键词: 视频教程 / 基础概念 / 容器 / 镜像 / image / 任务模板 / job template / 任务流 / pipeline / DAG / 运行实例 / notebook / 概念 - 最后更新: 2026-06-30 # 一、视频教程 [新人使用教程](https://www.bilibili.com/video/BV1zA4y1f7Rf) # 二、基础认识 **容器**:对于建模人员,可以认为容器是一个轻量的虚拟机,一个机器可以同时启动多个容器,容器之间资源是隔离的。在平台上运行的任务,最终都会以容器内进程的形式运行在实体机上。所有容器的 `/mnt` 目录下都是自己的个人工作目录,容器重启后环境消失。 **镜像**:可以将容器整个操作系统的文件和目录打包成镜像,只需要解压打包好的容器镜像,容器就被重现出来了。所以我们可以用这种方式打包运行 ml 任务的复杂环境。 **任务模板**:当我们要在平台例行化运行一个 ml 任务(例如 xgb 分类),可以先定义好这个任务用到的镜像,需要什么参数,分配多少资源等信息,形成一个任务模板。以后使用的时候只需选择模板并填写相应参数即可。 **任务流(pipeline)**:多个任务及其依赖关系形成的 DAG 图。任务的构建产物可以在任务间传递。 **运行实例**:任务流的一次运行。 **notebook**:开启一个 jupyter-notebook,自动挂载个人工作目录。有 jupyter、vscode 两种模式。 > 补充(与代码核对):notebook 实际支持的 IDE 类型为 `jupyter`、`theia`(即 VSCode 形态)、`matlab`、`rstudio`(见 `myapp/models/model_notebook.py:67`-`71`)。 --- 下一步:[02-加入项目组与权限](02-加入项目组与权限.md)。返回 [指南目录](README.md)。 --- ### 新人指南-加入项目组与权限 - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/01-%E5%85%A5%E9%97%A8%E4%B8%8E%E6%9D%83%E9%99%90/%E6%96%B0%E4%BA%BA%E7%94%A8%E6%88%B7%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97/02-%E5%8A%A0%E5%85%A5%E9%A1%B9%E7%9B%AE%E7%BB%84%E4%B8%8E%E6%9D%83%E9%99%90 - 分类: 平台使用 / 入门与权限 - 适用场景: 想知道怎么注册、怎么加入或创建项目组、creator 怎么加人、管理员怎么用项目组划分集群/资源/挂载时读这篇 - 关键词: 注册 / 新用户 / 用户角色 / gamma / 激活 / 限制登录 / 加入项目组 / 项目分组 / 组成员 / creator / 添加用户 / 集群 cluster / 资源组 node_selector / 挂载 volume_mount / pvc / hostpath / 服务代理 ip / SERVICE_EXTERNAL_IP - 最后更新: 2026-06-30 # 三、加入项目组 ## 注册新用户 登录即注册,使用新的用户名及密码登录进平台,即自动注册新用户,之后用这个用户名及密码登录即可。 ![注册](https://foruda.gitee.com/images/1700036888288825614/6070e8f3_1019082.png "屏幕截图") 注册成功后,通过右上角的个人头像 - 用户中心,可查看新注册用户的个人信息,比如是否激活、用户角色等等。 ![用户中心](https://foruda.gitee.com/images/1700036964488825213/c095c7bb_1019082.png "屏幕截图") 另一种添加新用户的方法,是在项目空间 - 用户列表中直接添加新用户。 ![用户列表添加](https://foruda.gitee.com/images/1700037571508048572/5dc08d19_1019082.png "屏幕截图") 同样可以设定新用户的角色、用户名、密码、邮箱、是否激活等。 ![设定新用户](https://foruda.gitee.com/images/1700037632421275117/103bfa9d_1019082.png "屏幕截图") ## 用户角色权限管理 可以通过更改用户角色来控制用户权限,比如这里用户角色只有 gamma。 ![用户角色](https://foruda.gitee.com/images/1700037921393348452/0c31a7dc_1019082.png "屏幕截图") 该用户登录时,看不到机器资源、存储资源、用户列表等重要信息。 ![gamma 视图](https://foruda.gitee.com/images/1700037952893888223/096d5e60_1019082.png "屏幕截图") ## 限制用户登录 管理员可以通过取消用户激活来限制用户登录。 ![限制登录](https://foruda.gitee.com/images/1700037807899795219/99e2697f_1019082.png "屏幕截图") ## 加入项目组 路径:项目空间 -> 项目分组 -> 更多 -> 组成员,如果自己不在需要申请的项目组组成员列表中,可以联系项目组的 creator 将自己加入到项目组中。 ![加入项目组](https://foruda.gitee.com/images/1697599977554734697/9e0886cc_1019082.png) 备注: - 每个人自动都在 public 项目组中 - 可自行创建项目组 ## creator 添加用户 路径:项目空间 -> 项目分组 -> 更多 -> 组成员 -> 添加组成员,则 creator 角色的组成员可以添加其他用户进组。 ![添加组成员](https://foruda.gitee.com/images/1700037295869278624/d6b9a283_1019082.png "屏幕截图") 添加组成员时,管理员可以选择该组成员的角色,控制组成员能接触的资源和 pipeline 等。 ![选择角色](https://foruda.gitee.com/images/1700037346944963204/a2dce799_1019082.png "屏幕截图") > 补充(与代码核对):组成员角色可选值为 `['dev', 'ops', 'creator', 'auditor']`,默认 `dev`,且只有 creator 能添加 / 修改组成员(见 `myapp/views/view_team.py:108`、`view_team.py:155`)。 ## 项目组控制调度集群 cluster(管理员学习) 平台支持跨集群调度。需要管理员创建集群并配置到系统配置后,可通过项目组的"集群"字段控制项目组的调度集群。 ![集群字段](https://foruda.gitee.com/images/1697600683973018570/cb835fdc_1019082.png) ## 项目组控制调度机器 node_selector(管理员学习) 平台支持单集群中划分资源组。需要管理员配置不同机器所属的资源组后,可通过项目组的"资源组"字段控制项目组的调度机器。 项目组可以用来划分权限,同时也可以用来划分资源。一台调度机器只能划入一个资源组。如果我们单纯通过项目组来划分权限,而不划分资源,那么一个资源组就可以划入多个项目组,那么调度机器可以是不同项目组,不同机型,不同区域等划分方式,这种方式能提高我们机器的利用率,避免一个项目组不使用时,机器空闲。我们也可以用项目组划分权限的同时,划分资源,那么调度机器就只会属于一个项目组。 ## 项目组控制挂载 volume_mount(管理员学习) 平台支持单集群中划分挂载。可以配置项目组下成员将自有分布式存储挂载到平台,以及项目组内共享目录等功能,可通过项目组的"挂载"字段控制项目组的挂载。 - 挂载 pvc,会自动挂载 pvc 下面的个人用户子目录。默认挂载 kubeflow-user-workspace 的 pvc。管理员可自行创建 pvc 进行挂载 - 挂载 hostpath,不会自动挂载个人子目录,可以用来控制多人共享同一个公共目录 pvc 和 hostpath 可以同时存在,实现既有个人子目录,又有公共目录。 > 补充(与代码核对):未显式配置时,项目组会自动补上默认挂载 `kubeflow-user-workspace(pvc):/mnt`(见 `myapp/models/model_team.py:131`)。 示例: ``` { "volume_mount": "kubeflow-user-workspace(pvc):/mnt/;data/aidata(hostpath):/aidata" } ``` ## 项目组控制服务 service 代理 ip(管理员学习) 平台支持单集群中划分服务的代理 ip,多用于边缘集群,或多网关情况下。可通过项目组的"服务代理 ip"字段控制项目组的服务的代理 ip。 > 补充(与代码核对):该能力对应项目组扩展字段 `expand` 中的 `SERVICE_EXTERNAL_IP`,写法支持 `内网ip` 或 `内网ip|公网ip`(见 `myapp/views/view_team.py:360`、`myapp/views/view_serving.py:382`)。 --- ## 相关专题文档 本节为快速上手版,详细说明见本段专题文档: - 角色与权限体系(全局 / 项目组 / API token)→ [用户和角色](../用户和角色.md) - 项目组、成员、集群 / 资源组 / 挂载 / 额度全字段 → [项目空间](../项目空间.md) 返回 [指南目录](README.md)。下一步:[03-在线notebook开发](03-在线notebook开发.md)。 --- ### 新人指南-在线 notebook 开发 - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/01-%E5%85%A5%E9%97%A8%E4%B8%8E%E6%9D%83%E9%99%90/%E6%96%B0%E4%BA%BA%E7%94%A8%E6%88%B7%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97/03-%E5%9C%A8%E7%BA%BFnotebook%E5%BC%80%E5%8F%91 - 分类: 平台使用 / 入门与权限 - 适用场景: 想知道平台支持哪些在线 IDE、怎么添加 notebook、notebook 怎么挂载工作目录、怎么用 tensorboard 时读这篇 - 关键词: notebook / jupyter / vscode / theia / matlab / rstudio / 在线开发 / 在线 IDE / tensorboard / 个人工作目录 / /mnt / reset / 添加 notebook - 最后更新: 2026-06-30 # 四、在线 notebook 开发 ## notebook 支持类型 1. Jupyter(cpu/gpu) 2. vscode(cpu/gpu) 3. Matlab 4. Rstudio > 补充(与代码核对):代码中 `ide_type` 取值为 `jupyter` / `theia`(VSCode 形态)/ `matlab` / `rstudio`(见 `myapp/models/model_notebook.py:67`-`71`)。 ## 支持功能 代码开发 / 调试,上传 / 下载,命令行,git 工蜂 / github,内网 / 外网,tensorboard,自主安装插件。 ## 添加 notebook 路径:在线开发 -> notebook -> 添加 notebook。 ![添加 notebook](https://foruda.gitee.com/images/1697602257548451503/dbe8e3da_1019082.png) 备注: 1. Running 状态下,方可进入,Pending 状态不可 2. 无法进去时,reset 重新激活 3. notebook 会自动挂载以下目录: - 个人工作目录到容器 `/mnt/$username` ## jupyter 示例 ![jupyter](https://foruda.gitee.com/images/1700625447822528133/ba54fd24_1019082.png "屏幕截图") ## vscode 示例 ![vscode](https://foruda.gitee.com/images/1700625475503317082/841442a4_1019082.png "屏幕截图") ## tensorboard 示例 使用 pro 版本的 jupyter,在左侧目录树,进入到 tensorboard 对应的日志目录,再打开右侧的 tensorboard 按钮。 ![tensorboard](https://foruda.gitee.com/images/1700625494623793520/b66d98ee_1019082.png "屏幕截图") --- ## 相关专题文档 本节为快速上手版,IDE 类型、端口与 SSH、详细配置等见本段专题文档 [在线 IDE](../../03-在线开发/在线IDE.md)。 返回 [指南目录](README.md)。下一步:[04-在线构建镜像](04-在线构建镜像.md)。 --- ### 新人指南-在线构建镜像 - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/01-%E5%85%A5%E9%97%A8%E4%B8%8E%E6%9D%83%E9%99%90/%E6%96%B0%E4%BA%BA%E7%94%A8%E6%88%B7%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97/04-%E5%9C%A8%E7%BA%BF%E6%9E%84%E5%BB%BA%E9%95%9C%E5%83%8F - 分类: 平台使用 / 入门与权限 - 适用场景: 想在平台上在线构建 docker 镜像、设置基础镜像/目标镜像、用连续构建断点续传时读这篇 - 关键词: 镜像构建 / 在线构建 / docker / dockerfile / 基础镜像 / 目标镜像 / 连续构建 / 断点续建 / web shell / image build - 最后更新: 2026-06-30 # 五、在线构建镜像 在线开发 -> 镜像构建 -> 添加 docker。 ![添加 docker](https://foruda.gitee.com/images/1697602848644548292/33853ad4_1019082.png) 可配置基础镜像、目标镜像、挂载、内存等。 选择连续构建,可以在 pod 重启后,在断点处接着进行镜像构建。 > 链接修复:原文「基础镜像和封装方法参考」指向 `images/README.md`(docs1 之外)。按知识库规划,镜像构建 / 封装相关内容归入 `06-二次开发/` 段的镜像构建文档,请到该段检索「基础镜像 / 镜像封装」。 --- ## 相关专题文档 本节为快速上手版,在线构建镜像(Web Shell / Dockerfile)与保存的完整说明见本段专题文档 [镜像在线构建和管理](../../04-镜像构建与仓库/镜像在线构建和管理.md),镜像仓库凭据见 [镜像仓库](../../04-镜像构建与仓库/镜像仓库.md)。 返回 [指南目录](README.md)。下一步:[05-pipeline配置调试定时](05-pipeline配置调试定时.md)。 --- ### 新人指南-pipeline 配置/调试/定时运行 - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/01-%E5%85%A5%E9%97%A8%E4%B8%8E%E6%9D%83%E9%99%90/%E6%96%B0%E4%BA%BA%E7%94%A8%E6%88%B7%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97/05-pipeline%E9%85%8D%E7%BD%AE%E8%B0%83%E8%AF%95%E5%AE%9A%E6%97%B6 - 分类: 平台使用 / 入门与权限 - 适用场景: 想知道怎么新建并编排任务流、怎么单独调试 task、怎么发起 pipeline 调度、怎么配置定时调度时读这篇 - 关键词: pipeline / 任务流 / DAG / 编排 / 调试 / run / log / 运行实例 / 调度实例 / 定时调度 / cron / 定时 / comed / created / pod - 最后更新: 2026-06-30 # 六、配置 / 调试 / 定时运行 pipeline ## 创建 pipeline 路径:首页 -> 新建流水线,或者 模型训练 -> 任务流 -> 添加任务流。 ![创建 pipeline](https://foruda.gitee.com/images/1697613279954771360/a05fda1f_1019082.png) ## 编排 pipeline ![编排 pipeline](https://foruda.gitee.com/images/1697614938156758107/b4a5dc21_1019082.png) 编排 pipeline 包括三步: 1. 将右侧模板拖拉拽至面板,并按运行步骤连接好; 2. 点击单个任务模板,设置任务参数; - task 公共参数:参考每个配置的描述 - task 的模板参数:参考每个模板的链接教程文档 3. 点击 pipeline 名称右边的设置按钮,设置 pipeline 参数,比如是否定时调度、调度周期等。 ## 运行调试 ### task 运行调试 使用 task 的 run 按钮和 log 按钮可单独调试一个 task。 ![task 调试](https://foruda.gitee.com/images/1697615910883736528/256d6831_1019082.png) ### pipeline 运行调试 pipeline 的运行按钮发起调度。 ![pipeline 调度](https://foruda.gitee.com/images/1697698641272797172/c7fd9842_1019082.png) ### pipeline 日志效果 ![pipeline 日志 1](https://foruda.gitee.com/images/1697698801734112395/19f50d9a_1019082.png) ![pipeline 日志 2](https://foruda.gitee.com/images/1697698861059204545/4bb369f7_1019082.png) ## pod 查看示意图 ![pod 查看](https://foruda.gitee.com/images/1697699003763442262/09693de1_1019082.png) pod 效果: ![pod 效果](https://foruda.gitee.com/images/1700625527426424911/8a6cc9b9_1019082.png "屏幕截图") ## 实例记录 调度实例记录。停止可以清除调度容器。 ![实例记录 1](https://foruda.gitee.com/images/1697699171330172439/55769d07_1019082.png) ![实例记录 2](https://foruda.gitee.com/images/1697699214856454580/11c558bd_1019082.png) ## 定时调度 配置定时:pipeline 编辑界面。 ![配置定时](https://foruda.gitee.com/images/1700625554263873443/91395afb_1019082.png "屏幕截图") 查看路径:模型训练 - 定时调度。 ![定时调度查看](https://foruda.gitee.com/images/1697699543038076104/b73d4a6c_1019082.png) 字段说明:执行时间为这个 pipeline 本次调度该发起的时间点。 状态:comed 为调度配置已经产生;created 为调度已经发起。 ### 操作说明 ``` 1、平台会根据 pipeline 的配置决定是否发起调度。 2、pipeline 的"调度实例"中可以看到本地调度发起的 pipeline 的运行情况 3、pipeline 的"日志"中可以看到最近一次发起的本地调度的日志 ``` --- ## 相关专题文档 本节为快速上手版,Pipeline 编排、变量传递与可视化结果(`/metric.json`)等完整说明见本段专题文档 [任务流](../../06-任务流与训练/任务流.md)。任务模板字段说明见 `05-任务模板/` 段。 返回 [指南目录](README.md)。下一步:[06-nni超参搜索](06-nni超参搜索.md)。 --- ### 新人指南-NNI 超参搜索 - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/01-%E5%85%A5%E9%97%A8%E4%B8%8E%E6%9D%83%E9%99%90/%E6%96%B0%E4%BA%BA%E7%94%A8%E6%88%B7%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97/06-nni%E8%B6%85%E5%8F%82%E6%90%9C%E7%B4%A2 - 分类: 平台使用 / 入门与权限 - 适用场景: 想用 NNI 做超参搜索、怎么写超参空间 json、代码怎么接收超参与上报结果、Web 怎么发起和查看实验时读这篇 - 关键词: nni / 超参搜索 / hyperparameter / 超参空间 / search space / tuner / TPE / Random Search / Anneal / SMAC / Grid Search / Hyperband / report_intermediate_result / report_final_result / get_next_parameter - 最后更新: 2026-06-30 # 七、nni 超参搜索 可以参考 [nni 官网](https://github.com/microsoft/nni) 的书写方式,[简体中文版链接](https://nni.readthedocs.io/zh/stable/)。 ## 超参空间 必须是标准的 json。示例: ``` { "batch_size": {"_type":"choice", "_value": [16, 32, 64, 128]}, "hidden_size":{"_type":"choice","_value":[128, 256, 512, 1024]}, "lr":{"_type":"choice","_value":[0.0001, 0.001, 0.01, 0.1]}, "momentum":{"_type":"uniform","_value":[0, 1]} } ``` 不同超参算法支持不同的超参空间: | 算法 / Tuner | choice | choice(nested) | randint | uniform | quniform | loguniform | qloguniform | normal | qnormal | lognormal | qlognormal | | :----- | :----- | :----- | :----- | :----- | :----- | :----- | :----- | :----- | :----- | :----- | | TPE Tuner | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | Random Search Tuner | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | Anneal Tuner | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | Evolution Tuner | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | SMAC Tuner | ✓ | | ✓ | ✓ | ✓ | ✓ | | | | | | | Batch Tuner | ✓ | | | | | | | | | | | | Grid Search Tuner | ✓ | | ✓ | | ✓ | | | | | | | | Hyperband Advisor | ✓ | | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | Metis Tuner | ✓ | | ✓ | ✓ | ✓ | | | | | | | | GP Tuner | ✓ | | ✓ | ✓ | ✓ | ✓ | ✓ | | | | | > 说明:上表为 NNI 各 Tuner 支持的搜索空间类型,源自 NNI 官方文档(非平台代码定义),以 NNI 对应版本文档为准。 ## 代码要求 ### 参数接收 启动超参搜索,会根据用户配置的超参搜索算法,选择好超参的可选值,并将选择值传递给用户的容器。例如上面的超参定义会在用户 docker 运行时传递下面的参数。所以用户不需要在启动命令或参数中添加这些变量,系统会自动添加,用户只需要在自己的业务代码中接收这些参数,并根据这些参数输出值就可以了。 ``` --lr=0.021593113434583065 --num-layers=5 --optimizer=ftrl ``` ### 结果上报 业务方容器和代码启动接收超参进行迭代计算,通过主动上报结果来进行迭代。示例如下,用户代码需要能接受超参可取值为输入参数,同时每次迭代通过 `nni.report_intermediate_result` 上报每次 epoch 的结果值,并使用 `nni.report_final_result` 上报每次实例的结果值。 ``` import os import argparse import logging,random,time import nni from nni.utils import merge_parameter logger = logging.getLogger('mnist_AutoML') def main(args): test_acc=random.randint(30,50) for epoch in range(1, 11): test_acc_epoch= random.randint(3,5) time.sleep(3) test_acc+=test_acc_epoch # 上报当前迭代目标值 nni.report_intermediate_result(test_acc) # 上报最终目标值 nni.report_final_result(test_acc) def get_params(): # 必须接收超参数为输入参数 parser = argparse.ArgumentParser(description='PyTorch MNIST Example') parser.add_argument('--batch_size', type=int, default=64, help='input batch size for training (default: 64)') args, _ = parser.parse_known_args() return args if __name__ == '__main__': try: # get parameters form tuner tuner_params = nni.get_next_parameter() params = vars(merge_parameter(get_params(), tuner_params)) print(tuner_params,params) main(params) except Exception as exception: logger.exception(exception) raise ``` ## web 发起一个搜索实验 ![发起搜索实验](https://foruda.gitee.com/images/1700625588695626727/90e499a1_1019082.png "屏幕截图") ## web 查看搜索效果 可以参考:https://nni.readthedocs.io/zh/stable/Tutorial/WebUI.html 总览界面可以看到实验的 id,和当前示例运行的状态。 ![总览](https://foruda.gitee.com/images/1700625623060713129/955b220b_1019082.png "屏幕截图") ![实验状态](https://foruda.gitee.com/images/1700625655357761300/f95f77c6_1019082.png "屏幕截图") 可以看每次 trial 的运行情况,计算出来的目标值。 ![trial](https://foruda.gitee.com/images/1700625674949560695/1a7eca66_1019082.png "屏幕截图") 也可以看某次 trial 中每次 epoch 得到的结果值。 --- ## 相关专题文档 本节为快速上手版,NNI 超参搜索的完整使用方式见本段专题文档 [超参搜索](../../06-任务流与训练/超参搜索.md)。超参搜索算子模板见 `05-任务模板/` 段。 返回 [指南目录](README.md)。下一步:[07-内部服务](07-内部服务.md)。 --- ### 新人指南-内部服务 - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/01-%E5%85%A5%E9%97%A8%E4%B8%8E%E6%9D%83%E9%99%90/%E6%96%B0%E4%BA%BA%E7%94%A8%E6%88%B7%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97/07-%E5%86%85%E9%83%A8%E6%9C%8D%E5%8A%A1 - 分类: 平台使用 / 入门与权限 - 适用场景: 想在平台上注册内部服务(数据库 Web 管理端、链路追踪等)、各类服务镜像与环境变量怎么填、服务怎么对外暴露时读这篇 - 关键词: 内部服务 / internal service / phpmyadmin / mysql web / mongo-express / mongo web / redis web / patrikx3 / neo4j / 图数据库 / jaeger / 链路追踪 / 环境变量 / 端口 / 服务暴露 / SERVICE_DOMAIN / SERVICE_EXTERNAL_IP - 最后更新: 2026-06-30 # 八、内部服务 ## 添加内部服务 1. 开发你的服务化镜像,push 到 docker 仓库内 2. 注册你的服务 ![注册内部服务](https://foruda.gitee.com/images/1697772623693090126/f1a22ffb_1019082.png) > 说明:以下各服务的镜像名与环境变量为常见使用示例(由用户填写到内部服务配置中),非平台代码内置,请按你实际使用的镜像版本调整。 ## mysql web 服务 镜像:`phpmyadmin:5.2.1` 环境变量: ``` PMA_HOST=xx.xx.xx.xx PMA_PORT=xx PMA_USER=xx PMA_PASSWORD=xx ``` 端口:80 ## mongo web 服务 镜像:`mongo-express:0.54.0` 环境变量: ``` ME_CONFIG_MONGODB_SERVER=xx.xx.xx.xx ME_CONFIG_MONGODB_PORT=xx ME_CONFIG_MONGODB_ENABLE_ADMIN=true ME_CONFIG_MONGODB_ADMINUSERNAME=xx ME_CONFIG_MONGODB_ADMINPASSWORD=xx ME_CONFIG_MONGODB_AUTH_DATABASE=xx VCAP_APP_HOST=0.0.0.0 VCAP_APP_PORT=8081 ME_CONFIG_OPTIONS_EDITORTHEME=ambiance ``` 端口:8081 ## redis web 镜像:`ccr.ccs.tencentyun.com/cube-studio/patrikx3:latest` 环境变量: ``` REDIS_NAME=xx REDIS_HOST=xx REDIS_PORT=xx REDIS_PASSWORD=xx ``` 端口:7843 ## 图数据库 neo4j 镜像:`ccr.ccs.tencentyun.com/cube-studio/neo4j:4.4` 环境变量: ``` NEO4J_AUTH=neo4j/admin ``` 端口:7474、7687 ## jaeger 链路追踪 镜像:`jaegertracing/all-in-one:1.29` 端口:5775、16686 ## 服务暴露 - **域名暴露**:平台会按 `{$service_name}.{$SERVICE_DOMAIN}` 生成访问域名。`SERVICE_DOMAIN` 默认为集群内后缀 `service.svc.cluster.local`(见 `myapp/config.py:1378`),外网访问通常需要你们在网关 / Ingress 层配置可解析的泛域名后缀。 - **ip 暴露**:配置 `SERVICE_EXTERNAL_IP=["内网ip|外网ip"]`(或仅内网 IP),默认 `[]`(见 `myapp/config.py:837`)。也可在项目组扩展字段 `expand` 里单独配置 `SERVICE_EXTERNAL_IP` 覆盖全局 / 集群默认值(见 `myapp/views/view_serving.py:382`)。 --- ## 相关专题文档 本节为快速上手版,内部服务(phpmyadmin / pgadmin / mongo-express / redis-ui 等)的完整示例见本段专题文档 [内部服务](../../07-服务化与推理/内部服务.md)。 返回 [指南目录](README.md)。下一步:[08-推理服务](08-推理服务.md)。 --- ### 新人指南-推理服务 - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/01-%E5%85%A5%E9%97%A8%E4%B8%8E%E6%9D%83%E9%99%90/%E6%96%B0%E4%BA%BA%E7%94%A8%E6%88%B7%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97/08-%E6%8E%A8%E7%90%86%E6%9C%8D%E5%8A%A1 - 分类: 平台使用 / 入门与权限 - 适用场景: 想理解推理服务的服务名/域名/pod 命名规则、系统域名与自定义域名、流量分流与灰度、弹性伸缩、注入的环境变量时读这篇 - 关键词: 推理服务 / inference / 模型服务 / serving / 服务名 / deployment / service / hpa / 弹性伸缩 / 域名 / 泛域名 / 自定义域名 / 流量复制 / 分流 / 灰度升级 / 环境变量 / KUBEFLOW_MODEL_PATH / KUBEFLOW_ENV / SERVICE_EXTERNAL_IP - 最后更新: 2026-06-30 # 九、推理服务 ## 版本 / 域名 / pod 的关系 服务名规则:**`$服务名 = $模型名-$模型版本`**(不含服务类型前缀)。其中模型名做字符替换(`/`、`:`、`.` → `-`,并去掉首尾的 `-`),模型版本做归一化(去掉 `v`、`.`、`:`),最终拼接后截断到 60 字符。见 `myapp/views/view_inferenceserving.py:608`(版本归一化)、`:764`(拼接服务名)、`:1954`(灰度新建服务时的命名)。 ![服务名](https://foruda.gitee.com/images/1700625702009674051/9ad4e1b4_1019082.png "屏幕截图") `$k8s-deployment-name = $服务名` ![deployment](https://foruda.gitee.com/images/1700625722366413016/60b49aef_1019082.png "屏幕截图") `$k8s-hpa-name = $服务名` 在最大最小副本数不一致时创建 hpa。 > 补充(与代码核对):仅在**未配置 cronhpa** 时才定制 hpa(见 `myapp/views/view_inferenceserving.py:1861`-`1862`)。 ![hpa](https://foruda.gitee.com/images/1700625740344758415/7d6011c4_1019082.png "屏幕截图") `$k8s-service-name = $服务名` 用于域名的代理 `$k8s-service-name = $服务名-external` 用于 ip/L5 的代理(见 `myapp/views/view_inferenceserving.py:857`、`:1671`) ![service](https://foruda.gitee.com/images/1700625758934043145/9155c176_1019082.png "屏幕截图") ## 系统自带域名 自动配置域名需要泛域名支持。例如泛域名为 `domain = *.kfserving.woa.com`。 生产域名: ``` http://$服务名.service.$domain ``` 测试环境域名: ``` http://test.$服务名.service.$domain http://debug.$服务名.service.$domain ``` ## 自定义域名 用户可通过 host 字段配置服务的访问域名,但是必须与泛域名结尾。 多个服务可以配置相同的域名。 ## 流量复制和分流 多个服务(可以是相同模型或者不同模型间)配置相同的域名: 1. 分流属性字段控制分配多少流量到其他服务上,剩余流量归属于当前服务 2. 流量镜像字段控制复制多少流量到其他服务上。但只会将当前服务的响应返回给客户端 ![流量分流](https://foruda.gitee.com/images/1700550812054510346/6cb58aa3_1019082.png "屏幕截图") ## 灰度升级 1. 同一个服务灰度升级,只需要修改服务的配置,重新部署,服务会自动滚动升级 pod 2. 不同服务进行灰度升级。比如同一个模型的不同版本之间,那么多个服务使用相同的域名,新部署的服务上线正常后,会自动下线同域名的旧服务 ## 弹性伸缩容 弹性伸缩容的触发条件:可以使用自定义指标,可以使用其中一个指标或者多个指标,示例:`cpu:50%,mem:50%,gpu:50%`。 ## 环境变量 平台会自动为推理服务容器注入以下环境变量(与代码核对,见 `myapp/views/view_inferenceserving.py:1122`-`1136`): ```bash KUBEFLOW_ENV=test # 环境标识(test/prod 等) KUBEFLOW_MODEL_PATH= # 模型路径 KUBEFLOW_MODEL_VERSION= # 模型版本 KUBEFLOW_MODEL_IMAGES= # 服务镜像 KUBEFLOW_MODEL_NAME= # 模型名 KUBEFLOW_INFERENCE_ID= # 推理服务 id KUBEFLOW_RUN_ID= # 本次运行的随机 id RESOURCE_CPU= # 申请的 CPU RESOURCE_MEMORY= # 申请的内存 RESOURCE_MIN_REPLICAS= # 最小副本数 RESOURCE_MAX_REPLICAS= # 最大副本数 RESOURCE_GPU= # 申请的 GPU 卡数 MODEL_PATH= # 模型路径(去尾部 /) MODEL_NAME= # 模型名 INFERENCE_NAME= # 推理服务名 ``` 此外,平台为所有 pod 统一注入以下 K8s 下行字段环境变量(见 `myapp/utils/py/py_k8s.py:1122`-`1126`): ```bash K8S_NODE_NAME= # spec.nodeName K8S_POD_NAMESPACE= # metadata.namespace K8S_POD_IP= # status.podIP K8S_HOST_IP= # status.hostIP K8S_POD_NAME= # metadata.name ``` > 注意:较早的文档里曾列出 `KUBEFLOW_AREA=shanghai/guangzhou`,但当前推理服务注入逻辑(`myapp/views/view_inferenceserving.py:1121`-`1136`)并不注入该变量,已从上面的列表中移除。 ## 服务暴露 - **域名暴露**:依赖 `SERVICE_DOMAIN`(默认 `service.svc.cluster.local`,见 `myapp/config.py:1378`)与网关层泛域名解析 / 转发。 - **ip 暴露**:依赖 `SERVICE_EXTERNAL_IP`(支持 `内网|外网` 写法,默认 `[]`,见 `myapp/config.py:837`;可在项目组 `expand` 覆盖,见 `myapp/views/view_serving.py:382`)。 --- ## 相关专题文档 本节为快速上手版,模型管理与推理服务发布、端口规则、各推理框架的完整说明见本段专题文档 [模型服务](../../07-服务化与推理/模型服务.md)、[推理服务-ml](../../07-服务化与推理/推理服务-ml.md)、[推理服务-tfserving](../../07-服务化与推理/推理服务-tfserving.md)、[推理服务-torchserve](../../07-服务化与推理/推理服务-torchserve.md)、[推理服务-triton](../../07-服务化与推理/推理服务-triton.md)。 返回 [指南目录](README.md)。 --- ### 新人用户使用指南(总览与目录) - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/01-%E5%85%A5%E9%97%A8%E4%B8%8E%E6%9D%83%E9%99%90/%E6%96%B0%E4%BA%BA%E7%94%A8%E6%88%B7%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97/README - 分类: 平台使用 / 入门与权限 - 适用场景: 新用户第一次用平台,想按"注册→加项目组→在线开发→构建镜像→任务流→超参→内部服务→推理服务"一站式走一遍时,从这里进入 - 关键词: 新人指南 / 新手 / 上手 / 快速开始 / getting started / walkthrough / 入门教程 / 视频教程 / 一站式 - 最后更新: 2026-06-30 # 新人用户使用指南 本指南是平台的一站式上手 walkthrough,覆盖从注册到推理服务发布的完整链路。原单页内容较长(约 500 行),已按主题拆为下列子文件,便于快速定位与按需阅读。 > 定位:本指南是**快速上手版**(含界面截图与最短操作路径)。每个主题的**详细说明**见本段对应专题文档,子文件结尾均给出交叉链接,避免内容长期重复维护。 ## 子文件目录 | 子文件 | 内容 | 对应专题文档 | |---|---|---| | [01-基础认识与视频教程](01-基础认识与视频教程.md) | 视频教程入口;容器 / 镜像 / 任务模板 / 任务流 / 运行实例 / notebook 核心概念 | — | | [02-加入项目组与权限](02-加入项目组与权限.md) | 注册新用户、角色与激活、加入 / 创建项目组、creator 加人、项目组控制集群 / 资源组 / 挂载 / 服务代理 IP | 用户和角色、项目空间 | | [03-在线notebook开发](03-在线notebook开发.md) | notebook 类型与功能、添加 notebook、jupyter / vscode / tensorboard 示例 | 在线 IDE | | [04-在线构建镜像](04-在线构建镜像.md) | 在线构建 docker 镜像、基础镜像 / 目标镜像 / 连续构建 | 镜像在线构建和管理 | | [05-pipeline配置调试定时](05-pipeline配置调试定时.md) | 创建 / 编排 pipeline、task 与 pipeline 调试、实例记录、定时调度 | 任务流 | | [06-nni超参搜索](06-nni超参搜索.md) | 超参空间 json、各 Tuner 支持的搜索空间、参数接收与结果上报、Web 发起与查看 | 超参搜索 | | [07-内部服务](07-内部服务.md) | 注册内部服务、mysql / mongo / redis / neo4j / jaeger 镜像与环境变量、服务暴露 | 内部服务 | | [08-推理服务](08-推理服务.md) | 服务名 / 域名 / pod 关系、系统域名与自定义域名、流量复制 / 分流、灰度、弹性伸缩、环境变量 | 模型服务 | ## 推荐阅读顺序 按 01 → 08 顺序即为一条完整的上手路径。其中 02 中的「项目组控制集群 / 资源组 / 挂载」部分主要面向**管理员**,普通用户可先跳过。 返回 [03-平台使用 段导航](../../README.md)。 --- ### 存储资源配置 - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/02-%E8%B5%84%E6%BA%90%E4%B8%8E%E5%AD%98%E5%82%A8/%E5%AD%98%E5%82%A8%E8%B5%84%E6%BA%90%E9%85%8D%E7%BD%AE - 分类: 平台使用 / 资源与存储 - 适用场景: 想添加分布式存储(NFS/CFS/COS/NAS/OSS/S3/GlusterFS/CephFS)、把它挂载成 PVC 并在项目组中启用时读这篇 - 关键词: 存储资源 / 分布式存储 / storage / 挂载 / mount / PVC / PV / nfs / cfs / cos / nas / oss / s3 / minio / glusterfs / cephfs / ceph / geesefs / csi / 腾讯云 / 阿里云 - 最后更新: 2026-07-04 # 存储资源 和[机器资源](机器资源配置.md)不同,存储资源是需要自己手动添加的。因为 CubeStudio 的分布式存储是用户自己提供的,所以用户需要自己配置分布式存储的信息。 ![输入图片说明](https://foruda.gitee.com/images/1698589912177475530/1f35e8ff_1019082.png "屏幕截图") 存储资源挂载绑定的“集群”是必填项(表单 `clusters` 字段 `DataRequired`)。添加好存储资源后,需要点击 “mount” 按钮挂载成 pvc 才可以使用,并且需要在项目组中添加相应的挂载配置(项目组 `volume_mount` 中以 `存储名(storage):/路径` 引用,见 [项目空间](../01-入门与权限/项目空间.md))。 ![输入图片说明](https://foruda.gitee.com/images/1698590097854904864/a276aac0_1019082.png "屏幕截图") ![输入图片说明](https://foruda.gitee.com/images/1698590273673732552/24135793_1019082.png "屏幕截图") > 支持的存储类型(表单 `storage_type` 可选值,见 `myapp/views/view_resource_storage.py:70`):`nfs`(默认)、`cfs`(腾讯云)、`cos`(腾讯云)、`nas`(阿里云)、`oss`(阿里云)、`s3`(s3/minio)、`glusterfs`、`cephfs`、`自定义`。 > > mount 行为(见 `myapp/models/model_storage.py` 的 `k8s_resource_list` 与 `view_resource_storage.py` 的 `mount` action):会在 `pipeline`、`service`、`jupyter`、`automl` 四个命名空间下分别创建 PV(名为 `命名空间-存储名`)和 PVC(名为 `存储名`),默认容量 `10Gi`、访问模式 `ReadWriteMany`、回收策略 `Retain`;带密钥的存储(cos/oss/s3/cephfs 等)会在 `kube-system` 命名空间下创建对应 Secret。卸载用 “umount” action。 > > 存储底层(CSI 插件部署等)准备参见 [02-部署安装](../../02-部署安装/) 段。 ## cfs 腾讯云购买 cfs 存储。 ![在这里插入图片描述](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/tengxunyun-cfs.png) 自建 k8s 挂载,需要参考 https://github.com/TencentCloud/kubernetes-csi-tencentcloud 部署插件。 配置示例(yaml,对应表单默认值): ```yaml csi: driver: com.tencent.cloud.csi.cfs volumeAttributes: fsid: xx host: xx.xx.xx.xx # 需要与k8s集群同一个区 path: /xx/ # 需要确保目录存在 ``` ## cos 腾讯云购买 cos 存储。 账号密钥参考:https://console.cloud.tencent.com/cam/capi ![在这里插入图片描述](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/tengxunyun-cos1.png) ![在这里插入图片描述](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/tengxunyun-cos1.png) 自建 k8s 挂载,需要参考 https://github.com/TencentCloud/kubernetes-csi-tencentcloud 部署插件。 配置示例(yaml,对应表单默认值;`SecretId/SecretKey` 会被抽取为 Secret): ```yaml csi: driver: com.tencent.cloud.csi.cosfs SecretId: xxxx # https://console.cloud.tencent.com/cam/capi SecretKey: xxxx # https://console.cloud.tencent.com/cam/capi volumeAttributes: url: http://cos.ap-xxx.myqcloud.com # 需要在同一个子网下 bucket: xxx path: /xx ``` ## nas 阿里云购买 nas 存储。 ![在这里插入图片描述](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/nas1.png) ![在这里插入图片描述](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/nas2.png) 配置示例(yaml,对应表单默认值): ```yaml csi: driver: nasplugin.csi.alibabacloud.com volumeAttributes: path: /xx/xx # 需要确保目录存在 server: xx.cn-xx.nas.aliyuncs.com # 需要在同一个子网下 vers: '3' ``` ## oss 阿里云购买 oss 存储。 id 和密钥: ![在这里插入图片描述](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/oss1.png) oss 地址: ![在这里插入图片描述](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/oss2.png) 配置: ![在这里插入图片描述](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/oss3.png) 配置示例(yaml,对应表单默认值;`akId/akSecret` 会被抽取为 Secret): ```yaml csi: driver: ossplugin.csi.alibabacloud.com akId: xxxx akSecret: xxxx volumeAttributes: url: your-oss-url.aliyuncs.com # 需要在同一个子网下 bucket: XXX-1251707795 path: /osstest ``` ## s3 开放 kubeflow/minio 服务。 ### csi 方式 参考:https://github.com/yandex-cloud/k8s-csi-s3 部署 csi 驱动。 ![在这里插入图片描述](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/csi1.png) 设置 minio 为外部存储: ![在这里插入图片描述](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/minio.png) 配置示例(yaml,对应表单默认值;`accessKeyID/secretAccessKey/endpoint/region` 会被抽取为 Secret): ```yaml csi: driver: ru.yandex.s3.csi accessKeyID: xxxx secretAccessKey: xxxx endpoint: https://xx region: "" volumeAttributes: mounter: geesefs options: "--memory-limit 1000 --dir-mode 0777 --file-mode 0666" bucket: xx ``` ### 另外一种方式 容器中安装插件: ```bash sudo apt-get install -y fuse # 或者 sudo yum install -y fuse wget https://github.com/yandex-cloud/geesefs/releases/latest/download/geesefs-linux-amd64 chmod a+x geesefs-linux-amd64 sudo cp geesefs-linux-amd64 /usr/bin/geesefs ``` 容器尝试挂载: ```bash export AWS_ACCESS_KEY_ID=xxxxx export AWS_SECRET_ACCESS_KEY=xxxxx mkdir /test geesefs --endpoint http://192.168.3.7:9000 test /test ``` ## glusterfs 容器部署 glusterfs 存储: ```bash docker run -d --name gluster \ -v /etc/glusterfs:/etc/glusterfs:z \ -v /var/lib/glusterd:/var/lib/glusterd:z \ -v /var/log/glusterfs:/var/log/glusterfs:z \ -v /sys/fs/cgroup:/sys/fs/cgroup:ro \ -v /dev/:/dev --restart=always \ -v /glusterfs/:/glusterfs \ --privileged=true --net=host \ gluster/gluster-centos docker exec -it gluster bash systemctl status glusterd gluster peer probe 192.168.3.7 # ip为机器ip # gluster volume create testvol localhost:/glusterfs/vol1 force gluster volume create testvol transport tcp 192.168.3.7:/glusterfs/vol1 force gluster volume start testvol gluster volume info echo "aa" >> /glusterfs/vol1/aa # 主机客户端测试 apt -y install glusterfs-client # 或者 yum install -y centos-release-gluster glusterfs glusterfs-fuse mount -t glusterfs 192.168.3.7:/testvol /mnt cat /mnt/aa ``` web 界面配置: ![在这里插入图片描述](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/gfs.png) 配置示例(yaml,对应表单默认值;平台会据此创建 Endpoints/Service 连到 gluster): ```yaml parameters: ip: xx.xx.xx,xx.xx.xx,xx.xx.xx port: 49152 path: testvol # gluster volume create NAME ``` ## cephfs 前提条件:创建 ceph 文件存储。 查看管理密钥: ```bash root@node0:~# cat /etc/ceph/ceph.client.admin.keyring [client.admin] key = <密钥> caps mds = "allow *" caps mgr = "allow *" caps mon = "allow *" caps osd = "allow *" ``` 如果 ceph 为单独文件存储机器,需要复制以下两个文件到 CubeStudio 管理节点: ```bash scp cephserverip:/etc/ceph/ceph.conf /etc/ceph/ scp cephserverip:/etc/ceph/ceph.client.admin.keyring /etc/ceph/keyring ``` ![在这里插入图片描述](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/bfab16310255423bb205b29974743e0e.png) 在配置处,将 `ceph.client.admin.keyring` 的用户名、key 填写在配置当中: - Monitors:监视器 `cephserverip:6789` - Path:ceph 文件存储路径 - 集群:选择对应集群,集群中才会创建 ceph pv 配置示例(yaml,对应表单默认值;`key` 会被抽取为 Secret): ```yaml parameters: user: admin # ceph认证用户 key: 秘钥 monitors: xx.xx.xx:6789,xx.xx.xx:6789,xx.xx.xx:6789 # ceph集群mon节点 path: / ``` ![在这里插入图片描述](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/787e16de6bfa438fbdaa43a28b71dc3f.png) ceph 配置填写完毕,点击挂载: ![在这里插入图片描述](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/c874fc28cbd5439f874ca3c22ea6d54f.png) ![在这里插入图片描述](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/f26093b6a9ad480c816c7477ca185aad.png) 点击 ceph 名称: ![在这里插入图片描述](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/fb543146b38b41e0971e836630f14b9b.png) 可以看到已经存在 `xxxx-ceph` 的 pv: ![在这里插入图片描述](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/42ca58fadef94eebb0c5c9f125b1d7c0.png) Public 项目分组下的集群为 dev(项目组与挂载配置见 [项目空间](../01-入门与权限/项目空间.md)): ![在这里插入图片描述](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/353c9e85ad4c4c669f6262d31e92517a.png) 修改项目分组下的挂载: ![在这里插入图片描述](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/092a96009c3146d498182aa223576519.png) 选择上方添加挂载的项目组: ![在这里插入图片描述](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/d2d4a03131da4036909df2b07080e98f.png) 等待 notebook 状态 running,点击名称进入 notebook: ![在这里插入图片描述](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/87edac6dc0cc42a1b73eb0766eab7ce8.png) `df -h` 可以看到已经添加 `/ceph` 的挂载。 --- ### 机器资源配置 - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/02-%E8%B5%84%E6%BA%90%E4%B8%8E%E5%AD%98%E5%82%A8/%E6%9C%BA%E5%99%A8%E8%B5%84%E6%BA%90%E9%85%8D%E7%BD%AE - 分类: 平台使用 / 资源与存储 - 适用场景: 想了解机器资源从哪来、如何配置某台机器是否允许 CPU/GPU/vGPU/RDMA 调度、归属哪个资源组时读这篇 - 关键词: 机器资源 / 节点 / node / 机器 / 调度 / CPU调度 / GPU调度 / vGPU / RDMA / gpu_type / gpu卡型 / 资源组 / org / 节点标签 / node label / 可调度标签 / K8S Dashboard / 集群扫描 - 最后更新: 2026-07-04 # 机器资源 机器资源不是手动添加的,而是平台主动扫描集群(每次进入机器资源列表会拉取各 `CLUSTERS` 集群的节点信息并写入/更新数据库 `node` 表,见 `myapp/views/view_resource_node.py` 的 `pre_list_req`),所以界面上没有“新增机器资源”的按钮(`base_permissions` 仅含 `can_show / can_edit / can_list / can_delete`,无 `can_add`)。 > 集群、GPU 驱动、节点加入等基础设施准备属于管理员/集群准备工作,参见 [02-部署安装](../../02-部署安装/) 段。 ## 可配置的调度属性 已发现的机器资源可以配置以下调度相关属性(界面“调度配置”分组,对应 `node` 表字段;底层会把这些配置写回 k8s 节点 label,见 `view_resource_node.py` 的 `pre_update`): - `enable_cpu`:是否允许 CPU 任务调度(label `cpu`,默认 `true`)。 - `enable_gpu`:是否允许 GPU 任务调度(label `gpu`,默认 `true`)。 - `enable_vgpu`:是否允许 vGPU 任务调度(label `vgpu`,默认 `false`)。启用 vGPU 时会自动关闭 GPU 独占(`enable_gpu` 置为 `false`)。 - `enable_rdma`:是否允许 RDMA 任务调度(label `rdma`,默认 `false`)。 - `gpu_type`:GPU 卡型(label `gpu-type`),可选 `T4 / V100 / A10 / A100 / A800 / H100 / H800`,也支持手动输入。 - `org`:资源组(label `org`,默认 `public`),一台机器只能归属一个资源组,由项目组通过它控制调度目标,详见 [项目空间](../01-入门与权限/项目空间.md)。 - `worker_type`:机器允许的任务类型,可多选 `notebook / train / service`。 “属性配置”分组还可配置 `gpu_memory`(单卡显存 GB)、`gpu_price`(单卡每小时价格)、`rental_type`(租赁类型)等扩展属性。 ![输入图片说明](https://foruda.gitee.com/images/1698589506624949017/476e5a90_1019082.png "屏幕截图") ![输入图片说明](https://foruda.gitee.com/images/1698589553500056021/1ba18ef7_1019082.png "屏幕截图") ## 在 K8S Dashboard 中修改 除了在 CubeStudio 界面上修改,还可以在 k8s dashboard 中直接修改节点 label。从 CubeStudio 的“项目空间” -> “链接(管理员)” -> “K8S Dashboard” 可以进入。 ![输入图片说明](https://foruda.gitee.com/images/1698589633421290443/37ee1ff1_1019082.png "屏幕截图") ![输入图片说明](https://foruda.gitee.com/images/1698589756035081262/2ca1506c_1019082.png "屏幕截图") --- ### 机器/算力租赁(rental) - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/02-%E8%B5%84%E6%BA%90%E4%B8%8E%E5%AD%98%E5%82%A8/%E6%9C%BA%E5%99%A8%E7%A7%9F%E8%B5%81 - 分类: 平台使用 / 资源与存储 - 适用场景: 想把 GPU/算力以"租赁实例"的形式按量或按天租给用户使用、或想了解租赁实例与 Notebook 的区别、计费方式时读这篇 - 关键词: 机器租赁 / 算力租赁 / rental / 租赁实例 / ENABLE_RENTAL / 按量计费 / 按天计费 / on_demand / daily / 单卡 / 整机 / single_gpu / whole_machine / 单卡价格 / price_per_hour / 自动续费 / auto_renew / 泛域名 / 租赁卡片 - 最后更新: 2026-06-30 # 机器/算力租赁(rental) 租赁是一个独立的算力售卖模块:用户以"租赁实例"的形式按量或按天租用一段算力(含 GPU), 每个租赁实例是**独立于 Notebook 的独立 Pod**,通过泛域名访问。 默认关闭,需配置 `ENABLE_RENTAL=True`(`myapp/config.py:786`)开启。 > 后端:模型 `myapp/models/model_rental_instance.py`,视图 `myapp/views/view_rental.py`。 ## 租赁实例的关键属性 | 字段 | 取值 | 含义 | |---|---|---| | `rental_type` | `single_gpu` / `whole_machine` | 租赁类型:单卡 / 整机 | | `charge_mode` | `on_demand` / `daily` | 计费方式:按量计费 / 按天计费 | | `price_per_hour` | 数值 | 每小时单价(按量计费用) | | `price_text` | 文本 | 价格描述文本(展示用) | | `auto_renew` | true/false | 是否自动续费 | | `image_category` | `ide` / `dev` / `model_market` / `inference` / `custom` | 实例运行的镜像类目(在线 IDE / 开发 / 模型市场应用 / 推理 / 自定义) | | `resource_cpu` / `resource_memory` / `resource_gpu` | — | 申请的 CPU / 内存 / GPU | - **计费**:按量计费按使用时长 × `price_per_hour`;**按天计费的费用从账单 `Bill` 表读取** (见 `model_rental_instance.py:233-240`),与计量计费体系打通。 - **镜像类目** `image_category` 决定实例跑什么:如 `ide` 跑在线 IDE(jupyter 等)、`model_market` 跑 AIHub 应用、 `inference` 跑推理,具体配置存在 `image_config`(JSON)里。 ## 使用方式(界面) 1. 管理员开启 `ENABLE_RENTAL` 并准备好可租赁的镜像/资源。 2. 用户在租赁页选择租赁类型(单卡/整机)、计费方式(按量/按天)、镜像类目与资源规格,创建租赁实例。 3. 平台拉起独立 Pod,并分配泛域名访问入口;按所选计费方式计费,可选自动续费。 4. 费用与账单在[计量计费](../10-计量计费/计量计费.md)中查看(按天计费走 `Bill` 表)。 > 字段默认值/完整生命周期以 `myapp/models/model_rental_instance.py`、`myapp/views/view_rental.py` 为准。 > 多租户开启时,租赁实例同样按租户隔离,见 [多租户隔离.md](../../04-运维管理/多租户隔离.md)。 --- ### 整体资源(全局资源视角与 Pod 管理) - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/02-%E8%B5%84%E6%BA%90%E4%B8%8E%E5%AD%98%E5%82%A8/%E6%95%B4%E4%BD%93%E8%B5%84%E6%BA%90 - 分类: 03-平台使用 / 资源与存储 - 适用场景: 想从全局视角查看集群机器资源占用/使用率、查看平台所有 Pod、或批量删除 Pod 时读这篇 - 关键词: 整体资源 / total_resource / 全局资源 / 资源占用率 / 资源使用率 / cpu占用率 / 内存占用率 / pod批量删除 / grafana / 节点监控 / GPU监控 / node / cluster resource - 最后更新: 2026-06-30 # 整体资源 入口:左侧菜单 **服务化 - 整体资源**。 > 说明:该入口对应后端视图 `view_total_resource`,前端 URL 为 `/total_resource/api/`,菜单挂在"服务化"分组下。依据 `myapp/views/home.py:463-470`、`myapp/views/view_total_resource.py`。 该页面包含整体的资源量、占用率、使用率,以及平台中的所有 Pod。管理员还可以选中 Pod 进行批量删除。 > 说明:表格按"集群 / 资源组 / 机器 / 机型 / cpu占用率 / 内存占用率"等列展示各节点的资源情况。依据 `myapp/views/view_total_resource.py:74-76`。Pod 批量删除受权限控制,仅管理员可执行(`myapp/views/view_pod.py:107` 处对非管理员返回"仅管理员可批量删除")。 ![整体资源页面](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/ziyaun1.jpg) 同时该界面会展示每台机器的当前资源占用情况和资源配置情况。 ![每台机器资源占用](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/ziyuan2.jpg) # 快捷入口 快捷入口见上图中,可直接跳转到 Grafana 看板查看更细粒度的监控数据。 机器(节点)的资源使用情况: ![grafana 节点监控1](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/grafana-node1.png) ![grafana 节点监控2](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/grafana-node2.png) GPU 资源的使用情况: ![grafana GPU监控](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/grafana-gpu.png) --- 监控看板(Grafana / Prometheus)的部署与配置,详见运维管理段的 [监控部署与看板](../../04-运维管理/监控部署与看板.md)。 --- ### 在线 IDE(Notebook / VSCode / RStudio / Matlab) - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/03-%E5%9C%A8%E7%BA%BF%E5%BC%80%E5%8F%91/%E5%9C%A8%E7%BA%BFIDE - 分类: 03-平台使用 / 在线开发 - 适用场景: 创建/使用在线开发环境(Jupyter、VSCode、RStudio、Matlab),SSH 远程连接、端口预留、环境持久化、定时清理与续期等问题时读这篇 - 关键词: 在线IDE / notebook / jupyter / theia / vscode / rstudio / matlab / ssh / ProxyJump / tensorboard / spark / git / NOTEBOOK_PORT / PORT1 / PORT2 / SERVICE_EXTERNAL_IP / ENABLE_JUPYTER_PASSWORD / 镜像保存 / init.sh / 续期 / GPU监控 / vgpu - 最后更新: 2026-07-04 # 在线 IDE 在线开发是一个很重要的功能,对于大部分用户来说,在线的 IDE 比命令行 vim 要方便很多。CubeStudio 主要提供了 VSCode 和 Jupyter 两种在线 IDE,并没有将代码和数据进行分割存储。所以在 Notebook 中打开的就是完全用户自己的代码和数据,可以方便地进行调试。 # VSCode theia 是一个在线 VSCode,更像本地 IDE,主要服务纯代码开发(多实例,一个人可以同时开多个 theia)。 ![在线 VSCode](https://foruda.gitee.com/images/1698243872593119472/3f912994_1019082.png) 工作目录默认是 `/mnt`,归档目录是 `/archives`,可以把一些想永久保存、不易被误删的文件放在归档目录。 ![工作目录与归档目录](https://foruda.gitee.com/images/1698243810130126602/986cfcad_1019082.png) 在 VSCode 里面(本质为 theia),用户跟本地 VSCode 基本一致,可以上传下载文件/文件夹,也可以在 theia 中打开命令行终端。并且其中封装了用户的基本环境需求,比如 Python。 需要说明的是,由于 theia 的功能中有些进程(例如 `rg` 进程)会不停地搜索扫描目录下的所有文件。由于个人目录下包含了用户的代码和数据,文件可能非常多(千万到亿级别的文件数量),这些进程扫描会严重拖慢分布式存储的性能。所以 CubeStudio 做了定时检杀的功能,能够及时检杀 `rg` 和 `git` 进程,提高在线 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 多内核](https://foruda.gitee.com/images/1700470431893562980/b6b581d6_1019082.png "屏幕截图") ## tensorboard 可视化训练 Pro 版本的 Jupyter 有 tensorboard,创建 Notebook 时镜像选择 `jupyter-conda-pro(cpu)`,创建一个 Pro 版本的 Jupyter,运行 `/mnt/$username/pipeline/example/tensorboard/demo.py`,运行结束会产生结果文件。**进入结果文件夹**,此时点击"+"符号,打开 tensorboard,再选择需要进行可视化的文件,即可查看可视化结果,如下图所示。 ![tensorboard 可视化](https://foruda.gitee.com/images/1700469403119416888/229b29c1_1019082.png "屏幕截图") 需要注意的是,集成了 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 = False`;`myapp/views/view_notebook.py:713` 处 `if conf.get('ENABLE_JUPYTER_PASSWORD', False):` 时为 Jupyter 生成登录密码。 ![生成密码](https://foruda.gitee.com/images/1700641436635429563/7a8ae381_13742376.png "屏幕截图") 登录 Jupyter 时需要密码: ![登录需要密码](https://foruda.gitee.com/images/1700641469857970133/ce815430_13742376.png "屏幕截图") # SSH 远程连接 Jupyter 功能 ## 实现原理 Jupyter 版本的 Notebook 中提供了 sshd,会在 Notebook 创建时自动启动 ssh-server,并且会自动生成配置文件 `example/ssh链接`。 并为每个 Notebook 的 Pod 配置一个单独的 Service,支持通过 `ip:port` 访问。 端口分配以 `config.py` 的 `NOTEBOOK_PORT` 为准(仓库默认配置为 `10000+2*ID`),平台会在该基准端口上预留多个端口: - `基准端口+0`:IDE Web 服务端口(例如 JupyterLab / Theia / RStudio / Matlab 等) - `基准端口+1`:`sshd` 端口(用于 `ssh` 远程连接,对应环境变量 `SSH_PORT`) - `基准端口+2/+3`:预留给用户在 Notebook 内启动自定义服务(对应环境变量 `PORT1/PORT2`) > 依据(与代码核对):仓库默认 `config.py:1105` 配置为 `NOTEBOOK_PORT='10000+2*ID'`(注释"至少间隔 4");仅当该配置缺失时,代码兜底默认才取 `10000+10*ID`(`myapp/views/view_notebook.py:689`,`conf.get('NOTEBOOK_PORT','10000+10*ID')`)。端口分配的 `+0/+1/+2/+3` 含义与 `view_notebook.py:688` 注释及 `697-699` 行环境变量赋值一致。实际端口以你部署的 `config.py` 取值为准。 需要公司网络能通过 `ip+端口` 的形式访问 Notebook 的服务。 ## 操作方法 按照 `example/ssh链接` 文件中的描述,在本地 `~/.ssh/config` 中添加链接配置: ```bash # 将此文件内容追加到 ~/.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 功能: ```bash 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,连接后在容器命令行执行: ```bash 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。 ```python # 创建 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 按钮](https://foruda.gitee.com/images/1700625376161747633/7cca4151_1019082.png "屏幕截图") 就可以查看日志目录中所包含的训练过程中的信息和模型的信息。 ![tensorboard 展示](https://foruda.gitee.com/images/1700625399923831886/b5932679_1019082.png "屏幕截图") # git 功能 Pro 版本的 Notebook 中可以直接使用 git。比如直接 clone 一个项目到 Notebook 中,修改文件,点击 git 图标,就能直接看到原文件和修改后文件的对比。 ![git 对比](https://foruda.gitee.com/images/1700556250123422883/47bc3a09_1019082.png "屏幕截图") # GPU、CPU、内存监控 图示按钮可帮助用户在 Notebook 中查看资源的使用情况。需要注意的是,只有 GPU 版本的 Notebook 可以在 Notebook 中查看 GPU 监控,其他版本的 Notebook 即使调用了 GPU,也只能在 Grafana 中统一查看 GPU 资源的监控。 ![Notebook 内资源监控](https://foruda.gitee.com/images/1700556607536577985/d39c990d_1019082.png "屏幕截图") # Jupyter 多内核态 在使用自定义 Notebook 时,需要注意安装包时应该先激活对应的环境,然后再进行安装。这是因为 Jupyter 的内核和 conda 环境是两个不同的概念,需要分别进行管理。 # 在线 IDE 的资源占用问题 CubeStudio 采用的方案是只设置 Notebook 的 Pod 的 limit,而不设置 request。这种方案就对资源不进行独占,这样也就不用清理 Notebook,只是允许了 Notebook 中的资源干扰。 GPU 的占用方式上,允许独占、共享、VGPU 三种方式。GPU 申请(单位卡)示例:填写 `1`、`2`,表示训练任务每个容器独占整卡;填写 `-1` 为共享占用方式;填写小数(`0.1`)为 vGPU 方式;申请具体的卡型号可以类似 `1(V100)`,目前支持 T4 / V100 / A100。 ![GPU 申请方式](https://foruda.gitee.com/images/1700462101834532478/ec41b8e4_1019082.png "屏幕截图") # 在线 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.sh`(`myapp/views/view_notebook.py:558`、`708`)。 ![Notebook 镜像保存](https://foruda.gitee.com/images/1698246135763665129/4e3cf860_1019082.png) # 多实例的 VirtualService 代理 多实例在线 IDE 图示: ![多实例在线 IDE](https://foruda.gitee.com/images/1698246617512815761/61778e9d_1019082.png) 每个用户可以配置多个在线 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](https://foruda.gitee.com/images/1698246688418232136/6eca90a7_1019082.png) 名为 `admin-e00f` 的在线 IDE 的 URL prefix: ![URL prefix 示例2](https://foruda.gitee.com/images/1698246746628457173/19975029_1019082.png) # 在线 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_notebook` 在 `myapp/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.py` 的 `renew`)。 ![续期按钮](https://foruda.gitee.com/images/1700641494907558934/b28e605e_13742376.png "屏幕截图") --- 集群级 GPU / 节点资源监控统一在 Grafana 查看,参见 [整体资源](../02-资源与存储/整体资源.md) 与运维管理段的 [监控部署与看板](../../04-运维管理/监控部署与看板.md)。 --- ### 在 Notebook 镜像中部署本地大模型版 Claude Code - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/03-%E5%9C%A8%E7%BA%BF%E5%BC%80%E5%8F%91/notebook%E9%83%A8%E7%BD%B2ClaudeCode - 分类: 03-平台使用 / 在线开发 - 适用场景: 想在自定义 Notebook 镜像里安装 Claude Code 并接入私有/兼容 Anthropic 协议的大模型(DeepSeek、Qwen 等)时读这篇 - 关键词: Claude Code / claude / notebook / Dockerfile / claude-wrapper / ANTHROPIC_BASE_URL / ANTHROPIC_AUTH_TOKEN / ANTHROPIC_DEFAULT_HAIKU_MODEL / ANTHROPIC_DEFAULT_SONNET_MODEL / ANTHROPIC_DEFAULT_OPUS_MODEL / 大模型 / deepseek / qwen / settings.json / 镜像构建 - 最后更新: 2026-07-04 # 在 Notebook 镜像中使用本地大模型部署 Claude Code 的方法 > 本文是一份镜像构建 + 使用配方:在 Notebook 镜像里安装 Claude Code 原生二进制,并通过包装脚本 `claude-wrapper.sh` 引导用户接入 Anthropic 兼容协议(`/v1/messages`)的大模型端点。镜像的在线构建与推送方式可参考 [镜像在线构建和管理](../04-镜像构建与仓库/镜像在线构建和管理.md);私有仓库地址/账号配置参考 [镜像仓库](../04-镜像构建与仓库/镜像仓库.md)。 > > 提示:平台官方 Notebook / Theia 镜像的 Dockerfile(仓库 `images/jupyter-notebook/Dockerfile-ubuntu-base`、`Dockerfile-ubuntu-conda`,以及 `images/theia-new/Dockerfile-*`)已内置下文"一、构建镜像"中的安装与包装脚本步骤,仓库也自带 `images/jupyter-notebook/claude-wrapper.sh`。若直接使用官方镜像,可跳过构建、直接进入"二、在 Notebook 中使用";本文构建步骤主要面向自定义镜像或需要更新 Claude Code 版本的场景。 ## 一、构建镜像 ### 1. 安装 Claude Code 原生二进制 基于当前的镜像,在 Dockerfile 中加入以下内容,把 Claude Code 安装到镜像环境中: ```dockerfile # 安装 Claude Code 原生二进制 RUN BASE=https://downloads.claude.ai/claude-code-releases && \ VERSION=$(curl -fsSL "$BASE/latest") && \ if [ "$TARGETARCH" = "amd64" ]; then PLATFORM=linux-x64; else PLATFORM=linux-arm64; fi && \ EXPECTED=$(curl -fsSL "$BASE/$VERSION/manifest.json" | python3 -c "import json,sys; print(json.load(sys.stdin)['platforms']['$PLATFORM']['checksum'])") && \ curl -fsSL -o /usr/local/bin/claude.real "$BASE/$VERSION/$PLATFORM/claude" && \ ACTUAL=$(sha256sum /usr/local/bin/claude.real | cut -d' ' -f1) && \ [ "$EXPECTED" = "$ACTUAL" ] || { echo "checksum mismatch: $EXPECTED vs $ACTUAL" >&2; exit 1; } && \ chmod +x /usr/local/bin/claude.real && \ echo "claude $VERSION ($PLATFORM) installed" ``` ### 2. 拷贝 claude-wrapper.sh 将 `claude-wrapper.sh` 拷贝到镜像中。为了后续运行方便,覆盖掉默认的 `claude` 命令: ```dockerfile # 拷贝 claude 包装脚本到 /usr/local/bin/claude # (首次启动引导用户配置私有大模型 settings.json) COPY claude-wrapper.sh /usr/local/bin/claude RUN chmod +x /usr/local/bin/claude ``` ![Dockerfile 构建](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/1fb2e28a9f4c916a4d62f2515796031f.png) ## 二、在 Notebook 中使用 ### 1. 创建 Notebook 构建完成镜像之后,在 Notebook 中点击添加 Notebook,镜像处填写您新构建的镜像名,并配置运行此 Notebook 所需要的 CPU、内存等。 ![创建 notebook](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/7f52af5cfb687fd6d25f7b23f74795fb.png) ### 2. 等待 Pod 启动 点击确定后,等待状态变为 `Running`。也可以点击 `ContainerCreating` 主动查看 Pod 当前的状态和日志情况。 ![等待 Pod 启动](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/f0bb0e6ca8078b5bc751010b835c22d0.png) ### 3. 进入终端 `Running` 之后,您可点击进入 Notebook,然后点击终端。 ![进入终端](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/0ab63a772d75534fff61720e334280b2.png) ### 4. 配置大模型 在命令行中输入 `claude` 命令启动脚本,按照脚本提示进行操作。 > **注意:** API Key 会隐藏输入信息,您可以直接粘贴即可。 例如,以 DeepSeek 模型为例: - 使用官方提供的 ANTHROPIC URL:`https://api.deepseek.com/anthropic` - 使用官方推荐的模型名称:`deepseek-v4-pro[1m]` 例如 Qwen: - ANTHROPIC URL:`https://dashscope.aliyuncs.com/apps/anthropic` - Haiku 模型名:`qwen3.6-flash` - Sonnet 模型名:`qwen3.6-plus` - Opus 模型名:`qwen3.6-plus` > 说明:以上模型名(`deepseek-v4-pro[1m]`、`qwen3.6-*`)与端点 URL 均为示例,请以你实际接入的大模型厂商提供的 Anthropic 兼容端点和模型名为准。原文此处第三行误写为"Haiku 模型名",按包装脚本三个槽位(Haiku / Sonnet / Opus)应为 **Opus 模型名**,已据此更正。 填写完成后将自动启动 claude。 ![配置大模型](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/b34a1fbf02fd9a5a00c1d7befd1aa40c.png) ### 5. 开始对话 您可以在对话框中直接与 claude 对话,会使用您配置的大模型进行对话。 ![开始对话](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/bccfd52fa60a108f4b31747ef4595dc3.png) ### 6. 配置持久化 此配置会在您的 CubeStudio 用户个人目录中留下配置文件,您重启此 Notebook 后仍然可以直接使用 claude。 ![配置持久化1](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/ee891097ea8e6a93df480abc34aec369.png) ![配置持久化2](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/809e3692853aac34480bcb1c6fc8c1ea.png) ### 7. 重置配置 若需要删除配置文件、重新进行配置,您可以在终端中运行以下命令删除可能存在的缓存文件,然后再次输入 `claude` 运行: ```bash rm -f /mnt/admin/.settings.json rm -f /root/.claude/settings.json ``` > 说明:上面的 `/mnt/admin/.settings.json` 中的 `admin` 是用户名示例,实际为 `/mnt/$USERNAME/.settings.json`(包装脚本中的 `USER_SETTINGS`);`/root/.claude/settings.json` 对应 `${HOME:-/root}/.claude/settings.json`(`CLAUDE_SETTINGS`)。 ![重置配置](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/5fcd5bb9e58ade488cf2d45b4a36f121.png) ## 附:claude-wrapper.sh ```bash #!/bin/bash # Claude Code 启动包装脚本:自动从用户目录加载/生成 settings.json # 后端必须是 Anthropic 兼容协议 (/v1/messages),例如官方 Claude API、 # Bedrock 代理或已做过协议转换的网关 set -e # ---------- 1. 解析用户目录 ---------- USER_DIR="/mnt/${USERNAME}" if [ -z "${USERNAME}" ] || [ ! -d "${USER_DIR}" ]; then if [ -d /mnt ] && [ "$(ls /mnt 2>/dev/null | wc -l)" = "1" ]; then USER_DIR="/mnt/$(ls /mnt)" else echo "[claude-wrapper] 无法定位用户目录 (\$USERNAME 未设置且 /mnt 下非唯一目录)" >&2 exec /usr/local/bin/claude.real "$@" fi fi USER_SETTINGS="${USER_DIR}/.settings.json" CLAUDE_DIR="${HOME:-/root}/.claude" CLAUDE_SETTINGS="${CLAUDE_DIR}/settings.json" mkdir -p "${CLAUDE_DIR}" # ---------- 2. 已有配置 -> 直接复用 ---------- if [ -f "${USER_SETTINGS}" ]; then cp -f "${USER_SETTINGS}" "${CLAUDE_SETTINGS}" exec /usr/local/bin/claude.real "$@" fi # ---------- 3. 引导用户输入 ---------- echo "================================================================" echo " 首次启动 Claude Code,请配置大模型接入参数 (Anthropic 兼容端点)" echo " 配置完成后将保存到: ${USER_SETTINGS}" echo "================================================================" read -r -p "ANTHROPIC_BASE_URL (示例: https://api.anthropic.com): " BASE_URL read -r -p "Haiku 模型名 (ANTHROPIC_DEFAULT_HAIKU_MODEL): " HAIKU_MODEL read -r -p "Sonnet 模型名 (ANTHROPIC_DEFAULT_SONNET_MODEL): " SONNET_MODEL read -r -p "Opus 模型名 (ANTHROPIC_DEFAULT_OPUS_MODEL): " OPUS_MODEL read -r -s -p "API Key (ANTHROPIC_AUTH_TOKEN): " API_KEY echo "" if [ -z "${BASE_URL}" ] || [ -z "${HAIKU_MODEL}" ] || [ -z "${SONNET_MODEL}" ] || [ -z "${OPUS_MODEL}" ] || [ -z "${API_KEY}" ]; then echo "[claude-wrapper] 五项配置均不能为空,已退出。" >&2 exit 1 fi # 通过环境变量传给 python (heredoc 加单引号禁用 shell 展开),避免值含特殊字符破坏 JSON ANTHROPIC_AUTH_TOKEN="${API_KEY}" \ ANTHROPIC_BASE_URL="${BASE_URL}" \ ANTHROPIC_DEFAULT_HAIKU_MODEL="${HAIKU_MODEL}" \ ANTHROPIC_DEFAULT_SONNET_MODEL="${SONNET_MODEL}" \ ANTHROPIC_DEFAULT_OPUS_MODEL="${OPUS_MODEL}" \ python3 - > "${USER_SETTINGS}" <<'PYEOF' import json, os print(json.dumps({ "env": { "ANTHROPIC_AUTH_TOKEN": os.environ["ANTHROPIC_AUTH_TOKEN"], "ANTHROPIC_BASE_URL": os.environ["ANTHROPIC_BASE_URL"], "ANTHROPIC_DEFAULT_HAIKU_MODEL": os.environ["ANTHROPIC_DEFAULT_HAIKU_MODEL"], "ANTHROPIC_DEFAULT_SONNET_MODEL": os.environ["ANTHROPIC_DEFAULT_SONNET_MODEL"], "ANTHROPIC_DEFAULT_OPUS_MODEL": os.environ["ANTHROPIC_DEFAULT_OPUS_MODEL"], "API_TIMEOUT_MS": "3000000" } }, indent=4, ensure_ascii=False)) PYEOF chmod 600 "${USER_SETTINGS}" cp -f "${USER_SETTINGS}" "${CLAUDE_SETTINGS}" chmod 600 "${CLAUDE_SETTINGS}" echo "[claude-wrapper] 配置已保存到 ${USER_SETTINGS}" echo "[claude-wrapper] 下次输入 claude 将直接启动,无需再次配置。" echo "------------------------------------------------------------------" exec /usr/local/bin/claude.real "$@" ``` --- 镜像构建与推送的更多说明,参见 [镜像在线构建和管理](../04-镜像构建与仓库/镜像在线构建和管理.md) 与 [镜像仓库](../04-镜像构建与仓库/镜像仓库.md)。Notebook 的创建、镜像保存等通用操作见 [在线 IDE](./在线IDE.md)。 --- ### cube-studio Python SDK 使用 - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/03-%E5%9C%A8%E7%BA%BF%E5%BC%80%E5%8F%91/SDK%E4%BD%BF%E7%94%A8 - 分类: 平台使用 / 在线开发 - 适用场景: 想用 Python 代码(而不是 Web 界面)对接平台,自动化创建/上传数据集、提交任务流、部署推理服务、启动 notebook 时读这篇 - 关键词: SDK / cubestudio / python sdk / Client / init / token / 数据集 / dataset / 推理 / inference / InferenceService / 任务 / task / pipeline / notebook / 编程接口 / API / 自动化 - 最后更新: 2026-07-04 # cube-studio Python SDK 使用 平台提供了 `cubestudio` Python SDK,可以用代码方式对接平台的**数据集、任务(任务流)、推理服务、notebook** 等模块,实现自动化操作。 > 代码核实依据:SDK 源码位于 `aihub/src/cubestudio/`,本文涉及的接口路径、方法名均与该目录下 `request/model_client.py`、`request/model.py`、`dataset/dataset.py`、`train/task.py` 对照核实。 ## 一、安装与引入 SDK 随平台镜像(如 notebook 镜像)内置。如在 notebook 中使用,需要先 `source` 到对应的 notebook 内核环境,才能正常使用对应内核的 SDK 与依赖: ```bash # 在同一行命令中先 source 环境名(base, python27, python36, python37, python38, python39, python310, CubeStudio), # 才能把包 pip 安装到指定虚拟环境。不清楚有哪些环境时,可用 conda info --envs 查看。 !source activate cube-studio && pip install pandas ``` 引入基础包: ```python import json, os, time, shutil from cubestudio.request.model_client import Client, init from cubestudio.dataset.dataset import Dataset ``` ## 二、初始化客户端 所有操作前必须先调用 `init(host, username, token)` 初始化全局连接信息。 ```python HOST = 'http://xx.xx.xx.xx' # 平台访问地址 token = '' # 当前用户的访问 token(见下文“token 获取”) username = 'admin' # 与 token 对应的用户名 init(host=HOST, username=username, token=token) ``` 初始化逻辑(`request/model_client.py` 的 `init`): - 用 `token` 作为 `Authorization` 请求头,向 `/users/api/` 发起查询,按 `username` 过滤,验证 token 与用户名是否匹配;匹配成功打印“初始化验证成功”,否则抛出 `token和用户名不匹配`。 - 验证通过后,会预先实例化一批内置 Client:`Images / Project / Pipeline / Repository / Workflow / Task / Job_Template / MyUser / User / Notebook / InferenceService`。 ### token 获取 token 即平台为每个用户生成的访问密钥(用户模型的 `secret` 字段,是用 `JWT_PASSWORD` 签名的 JWT,去掉了固定的 HS256 头,仅保留 `payload.signature` 两段,见 `myapp/security.py:155-174`)。请求时放入 `Authorization` 请求头即可(`myapp/security.py:649-677` 的 `load_user_from_header` 负责解析)。 > 在平台“用户管理 / 个人信息”页面可查看到当前用户的 token。用户与角色相关说明见 [01-入门与权限](../01-入门与权限/) 段。 ## 三、数据集 SDK 可以用代码自动上传数据集到平台,用于训练和推理等。数据集对象对应服务端接口 `/dataset_modelview/api`(`dataset/dataset.py:17`)。 ### 定义/获取一个数据集 ```python # one() 按字段过滤取一条;不存在则用 add() 新建 dataset = Client(Dataset).one(name="coco") if not dataset: dataset = Client(Dataset).add( name='coco', version='v2014', label='coco未标注数据集', describe='来自于2014年数据,未标注的coco数据集', icon='https://pic2.zhimg.com/80/v2-399df41d8562f8f09b98d288b97c8f8d_1440w.webp', ) ``` ### 压缩、加密、上传数据集 ```python features = json.dumps(json.load(open('coco/coco.json')), indent=4, ensure_ascii=False) dataset = dataset.update(path='', features=features) # 更新数据集元信息 # 压缩:compress(zip_path, compress_dir),把 compress_dir 目录打包为 zip dataset.compress('coco.zip', 'vision/coco') # 加密:encrypt(file_path, save_path, key) dataset.encrypt('coco.zip', "coco.zip.crypt", key) # 上传:upload(file_path_list, partition=''),可指定分区 dataset.upload('coco.zip.crypt', partition='20230201') ``` > 说明:`encrypt/decrypt` 使用 `cryptography.fernet.Fernet(key)` 做对称加解密(`dataset/dataset.py:63-97`),`key` 需为 Fernet 密钥(如 `from cryptography.fernet import Fernet; key = Fernet.generate_key()`),加解密两端需使用同一 key。 ### 下载、解密、解压数据集 ```python # 清理本地旧文件 os.remove('coco.zip.crypt') if os.path.exists('coco.zip.crypt') else '' os.remove('coco.zip') if os.path.exists('coco.zip') else '' shutil.rmtree('coco') if os.path.exists('coco') else '' dataset.download(partition='20230201') # 按分区下载(默认下到当前工作目录) dataset.decrypt("coco.zip.crypt", 'coco.zip', key) # 解密 dataset.decompress('coco.zip', 'coco') # 解压到 coco 目录 ``` 数据集方法一览(`dataset/dataset.py`):`download(partition='', des_dir=None)`、`upload(file_path_list, partition='')`、`compress(zip_path, compress_dir)`、`decompress(zip_path, extract_dir=None)`、`encrypt(file_path, save_path, key)`、`decrypt(file_path, save_path, key)`。 ## 四、推理 SDK 引入基础包: ```python import time, json from cubestudio.request.model_client import Client, init from cubestudio.train.task import InferenceService, Project ``` 初始化客户端(同上 `init(...)`),然后添加一个 inferenceservice: ```python inferenceservice = Client(InferenceService).add_or_update( service_type='serving', project=Client(Project).one(name='public'), label='sdk创建inference service', model_name='nginx', model_version='v202300801', images='nginx', resource_memory='2G', resource_cpu='2', resource_gpu='0', min_replicas='1', max_replicas='1', ports='80', volume_mount='kubeflow-user-workspace(pvc):/mnt', working_dir='', command='', env='', ) ``` 部署推理服务: ```python print(json.dumps(inferenceservice.to_dict(), indent=4)) if inferenceservice.model_status != 'online': inferenceservice.deploy() ``` `InferenceService` 对应服务端 `/inferenceservice_modelview/api`,`deploy()` 实际请求 `/inferenceservice_modelview/api/deploy/prod/{id}`(`train/task.py:136-148`)。 ## 五、训练(任务流)SDK 如在 notebook 中使用需先 source 到对应内核环境(同第一节)。引入基础包: ```python from cubestudio.request.model_client import Client, init from cubestudio.train.task import Job_Template, Project, Pipeline, Task import json ``` 初始化客户端后: ### 添加一个画布(pipeline) ```python pipeline = Client(Pipeline).add_or_update( name=f'{username}-default', describe='sdk画布', project=Client(Project).one(name='public'), ) ``` ### 添加一个任务(task) ```python job_template = Client(Job_Template).one(name="自定义镜像") task = Client(Task).add_or_update( name='sdk-test1', label='sdk发起的任务', pipeline=pipeline, job_template=Client(Job_Template).one(name="自定义镜像"), timeout=3600, retry=0, args=json.dumps({ "images": "ubuntu:20.04", "command": 'for i in {1..50}; do date; sleep 1; done', "workdir": "/", }), ) ``` ### 运行 / 跟踪日志 / 关闭任务 ```python task.run() # 启动任务,请求 /task_modelview/api/run/{id} task.log(follow=True) # 跟踪日志(follow=True 会持续轮询) task.stop() # 关闭任务,请求 /task_modelview/api/clear/{id} ``` 对照 `train/task.py`:`Task` 路径 `/task_modelview/api`,`run()` → `/run/{id}`、`stop()` → `/clear/{id}`、`log()` 读取运行 pod 日志;`Pipeline` 路径 `/pipeline_modelview/api`,`run()` → `/run_pipeline/{id}`。 ## 六、Notebook SDK 引入基础包: ```python import datetime, json, random, time from cubestudio.request.model import Model from cubestudio.request.model_client import Client, init from cubestudio.train.task import Notebook, Project ``` 初始化客户端后,添加一个 notebook: ```python notebook = Client(Notebook).add_or_update( name='sdk-test', project=Client(Project).one(name='public'), describe='sdk创建notebook,并直接提供给其他平台跳转使用', images='ccr.ccs.tencentyun.com/cube-studio/notebook-enterprise:jupyter-ubuntu-machinelearning', volume_mount='kubeflow-user-workspace(pvc):/mnt', image_pull_policy='Always', resource_memory='10G', resource_cpu='10', resource_gpu='0', expand=json.dumps({"root": "examples/Bayesian/bayesian_network.ipynb"}), ) ``` 启动 / 重置 notebook: ```python print(json.dumps(notebook.to_dict(), indent=4)) notebook.reset() # 重置并等待重启成功,完成后打印 JupyterLab 访问地址 ``` > 注意:`Notebook` 的服务端路径是 `/notebook_modelview/sdk`(区别于普通 `*_modelview/api`,见 `train/task.py:112-133`),`reset()` 请求 `/notebook_modelview/sdk/reset/{id}`,启动完成后会按 `expand.root` 拼出 `{HOST}/notebook/jupyter/{name}/lab/tree/{root}` 访问地址。 ## 七、SDK 对象与服务端接口对照表 (依据 `aihub/src/cubestudio/train/task.py`、`dataset/dataset.py` 核实,供导航;具体以源码为准) | SDK 对象 | path | 主要动作方法 → 实际请求 | |---|---|---| | `Project` | `/project_modelview/api` | CRUD(`one/add/add_or_update/...`) | | `Job_Template` | `/job_template_modelview/api` | CRUD | | `Pipeline` | `/pipeline_modelview/api` | `run()` → `/run_pipeline/{id}` | | `Task` | `/task_modelview/api` | `run()` → `/run/{id}`、`stop()` → `/clear/{id}`、`log(follow)` | | `Notebook` | `/notebook_modelview/sdk` | `reset()` → `/reset/{id}` | | `InferenceService` | `/inferenceservice_modelview/api` | `deploy()` → `/deploy/prod/{id}`、`clear()` → `/clear/{id}` | | `Dataset` | `/dataset_modelview/api` | `upload/download/compress/decompress/encrypt/decrypt` | | `Images` | `/images_modelview/api` | CRUD | | `Repository` | `/repository_modelview/api` | CRUD | | `Workflow` | `/workflow_modelview/api` | CRUD | | `MyUser` / `User` | `/users/api` | CRUD(init 即用此接口校验 token) | `Client(ModelClass)` 通用 CRUD 方法(`request/model_client.py` 的 `Model_Client`):`add / update / show / one / search / list / add_or_update / delete / single_action / multi_action`。这些通用编程接口的更深入说明,可参见 [06-二次开发](../../06-二次开发/) 段(后端框架与 API)。 --- ### 手动安装 Hadoop 生态:Spark 配置与测试 - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/03-%E5%9C%A8%E7%BA%BF%E5%BC%80%E5%8F%91/%E6%9C%AC%E5%9C%B0Jupyter%E5%AF%B9%E6%8E%A5Hadoop%E7%94%9F%E6%80%81/01-%E6%89%8B%E5%8A%A8%E5%AE%89%E8%A3%85-Spark%E9%85%8D%E7%BD%AE%E4%B8%8E%E6%B5%8B%E8%AF%95 - 分类: 平台使用 / 在线开发 - 适用场景: 想在 JupyterLab 里手动把 PySpark 跑起来(本地 / 访问 Hive / 提交到 Yarn)时读这篇 - 关键词: Spark / pyspark / findspark / Yarn / yarn-client / spark-submit / spark-defaults / Hive / JupyterLab / Hadoop配置 / core-site / hdfs-site / yarn-site - 最后更新: 2026-07-09 # 手动安装 Hadoop 生态:Spark 配置与测试 > 本文是“基于已有镜像手动安装”路线的第一部分(Spark)。版本号沿用原始教程示例(Spark 3.1.3),如需与集成镜像一致请改用 README 中的版本。Flink 部分见 [02-手动安装:Flink 配置与测试](02-手动安装-Flink配置与测试.md)。 ## 一、启动基础容器 基于 `ccr.ccs.tencentyun.com/cube-studio/notebook:jupyter-ubuntu-cpu-base` 镜像启动 JupyterLab: ```shell docker run --name jupyter -p 3000:3000 -p 32788-32888:32788-32888 \ -d ccr.ccs.tencentyun.com/cube-studio/notebook:jupyter-ubuntu-cpu-base \ jupyter lab \ --notebook-dir=/ --ip=0.0.0.0 --no-browser --allow-root \ --port=3000 --NotebookApp.token='' --NotebookApp.password='' \ --NotebookApp.allow_origin='*' ``` 注意:增加映射端口范围 `32788-32888`,用于下文提交 Spark 作业到 Yarn 运行。 > 注意:当前商业版源码使用的基础镜像名为 `notebook-enterprise:jupyter-ubuntu-cpu-base`(见 `images/jupyter-notebook/bigdata/Dockerfile:1`)。如使用商业版仓库,请把上面镜像名中的 `notebook` 替换为 `notebook-enterprise`。 ## 二、安装配置 Spark ### 2.1 上传 Hadoop 集群配置文件 提交 Spark 作业到 Yarn 需要 Hadoop 集群的配置文件:`core-site.xml`、`hdfs-site.xml`、`yarn-site.xml`。如果没有 Hadoop 集群,可参考 [04-其他辅助文档](04-其他辅助文档.md) 搭建单机伪分布式集群测试。 在 JupyterLab 新建 Terminal 执行: ```shell # 新建 HADOOP_CONF_DIR 目录 mkdir -p /opt/third/hadoop/etc/hadoop/ ``` 在 Web 界面中上传 3 个 xml 到 `/opt/third/hadoop/etc/hadoop/` 目录下。 注意检查 `yarn-site.xml` 一定要有 `yarn.resourcemanager.address` 配置项,否则默认值是 `0.0.0.0:8032`,会导致 JupyterLab 中的作业无法提交到 Yarn。示例: ```xml yarn.resourcemanager.address xxx.xxx.xxx.xxx:8032 ``` ### 2.2 下载配置 Spark 参考 [Spark 官网](https://spark.apache.org/docs/3.1.3/api/python/getting_started/install.html#dependencies),安装方式本质上有两种:一是 `pip install pyspark`,二是手动下载 Spark 安装包。第一种针对 Apache Spark 快速简单,但不支持其他大数据厂商的 Spark(如华为 FusionInsight、星环 TDH、Cloudera CDH)。因此本教程采用第二种,扩展性好、各厂商通用。 **下载安装包** ```shell cd /opt/third # 下载安装包 wget http://dlcdn.apache.org/spark/spark-3.1.3/spark-3.1.3-bin-hadoop3.2.tgz # 解压,建立软连接 tar -xvzf spark-3.1.3-bin-hadoop3.2.tgz ln -s spark-3.1.3-bin-hadoop3.2 spark ``` **设置环境变量** ```shell vi ~/.bashrc # hadoop export HADOOP_CONF_DIR=/opt/third/hadoop/etc/hadoop # spark export SPARK_HOME=/opt/third/spark export PATH=$PATH:$SPARK_HOME/bin export PYTHONPATH=$(ZIPS=("$SPARK_HOME"/python/lib/*.zip); IFS=:; echo "${ZIPS[*]}"):$PYTHONPATH source ~/.bashrc ``` **配置 spark-defaults.conf** ```shell cd /opt/third/spark/conf mv spark-defaults.conf.template spark-defaults.conf # 增加 spark 作业配置项 vi spark-defaults.conf ``` 输入以下内容: ```shell spark.ui.enabled=false spark.driver.port=32788 spark.blockManager.port=32789 spark.driver.bindAddress=0.0.0.0 spark.driver.host=xxx.xxx.xxx.xxx ``` 其中 `spark.driver.host` 是宿主机的 IP 地址,`spark.driver.port`、`spark.blockManager.port`(32788、32789)是启动容器时增加的映射端口。两个参数: - `spark.driver.port`:driver 监听来自 executor 请求的端口,executor 启动时要跟 driver 通信、获取任务信息。 - `spark.blockManager.port`:driver 和 executor 进行数据传输的端口。 ### 2.3 安装 findspark 参考 [pyspark 开发环境搭建](https://blog.csdn.net/syani/article/details/72851425),在 notebook 中加载 spark 依赖包有三种方案: 1. **使用 findspark 库自动识别 spark 依赖包**: ```python import findspark findspark.init() ``` 2. **动态加载依赖文件**: ```python os.environ['SPARK_HOME'] = "/opt/third/spark" sys.path.append("/opt/third/spark/python") sys.path.append("/opt/third/spark/python/lib/py4j-0.10.9-src.zip") ``` 3. **设置环境变量**:`SPARK_HOME` 和 `PYTHONPATH`(上文已设置,但在 notebook 中不生效,放弃此法)。 第二种方法对用户成本过高,因此本文采用 findspark: ```shell pip install findspark ``` ### 2.4 修改 python3 的软链接 当前 `python3 -> python3.6*`,要把 `python3` 链接到 `python3.8*`: ```shell cd /usr/bin rm -rf python3 ln -s python3.8* python3 ``` ## 三、测试 Spark 新建 Python3 Notebook 来测试。 ### 3.1 本地运行 ```python import os from random import random from operator import add import findspark os.environ['SPARK_HOME'] = '/opt/third/spark' findspark.init() from pyspark.sql import SparkSession if __name__ == "__main__": spark = SparkSession \ .builder \ .appName("PythonPi-Local") \ .master("local") \ .getOrCreate() n = 100000 * 2 def f(_): x = random() * 2 - 1 y = random() * 2 - 1 return 1 if x ** 2 + y ** 2 <= 1 else 0 count = spark.sparkContext.parallelize(range(1, n + 1), 2).map(f).reduce(add) print("Pi is roughly %f" % (4.0 * count / n)) spark.stop() ``` ### 3.2 本地运行访问 Hive ```python import os import findspark os.environ['SPARK_HOME'] = '/opt/third/spark' findspark.init() from pyspark.sql import SparkSession if __name__ == "__main__": spark = SparkSession.builder \ .appName('spark-hive-demo') \ .config("hive.metastore.uris", "thrift://xxx.xxx.xxx.xxx:9083") \ .enableHiveSupport() \ .getOrCreate() spark.sql("create table if not exists demo(id bigint,name String)") spark.sql("insert overwrite demo values (1,'hamawhite'),(2,'song.bs')") spark.sql("select * from demo").show() ``` 其中 `xxx.xxx.xxx.xxx:9083` 是 Hive MetaStore 的地址。 ### 3.3 Yarn-client 模式运行 jar 作业 命令行模式测试 spark jar 作业,确保容器、spark、yarn 的配置都正确: ```shell cd /opt/third/spark # 运行作业 spark-submit --class org.apache.spark.examples.SparkPi \ --master yarn \ --deploy-mode client \ --driver-memory 4g \ --executor-memory 2g \ --executor-cores 1 \ --queue default \ examples/jars/spark-examples*.jar \ 10 ``` 可以在 Yarn Web 界面上看到提交过去的作业。 ### 3.4 Yarn-client 模式运行 pyspark 作业 ```python import os import sys from random import random from operator import add import findspark os.environ['SPARK_HOME'] = '/opt/third/spark' os.environ['HADOOP_CONF_DIR'] = '/opt/third/hadoop/etc/hadoop' findspark.init() from pyspark.sql import SparkSession if __name__ == "__main__": spark = SparkSession \ .builder \ .appName("PythonPi-Yarn-Client") \ .master("yarn") \ .config("spark.submit.deployMode", "client") \ .getOrCreate() n = 100000 * 2 def f(_): x = random() * 2 - 1 y = random() * 2 - 1 return 1 if x ** 2 + y ** 2 <= 1 else 0 count = spark.sparkContext.parallelize(range(1, n + 1), 2).map(f).reduce(add) print("Pi is roughly %f" % (4.0 * count / n)) spark.stop() ``` 可以在 Yarn Web 界面上看到提交过去的作业。 ![Yarn 提交的作业](https://cdn.nlark.com/yuque/0/2022/png/499433/1661516274041-757022e6-bea7-4262-b27d-0fb7331c261e.png) --- ### 手动安装 Hadoop 生态:Flink 配置与测试 - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/03-%E5%9C%A8%E7%BA%BF%E5%BC%80%E5%8F%91/%E6%9C%AC%E5%9C%B0Jupyter%E5%AF%B9%E6%8E%A5Hadoop%E7%94%9F%E6%80%81/02-%E6%89%8B%E5%8A%A8%E5%AE%89%E8%A3%85-Flink%E9%85%8D%E7%BD%AE%E4%B8%8E%E6%B5%8B%E8%AF%95 - 分类: 平台使用 / 在线开发 - 适用场景: 想在 JupyterLab 里手动把 PyFlink 跑起来(本地 / 对接 HiveCatalog)时读这篇 - 关键词: Flink / pyflink / apache-flink / HiveCatalog / Hive / Maven / flink-dep / JDK8 / flink-connector-hive / TableEnvironment / datagen - 最后更新: 2026-06-30 # 手动安装 Hadoop 生态:Flink 配置与测试 > 本文是“基于已有镜像手动安装”路线的第二部分(Flink)。前置环境(启动容器、Hadoop 配置)见 [01-手动安装:Spark 配置与测试](01-手动安装-Spark配置与测试.md)。版本号沿用原始教程示例(Flink 1.15.1),如需与集成镜像一致请改用 README 中的版本(1.17.0)。 ## 一、安装配置 Flink ### 1.1 安装 PyFlink ```shell pip install apache-flink==1.15.1 ``` 如果不需要用到 HiveCatalog,可直接进入 [二、测试 Flink](#二测试-flink) 进行测试。 ### 1.2 修改 JDK 版本 镜像里自带的是 JDK11,但 Hive3 是基于 Java8 编译的,基于 JDK11 运行时 PyFlink 连接 HiveCatalog 会报错。因此修改 JDK 版本为 8: ```shell # 删除已有的 JDK11 rm -rf /usr/lib/jvm/ # 安装 JDK8 apt-get update apt-get install -y openjdk-8-jdk # 设置环境变量 vi ~/.bashrc # java export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64 export PATH=$PATH:$JAVA_HOME/bin source ~/.bashrc # 测试 java 命令 java -version ``` ### 1.3 安装 Maven PyFlink 连接 Hive Catalog 时要配置一些依赖 jar 包,可以通过 maven 一次性批量安装: ```shell cd /opt/third wget http://dlcdn.apache.org/maven/maven-3/3.8.6/binaries/apache-maven-3.8.6-bin.tar.gz tar -xvzf apache-maven-3.8.6-bin.tar.gz ln -s apache-maven-3.8.6 maven # 配置 maven 镜像 vi maven/conf/settings.xml # 内添加如下内容 ``` ```xml huaweimaven huawei maven https://mirrors.huaweicloud.com/repository/maven/ central nexus-aliyun central Nexus aliyun http://maven.aliyun.com/nexus/content/groups/public ``` ```shell # 设置环境变量 vi ~/.bashrc # maven export M2_HOME=/opt/third/maven export PATH=$PATH:$M2_HOME/bin source ~/.bashrc mvn -v ``` ### 1.4 批量安装依赖 ```shell mkdir -p /opt/third/flink cd /opt/third/flink mkdir lib # 新建 flink-dep.xml 定义依赖的 jar(后续可直接扩展) vi flink-dep.xml ``` ```xml 4.0.0 com.flink.dep flink-dep 1.0.0 1.15.1 3.2.2 3.1.2 2.12 org.apache.flink flink-connector-hive_${scala.binary.version} ${flink.version} org.apache.hive hive-exec ${hive.version} org.apache.hadoop hadoop-mapreduce-client-core ${hadoop.version} ``` ```shell # 运行命令下载依赖 mvn -f flink-dep.xml dependency:copy-dependencies -DoutputDirectory=/opt/third/flink/lib ``` > 集成镜像中也内置了这份 `flink-dep.xml`(见 `images/jupyter-notebook/bigdata/conf/flink/flink-dep.xml`),可直接参考。 ### 1.5 上传 Hive 配置文件 在 JupyterLab 新建 Terminal 执行: ```shell # 新建目录 mkdir -p /opt/third/hive/conf ``` 在 Web 界面中上传 `hive-site.xml` 到 `/opt/third/hive/conf` 目录下。 ## 二、测试 Flink 新建 Python3 Notebook 来测试。 ### 2.1 本地运行 `pyflink_sql.ipynb`: ```python from pyflink.table import EnvironmentSettings, TableEnvironment env_settings = EnvironmentSettings.in_streaming_mode() t_env = TableEnvironment.create(env_settings) t_env.execute_sql(""" CREATE TABLE random_source( id BIGINT, data TINYINT ) WITH ( 'connector' = 'datagen', 'fields.id.kind'='sequence', 'fields.id.start'='1', 'fields.id.end'='8', 'fields.data.kind'='sequence', 'fields.data.start'='4', 'fields.data.end'='11' ) """) t_env.execute_sql(""" CREATE TABLE print_sink ( id BIGINT, data_sum TINYINT ) WITH ( 'connector' = 'print' ) """) t_env.execute_sql(""" INSERT INTO print_sink SELECT id, sum(data) as data_sum FROM (SELECT id / 2 as id, data FROM random_source ) WHERE id > 1 GROUP BY id """).wait() ``` ### 2.2 本地运行(HiveCatalog) 元数据会存储到 Hive MetaStore 中,`pyflink_sql_hivecatalog.ipynb`: ```python import os from pyflink.table import EnvironmentSettings, TableEnvironment env_settings = EnvironmentSettings.in_streaming_mode() t_env = TableEnvironment.create(env_settings) flink_lib_path = "/opt/third/flink/lib" jars = [] for file in os.listdir(flink_lib_path): if file.endswith('.jar'): jars.append(os.path.basename(file)) str_jars = ';'.join(['file://' + flink_lib_path + '/' + jar for jar in jars]) t_env.get_config().get_configuration().set_string("pipeline.jars", str_jars) from pyflink.table.catalog import HiveCatalog # Create a HiveCatalog catalog_name = "hive" default_database = "default" catalog = HiveCatalog(catalog_name, default_database, "/opt/third/hive/conf") t_env.register_catalog(catalog_name, catalog) t_env.use_catalog(catalog_name) t_env.execute_sql("DROP TABLE IF EXISTS random_source_pyflink") t_env.execute_sql(""" CREATE TABLE IF NOT EXISTS random_source_pyflink ( id BIGINT, data TINYINT ) WITH ( 'connector' = 'datagen', 'fields.id.kind'='sequence', 'fields.id.start'='1', 'fields.id.end'='8', 'fields.data.kind'='sequence', 'fields.data.start'='4', 'fields.data.end'='11' ) """) t_env.execute_sql("DROP TABLE IF EXISTS print_sink_pyflink") t_env.execute_sql(""" CREATE TABLE IF NOT EXISTS print_sink_pyflink ( id BIGINT, data_sum TINYINT ) WITH ( 'connector' = 'print' ) """) t_env.execute_sql(""" INSERT INTO print_sink_pyflink SELECT id, sum(data) as data_sum FROM (SELECT id / 2 as id, data FROM random_source_pyflink ) WHERE id > 1 GROUP BY id """).wait() ``` 上述操作完成后,可通过 pyspark 作业查看到新建的表 `random_source_pyflink`、`print_sink_pyflink`: ```python import os import findspark os.environ['SPARK_HOME'] = '/opt/third/spark' findspark.init() from pyspark.sql import SparkSession if __name__ == "__main__": spark = SparkSession.builder \ .appName('spark-hive-demo') \ .config("hive.metastore.uris", "thrift://192.168.90.150:9083") \ .enableHiveSupport() \ .getOrCreate() spark.sql("show tables").show() ``` --- ### 基于 Dockerfile 的 Hadoop 生态集成镜像(bigdata) - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/03-%E5%9C%A8%E7%BA%BF%E5%BC%80%E5%8F%91/%E6%9C%AC%E5%9C%B0Jupyter%E5%AF%B9%E6%8E%A5Hadoop%E7%94%9F%E6%80%81/03-%E5%9F%BA%E4%BA%8EDockerfile%E9%9B%86%E6%88%90%E9%95%9C%E5%83%8F - 分类: 平台使用 / 在线开发 - 适用场景: 想直接用平台源码里已打包好的大数据 notebook 镜像(开箱即用,自带 Spark/Flink 示例)时读这篇;也包含该镜像的构建方式 - 关键词: Dockerfile / bigdata / 集成镜像 / 大数据镜像 / jupyter-ubuntu-bigdata / init.sh / build.sh / Spark / Flink / Hive / Yarn / examples / 开箱即用 - 最后更新: 2026-06-30 # 基于 Dockerfile 的 Hadoop 生态集成镜像(bigdata) 平台源码里已经把整套 Hadoop 生态(Spark / Flink / Hive / Hadoop / Maven / JDK8)打进了 `bigdata` 镜像,开箱即用。源码目录:`images/jupyter-notebook/bigdata/`。 > 本文内容已与当前源码核实(`images/jupyter-notebook/bigdata/Dockerfile`、`init.sh`、`build.sh`)。原始教程基于旧版 `hadoop/Dockerfile-ubuntu-hadoop` 与 `run-jupyter.sh`,相关命名/版本已更新如下。 ## 一、Dockerfile 与启动脚本 ### 1.1 Dockerfile(节选,以源码为准) 当前 `images/jupyter-notebook/bigdata/Dockerfile` 通过 `ARG` 统一管理版本,并直接安装 Hadoop / Hive / Spark / PyFlink: ```dockerfile FROM ccr.ccs.tencentyun.com/cube-studio/notebook-enterprise:jupyter-ubuntu-cpu-base ARG TARGETARCH ARG SPARK_HADOOP_VERSION=3 ARG SPARK_VERSION=3.4.3 ARG FLINK_VERSION=1.17.0 ARG MAVEN_VERSION=3.8.8 ARG APACHE_MIRROR=https://mirrors.aliyun.com/apache ARG JDK_VERSION=8 RUN apt update -y && apt install -y lsof # 安装大数据 python 包(爬虫 / 数据库查询 / 数据挖掘 / 可视化等,详见源码) RUN pip config set global.index-url https://mirrors.aliyun.com/pypi/simple # ... pip install pymysql/pyhive/presto-python-client/clickhouse-driver/pandas/scikit-learn/... ... # 安装 java8 RUN rm -rf /usr/lib/jvm/ && apt-get install -y openjdk-${JDK_VERSION}-jdk ENV JAVA_HOME=/usr/lib/jvm/java-8-openjdk-${TARGETARCH} WORKDIR /opt/third/ # 安装 maven RUN wget ${APACHE_MIRROR}/maven/maven-3/${MAVEN_VERSION}/binaries/apache-maven-${MAVEN_VERSION}-bin.tar.gz \ && tar -xvzf apache-maven-${MAVEN_VERSION}-bin.tar.gz && mv apache-maven-${MAVEN_VERSION} maven \ && rm -rf apache-maven-${MAVEN_VERSION}-bin.tar.gz ENV M2_HOME=/opt/third/maven # 安装 hadoop 3.3.6 RUN wget ${APACHE_MIRROR}/hadoop/common/hadoop-3.3.6/hadoop-3.3.6.tar.gz \ && tar -zxvf hadoop-3.3.6.tar.gz -C /opt/third/ && rm hadoop-3.3.6.tar.gz \ && mv /opt/third/hadoop-3.3.6 /opt/third/hadoop ENV HADOOP_HOME=/opt/third/hadoop ENV HADOOP_CONF_DIR=/opt/third/hadoop/etc/hadoop ENV YARN_CONF_DIR=/opt/third/hadoop/etc/hadoop # 安装 hive 3.1.3 RUN wget ${APACHE_MIRROR}/hive/hive-3.1.3/apache-hive-3.1.3-bin.tar.gz \ && tar -zxvf apache-hive-3.1.3-bin.tar.gz -C /opt/third/ && rm apache-hive-3.1.3-bin.tar.gz \ && mv apache-hive-3.1.3-bin /opt/third/hive ENV HIVE_HOME=/opt/third/hive ENV HIVE_CONF_DIR=/opt/third/hive/conf # 下载 apache spark 安装包 RUN wget ${APACHE_MIRROR}/spark/spark-${SPARK_VERSION}/spark-${SPARK_VERSION}-bin-hadoop${SPARK_HADOOP_VERSION}.tgz \ && tar -xvzf spark-${SPARK_VERSION}-bin-hadoop${SPARK_HADOOP_VERSION}.tgz \ && mv spark-${SPARK_VERSION}-bin-hadoop${SPARK_HADOOP_VERSION} spark \ && rm -rf spark-${SPARK_VERSION}-bin-hadoop${SPARK_HADOOP_VERSION}.tgz ENV SPARK_HOME=/opt/third/spark # 安装 pyflink RUN pip install apache-flink==${FLINK_VERSION} # 拷贝 examples 与示例的 hadoop/hive/spark/flink 配置 COPY examples/* /examples/ COPY maven/conf/settings.xml /opt/third/maven/conf/settings.xml COPY conf/hive/* /opt/third/hive/conf/ COPY conf/hadoop/* /opt/third/hadoop/etc/hadoop/ COPY conf/spark/* /opt/third/spark/conf/ COPY conf/flink/flink-dep.xml /opt/third/flink/ # 设置环境变量到全局 ENV PATH=${PATH:-}:$JAVA_HOME/bin:$M2_HOME/bin:$HADOOP_HOME/bin:$HIVE_HOME/bin:$SPARK_HOME/bin ENV PYTHONPATH=${SPARK_HOME}/python:${SPARK_HOME}/python/lib/py4j-0.10.9.7-src.zip:${SPARK_HOME}/python/lib/pyspark.zip:${PYTHONPATH:-} # 环境初始化配置 COPY init.sh /init.sh ``` 主要变化(相对旧版教程): - 基础镜像 `notebook` → `notebook-enterprise`; - 版本升级:Spark 3.4.3 / Flink 1.17.0 / Hadoop 3.3.6 / Hive 3.1.3 / Maven 3.8.8; - 各组件 HOME 与 `PATH`、`PYTHONPATH` 全部用 `ENV` 固化进镜像,无需再手动 `findspark.init()` 或改 python 软链; - 配置文件目录从源码 `conf/{hadoop,hive,spark,flink}` 直接 `COPY` 进镜像,可启动后再覆盖。 ### 1.2 启动脚本 init.sh(以源码为准) 旧版 `run-jupyter.sh` 接收宿主机 IP 作为 `$1` 并硬编码端口 32788/32789;当前 `images/jupyter-notebook/bigdata/init.sh` 改为读取由 notebook 控制器注入的环境变量(`PORT1`、`PORT2`、`SERVICE_EXTERNAL_IP`、`NOTEBOOK_NAME`、`USERNAME`、`SSH_PORT`): ```bash #!/bin/bash # 配置 spark-defaults.conf(端口与 driver host 由控制器注入的环境变量决定) echo "spark.ui.enabled=false" >> ${SPARK_HOME}/conf/spark-defaults.conf echo "spark.driver.port=${PORT1}" >> ${SPARK_HOME}/conf/spark-defaults.conf echo "spark.blockManager.port=${PORT2}" >> ${SPARK_HOME}/conf/spark-defaults.conf echo "spark.driver.bindAddress=0.0.0.0" >> ${SPARK_HOME}/conf/spark-defaults.conf echo "spark.driver.host=${SERVICE_EXTERNAL_IP}" >> ${SPARK_HOME}/conf/spark-defaults.conf # (另含配置 ssh、软链 /examples 等,详见源码) ``` > 说明(与源码核对):旧教程里 `docker run ... <镜像> xxx.xxx.xxx.xxx`(把宿主机 IP 作为参数传给 run-jupyter.sh)的用法已不适用——当前 `init.sh` 不再接收位置参数,而是依赖平台 notebook 控制器注入的 `PORT1/PORT2/SERVICE_EXTERNAL_IP` 等环境变量(见 `images/jupyter-notebook/bigdata/init.sh`)。该镜像主要作为平台 notebook 镜像使用;若要 `docker run` 独立启动,需要自行提供这些环境变量。 ### 1.3 构建命令 依据 `images/jupyter-notebook/bigdata/build.sh`: ```shell # 在 images/jupyter-notebook/bigdata 目录下 hubhost=ccr.ccs.tencentyun.com/cube-studio TARGETARCH=amd64 docker build --network=host -t $hubhost/notebook-enterprise:jupyter-ubuntu-bigdata-$TARGETARCH -f Dockerfile . docker push $hubhost/notebook-enterprise:jupyter-ubuntu-bigdata-$TARGETARCH ``` > 该镜像的构建/管理也可走平台的在线构建能力,参见 [04-镜像构建与仓库 / 镜像在线构建和管理](../../04-镜像构建与仓库/镜像在线构建和管理.md) 与 [06-二次开发](../../../06-二次开发/) 段。 ## 二、使用集成镜像 ### 2.1 上传集群配置文件 `/opt/third/hadoop/etc/hadoop` 和 `/opt/third/hive/conf` 已自带默认配置文件(源码 `conf/` 目录),可以直接修改其中参数,或按下面步骤上传覆盖。 **上传 Hadoop 配置文件**:在 Web 界面中上传 `core-site.xml`、`hdfs-site.xml`、`yarn-site.xml` 到 `/opt/third/hadoop/etc/hadoop` 目录下。注意检查 `yarn-site.xml` 一定要有 `yarn.resourcemanager.address` 配置项,否则默认值 `0.0.0.0:8032` 会导致作业无法提交到 Yarn: ```xml yarn.resourcemanager.address xxx.xxx.xxx.xxx:8032 ``` **上传 Hive 配置文件**:在 Web 界面中上传 `hive-site.xml` 到 `/opt/third/hive/conf` 目录下。 ### 2.2 测试 Spark 因为镜像启动时已设置好相关环境变量,代码中无需再设置环境变量或使用 findspark。`/examples` 目录下已内置示例(`pyspark_local.ipynb`、`pyspark_local_hive.ipynb`、`pyspark_yarn.ipynb`),可直接运行。 **本地运行** `pyspark_local.ipynb`: ```python from random import random from operator import add from pyspark.sql import SparkSession if __name__ == "__main__": spark = SparkSession \ .builder \ .appName("PythonPi-Local") \ .master("local") \ .getOrCreate() n = 100000 * 2 def f(_): x = random() * 2 - 1 y = random() * 2 - 1 return 1 if x ** 2 + y ** 2 <= 1 else 0 count = spark.sparkContext.parallelize(range(1, n + 1), 2).map(f).reduce(add) print("Pi is roughly %f" % (4.0 * count / n)) spark.stop() ``` **本地运行访问 Hive** `pyspark_local_hive.ipynb`: ```python from pyspark.sql import SparkSession if __name__ == "__main__": spark = SparkSession.builder \ .appName('spark-hive-demo') \ .config("hive.metastore.uris", "thrift://xxx.xxx.xxx.xxx:9083") \ .enableHiveSupport() \ .getOrCreate() spark.sql("create table if not exists demo(id bigint,name String)") spark.sql("insert overwrite demo values (1,'hamawhite'),(2,'song.bs')") spark.sql("select * from demo").show() ``` 其中 `xxx.xxx.xxx.xxx:9083` 是 Hive MetaStore 的地址。 **Yarn-client 模式运行 pyspark 作业** `pyspark_yarn.ipynb`: ```python from random import random from operator import add from pyspark.sql import SparkSession if __name__ == "__main__": spark = SparkSession \ .builder \ .appName("PythonPi-Yarn-Client-Dockerfile") \ .master("yarn") \ .config("spark.submit.deployMode", "client") \ .getOrCreate() n = 100000 * 2 def f(_): x = random() * 2 - 1 y = random() * 2 - 1 return 1 if x ** 2 + y ** 2 <= 1 else 0 count = spark.sparkContext.parallelize(range(1, n + 1), 2).map(f).reduce(add) print("Pi is roughly %f" % (4.0 * count / n)) spark.stop() ``` 可以在 Yarn Web 界面上看到提交过去的作业。 ![Yarn 提交的作业](https://cdn.nlark.com/yuque/0/2022/png/499433/1661620956482-74ad85ab-e16b-46a5-85cf-0caa684d1964.png) ### 2.3 测试 Flink 与手动安装路线的测试方法类似(见 [02-手动安装:Flink 配置与测试](02-手动安装-Flink配置与测试.md))。`/examples` 目录下已内置 `pyflink_sql.ipynb`、`pyflink_sql_hivecatalog.ipynb` 等示例,可直接运行。 --- ### Hadoop 生态对接:其他辅助文档 - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/03-%E5%9C%A8%E7%BA%BF%E5%BC%80%E5%8F%91/%E6%9C%AC%E5%9C%B0Jupyter%E5%AF%B9%E6%8E%A5Hadoop%E7%94%9F%E6%80%81/04-%E5%85%B6%E4%BB%96%E8%BE%85%E5%8A%A9%E6%96%87%E6%A1%A3 - 分类: 平台使用 / 在线开发 - 适用场景: 搭建用于测试的 Hadoop / Hive 集群,或在 CentOS 上把 python 版本对齐到 3.8 时读这篇 - 关键词: CentOS / Python3.8 / 安装Python / Hadoop安装 / Hive安装 / 单机伪分布式 / SingleCluster - 最后更新: 2026-06-30 # Hadoop 生态对接:其他辅助文档 本文是手动安装路线的补充:在 CentOS 上安装 Python3.8、以及安装 Hadoop / Hive 的参考链接。 ## 一、CentOS 下安装 Python3.8 若用到的 Hadoop 集群基于 CentOS7 搭建,默认 python 版本是 2.7,与镜像中的 Python3.8 不一致,会导致 Yarn 作业运行失败。因此补充安装 Python3.8 的步骤: ```shell # 安装基础依赖 yum install -y zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gcc make libffi-devel # 下载 Python 安装包 wget https://www.python.org/ftp/python/3.8.12/Python-3.8.12.tgz tar -zxvf Python-3.8.12.tgz cd Python-3.8.12 ./configure prefix=/usr/local/python3 # 安装 make && make install # 最终在 /usr/local/ 目录下会有 python3 目录 # 添加 python3 的软链接 ln -s /usr/local/python3/bin/python3.8 /usr/bin/python3 # 添加 pip3 的软链接 ln -s /usr/local/python3/bin/pip3.8 /usr/bin/pip3 ``` 然后把默认 python 软链接到 python3 上: ```shell rm -rf /bin/python ln -s /usr/local/python3/bin/python3.8 /bin/python ``` ## 二、安装 Hadoop 参考官网: ## 三、安装 Hive 参考官网: --- ### 本地 Jupyter 对接 Hadoop 生态(总览) - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/03-%E5%9C%A8%E7%BA%BF%E5%BC%80%E5%8F%91/%E6%9C%AC%E5%9C%B0Jupyter%E5%AF%B9%E6%8E%A5Hadoop%E7%94%9F%E6%80%81/README - 分类: 平台使用 / 在线开发 - 适用场景: 想在 JupyterLab notebook 里跑 PySpark / PyFlink 并提交到 Yarn、对接 Hive 时,先看这篇了解整体路线与组件版本 - 关键词: Jupyter / JupyterLab / Hadoop / Spark / pyspark / Flink / pyflink / Hive / HiveCatalog / Yarn / bigdata / 大数据 / findspark / 组件版本 - 最后更新: 2026-07-09 # 本地 Jupyter 对接 Hadoop 生态(总览) 本系列介绍如何在 JupyterLab notebook 中对接 Hadoop 生态(Spark / Flink / Hive / Yarn),让 PySpark、PyFlink 作业既能本地运行,也能提交到 Yarn 集群运行、对接 Hive 元数据。 提供两种路线,可按需选择: 1. **基于已有镜像手动安装**——从基础 notebook 镜像出发,逐步手动安装配置 Spark / Flink(适合理解原理、对接各厂商发行版)。 2. **基于 Dockerfile 的集成镜像**——平台源码里已经把整套 Hadoop 生态打进了 `bigdata` 镜像,开箱即用,`/examples` 下自带示例。 > 建议:想快速体验直接用集成镜像(见 [03-基于 Dockerfile 集成镜像](03-基于Dockerfile集成镜像.md));想了解原理或对接华为 FusionInsight / 星环 TDH / Cloudera CDH 等非 Apache 发行版,按手动安装路线来。 ## 一、组件版本 ### 1.1 当前集成镜像版本(以源码为准) 平台源码已将 Hadoop 生态集成进 `bigdata` 镜像。下表依据 `images/jupyter-notebook/bigdata/Dockerfile` 与 `build.sh` 核实: | 组件 | 版本 | 依据(`images/jupyter-notebook/bigdata/Dockerfile`) | | --- | --- | --- | | 基础镜像 | `ccr.ccs.tencentyun.com/cube-studio/notebook-enterprise:jupyter-ubuntu-cpu-base` | 第 1 行 `FROM` | | Spark | 3.4.3(bin-hadoop3) | `ARG SPARK_VERSION=3.4.3` | | Flink(pyflink) | 1.17.0 | `ARG FLINK_VERSION=1.17.0` | | Hadoop | 3.3.6 | 安装 hadoop 一节 | | Hive | 3.1.3 | 安装 hive 一节 | | Maven | 3.8.8 | `ARG MAVEN_VERSION=3.8.8` | | JDK | 8 | `ARG JDK_VERSION=8` | | 构建产物镜像 | `ccr.ccs.tencentyun.com/cube-studio/notebook-enterprise:jupyter-ubuntu-bigdata-amd64` | `build.sh:5` | ### 1.2 手动安装教程使用的示例版本 下文“手动安装”路线([01](01-手动安装-Spark配置与测试.md)、[02](02-手动安装-Flink配置与测试.md))沿用原始教程的示例版本,仅用于演示步骤;如需与集成镜像保持一致,请把版本号替换为上表中的版本。 | 组件 | 教程示例版本 | 备注 | | --- | --- | --- | | Hadoop | 3.2.2 | hadoop-3.2.2 | | Spark | 3.1.3 | spark-3.1.3-bin-hadoop3.2 | | Hive | 3.1.2 | apache-hive-3.1.2-bin | | Flink | 1.15.1 | pyflink | | Python | 3.8.12 | 基础镜像自带版本 | > 说明(与源码核对):原始教程基于 `notebook:jupyter-ubuntu-cpu-base` 与旧版组件(Spark 3.1.3 / Flink 1.15.1 / Hadoop 3.2.2 / Hive 3.1.2),而当前商业版源码(`images/jupyter-notebook/bigdata/Dockerfile`)已改名为 `notebook-enterprise:*` 并升级到 Spark 3.4.3 / Flink 1.17.0 / Hadoop 3.3.6 / Hive 3.1.3。下文"手动安装"步骤的命令与下载链接仍以旧版本演示,可正常理解流程,具体版本/路径请以最新源码为准。 ## 二、子文档目录(TOC) | 文档 | 内容 | | --- | --- | | [01-手动安装:Spark 配置与测试](01-手动安装-Spark配置与测试.md) | 启动基础容器、上传 Hadoop 配置、下载配置 Spark、findspark、本地 / 访问 Hive / Yarn-client 运行 PySpark | | [02-手动安装:Flink 配置与测试](02-手动安装-Flink配置与测试.md) | 安装 PyFlink、改 JDK8、装 Maven、批量拉依赖、HiveCatalog 配置、本地 / HiveCatalog 运行 PyFlink | | [03-基于 Dockerfile 的集成镜像](03-基于Dockerfile集成镜像.md) | 集成镜像 Dockerfile 与启动脚本、启动容器、上传集群配置、开箱即用的 Spark / Flink 示例 | | [04-其他辅助文档](04-其他辅助文档.md) | CentOS 下装 Python3.8、安装 Hadoop / Hive 的参考 | ## 三、整体路线 1. 准备一个 Hadoop / Yarn 集群(没有的话可参考 [04-其他辅助文档](04-其他辅助文档.md) 搭建单机伪分布式集群测试)。 2. 在 JupyterLab 中配置好 Spark / Flink,并上传集群的 `core-site.xml`、`hdfs-site.xml`、`yarn-site.xml`、`hive-site.xml`。 3. 用 notebook 跑本地模式验证,再跑 Yarn-client 模式提交到集群,最后对接 Hive。 > 集成镜像本身的构建属于镜像构建范畴,可参见 [04-镜像构建与仓库 / 镜像在线构建和管理](../../04-镜像构建与仓库/镜像在线构建和管理.md) 与 [06-二次开发](../../../06-二次开发/) 段。 --- ### 镜像仓库(凭据管理与拉取/推送策略) - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/04-%E9%95%9C%E5%83%8F%E6%9E%84%E5%BB%BA%E4%B8%8E%E4%BB%93%E5%BA%93/%E9%95%9C%E5%83%8F%E4%BB%93%E5%BA%93 - 分类: 平台使用 / 镜像构建与仓库 - 适用场景: 配置镜像仓库账号密码、让全平台用户免密拉取/推送镜像,或排查拉取/推送权限问题时读这篇 - 关键词: 镜像仓库 / registry / hubsecret / imagePullSecret / 镜像拉取 / 镜像推送 / image pull / image push / docker login / HUBSECRET / REPOSITORY_ORG / PUSH_REPOSITORY_ORG / k8s secret / 私有仓库 - 最后更新: 2026-06-30 # 镜像仓库简介 镜像仓库这个功能的存在,是为了在推送和拉取镜像的时候,不用每次输入账号密码。在“在线开发 -> 镜像管理 -> 镜像仓库”界面中配置好镜像仓库的域名、用户名、密码之后,平台会自动在 k8s 集群中以 Secret 形式保存镜像仓库的账号密码。 ![输入图片说明](https://foruda.gitee.com/images/1698496332784856511/ba1b41b5_1019082.png "屏幕截图") > 后端入口:`Repository_ModelView_Api`,`route_base = /repository_modelview/api`(见 `myapp/views/view_images.py:164`)。 > 保存的表单字段为 `name / server / user / password / hubsecret`,其中 `hubsecret` 默认名为 `<用户名>-hubsecret`(`myapp/views/view_images.py:68`、`:117`)。 # 命名空间的信息 添加(或修改保存)镜像仓库后,平台会把镜像仓库账号密码以 k8s Secret(docker-registry 类型,即 `hubsecret`)的形式写入到一批命名空间中。 ![输入图片说明](https://foruda.gitee.com/images/1698496974236713345/e1d2cb81_1019082.png "屏幕截图") 具体写入哪些命名空间由 `security_manager.get_all_namespace()` 决定(见 `myapp/views/view_images.py:141`、`myapp/security.py:1092`):它会遍历所有项目组(Project),收集每个项目组配置的 notebook / pipeline / service / automl 四类命名空间。在默认配置下,这四类命名空间分别为 `jupyter`、`pipeline`、`service`、`automl`(见 `myapp/config.py:768`-`780`),因此默认会在这四个命名空间各创建一份 Secret。 > 说明:`myapp/config.py:990` 虽然定义了 `HUBSECRET_NAMESPACE`(默认含 `pipeline/automl/jupyter/service/aihub/rental` 六个命名空间),但全代码检索中该变量仅在定义行出现、并未被任何凭据下发逻辑引用(属未启用的配置项)。实际下发由 `apply_hubsecret` 调用 `get_all_namespace`(`myapp/views/view_images.py:133`-`155`、`myapp/security.py:1092`)决定,后者只收集各项目组的 notebook / pipeline / service / automl 四类命名空间。因此默认情况下 `aihub`、`rental` 命名空间不会收到 hubsecret(除非某项目组把这四类命名空间显式配置为 aihub/rental)。 # 增加集群、仓库 ## 新增 k8s 集群 凭据下发逻辑会在保存仓库时遍历当时 `CLUSTERS` 中配置的所有集群 kubeconfig 并逐个写入 Secret(见 `myapp/views/view_images.py:135`-`150`)。因此如果之后**新增了 k8s 集群**,已有的镜像仓库 Secret 不会自动同步到新集群,需要重新修改、保存一次镜像仓库的配置,信息才会在新集群上生效。 # 全局秘钥 ## 镜像拉取 镜像拉取时使用的 `imagePullSecrets` 由两部分合并而成(见 `myapp/views/view_images.py:334`-`336`): 1. 配置文件中的 `HUBSECRET` 变量(默认 `['hubsecret']`,见 `myapp/config.py:975`); 2. 当前用户在“在线开发 -> 镜像管理 -> 镜像仓库”中个人创建的全部仓库秘钥(`hubsecret`)。 > 配置文件位置:本地为仓库内 `install/docker/config.py`(实际加载哪个由环境变量 `MYAPP_CONFIG` 决定,默认 `myapp/config.py`);线上为 `infra` 命名空间下名为 `kubeflow-dashboard-config` 的 ConfigMap(kustomize 生成时可能带 hash 后缀,见 `install/kubernetes/cube/overlays/kustomization.yml`)。 所以如果想让所有人都能拉取某个私有镜像,可选: - 方法一:把镜像设置为 public 公开镜像。 - 方法二:在“在线开发 -> 镜像管理 -> 镜像仓库”中创建一个有拉取(推送)权限的仓库秘钥,并把对应的 k8s Secret 名称加入配置文件的 `HUBSECRET` 变量中,使其对全平台生效。 ## 镜像推送 为了避免每个同学都单独配置推送秘钥,平台在保存/推送镜像时(镜像调试构建、notebook 保存镜像等)会自动挑选推送秘钥。以在线构建推送为例,挑选规则见 `myapp/views/view_images.py:312`-`322`: - 先筛出 `server` 出现在目标镜像名中的仓库; - 在这些仓库里取“打分最高”的一个:打分公式为 `len(server) + 1000 * (是否为本人创建)`。即**优先使用本人创建的仓库秘钥**,其次选择 `server` 与镜像名匹配字符前缀最长的那个仓库秘钥;选中后用该仓库的账号密码执行 `docker login` 再推送。 所以为了让所有人都能推送到同一个镜像仓库,可以在“在线开发 -> 镜像管理 -> 镜像仓库”中创建一个具有推送权限的仓库秘钥。 镜像构建/推送时的**默认目标组织**由配置文件中的 `PUSH_REPOSITORY_ORG` 控制(默认 `ccr.ccs.tencentyun.com/cube-studio/`,见 `myapp/config.py:980`、`myapp/views/view_docker.py:153`);而拉取/通用默认镜像所在组织为 `REPOSITORY_ORG`(默认同样为 `ccr.ccs.tencentyun.com/cube-studio/`,见 `myapp/config.py:978`)。如需改为自己的内网仓库,请按需修改这两个变量。 > 原文档此处只提到修改 `REPOSITORY_ORG` 作为推送默认仓库;按当前代码,推送默认组织实际由 `PUSH_REPOSITORY_ORG` 决定,已据代码更正。 # 相关文档 - 私有镜像仓库的部署与运维(Harbor):见 [04-运维管理/私有镜像仓库Harbor.md](../../04-运维管理/私有镜像仓库Harbor.md) - 配置文件(含 `HUBSECRET`、`REPOSITORY_ORG`、`PUSH_REPOSITORY_ORG` 等变量)的管理:见 [04-运维管理/配置文件管理.md](../../04-运维管理/配置文件管理.md) --- ### 镜像在线构建和管理 - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/04-%E9%95%9C%E5%83%8F%E6%9E%84%E5%BB%BA%E4%B8%8E%E4%BB%93%E5%BA%93/%E9%95%9C%E5%83%8F%E5%9C%A8%E7%BA%BF%E6%9E%84%E5%BB%BA%E5%92%8C%E7%AE%A1%E7%90%86 - 分类: 平台使用 / 镜像构建与仓库 - 适用场景: 不熟悉 Docker、想在平台上通过 Web Shell 或 Dockerfile 在线构建并保存自己的工作镜像、或想知道有哪些 GPU 基础镜像时读这篇 - 关键词: 镜像构建 / 在线构建 / web shell / docker / dockerfile / commit / push / 镜像仓库 / repository / 基础镜像 / base image / target image / GPU基础镜像 / cuda / cudnn - 最后更新: 2026-07-04 # 在线构建镜像 在云原生里面,所有的调度都是基于容器的,但这一部分的门槛比较高: 1. 算法工程师并不熟悉 Docker 技术,部分环境在转化为 Dockerfile 时浪费了很多时间,编写 Dockerfile 也可能比较难(比如在一个镜像中安装多个 CUDA 的场景)。 2. 基础镜像封装太多,用户不知道该选择什么镜像。 ![docker-build](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/docker-build.png) 针对用户不熟悉 Docker 技术的情况,CubeStudio 加入了**在线构建镜像**的功能:启动调试后直接进入 bash 命令行,像在 Linux 上一样随意运行命令、安装环境,之后点击保存就会自动生成用户的工作镜像并 push 到仓库。期间 CubeStudio 会自动寻找用户进行镜像调试的 pod,在同一台机器上把用户的容器 `commit` 成镜像,并将构建好的镜像推送到仓库。 对于基础镜像太多的问题,CubeStudio 的方案是仅封装 cuda / python 这类基础环境,更上层的环境在任务运行时现场安装——基本模板中都保留了让用户自定义初始化命令的能力。对于长期运行的任务,安装环境的时间成本并不高。 ![docker-add](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/docker-add.png) 平台支持用户通过 Web Shell 形式在线构建镜像,安装环境后保存镜像到自己的仓库,方便快速构建和部署。 ## 一、Web Shell 构建镜像 “在线开发” → “镜像构建”,在 docker 记录上点击“调试”,即可进入 Web Shell 界面进行交互式镜像构建。 ![web shell 入口](https://foruda.gitee.com/images/1700398661342253130/18791017_1019082.png "屏幕截图") 进入 Web Shell 后,直接通过 `pip` 等命令就能安装镜像中所需要的环境,不需要编写 Dockerfile。 ![web shell 安装环境](https://foruda.gitee.com/images/1700398833225107413/cde7e190_1019082.png "屏幕截图") > 注意:镜像调试只用于安装环境,请不要在调试容器里运行业务代码;当晚前请注意点击“保存”生成新镜像(调试 pod 有自动回收策略,见 `myapp/views/view_docker.py` 中 `debug` 创建的 `sleep` 看护命令)。 ## 二、Dockerfile 构建镜像 在“镜像管理”中添加镜像时可以填入 Dockerfile,填了 Dockerfile 之后,“构建”列会出现“在线构建”。 ![添加 dockerfile](https://foruda.gitee.com/images/1700399514316150583/24f91361_1019082.png "屏幕截图") 点击“在线构建”,即可进入在线构建界面: ![在线构建界面](https://foruda.gitee.com/images/1700399650972692513/eb32d156_1019082.png "屏幕截图") ## 三、平台后端构建流程(基于源码核实) 镜像在线构建由 `Docker` 模型与 `Docker_ModelView_Api`(路由 `/docker_modelview/api`)实现。核实依据:`myapp/models/model_docker.py`、`myapp/views/view_docker.py`。 - **Docker 记录字段**(`model_docker.py:20-34`):`project`(项目组)、`describe`(描述)、`base_image`(基础镜像)、`target_image`(目标镜像)、`last_image`(最后生成镜像)、`consecutive_build`(连续构建,默认 True)、`namespace`(默认 `jupyter`)、`expand`(扩展参数,含 `resource_memory/resource_cpu/resource_gpu/volume_mount`)。 - **目标镜像默认值**(`view_docker.py:151-157`):`PUSH_REPOSITORY_ORG + 用户名 + ":" + 日期`(如 `ccr.ccs.tencentyun.com/cube-studio/:2026.06.29.1`)。目标镜像所在仓库必须先在“镜像仓库”中配置账号密码,否则保存时会提示“构建推送镜像前,请先添加镜像仓库信息”。 - **调试**(`/docker_modelview/api/debug/`):在 notebook 命名空间创建名为 `docker--` 的调试 pod,挂载用户工作目录,默认资源 `8G / 4核 / 0 GPU`(`expand` 可覆盖),就绪后跳转到 Web Shell。 - **保存**(`/docker_modelview/api/save/`):找到调试 pod 所在节点和容器 id,新建 `docker-commit--` pod,用 `docker` / `nerdctl`(取决于集群 `CONTAINER_CLI`)登录目标仓库 → `commit` 容器为 `target_image` → `push` 到仓库。commit 时会先 `inspect` 原始镜像的 ENTRYPOINT/CMD 并通过 `--change` 写回,避免调试用的 `sleep` 启动命令覆盖原始入口。 - **清理**(`/docker_modelview/api/delete_pod/`):删除调试 pod 与 commit pod;切换项目组(集群)或更换基础镜像时会自动清理旧调试容器。 - **连续构建**(`consecutive_build`):开启时,下次调试基于上次生成的 `last_image` 继续,而非每次都从 `base_image` 重新开始。 > 与“二次开发”中的镜像构建相关内容相互参照,见 [06-二次开发](../../06-二次开发/) 段。 ## 四、Dockerfile 常用片段参考 以下为常见的镜像内环境配置片段,仅作示例(实际 Python 版本以所用基础镜像为准)。 ### 修改默认 python 版本 ```dockerfile rm /usr/bin/python ln -s /usr/bin/python3.6 /usr/bin/python rm /usr/bin/pip ln -s /usr/bin/pip3 /usr/bin/pip pip install pip --upgrade ``` ### Ubuntu 容器基础工具的封装 ```dockerfile RUN apt update -y # 安装运维工具 RUN apt install -y --force-yes --no-install-recommends vim apt-transport-https gnupg2 ca-certificates-java rsync jq wget git dnsutils iputils-ping net-tools curl mysql-client locales zip traceroute # 安装 python RUN apt install -y python3.6-dev python3-pip libsasl2-dev libpq-dev \ && ln -s /usr/bin/python3 /usr/bin/python \ && ln -s /usr/bin/pip3 /usr/bin/pip # 安装中文 RUN apt install -y --force-yes --no-install-recommends locales ttf-wqy-microhei ttf-wqy-zenhei xfonts-wqy && locale-gen zh_CN && locale-gen zh_CN.utf8 ENV LANG=zh_CN.UTF-8 ENV LC_ALL=zh_CN.UTF-8 ENV LANGUAGE=zh_CN.UTF-8 # 便捷操作 RUN echo "alias ll='ls -alF'" >> ~/.bashrc && \ echo "alias la='ls -A'" >> ~/.bashrc && \ echo "alias vi='vim'" >> ~/.bashrc # 安装其他工具 ### 安装 kubectl RUN curl -LO https://dl.k8s.io/release/v1.16.0/bin/linux/amd64/kubectl && chmod +x kubectl && mv kubectl /usr/local/bin/ ### 安装 mysql 客户端 RUN apt install -y mysql-client-5.7 ### 安装 java RUN apt install -y openjdk-8-jdk ### 安装最新版的 nodejs RUN curl -sL https://deb.nodesource.com/setup_13.x | bash - RUN apt-get install -y nodejs && npm config set unicode false ``` ## 五、常用 GPU 基础镜像 构建脚本位于源码 `images/ubuntu-gpu/build.sh`(基础镜像基于 `nvidia/cuda:*-cudnn8-devel-ubuntu20.04` 构建,再叠加指定 Python 版本)。 ### Ubuntu / CUDA 12.1.0-cudnn8 - `ccr.ccs.tencentyun.com/cube-studio/ubuntu-gpu:cuda12.1.0-cudnn8-amd64` - python3.11:`ccr.ccs.tencentyun.com/cube-studio/ubuntu-gpu:cuda12.1.0-cudnn8-python3.11-amd64` - python3.10:`ccr.ccs.tencentyun.com/cube-studio/ubuntu-gpu:cuda12.1.0-cudnn8-python3.10-amd64` - python3.9:`ccr.ccs.tencentyun.com/cube-studio/ubuntu-gpu:cuda12.1.0-cudnn8-python3.9-amd64` ### Ubuntu / CUDA 11.8.0-cudnn8 - `ccr.ccs.tencentyun.com/cube-studio/ubuntu-gpu:cuda11.8.0-cudnn8-amd64` - python3.11:`ccr.ccs.tencentyun.com/cube-studio/ubuntu-gpu:cuda11.8.0-cudnn8-python3.11-amd64` - python3.10:`ccr.ccs.tencentyun.com/cube-studio/ubuntu-gpu:cuda11.8.0-cudnn8-python3.10-amd64` - python3.9:`ccr.ccs.tencentyun.com/cube-studio/ubuntu-gpu:cuda11.8.0-cudnn8-python3.9` - python3.8:`ccr.ccs.tencentyun.com/cube-studio/ubuntu-gpu:cuda11.8.0-cudnn8-python3.8` - python3.7:`ccr.ccs.tencentyun.com/cube-studio/ubuntu-gpu:cuda11.8.0-cudnn8-python3.7` > 注意:当前 `images/ubuntu-gpu/build.sh` 只构建并推送 `cuda11.8.0-cudnn8`、`cuda12.1.0-cudnn8` 两个基础镜像及其 **python3.9** 变体(见 `images/ubuntu-gpu/build.sh:7-22`),脚本本身不构建 python3.7 / 3.8 / 3.10 / 3.11 变体。上面列出的完整 Python 版本镜像在 `images/README.md` 中作为已发布镜像列出,可能由历史构建或其他流程产出。使用前请确认对应 tag 是否确实存在于你的镜像仓库。 --- ### 库表(离线元数据库表管理) - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/05-%E6%95%B0%E6%8D%AE%E8%B5%84%E4%BA%A7%E4%B8%8E%E5%A4%84%E7%90%86/%E5%BA%93%E8%A1%A8 - 分类: 平台使用 / 数据资产与处理 - 适用场景: 登记/检索离线数仓库表元数据、配置库表可见范围与责任人、批量导入导出库表信息时读这篇 - 关键词: 库表 / 元数据 / metadata table / 数据资产 / 数仓分层 / warehouse_level / owner / 责任人 / 多租户 / ENABLE_MULTI_TENANT / 建表DDL / 数据治理 / metadata_table - 最后更新: 2026-06-30 # 库表(离线元数据库表管理)使用说明 ## 1. 功能定位 “库表”用于统一登记离线数仓/数据库中的元数据,核心目标是: - 提供统一的库表检索与展示入口(表基础信息、责任人、生命周期、成本、访问情况等)。 - 支持人工维护与批量导入,弥补外部系统元数据分散、缺少统一 Web 门户的问题。 - 为后续治理能力(分级分域、生命周期治理、成本治理)提供基础数据。 当前入口为:`/metadata_table_modelview/api`(见 `myapp/views/view_metadata.py:293`,对应数据表 `metadata_table`,见 `myapp/models/model_metadata.py:21`)。 ## 2. 可见范围与权限说明 库表可见性与编辑删除权限由责任人(`owner`)和租户配置共同决定(过滤逻辑见 `myapp/views/view_metadata.py:72`-`100`)。 ### 2.1 可见范围(列表/查询) - 当 `ENABLE_MULTI_TENANT=False`(默认情况): - 管理员可见全部记录。 - 普通用户仅可见: - `owner` 包含 `*` 的记录(公开); - `owner` 包含当前用户名的记录。 - 当 `ENABLE_MULTI_TENANT=True`: - 系统管理员可见全部记录; - 组织管理员可见本组织用户创建的记录; - 普通用户可见: - `owner` 包含当前用户名的记录; - `owner` 包含 `*` 且创建者在同组织内的记录。 ### 2.2 编辑/删除权限 - 管理员可编辑、删除任意记录。 - 非管理员仅可编辑、删除 `owner` 中包含自己用户名的记录(`check_edit_permission`,见 `myapp/views/view_metadata.py:257`-`261`)。 - 批量删除(“删除”动作 `muldelete`)同样遵循上述规则(见 `myapp/views/view_metadata.py:263`-`272`)。 ## 3. 新增与编辑(字段说明) 新增与编辑字段一致(`add_columns` 与 `edit_columns` 相同,见 `myapp/views/view_metadata.py:111`、`:121`),主要字段如下: - `app`:产品,支持下拉选择与手动输入。 - `db`:数据库,必填,限制为 ASCII 字符(正则 `^[\x00-\x7F]*$`)。 - `table`:表名,必填,需匹配正则 `^[a-z][a-z0-9\-_]*[a-z0-9]$`,长度 1~54。 - `describe`:表描述,必填。 - `field`:数据域,支持多选与手动输入。 - `warehouse_level`:数仓分层(表单标签为“数仓等级”),默认 `TMP`,可选 `ODS/DWD/DWS/TOPIC/APP/DIM/TMP`。 - `value_score`:价值评分,默认 `0`。 - `security_level`:安全等级,默认“普通”,可选 普通/机密/秘密/高度机密。 - `ttl`:保留周期,默认 `1 year`,可选 1 week / 1 month / 3 month / 6 month / 1 year / forever。 - `storage_cost`:数据成本,必填,默认 `0`,仅允许数字字符(正则 `^[0-9]*$`)。 - `owner`:责任人,逗号分隔;默认 `*`(公开)。 - `create_table_ddl`:建表 SQL(文本)。 > 字段定义见 `myapp/views/view_metadata.py:145`-`253`。原文档将 `warehouse_level` 表述为“数仓分层”,代码中表单标签实为“数仓等级”,二者指同一字段;并据代码补充了 `value_score` 字段。 ### 3.1 表名命名建议 表单中给出的推荐命名格式(见 `myapp/views/view_metadata.py:149`): `dwd_[产品]_[数据域]_[数据域描述]_[刷新周期d/w/m/y][存储策略i(增量)/f(全量)]` 示例:`dwd_qq_common_click_di` ## 4. 新增时系统自动处理逻辑 创建记录时,系统会自动补充以下信息(`pre_add`,见 `myapp/views/view_metadata.py:275`-`280`): - 若 `owner` 为空或仅为 `*`,会自动写为:`当前用户名,*`(既保留责任人又允许公开)。 - 自动生成 `node_id = db::table`。 - 自动记录 `creator = 当前用户名`。 ## 5. 批量导入与导出 - 支持批量导入(`import_data=True`,见 `myapp/views/view_metadata.py:136`)。 - 支持数据下载导出(`download_data=True`,见 `myapp/views/view_metadata.py:137`)。 - 导入预处理:若 `recent_visit` 为空,会自动置为 `None`,避免脏值(`pre_upload`,见 `myapp/views/view_metadata.py:139`-`143`)。 建议导入前重点校验:`table`、`db`、`storage_cost`、`owner`。 ## 6. 展示与查询建议 - 列表页默认按 `id desc` 排序(`base_order`,见 `myapp/views/view_metadata.py:108`);可排序字段为 `id / storage_cost / visits_seven`。 - 常用搜索字段:`app`、`db`、`table`、`describe`、`field`、`warehouse_level`、`owner`(见 `myapp/views/view_metadata.py:116`)。 - 详情页可查看治理相关信息(如存储大小、生命周期、推荐生命周期、最近访问、建表 SQL、字段信息等,见 `show_columns`,`myapp/views/view_metadata.py:112`-`115`)。 ## 7. 推荐运维方式 ### 7.1 定时同步(需二开) 通过二开,实现离线任务定时拉取外部系统元数据并回填到库表(例如每日凌晨增量同步),适用于 Hive、Presto、MySQL、Redis 等多源场景。 ### 7.2 在线同步(需二开) 如需“变更即同步”,可扩展事件驱动或 CDC 方案,实现近实时元数据更新。 ### 7.3 反向同步(需二开) 可扩展“平台建表元数据 -> 外部数据库 DDL 执行”的能力,实现元数据与实际表结构联动。 ## 8. 二开扩展点 可优先从以下扩展点入手: - 扩展字段类型与字段级校验规则(例如分区策略、血缘信息、敏感字段标签)。 - 增加“更新远程表结构”动作(当前代码中预留了 DDL 动作位置,见 `myapp/views/view_metadata.py:284`-`287` 的注释代码)。 - 对接统一元数据中心、数据地图或治理平台,形成完整元数据闭环。 --- ### 数据集导入与管理 - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/05-%E6%95%B0%E6%8D%AE%E8%B5%84%E4%BA%A7%E4%B8%8E%E5%A4%84%E7%90%86/%E6%95%B0%E6%8D%AE%E9%9B%86 - 分类: 平台使用 / 数据资产与处理 - 适用场景: 需要把图文音数据集导入平台、用 dataset 算子下载在线数据、上传本地数据到分布式存储,或对数据集做增删改查与备份时阅读 - 关键词: 数据集 / dataset / 数据导入 / sdk导入 / 在线数据 / 本地数据 / dataset模板 / pipeline / 分布式存储 / 数据备份 / backup / 增删改查 - 最后更新: 2026-06-30 # 数据集 ## 简介 数据集一般用于管理图、文、音的数据集。 > 入口:「数据资产」-「数据集」。后端模型 `Dataset`(表名 `dataset`),视图 `dataset_modelview`,列表以卡片形式展示(`myapp/views/view_dataset.py:1343-1347`)。同名数据集可有多个版本(`version` 字段),列表按主版本聚合展示历史版本。 ![输入图片说明](https://foruda.gitee.com/images/1698498705142855198/e8fb600a_1019082.png "屏幕截图") ## 数据集的建立 数据集有三种方式导入到平台。 ### SDK 导入数据集 数据集可以通过 SDK 上传,具体使用方法见 [SDK 使用](../03-在线开发/SDK使用.md)。 ### 在线数据导入 在线数据集可以直接配置下载地址(`download_url` 字段),点击下载地址会直接下载到本地。 ![输入图片说明](https://foruda.gitee.com/images/1698498954082975499/20de1c52_1019082.png "屏幕截图") 想要将在线数据集下载到平台、方便进入模型使用,需要使用 pipeline 的 **dataset 模板**(任务模板 `job-template/job/dataset`)。dataset 模板会把在线数据集下载到平台,保存在分布式存储中,供后续建模、推理等使用。 ![输入图片说明](https://foruda.gitee.com/images/1698499159848734085/bdc97dd9_1019082.png "屏幕截图") > dataset 模板属于任务模板,编排在任务流中执行。详见 [任务模板总览](../../05-任务模板/00-模板总览.md) 与 [任务流编排](../06-任务流与训练/任务流.md)。 ### 本地数据导入 本地数据集上传到平台,需要先用 notebook 把数据上传到分布式存储(参见 [在线开发 / 在线 IDE](../03-在线开发/在线IDE.md)),再在数据集中增加元数据信息,也就是手动添加分布式存储的路径(`path` 字段)。 ## 数据集的增删改查与备份 数据集可以进行增删改查与备份。删改和详情查看在数据集卡片的「更多」按钮处。 备份对应「备份」动作(`save_store`,`myapp/views/view_dataset.py:353`),通过异步任务 `update_dataset` 把数据复制到当前集群的全局目录: ``` /data/k8s/kubeflow/global/dataset/<数据集名>/<版本>/ ``` (路径见 `myapp/tasks/async_task.py:389-394`;删除数据集时该备份目录会被一并清理,见 `myapp/views/view_dataset.py:1330-1334`。版本为空时按 `latest` 处理。) > 注:源文档写作 `/data/k8s/Kubeflow/global/dataset`,代码中目录全为小写 `kubeflow`,已据代码更正。 ![输入图片说明](https://foruda.gitee.com/images/1700396235642858954/f0178a88_1019082.png "屏幕截图") --- ### 数据 ETL 任务流 - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/05-%E6%95%B0%E6%8D%AE%E8%B5%84%E4%BA%A7%E4%B8%8E%E5%A4%84%E7%90%86/%E6%95%B0%E6%8D%AEETL - 分类: 平台使用 / 数据资产与处理 - 适用场景: 需要对接外部数据中台、在平台上编排数据 ETL 任务节点(入库/出库/计算/脚本),并查看任务流 JSON 与运行实例时阅读 - 关键词: 数据ETL / ETL / etl pipeline / 数据中台 / 任务流 / pipeline / 编排 / dag_json / hdfs / hive / spark / sparkjob / hadoop / datax / cos / 数据入库 / 数据出库 - 最后更新: 2026-07-04 # 数据 ETL 任务流 数据 ETL 用于在平台上对接外部数据中台,编排并触发数据 ETL 操作。它是专用于数据 ETL 的任务流:对接数据中台之后,在此处添加数据 ETL 任务流,拖拉拽 ETL 任务模板编排任务节点。 **这里只负责编排任务节点,实际的数据 ETL 任务运行仍在二次开发时对接的外部调度/任务系统上。** > 这是一种特化的任务流(DAG)编排,编排交互与通用 ML 任务流类似,可对照 [任务流编排](../06-任务流与训练/任务流.md);可拖拽的节点模板含义见 [任务模板总览](../../05-任务模板/00-模板总览.md)。 > 入口:「数据 ETL」。后端模型 `ETL_Pipeline`(表名 `etl_pipeline`),视图 `etl_pipeline_modelview`。每条任务流有「计算引擎(workflow)」字段,取值 `etl` 或 `data_analysis`:`data_analysis` 为 CubeStudio 内置的数据分析任务流,`etl` 用于对接外部调度系统(`myapp/views/view_etl_pipeline.py:248,247`)。 ## 新建与编排 点击「数据 ETL」的「新建任务流」,再点击新建好的任务流名称链接,即可进入 pipeline 编排界面(链接指向 `/etl_pipeline_modelview/api/web/`,见 `myapp/models/model_etl_pipeline.py:41`)。 ![输入图片说明](https://foruda.gitee.com/images/1698592047367105187/bc378068_1019082.png "屏幕截图") 生成的任务流编排信息会自动保存为 JSON 格式存入数据库(`ETL_Pipeline.dag_json` 字段,`myapp/models/model_etl_pipeline.py:30`),在任务流详情界面可以查看该 JSON。 ![输入图片说明](https://foruda.gitee.com/images/1700395966442475029/42dbea5f_1019082.png "屏幕截图") 下图是一个典型的 ETL 任务流。左侧边栏有一系列可进行 ETL 操作的模板,拖拉拽需要的模板并配置每个任务节点,即可完成数据中台的数据入库、数据 ETL、数据出库等操作。 ![输入图片说明](https://foruda.gitee.com/images/1698592387085870404/783ca5dd_1019082.png "屏幕截图") ## ETL 任务模板 ETL 编排界面内置的任务模板分为四组(`myapp/views/view_etl_pipeline_etl.py:123,125`): - **绑定任务**:已存在任务、xx 平台任务流 - **出库入库**:hdfs 入库至 hive、hive 出库至 hdfs、hdfs 导入 cos、cos 导入 hdfs - **数据计算**:SparkScala、SQL - **脚本执行**:pyspark、shell > 说明:早期文档曾称「主要是使用 hadoop、sparkjob 等任务模板来实现」,但 ETL 任务流的内置模板实为上列四组(`myapp/views/view_etl_pipeline_etl.py:123`、`:128`-`900`),并无名为 `hadoop` / `sparkjob` 的模板。仓库另有通用 ML pipeline 的 `hadoop`、`spark`、`datax` 任务模板(`job-template/job/`),与此处 ETL 任务流的内置模板不是同一套。除内置模板外,还可通过二次开发扩展模板。 对接数据中台、数据 ETL 的各类模板,除了平台内置的,还可以通过二次开发增加模板(参见「二次开发」相关文档)。 ## 运行与跟踪 任务流提交后会产生运行实例(`ETL_Pipeline_Run`,表名 `etl_pipeline_run`)。列表页可查看每次运行的状态、耗时,并通过「跟踪」查看各 DAG 节点的状态、日志与数据预览(`myapp/models/model_etl_pipeline.py:116-151`)。 --- ### 维表(维度表资产)使用 - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/05-%E6%95%B0%E6%8D%AE%E8%B5%84%E4%BA%A7%E4%B8%8E%E5%A4%84%E7%90%86/%E7%BB%B4%E8%A1%A8 - 分类: 平台使用 / 数据资产与处理 - 适用场景: 需要在平台上登记/管理维度表,配置数据库链接串、扩列、把平台维表同步到远程库,或批量导入导出维表数据时阅读 - 关键词: 维表 / 维度表 / dimension / dimension table / 数据资产 / 远程表 / 更新远程表 / 批量导入 / 批量导出 / 批量清除 / 批量删除 / mysql / postgresql / 链接串 / sqlalchemy_uri / sqllchemy_uri - 最后更新: 2026-06-30 # 维表(维度表资产) 维表用于在平台上登记和管理维度表资产。每条维表记录绑定一个远程数据库(MySQL 或 PostgreSQL)的链接串与表名,平台据此读取/同步表结构与数据,并附带中文名、应用、责任人、描述等业务元信息。 > 入口:「数据资产」-「维表」。后端模型 `Dimension_table`(表名 `dimension`),视图 `dimension_table_modelview`。 ## 新建维表 通过「数据资产」-「维表」-「添加维表」新增维表。维表的表结构信息从 MySQL / PostgreSQL 获取,因此**链接串地址**需要写明数据库类型、账号、密码、IP、端口、库名等信息。其余的应用、标签、描述、责任人等,均为客户自行定义的维表元信息。 链接串支持以下两种格式(见 `myapp/views/view_dimension.py:247,249`): - MySQL:`mysql+pymysql://账号:密码@ip:端口/库名?charset=utf8` - PostgreSQL:`postgresql+psycopg2://账号:密码@ip:端口/库名` > 链接串受正则校验,必须以 `mysql+pymysql://` 或 `postgresql+psycopg2://` 开头(`myapp/views/view_dimension.py:249`)。 ![输入图片说明](https://foruda.gitee.com/images/1700365041831965278/5d3cf436_1019082.png "屏幕截图") 维表可以由用户自行扩充列,定义好列名、字段类型等,在基础字段之外新增字段。列信息保存在维表记录的 `columns` 字段中。 ![输入图片说明](https://foruda.gitee.com/images/1700365334633884621/f7142e61_1019082.png "屏幕截图") > 权限:维表的「责任人(owner)」字段以逗号分隔多个用户,`*` 表示全部可见。只有管理员、或维表明确列出的责任人才能编辑维表结构、增删远程数据、清空、批量上传、更新远程表(`myapp/views/view_dimension.py` 中 `user_can_view_dimension_data` / `user_can_edit_dimension_data`)。 ## 修改维表 在每个维表最后的「更多」按钮中,点击「修改」即可更改维表信息。 ![输入图片说明](https://foruda.gitee.com/images/1700365470055336046/86968299_1019082.png "屏幕截图") ## 删除维表 在每个维表最后的「更多」按钮中,点击「删除」即可删除该维表记录。 > 说明:删除的是平台上的维表登记记录,不会改动远程数据库中的真实表。 ## 更新维表(同步到远程) 点击「更新远程表」可以把平台上更新的维表结构同步到远程数据库。该操作对应接口 `GET /dimension_table_modelview/api/create_remote_table/`(`myapp/views/view_dimension.py:415-417`),会按平台维表的列定义在远程库中创建/更新对应的表结构。 ![输入图片说明](https://foruda.gitee.com/images/1700366150056336603/4884f264_1019082.png "屏幕截图") ## 清空与批量删除 - **清空(clear)**:清空选中维表在远程库中的所有数据内容。对应 `clear` 动作(`myapp/views/view_dimension.py:389` 的 `delete_all`),该动作标注为 `single=True, multiple=False`,即一次只能对单个维表执行清空,不支持列表多选。 - **批量删除**:删除选中维表在平台上的登记记录(支持列表多选,走框架默认 delete 动作),但**不更改远程数据库中的真实表数据**。 ## 批量导入导出 点击单个维表的表名链接,可进入该维表的数据查看界面(前端 `metadata_dimension` 页面,`myapp/models/model_dimension.py:33,36`)。例如点击表名为「aihub 应用」的维表链接,进入「aihub 应用」的数据列表,在此界面可对该维表数据进行批量导入和导出。 相关接口(`myapp/views/view_dimension.py`): - 批量上传:`POST /dimension_table_modelview/api//api/upload/` - 下载上传模板:`GET /dimension_table_modelview/api//api/download_template/` - 批量下载:`GET /dimension_table_modelview/api//api/download/` - 单行增删改查:`/dimension_table_modelview/api//api/`(GET 列表 / POST 新增 / `` 的 PUT、DELETE) ![输入图片说明](https://foruda.gitee.com/images/1700366693370244461/77407159_1019082.png "屏幕截图") --- ### 指标(数据资产指标管理) - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/05-%E6%95%B0%E6%8D%AE%E8%B5%84%E4%BA%A7%E4%B8%8E%E5%A4%84%E7%90%86/%E6%8C%87%E6%A0%87 - 分类: 平台使用 / 数据资产与处理 - 适用场景: 在数据资产中批量导入/新增/删除业务指标时读这篇 - 关键词: 指标 / metric / 数据资产 / 指标导入 / 批量导入 / 新增指标 / 删除指标 / 原子指标 / 衍生指标 / metadata_metric - 最后更新: 2026-06-30 # 指标(数据资产指标管理) 数据资产中的“指标”用于登记业务指标(指标英文名/中文名、类型、等级、维度、口径、责任人等)。 > 后端入口:`Metadata_metric_ModelView_Api`,`route_base = /metadata_metric_modelview/api`(见 `myapp/views/view_metadata_metric.py:193`,对应数据表 `metadata_metric`,见 `myapp/models/model_metadata_metric.py:19`)。 ## 指标导入 指标可以批量导入。在批量导入数据这里,下载导入模板,批量填好信息,再上传 csv,即可批量导入指标(批量导入能力对应 `import_data=True`,见 `myapp/views/view_metadata_metric.py:168`;同时支持导出 `download_data=True`)。 ![输入图片说明](https://foruda.gitee.com/images/1700040256412791344/537e2394_1019082.png "屏幕截图") ## 新增指标 数据资产 - 指标 - 添加指标,可新增指标。主要字段包括:产品(`app`)、名称(`name`,指标英文名,限 ASCII)、标签(`label`,指标中文名)、描述、指标类型(原子指标/衍生指标)、归属模块、指标等级(普通/重要/核心)、指标维度(day/week/month)、责任人(`owner`,逗号分隔,`*` 表示公开)、口径、任务 id(字段定义见 `myapp/views/view_metadata_metric.py:88`-`165`)。 > 新增/编辑时,若 `owner` 为空或仅为 `*`,系统会自动写为 `当前用户名,*`(见 `myapp/views/view_metadata_metric.py:171`-`175`)。 ![输入图片说明](https://foruda.gitee.com/images/1700040731314377386/f4b68d03_1019082.png "屏幕截图") ## 删除指标 在单个指标末尾处有个“更多”按钮,点击此按钮可以查看指标详情、修改指标、删除指标。 ![输入图片说明](https://foruda.gitee.com/images/1700041036633658585/f8e79a57_1019082.png "屏幕截图") 选中需要删除的指标,还可以批量删除。 > 批量删除时仅会删除“本人创建”的记录(管理员可删除任意记录),其余记录会被跳过(`muldelete`,见 `myapp/views/view_metadata_metric.py:177`-`188`)。 ![输入图片说明](https://foruda.gitee.com/images/1700041100546767919/83b7afd4_1019082.png "屏幕截图") --- ### SQLLab 在线数据库查询 - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/05-%E6%95%B0%E6%8D%AE%E8%B5%84%E4%BA%A7%E4%B8%8E%E5%A4%84%E7%90%86/SQLLab - 分类: 平台使用 / 数据资产与处理 - 适用场景: 想在平台内直接连接 MySQL/PostgreSQL/ClickHouse/Hive 等数据库执行 SQL 查询并查看/下载结果时阅读 - 关键词: SQLLab / sqllab / idex / SQL查询 / 在线查询 / 数据库连接 / mysql / postgresql / clickhouse / hive / presto / impala / 达梦 / dm / gauss / select / limit - 最后更新: 2026-06-30 # SQLLab 在线数据库查询 ## 一、SQLLab 简介 SQLLab 用来对接各类型数据库,可以在计算平台内直接查询数据库中的数据,避免在计算平台和数据库客户端之间来回切换。 查询采用异步任务方式执行:提交查询后生成一条查询记录(异步任务),平台轮询任务状态,运行结束后可在线查看或下载结果。 ## 二、SQLLab 使用 ### 1. 连接数据库 选择好数据库类型(引擎)后,按照规定的格式填写连接串(含用户名、密码、主机、端口、库名等)。 平台内置支持的引擎及连接串模板如下(来源:`myapp/views/view_sqllab.py:41-51` 的 `db_uri_demo`): | 引擎 (engine) | 连接串模板 | |---|---| | mysql | `mysql+pymysql://$username:$password@$host:3306/$database` | | postgres | `postgresql+psycopg2://$username:$password@$host:5432/$database` | | clickhouse | `clickhouse+native://$username:$password@$host:9000/$database` | | hive | `hive://$host:10000/default?auth=NOSASL` | | presto | `presto://$username:$password@$host:8080/$catalog/$schema` | | impala | `impala://host:port/database` | | dm(达梦) | `dm+dmPython://$username:$password@$host:5236/$schema` | | gauss | `postgresql+psycopg2://$username:$password@$host:5432/$database` | > 说明:平台还会把你近 30 天内查询成功过的连接串自动加入下拉候选,方便复用(`view_sqllab.py:109-111`)。 历史文档中常用示例: - MySQL:`mysql+pymysql://:@mysql-service.infra:3306/` - PostgreSQL:`postgresql+psycopg2://:@postgresql.kubeflow:5432/` - ClickHouse:`clickhouse+native://username:password@host:port/database`(默认端口 9000) - Hive:`hive://host:10000/default?auth=NOSASL` 或 `hive://username:passwd@host:10000/default?auth=LDAP` ### 2. 查询数据库 在 SQLLab 窗口中填写需要查询的语句,点击运行即可。查询结果可以在线查看,也可以下载(结果以 CSV 形式保存在服务端 `/data/k8s/kubeflow/global/sqllab/result/<查询id>.csv`,见 `myapp/utils/sqllab/base_impl.py:67`)。 注意事项: - **SQL 必须包含 `limit`**:这是平台的硬性校验,不含 `limit` 会直接报错"查询sql必须包含limit"(`myapp/utils/sqllab/base_impl.py:53-54`)。 - **仅适合 select 查询**:查询通过 `pandas.read_sql_query` 执行(`view_sqllab.py` 异步任务 `handle_task`),因此实际只适合 select 类只读查询。 > 说明:代码层面只强制校验"SQL 必须包含 limit"(`myapp/utils/sqllab/base_impl.py:53-54`),并无针对非 select 语句的显式拦截。"仅支持 select"是执行方式的天然限制——查询通过 `pandas.read_sql_query` / `read_sql` 执行(`base_impl.py:73`、`:82`、`:89`),只适合返回结果集的只读查询。 ![](https://foruda.gitee.com/images/1698378204862496999/c9dd9cb4_1019082.png) #### MySQL 查询示例 SQL: ```sql select * from ab_user limit 1; ``` 数据库:`mysql+pymysql://:@mysql-service.infra:3306/` #### PostgreSQL 查询示例 SQL: ```sql select * from task limit 1; ``` 数据库:`postgresql+psycopg2://:@postgresql.kubeflow:5432/` #### ClickHouse 查询示例 SQL: ```sql select * from task limit 1; ``` 数据库:`clickhouse+native://username:password@host:port/database` #### Hive 查询示例 SQL: ```sql select * from test limit 1; ``` 数据库:`hive://host:10000/default?auth=NOSASL` 或 `hive://username:passwd@host:10000/default?auth=LDAP` 在线查看查询结果如图所示: ![输入图片说明](https://foruda.gitee.com/images/1698378827234990067/6359d2eb_1019082.png "屏幕截图") ### 3. 可能出现的错误 如果查询任务运行显示 fail,排查顺序: 1. 数据库的账号、密码、主机、端口等连接信息是否正确; 2. 所写的查询语句是否被支持、是否正确; 3. 是否加了 `limit`(未加 limit 必报错)。 ## 三、接口参考(供检索) SQLLab 后端路由前缀为 `/idex`(`myapp/views/view_sqllab.py:103` 中 `route_base = '/idex'`),主要接口: | 接口 | 方法 | 说明 | |---|---|---| | `/idex/config` | GET/POST | 获取引擎与连接串候选配置 | | `/idex/submit_task` | POST | 提交 SQL 查询任务,返回 `task_id` | | `/idex/look/` | GET | 查询任务状态(stage/state 等) | | `/idex/result/` | GET | 获取查询结果 | | `/idex/download_url/` | GET | 获取结果下载地址 | | `/idex/stop/` | GET | 终止查询任务 | > 浏览器侧访问后端接口需带 `/backend` 前缀(平台 URL 前缀架构),上表为后端实际路由路径。 --- ### NNI 超参搜索 - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/06-%E4%BB%BB%E5%8A%A1%E6%B5%81%E4%B8%8E%E8%AE%AD%E7%BB%83/%E8%B6%85%E5%8F%82%E6%90%9C%E7%B4%A2 - 分类: 平台使用 / 任务流与训练 - 适用场景: 想用 NNI 在平台上做超参数自动搜索(编写可接收超参的代码、配置参数空间与算法、启动并查看搜索结果)时阅读 - 关键词: 超参搜索 / 超参数优化 / NNI / nni / AutoML / HPO / hyperparameter / tuner / TPE / 参数空间 / search space / report_final_result / report_intermediate_result / trial - 最后更新: 2026-06-30 # NNI 超参搜索介绍 NNI(Neural Network Intelligence)是微软开源的一个 AutoML 工具包,用于超参数优化、神经架构搜索、模型压缩和特征工程。 NNI 的超参搜索支持更多的算法。同时在 pipeline 中也支持了"边训练边超参搜索"的模板。只需要用户的代码能接受超参数作为输入,同时上报作为超参算法的目标值即可。 每个用户可以启动多个超参搜索的实例,通过 url prefix(`/nni/<实验名>/`)作为前端的路由(路由前缀实现见 `myapp/views/view_nni.py:434`,nni web 服务监听容器内 `8888` 端口)。 可以参考 [NNI 官网](https://github.com/microsoft/nni) 的书写方式。 # NNI 超参搜索 ## 1、编写超参搜索代码 ### 参数接收 启动超参搜索时,会根据用户配置的超参搜索算法选择好超参的可选值,并将选择值传递给用户的容器。例如下面的超参定义会在用户 docker 运行时传递下面的参数。所以用户不需要在启动命令或参数中添加这些变量,系统会自动添加,用户只需要在自己的业务代码中接收这些参数,并根据这些参数输出值即可。 ``` --lr=0.021593113434583065 --num-layers=5 --optimizer=ftrl ``` ### 结果上报 业务方容器和代码启动接收超参进行迭代计算,通过主动上报结果来进行迭代。示例如下:用户代码需要能接受超参可取值为输入参数,同时每次迭代通过 `nni.report_intermediate_result` 上报每次 epoch 的结果值,并使用 `nni.report_final_result` 上报每次实例的最终结果值。 ```python import os import argparse import logging, random, time import nni from nni.utils import merge_parameter logger = logging.getLogger('mnist_AutoML') def main(args): test_acc = random.randint(30, 50) for epoch in range(1, 11): test_acc_epoch = random.randint(3, 5) time.sleep(3) test_acc += test_acc_epoch # 上报当前迭代目标值 nni.report_intermediate_result(test_acc) # 上报最终目标值 nni.report_final_result(test_acc) def get_params(): # 必须接收超参数为输入参数 parser = argparse.ArgumentParser(description='PyTorch MNIST Example') parser.add_argument('--batch_size', type=int, default=64, help='input batch size for training (default: 64)') args, _ = parser.parse_known_args() return args if __name__ == '__main__': try: # get parameters form tuner tuner_params = nni.get_next_parameter() params = vars(merge_parameter(get_params(), tuner_params)) print(tuner_params, params) main(params) except Exception as exception: logger.exception(exception) raise ``` ## 2、添加一个超参搜索实验 ![在这里插入图片描述](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/nni1.png) 创建实验时需要配置:搜索算法、目标函数类型(maximize/minimize)、目标指标名、超参数(搜索空间)、任务镜像、工作目录、启动命令、资源(cpu/memory/gpu)、任务并行数、最大任务数、最大运行时长、任务并行方式等。 > 平台实际可选的搜索算法(`myapp/views/view_nni.py:191-206`):TPE、Random、Anneal、Evolution、SMAC、BatchTuner、GridSearch、Hyperband、NetworkMorphism、MetisTuner、BOHB、GPTuner、PPOTuner、PBTTuner。 > > 任务并行方式(`parallel_trial_type`)有两种(`view_nni.py:132-138`): > - `multi-process`:单机多进程,平台创建单个 nni Pod 运行(`make_nnijob`); > - `multi-machine`:多机多进程,平台创建 Volcano Job 拉起 master + 多个 worker(`make_volcanojob`)。 ### 不同超参算法支持不同的超参空间 下表为 NNI 各 Tuner 对不同搜索空间类型的支持情况(参考 NNI 官方文档): | Tuner | choice | choice(nested) | randint | uniform | quniform | loguniform | qloguniform | normal | qnormal | lognormal | qlognormal | | :----- | :----- | :----- | :----- | :----- | :----- | :----- | :----- | :----- | :----- | :----- | :----- | | TPE Tuner | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | Random Search Tuner | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | Anneal Tuner | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | Evolution Tuner | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | SMAC Tuner | ✓ | | ✓ | ✓ | ✓ | ✓ | | | | | | | Batch Tuner | ✓ | | | | | | | | | | | | Grid Search Tuner | ✓ | | ✓ | | ✓ | | | | | | | | Hyperband Advisor | ✓ | | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | Metis Tuner | ✓ | | ✓ | ✓ | ✓ | | | | | | | | GP Tuner | ✓ | | ✓ | ✓ | ✓ | ✓ | ✓ | | | | | ### 超参空间 必须是标准的 json。示例: ```json { "batch_size": {"_type":"choice", "_value": [16, 32, 64, 128]}, "hidden_size":{"_type":"choice","_value":[128, 256, 512, 1024]}, "lr":{"_type":"choice","_value":[0.0001, 0.001, 0.01, 0.1]}, "momentum":{"_type":"uniform","_value":[0, 1]} } ``` > 该示例与平台内置示例 `core.nni_parameters_demo()` 一致(`myapp/utils/core.py:574`)。 ## 3、启动超参搜索 点击 `运行 | 容器 | 日志 | 清理` 中的 `运行` 按钮: - **运行**按钮:启动搜索实验(部署 nni 服务,接口 `/nni_modelview/api/run/`,`view_nni.py:791`); - **容器**按钮:查看搜索实验容器运行状况; - **日志**按钮:查看平台日志(这里不是业务代码日志,接口 `/nni_modelview/api/log/`,`view_nni.py:925`); - **清理**按钮:删除清理实验(接口 `/nni_modelview/api/stop/`,`view_nni.py:776`)。 ## 4、查看超参搜索进度和结果 等待全部容器运行中时,点击名称,进入 web 界面查看实验进度和日志(跳转到 `/nni/<实验名>/`,`view_nni.py:938-954`)。 ### web 查看搜索效果 总览界面可以看到实验的 id 和当前实例运行的状态。 ![输入图片说明](https://foruda.gitee.com/images/1700641607516569138/baa97cc1_13742376.png "屏幕截图") ![输入图片说明](https://foruda.gitee.com/images/1700641625773844009/413851da_13742376.png "屏幕截图") 可以看每次 trial 的运行情况、计算出来的目标值。 ![输入图片说明](https://foruda.gitee.com/images/1700641645771764051/b36dcf56_13742376.png "屏幕截图") 也可以看某次 trial 中每次 epoch 得到的结果值。 ### 分布式超参搜索日志查看 由于是分布式进行超参数搜索,日志保存在分布式存储。想看某次搜索运行实例的日志: ![在这里插入图片描述](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/nni2.png) 在 web 界面看到的日志地址为: ``` Trial stdout: file://test-worker-2.test:/tmp/nni-experiments/$实验名/envs/$任务名 ``` 则对应分布式存储日志路径地址为: ``` /mnt/$用户名/nni/$nni名称/log/$实验名/envs/$任务名 ``` > 说明:nni 代码、配置和 log 都在 `/mnt/${username}/nni/` 目录下。实验工作目录为 `/mnt//nni//log/`,容器内 `/tmp/nni-experiments/` 挂载到该 log 目录(`view_nni.py:393/489/834`)。 ![在这里插入图片描述](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/nni3.png) ## 5、清理超参搜索实验 点击 `运行 | 容器 | 日志 | 清理` 中的 `清理` 按钮。运行结束后记得主动清理,以释放集群资源。 --- ### 任务可视化 echart 数据格式说明 - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/06-%E4%BB%BB%E5%8A%A1%E6%B5%81%E4%B8%8E%E8%AE%AD%E7%BB%83/%E4%BB%BB%E5%8A%A1%E5%8F%AF%E8%A7%86%E5%8C%96echart%E6%95%B0%E6%8D%AE%E6%A0%BC%E5%BC%8F - 分类: 平台使用 / 任务流与训练 - 适用场景: 任务/算子要在任务流运行结果里输出 ECharts 图表时,如何准备 CSV/JSON 数据并通过 metric.json 关联可视化 - 关键词: echart / ECharts / py_echart / 任务可视化 / metric.json / 图表 / chart / 折线图 line / 柱状图 bar / 饼图 pie / 散点图 scatter / 雷达图 radar / K线图 candlestick / 热力图 heatmap / 漏斗图 funnel / 平行坐标 parallel / 树图 tree / 旭日图 sunburst / CSV / JSON / draw - 最后更新: 2026-06-30 # 任务可视化 echart 数据格式说明 本文档说明如何准备 **CSV** 或 **JSON** 数据,以便使用 `py_echart` 生成各类 ECharts 图表,并在任务流运行结果中以可视化形式展示。 支持的文件格式:`.csv`(表格类图表)、`.json`(树形/层级类图表)。 > 实现源码:`myapp/utils/py/py_echart.py`(任务流可视化插件版本为 `myapp/utils/plugin/plugin_echart.py`)。 --- ## 一、通用说明 - **CSV**:第一行为表头(列名),从第二行起为数据行;列之间用逗号分隔。 - **JSON**:仅用于 **树图** 和 **旭日图**,需为层级结构。 - 表头(列名)会作为图例名或坐标轴名称使用,请使用有意义的名称。 --- ## 二、各图表类型的数据格式 ### 1. 折线图 (line) **数据含义**:第 1 列为 X 轴类目;其余每一列为一组折线,列名为图例。 **CSV 示例:** ```csv 月份,销售额,成本,利润 1月,120,80,40 2月,200,120,80 3月,150,90,60 4月,280,160,120 ``` - 第 1 列:X 轴(如月份)。 - 第 2~N 列:每条线对应一列,列名为图例(如「销售额」「成本」「利润」)。 --- ### 2. 柱状图 (bar) **数据含义**:第 1 列为类目(如型号/名称);其余列为不同系列的柱形,列名为图例。 **CSV 示例:** ```csv 型号,分数A,分数B,分数C 模型1,43.3,85.8,93.7 模型2,83.1,73.4,55.1 模型3,86.4,65.2,82.5 ``` - 第 1 列:横轴类目(如型号)。 - 其余列:每个类目下多根柱子,列名为图例。 --- ### 3. 饼图 (pie) **数据含义**:第 1 列为扇区名称;其余每一列对应一张饼图(多列会生成多张饼图并排),列名为该图的标题。 **CSV 示例:** ```csv 类别,占比2023,占比2024 产品A,35,40 产品B,25,30 产品C,40,30 ``` - 第 1 列:扇区名称(如类别)。 - 第 2~N 列:每列数值为一张饼图,列名作为该图标题。 --- ### 4. 散点图 (scatter) **数据含义**:与折线图相同——第 1 列为 X 轴类目,其余列为多组散点,列名为图例。 **CSV 示例:** ```csv 批次,组A,组B,组C 第1批,12,25,18 第2批,30,22,35 第3批,15,40,28 ``` --- ### 5. 雷达图 (radar) **数据含义**:第 1 列为维度名称(雷达各轴);其余每一列为一组雷达数据(一个多边形),列名为图例。 **CSV 示例:** ```csv 维度,张三,李四,王五 销售,90,70,85 管理,80,85,75 技术,85,90,80 客服,75,80,90 研发,88,82,78 ``` - 第 1 列:雷达轴名称(维度)。 - 第 2~N 列:每个人/实体在各维度上的数值,列名为图例。 --- ### 6. K 线图 (candlestick) **数据含义**:第 1 列为时间或类目;第 2~5 列依次为 **开盘、最高、最低、收盘**(OHLC);第 6 列及以后为叠加的折线(可选)。 **CSV 示例:** ```csv 日期,开盘,最高,最低,收盘,成交量 2024-01-02,100,105,98,103,1000 2024-01-03,103,108,102,106,1200 2024-01-04,106,110,104,107,900 ``` - 第 1 列:日期或类目。 - 第 2~5 列:必须为 4 列,顺序为 开盘、最高、最低、收盘。 - 第 6 列起(可选):叠加的折线,列名为图例。 --- ### 7. 热力图 (heatmap) **数据含义**:第 1 列为 X 轴类目;其余列名为 Y 轴类目;单元格数值为颜色深浅。 **CSV 示例:** ```csv 时段,周一,周二,周三,周四,周五 9-10,23,45,12,34,56 10-11,45,67,34,56,78 11-12,12,34,56,78,23 ``` - 第 1 列:X 轴(如时段)。 - 第 2~N 列:列名为 Y 轴(如周一~周五),数值为热力值。 --- ### 8. 漏斗图 (funnel) **数据含义**:第 1 列为阶段名称;其余每一列为一组漏斗数据,列名为图例。 **CSV 示例:** ```csv 阶段,渠道A,渠道B 访问,1000,800 注册,600,500 下单,300,280 支付,200,220 ``` - 第 1 列:漏斗阶段名称。 - 第 2~N 列:每个渠道在该阶段的数值,列名为图例。 > 注意:任务流可视化通过 `view_workflow.py:1016` 调用 `myapp/utils/py/py_echart.py` 的统一入口 `draw()`。源码虽定义了 `draw_funnel`(`py_echart.py:417`),但 `draw()` 的分发分支(`py_echart.py:520-547`)中 **没有** `funnel`,因此当前通过 `echart-funnel` 暂不会渲染漏斗图(`draw('funnel', ...)` 返回空)。上方 CSV 数据格式作为约定保留,待 `draw()` 接入 `funnel` 分支后即可生效。 --- ### 9. 平行坐标系 (parallel) **数据含义**:每一列为一个坐标轴(维度),每一行为一条线(一个样本);支持数值列和字符串列(字符串会按类目轴处理)。 **CSV 示例:** ```csv 价格,销量,评分,地区 100,200,4.5,华北 150,180,4.2,华南 80,250,4.8,华东 ``` - 每列:一个维度(轴)。 - 每行:一条折线穿过各轴上的取值。 - 数值列自动按最小/最大缩放;字符串列会作为类目轴。 > 注意:任务流可视化通过 `view_workflow.py:1016` 调用 `myapp/utils/py/py_echart.py` 的 `draw()`,其中已分发 `parallel`(`py_echart.py:546`),平行坐标系可正常生效。另一份 `plugin_echart.py` 的 `draw()` 未包含 `parallel` 分支,但任务可视化并未使用该实现(仓库中无导入方)。 --- ### 10. 树图 (tree) — 仅 JSON **数据含义**:层级结构。每个节点有 `name`,子节点放在 `children` 中。若根级是数组,会自动包在一个名为 `root` 的根节点下。 **JSON 示例(单根):** ```json { "name": "根节点", "children": [ { "name": "分支A", "children": [ { "name": "叶子A1" }, { "name": "叶子A2" } ] }, { "name": "分支B", "children": [ { "name": "叶子B1" } ] } ] } ``` **JSON 示例(多根,会合并为 root):** ```json [ { "name": "节点1", "children": [ { "name": "子节点1-1" } ] }, { "name": "节点2", "children": [] } ] ``` --- ### 11. 旭日图 (sunburst) — 仅 JSON **数据含义**:与树图类似的层级结构,用于旭日图展示;顶层为内圈,逐层向外。 **JSON 示例:** ```json [ { "name": "类别1", "value": 100, "children": [ { "name": "子类1-1", "value": 60 }, { "name": "子类1-2", "value": 40 } ] }, { "name": "类别2", "value": 80, "children": [ { "name": "子类2-1", "value": 50 } ] } ] ``` - `name`:节点名称。 - `value`:该节点数值(影响扇区大小)。 - `children`:子节点,结构同上。 --- ## 三、图表类型与文件格式对照 | 图表类型 | 英文类型名 | 支持 CSV | 支持 JSON | `draw()` 已分发 | |------------|--------------|----------|-----------|------------------| | 折线图 | line | ✅ | ❌ | ✅ | | 柱状图 | bar | ✅ | ❌ | ✅ | | 饼图 | pie | ✅ | ❌ | ✅ | | 散点图 | scatter | ✅ | ❌ | ✅ | | 雷达图 | radar | ✅ | ❌ | ✅ | | K 线图 | candlestick | ✅ | ❌ | ✅ | | 热力图 | heatmap | ✅ | ❌ | ✅ | | 漏斗图 | funnel | ✅ | ❌ | ⚠️ 未分发(见上) | | 平行坐标系 | parallel | ✅ | ❌ | ⚠️ 仅 py 版本分发 | | 树图 | tree | ❌ | ✅ | ✅ | | 旭日图 | sunburst | ❌ | ✅ | ✅ | > 「`draw()` 已分发」一列依据 `myapp/utils/py/py_echart.py` 的 `draw()` 入口;任务流可视化插件 `plugin_echart.py` 的支持范围略窄(不含 parallel、funnel)。 --- ## 四、使用方式简述 在代码中通过 `draw(chart_type, file_path)` 调用(`myapp/utils/py/py_echart.py:520`): - `chart_type`:上表中的「英文类型名」,如 `'line'`、`'bar'`、`'pie'`、`'tree'` 等。 - `file_path`:CSV 或 JSON 文件的路径(树图、旭日图请使用 JSON)。 按上述格式准备 CSV/JSON 后,即可生成对应类型的 ECharts 图表配置。 ## 五、与任务流 metric.json 的配合 任务/算子在运行目录中写出 `metric.json`,平台据此在任务流运行结果页渲染 ECharts 图表。`metric.json` 形如(源码示例见 `myapp/utils/py/py_echart.py:566-571`): ```json { "metric_type": "echart-parallel", "file_path": "/mnt/admin/pipeline/ray_hyperparams/hyperparams_r_lightgbm.csv" } ``` - `metric_type`:`echart-`,其中 `` 取上表英文类型名(如 `echart-line`、`echart-bar`、`echart-parallel`)。 - `file_path`:上述格式的 CSV/JSON 数据文件路径。 任务流的整体使用见同目录 [任务流.md](任务流.md)。 --- ### 任务流(Pipeline)编排与调度 - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/06-%E4%BB%BB%E5%8A%A1%E6%B5%81%E4%B8%8E%E8%AE%AD%E7%BB%83/%E4%BB%BB%E5%8A%A1%E6%B5%81 - 分类: 平台使用 / 任务流与训练 - 适用场景: 想用拖拽方式编排 ML 流水线、配置任务资源、调试单任务、设置定时调度、传递变量、查看可视化结果或导入导出 pipeline 时阅读 - 关键词: 任务流 / pipeline / 编排 / DAG / 工作流 / workflow / 定时调度 / crontab / 调试 / debug / GPU / 全局变量 / 模板变量 / 系统环境变量 / KFJ_TASK / metric.json / 结果可视化 / 导入导出 / 补录 / catchup - 最后更新: 2026-06-30 # 任务流编排 平台有很多封装好的模板,比如数据导入、数据预处理、各种机器学习算法。可以将需要的模板按照计划执行的顺序拖拽(长按左侧任务模板拖拽,到指定位置松开)到面板中,按顺序连接起来。 > 每个任务模板的字段含义与使用方法,请参考 **05-任务模板** 段中对应模板的说明。 ![输入图片说明](https://foruda.gitee.com/images/1698632190283236558/5e9b9ea1_1019082.png "屏幕截图") 点击"运行",可验证任务流的执行顺序是否与编排的、期望的顺序一致。 ![输入图片说明](https://foruda.gitee.com/images/1700471865648240390/f747d05a_1019082.png "屏幕截图") ## 首页展示 如果想在首页展示编排好的任务流,可以在"模型训练"-"任务流"-"更多"-"修改"中,找到扩展参数,填写如: ```json { "demo": "true", "img": "/static/assets/images/pipeline/yolo.jpg" } ``` 设置 `demo` 为 `true` 则可在首页(示例 pipeline 列表)展示,必须同时配 `img` 参数,配一张图片才可以。 > 实现说明:该参数保存在 pipeline 的 `parameter` 字段,首页示例列表通过筛选 `"demo": "true"` 取出(`myapp/views/view_pipeline.py:1521-1524` 的 `/demo/list/` 接口)。标记为 `demo` 的示例 pipeline 不允许直接修改,需复制后编辑(`view_pipeline.py:1395-1396`)。 ![输入图片说明](https://foruda.gitee.com/images/1700548120735734702/f21173cd_1019082.png "屏幕截图") ## 任务配置 模板拖拽到面板区后,就形成了任务节点。点击任务节点,可以对任务进行配置,具体的配置方法和每个模板的设计有关,需要参照对应模板的使用说明(见 **05-任务模板**)。 ![输入图片说明](https://foruda.gitee.com/images/1698649557142724593/1f64a44d_1019082.png "屏幕截图") 任务还支持配置跳过、重试等,方便在执行过程中可根据情况调整适应。 ![输入图片说明](https://foruda.gitee.com/images/1700641860055442367/1276f210_13742376.png "屏幕截图") ### CPU、GPU 申请 任务的配置支持 CPU、GPU 配置,可以配置任务需要的内存资源、CPU、GPU 资源等。任务运行时,会自动根据申请的资源及资源状况进行分配。 GPU 支持多种卡型,比如填写 `1(V100)` 表示申请 1 张 V100 的 GPU 卡。平台目前支持不同 GPU 卡型(如 T4/V100/A100 等),还支持国产 GPU,如海光的 DCU、华为的 NPU。 任务对 CPU/GPU 等资源的占用,支持独占 GPU、共享 GPU 和 VGPU 等占用方式,以满足不同任务对资源需求的场景。如 `1`、`2` 表示独占;`0.1(T4)` 表示 VGPU;`-1` 表示共享。 ![输入图片说明](https://foruda.gitee.com/images/1700034313338817800/8d6d0ada_1019082.png "屏幕截图") ### 单任务运行、调试 单个任务节点可以独立进行调试。点击 Debug 是进入命令行进行调试,点击 Run 是直接运行模板的 py 文件,log 可以查看调试日志,clear 清除调试任务。 ![输入图片说明](https://foruda.gitee.com/images/1698649606682765417/850b1a8b_1019082.png "屏幕截图") 通过 notebook 我们可以进行代码的编辑,通过镜像调试,我们可以构建自己的镜像,然后就可以编排 pipeline 了。pipeline 运行前需要独立运行调试单个 task,所以平台添加了单 task 独立调试的功能。 ![输入图片说明](https://foruda.gitee.com/images/1700641885196271544/79c66294_13742376.png "屏幕截图") 每个 task 都可以独立 debug 和独立运行,这样就不用每次都运行整体 pipeline 才能进行调试。对于分布式任务的 task,平台在模板中借用 stern 实现了多个容器 log 聚合查看,这样就不用每个 worker 的日志都单独去看了。 ![在这里插入图片描述](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/mlrenwuchakan.png) **单个任务为分布式任务时:** 往往某个任务需要是分布式任务,需要启动分布式任务。云原生分布式任务需要 k8s 对应的 operator。分布式算法模板的实现方法,主要在模板中实现 launcher,创建对应分布式任务的 job yaml,提交到 k8s,对应的 job operator 创建每个 worker 的 pod 和 service,然后运行业务代码。launcher 端启动 stern 组件,监听该分布式任务所有 pod 的日志并输出,这样就可以在当前任务中查看到所有 worker 的日志。 ![输入图片说明](https://foruda.gitee.com/images/1700641913128211817/92d3f69f_13742376.png "屏幕截图") 每个任务启动后都可以看到相应的资源情况,这样可以边调试边配置资源的申请量,在 GPU 上也可以及时知道是否还有优化的空间、目前任务的主要瓶颈在哪里,更加直观地确定优化方向。 ![在这里插入图片描述](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/mlrenwuziyuan.png) ### 自定义镜像调试 有一个比较特殊的模板,是模板分类"基础命令"下面的"自定义镜像"模板。其他任务节点的调试都是为了调试模板对应的 py 文件,而自定义镜像是为了提供一个可视化面板,可以调试用户封装的镜像,避免有部分用户不熟悉镜像调试。 ### 任务其他参数配置 如果想修改其他任务配置,比如任务挂载、启动命令、启动目录,可以按照图中的方法修改: ![在这里插入图片描述](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/mlrenwucanshu1.png) ![在这里插入图片描述](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/mlrenwucanshu2.png) ![在这里插入图片描述](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/mlrenwucanshu3.png) ### 任务流中监听端口 部分特殊的模板需要在运行期间监听端口,比如 spark 任务提交,任务作为 spark driver 端需要监听端口。需要在此类任务的任务模板的扩展中添加扩展参数:`HostNetwork=True`。 ![在这里插入图片描述](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/mlrenwuduankou1.png) 则任务运行时会自动占用指派的端口,端口会以环境变量 `PORT1`、`PORT2` 的形式告诉代码,代码自行决定如何使用。 ![在这里插入图片描述](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/mlrenwuduankou2.png) ## 任务流配置 任务流也可以进行配置,主要是配置定时调度、项目组、任务流运行状态的监控及报警等。 ![输入图片说明](https://foruda.gitee.com/images/1698650109364232508/e5a3f204_1019082.png "屏幕截图") 1. **调度类型(schedule_type)**:触发任务流运行的方式,`crontab` 为定时触发,`once` 为手动触发。设置为定时触发的任务,也可以同时被手动触发,相互不影响。默认 `once`。 2. **调度周期(cron_time)**:定时触发任务的定时周期,格式 `* * * * *` 表示 minute hour day month week。 3. **监控状态(alert_status)**:当任务流达到哪些状态时会触发报警推送消息。可选状态:Created、Pending、Running、Succeeded、Failed、Unknown、Waiting、Terminated。 4. **报警人(alert_user)**:达到想要监控的状态时,发送消息给哪些用户。 5. **补录起点(cronjob_start_time)**:对于定时任务,每个定时周期触发时间点都需要设置启动任务,这个定时周期最开始计算的时间起点。默认设置为定时周期或修改定时周期的时间点。 6. **过往依赖(depends_on_past)**:定时任务每次实例运行时是否检查上一次的任务流是否完成,若完成才可以调度新一轮周期的任务流实例。默认 `True`。 7. **最大激活运行数(max_active_runs)**:同时可以运行的任务流实例数目。默认 `1`。 8. **任务并行数(parallelism)**:同一个任务流实例中,同时可以运行的任务数目。默认 `3`。 9. **全局环境变量(global_env)**:为任务流中每个任务都会添加的环境变量,每行一个,支持 `datetime/creator/runner/uuid/pipeline_id` 等模板变量,例如 `USERNAME={{creator}}`。 > 字段默认值与说明来源:`myapp/views/view_pipeline.py:1107-1214`。另有 `expired_limit`(过期保留数,定时调度最新实例限制数目,0 表示不限制,默认 1)和 `priority`(优先级,high/low,资源不足时低优先级会主动让出资源)。 另有一个值得一提的,就是任务流的**补录配置**,可以设置任务流回溯到哪个时间节点开始,定时补录数据。比如要计算过去 2 个月内、每一天往前 360 天的用户行为数据,就可以通过这个功能来实现。 ## 日志查看 可以查看任务实例的在线日志、离线日志、资源使用等。在线日志保留到任务结束,任务结束后的离线日志保留一个月。 ![输入图片说明](https://foruda.gitee.com/images/1700483197403397233/85fb0ed4_1019082.png "屏幕截图") ## 任务流变量输入输出 1. **文件中转(推荐)** 在前一个任务中将输出文件存储到分布式存储,在后续任务中读取这个分布式存储文件,实现任务间内容的传递。 2. **配置变量传递(不推荐)** 在上一个任务中将短文本内容直接输出到容器的 `/output` 文件内,在下一个任务的参数中直接把这个文件的内容当成字符串配置为参数。读取方法为 `{{$task_name.output}}`。 比如: ![在这里插入图片描述](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/mlshurushuchu1.png) ![在这里插入图片描述](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/mlshurushuchu2.png) ## 全局变量 往往我们想要在一次任务流运行实例的过程中,每个任务的中间数据总是在同一个目录下,但每次任务流实例又是不同的目录。这时往往需要一个全局变量:在每次运行时不一样,在同一次任务流实例的不同任务间又相同。这时可以使用全局变量。 可以在 pipeline 中定义全局变量,在任务参数中引用这个变量。 ![在这里插入图片描述](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/mlquanjubianliang1.png) 在任务中可以直接引用这里定义的变量,引用方式 `{{YYYYMMDD}}`。 ![在这里插入图片描述](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/mlquanjubianliang2.png) ## 模板变量 在任务参数配置中,还可以以模板变量的形式 `{{}}` 使用下列 Python 变量(渲染逻辑见 `myapp/views/view_pipeline.py:427-436`): ``` creator = pipeline.created_by.username 字符串:pipeline 的创建者 datetime = datetime 包 runner = g.user.username 字符串:实例的运行者 uuid = uuid 包 pipeline_id = pipeline.id 字符串 pipeline_name = pipeline.name 字符串:pipeline 的名称 cluster_name = pipeline.project.cluster['NAME'] 字符串:当前所属 k8s 集群 run_id = pipeline.run_id 字符串:本次运行实例的 run_id execution_date = eta.strftime('%Y-%m-%d %H:%M:%S') 字符串:实例的周期时间 ``` > 说明:`run_id` 为代码中实际可用、原文档未列出的模板变量(`view_pipeline.py:432`)。 使用示例: ``` {{uuid.uuid4().hex[:4]}} {{datetime.datetime.now().strftime("%Y%m%d-%H%M%S.%f")}} {{pipeline_id}} {{pipeline_name}} {{cluster_name}} {{runner}} {{execution_date}} ``` ## 系统环境变量 平台会自动将任务流/任务的信息以环境变量的形式传递给任务(来源:`myapp/views/view_pipeline.py:518-530`): ```bash KFJ_TASK_ID 任务的 id KFJ_TASK_NAME 任务的名称 KFJ_TASK_NODE_SELECTOR 任务的机器选择器 KFJ_TASK_VOLUME_MOUNT 任务的挂载 KFJ_TASK_IMAGES 任务使用的镜像 KFJ_TASK_RESOURCE_CPU 任务占用的 cpu 资源 KFJ_TASK_RESOURCE_MEMORY 任务占用的内存 KFJ_TASK_RESOURCE_GPU 任务占用的 gpu 资源 KFJ_TASK_RESOURCE_RDMA 任务占用的 rdma 资源 KFJ_TASK_PROJECT_NAME 任务所属的项目组名称 GPU_RESOURCE_NAME 任务占用的 gpu 所对应的 k8s 资源名 RDMA_RESOURCE_NAME 任务占用的 rdma 所对应的 k8s 资源名 USERNAME 用户名(pipeline 创建者) ``` # workflow(任务流调度实例) 通过 pipeline 的"调度实例"按钮,可以查看历史调度实例的启动时间、耗时、运行状态等。 ![输入图片说明](https://foruda.gitee.com/images/1700482446047627668/ebb00e67_1019082.png "屏幕截图") 再点击调度实例后面的"日志"链接,可以查看任务流的 workflow。 ![输入图片说明](https://foruda.gitee.com/images/1698651380512384284/75f2c95a_1019082.png "屏幕截图") 点击 workflow 中的单个任务节点,还可以查看任务的在线日志、可视化结果、pod 信息等。 ![输入图片说明](https://foruda.gitee.com/images/1700482596122950601/8c4d84f1_1019082.png "屏幕截图") # 定时调度 点击任务流名称旁边的锯齿状按钮,可调出任务流配置界面,通过设置调度类型和调度周期配置任务流的定时调度。 - **调度类型**:`once` 表示仅运行一次,`crontab` 表示周期运行,crontab 配置保存约 5 分钟后才生效; - **调度周期**:周期任务的时间设定,`* * * * *` 表示 minute hour day month week; - **过往依赖**:是否依赖上一次运行的该任务流结果(只在定时调度有效); - **有效实例数目**:定时调度最新实例限制数目,0 表示不限制。 > 注意:实际生效时间约 5 分钟——后端定时器 `task.make_timerun_config` 按 `crontab(minute='*/5')`(`myapp/config.py:698`)每 5 分钟扫描一次,每次向后展开到 `now+300s`(`myapp/tasks/schedules.py:521`)。配置界面字段提示仍写作"保存一个小时后才生效"(`myapp/views/view_pipeline.py:1199`),属过时文案,以实际调度为准。 ![输入图片说明](https://foruda.gitee.com/images/1700482019917550087/486a7804_1019082.png "屏幕截图") 定时调度的记录,可以点击"定时记录"按钮查看,定时调度记录将如下图所示。 ![输入图片说明](https://foruda.gitee.com/images/1700482346192169582/47fc1f8f_1019082.png "屏幕截图") # 结果可视化 构建任务模板时,在代码中按照规范格式在容器 `/metric.json` 中输出可视化结果(包括文字、图片和 echart 源码),即可在 web 界面上可视化展示。 > 实现说明:平台在 workflow 中为任务节点声明了名为 `metric` 的可选 artifact,路径为 `/metric.json`(`myapp/views/view_pipeline.py:288/777/849`)。 `/metric.json` 文件格式为: ```bash [ { "metric_type":"image", "describe":"指标描述", "image":"图片地址" }, { "metric_type":"text", "describe":"指标描述", "text":"文本内容" }, { "metric_type":"html", "describe":"指标描述", "html":"html源码内容" }, { "metric_type":"iframe", "describe":"指标描述", "url":"链接的地址" }, { "metric_type":"table", "describe":"指标描述", "file_path":"csv文件地址" }, { "metric_type":"echart-xx", # 其中 xx 可以为 line,bar,pie,scatter,radar,candlestick,heatmap,parallel,tree,sunburst;其中 tree、sunburst 数据为 json,其他类型数据为 csv "describe":"指标描述", "file_path":"csv或者json数据文件地址" # 详细配置方法参考 05-任务模板 中的 py_echart 数据格式说明 }, { ...或者是 echart 的 option 源码 } ] ``` ![输入图片说明](https://foruda.gitee.com/images/1700482742752960056/f3b20342_1019082.png "屏幕截图") 通过以上设置,在运行该模板时,就可以在对应的任务节点中查看结果图。 ![输入图片说明](https://foruda.gitee.com/images/1700482993406483676/6c2c7fa0_1019082.png "屏幕截图") # pipeline 导入导出 选中需要导出的任务流,点击批量导出,可将任务流导出为 json 文件(接口 `/pipeline_modelview/api/download/`,`view_pipeline.py:1926`)。 ![输入图片说明](https://foruda.gitee.com/images/1700548483781920959/fa5fb65b_1019082.png "屏幕截图") ![输入图片说明](https://foruda.gitee.com/images/1700548764307140140/edb67b01_1019082.png "屏幕截图") 如果平台需要重新部署,或者需要将 pipeline 迁移到新部署的集群,将导出的 json 文件再导入新的平台即可(导入接口 `/pipeline_modelview/api/upload/`,`view_pipeline.py:1897`;可通过 `/pipeline_modelview/api/download_template/` 下载模板)。 导出导入 json 格式说明(注意 `tasks` 中字段名为 `job_templete`,与代码模板一致,见 `view_pipeline.py:2104`): ```json { "pipeline英文名": { "pipeline": { "name": "pipeline英文名", "describe": "pipeline描述", "project": "public", "parameter": {}, "dag_json": { "任务1英文名": { "upstream": [] }, "任务2英文名": { "upstream": ["任务1英文名"] } }, "global_env": "AA=aa", "expand": [ { "id": "任务1英文名", "type": "dataSet", "position": { "x": 任务1_x坐标, "y": 任务1_y坐标 }, "data": { "info": { "describe": "任务1描述" }, "name": "任务1英文名", "label": "任务1中文名" } }, { "id": "任务2英文名", "type": "dataSet", "position": { "x": 任务2_x坐标, "y": 任务2_y坐标 }, "data": { "info": { "describe": "任务2描述" }, "name": "任务2英文名", "label": "任务2中文名" } }, { "source": "任务1", "arrowHeadType": "arrow", "target": "任务2", "id": "任务1英文名-任务2英文名" } ] }, "tasks": [ { "job_templete": "任务1模板名", "name": "任务1英文名", "label": "任务1中文名", "volume_mount": "kubeflow-user-workspace(pvc):/mnt", "resource_memory": "2G", "resource_cpu": "2", "resource_gpu": "0", "resource_rdma": "0", "args": { "images": "任务1对应的每个参数取值", "workdir": "任务1对应的每个参数取值", "command": "任务1对应的每个参数取值" } }, { "job_templete": "任务2模板名", "name": "任务2英文名", "label": "任务2中文名", "volume_mount": "kubeflow-user-workspace(pvc):/mnt", "resource_memory": "2G", "resource_cpu": "2", "resource_gpu": "0", "resource_rdma": "0", "args": { "images": "任务2对应的每个参数取值", "workdir": "任务2对应的每个参数取值", "command": "任务2对应的每个参数取值" } } ] } } ``` --- ### 大模型 OpenAI 服务网关 - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/07-%E6%9C%8D%E5%8A%A1%E5%8C%96%E4%B8%8E%E6%8E%A8%E7%90%86/%E6%9C%8D%E5%8A%A1%E7%BD%91%E5%85%B3 - 分类: 平台使用 / 服务化与推理 - 适用场景: 把多个 OpenAI 兼容大模型接口统一代理,配置认证/限流/提示词改写/参数映射/监控,并对外暴露 OpenAI 兼容接口时阅读 - 关键词: 服务网关 / 大模型网关 / OpenAI 兼容 / openai gateway / LLM 网关 / llm/api / 认证 auth / JWT / HS256 / 秘钥 secret / 限流 rate limit / 限速 / 白名单 whitelist / 黑名单 blacklist / token 额度 quota / 提示词模板 prompt / 参数值映射 value_map / 参数值固定 value_fixed / 联网搜索 / 内容安全 / chat completions - 最后更新: 2026-07-04 # 大模型 OpenAI 服务网关 大模型服务网关是为了代理多个 OpenAI 接口,并且在代理中实现认证、限流、接口输入输出的修正、监控等功能而设计的。 > 实现源码:`myapp/views/view_llm_ingress.py`(路由前缀 `route_base='/llm/api'`,对外接口 `//v1/chat/completions`)。 ![服务网关](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/16b77ba4452747819e31fd97db3a5737.png) ## 认证方式 网关支持以下认证方式(`auth_method`,见 `view_llm_ingress.py:292`): - **不认证(no)**:不校验秘钥。 - **数据库匹配(db_match)**:从秘钥位置获取到的秘钥跟服务网关设定的秘钥完全一致。 - **正则匹配(regex)**:从秘钥位置获取到的秘钥要符合服务网关设定的秘钥正则表达式。 - **JWT 认证(jwt-HS256)**:从秘钥位置获取到的秘钥要能使用服务网关设定的秘钥 key 进行 JWT 解码(HS256 算法)。 ## 秘钥位置 `secret_position`,格式为 `position:key`(默认 `header:Authorization`,见 `view_llm_ingress.py:279-285`)。 其中 `position` 为秘钥获取方法:`header` 表示从 http header 头中读取,`body` 表示从 json 请求体中读取,`arg` 表示从请求的 url 参数中读取。 `key` 为对应位置处的 key 值,比如: - `header:Authorization` 表示从 header 头中读取 `Authorization` 的值作为秘钥; - `body:user_id` 表示从 json 请求体中读取 `user_id` 的值作为秘钥; - `arg:key` 表示从 url 请求参数中读取参数 `key` 的值作为秘钥。 ## 秘钥 根据认证方法,可自己设定,也会随机生成。 ## 过期时间 `expires_at`,网关的过期时间,超过该时间后,对访问请求返回"该网关已过有效期"的应答。 ## token 额度 `quota`,整数或者 `no-limit`,是问答总 token 的最大累加和(默认 `no-limit`;填整数时要求大于 10000,见 `view_llm_ingress.py:303-307`)。 ## 服务列表 `services`,平台内创建的、自己有权限访问的 OpenAI 接口服务,但并不一定是当前上线的 llm 服务。在正式访问时会查询代理的 llm 服务是否上线中,再根据是否上线决定应答。 ## 外部服务 `external_services`,外部 OpenAI 兼容上游列表(含 `/v1`、不含 `/chat/completions`,见 `view_llm_ingress.py:173`、`405-410`),与内部推理服务一起按权重随机做负载均衡。 ## 失败重试 `retry`,请求大模型 OpenAI 接口报错后重试的次数。 ## 限速 `limit_rate`,访问速率限制(见 `view_llm_ingress.py:339-344`): - `no-limit`:没有限制。 - `ingress:n/minute` `ingress:n/hour` `ingress:n/day`:针对该网关(所有调用总和),限制最近 1 分钟/小时/天最多访问 n 次。 - `secret:n/minute` `secret:n/hour` `secret:n/day`:针对每个秘钥(用户),限制最近 1 分钟/小时/天最多访问 n 次。 - `secret:n(token)/hour` `secret:n(token)/day`:针对每个秘钥,按 **token 数** 限制最近 1 小时/天的累计用量。 - `ip:n/minute` `ip:n/hour` `ip:n/day`:针对每个客户端 IP,限制最近 1 分钟/小时/天最多访问 n 次。 其中 `n` 为整数。 ## 白名单 `whitelist`,如果设置了白名单,在白名单范围内的就放行,不在白名单范围内的就不放行,优先级高于黑名单。每行一个白名单规则(默认 `ip:0.0.0.0/0`、`secret:.*`、`time:0~24`,见 `view_llm_ingress.py:346-348`)。 每行的书写规则:`type:value`,其中 `type` 可为: - `ip`:客户端的访问 ip 范围,值为 ip 网段; - `secret`:访问者的秘钥,值为秘钥的正则表达式; - `time`:访问的时间,值为时间范围段(如 `0~24`)。 ## 黑名单 `blacklist`,书写规则同白名单,访问流量符合黑名单规范就阻拦,优先级低于白名单。 ## 激活 `active`,可控制当前网关是否有效。 ## 联网搜索 `search`,JSON 格式配置(见 `view_llm_ingress.py:368-374`)。`enable=true` 时按配置调用联网搜索(默认走 Tavily),字段示例: ```json { "enable": false, "endpoint": "https://api.tavily.com/search", "search_depth": "basic" } ``` `enable=false` 时整个联网搜索插件不生效;未配置字段使用平台默认值。 > 说明:原文档曾标注联网搜索"暂时无效",当前代码已提供可用的 JSON 配置开关,故据代码更新此节。 ## 内容安全 `security`,JSON 格式配置(见 `view_llm_ingress.py:360-365`)。`enable=true` 时按配置的 `url`/阈值调用安全检测服务;`enable=false` 时整个内容安全插件不生效,开启后 `url` 必填。 > 说明:原文档曾标注内容安全"暂时无效",当前代码已提供可用的 JSON 配置开关,故据代码更新此节。 ## 深度思考 / 数据脱敏 > ⚠️ 待核实: > - **深度思考**:模型字段 `deepseek`(`myapp/models/model_llm_ingress.py:35`,Boolean,默认 `True`)。请求流中确有逻辑引用它:当 `not ingress.deepseek` 且模型名含 `deepseek` 时,会注入 `extra_body.chat_template_kwargs.enable_thinking=False` 关闭思考(`view_llm_ingress.py:1012-1024`、`1099`、`1148`)。但该字段未出现在 `add_columns/edit_columns`(`view_llm_ingress.py:426-448`),界面无法修改;默认 `True` 下"关闭思考"分支永不触发,实际等同未向用户开放。请确认是否有意如此。 > - **数据脱敏**(`desensitization`):表单字段存在(在 `ops_columns` 中,`view_llm_ingress.py:430`)但默认空、`description` 仅为"数据脱敏配置",请求流中未检索到对应的脱敏处理逻辑(输出侧敏感信息拦截由"内容安全"的 `sensitive` 阈值承担),疑为占位未实现,请确认。 ## 提示词模板 `prompt`,最终发给大模型的问题。如果当前服务网关配置了提示词模板,其中一定要包含 `{{query}}`,比如: ```text CubeStudio是开源一站式机器学习平台,请你的回答尽可能专业。请问:{{query}} ``` 那么最终发给大模型的问题就是上面这一整段话,其中 `{{query}}` 被替换为用户最原始的问题。我们可以通过这种方式添加一些问答限制。 ## 参数值映射 `value_map`,对推理服务的 json 请求体的 value 进行映射,格式为 `"key":["old_value","new_value"]`。 例如 `"model":["deepseek","deepseek-qwen2-7b"]`,可以将请求 `deepseek` 的模型全部代理到 `deepseek-qwen2-7b` 模型服务上。 ## 参数值固定 `value_fixed`,对推理服务的 json 请求体的 value 进行固定,格式为 `"key":"new_value"`。 例如 `"model":"deepseek-qwen2-7b"`,可以将任何模型请求全部代理到 `deepseek-qwen2-7b` 模型服务上。 ## 调用测试 当配置了服务网关,网关会对外提供 OpenAI 接口,代理用户的请求到下面的 OpenAI 模型接口上。对外接口路径为 `/llm/api//v1/chat/completions`(见 `view_llm_ingress.py:210`、`763`)。 在外部智能体平台,主要需要配置如下环境变量: ```bash API_SECRET_KEY = "sk-xxxxxxxx" BASE_URL = "http://xx.xx.xx.xx/llm/api/xx/v1" ``` 也可以自己写 API 调用示例代码: ```bash curl -X POST http://xx.xx.xx.xx/llm/api/xx/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer sk-xxxxx" \ -d '{ "model": "xxxx", "messages": [ { "role": "user", "content": "你是谁?" } ], "temperature": 0.7, "stream": false }' ``` 参数说明: - `model`:替换为你的模型名称(当前可访问模型名取决于该网关代理的、且在线的大模型服务); - `messages`:对话历史,包含 `role`(user / assistant / system)和 `content`(消息内容); - `temperature`:控制生成文本的随机性(0~2,值越大越随机)。 ## 监控 客户端可以进行调用访问,每次调用访问,服务网关都会监控当前已使用 token 数目,和今日每小时的调用次数。 ![网关监控](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/f12586c6a91e4748a8f1ab5a1c1e8024.png) --- ### 模型管理与推理服务 - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/07-%E6%9C%8D%E5%8A%A1%E5%8C%96%E4%B8%8E%E6%8E%A8%E7%90%86/%E6%A8%A1%E5%9E%8B%E6%9C%8D%E5%8A%A1 - 分类: 平台使用 / 服务化与推理 - 适用场景: 把训练好的模型注册、发布成在线推理服务,配置域名/IP 访问、端口、灰度分流、弹性伸缩、资源与镜像时阅读 - 关键词: 模型管理 / 模型注册 / model-register / 推理服务 / inference service / serving / 模型发布 / 部署测试 / 部署生产 / 域名访问 / ip port / SERVICE_DOMAIN / SERVICE_EXTERNAL_IP / INFERENCE_PORT / 灰度升级 / 流量分流 / 流量复制 / canary / shadow / 弹性伸缩 hpa / sidecar / GPU VGPU / tfserving / torch-server / triton / onnxruntime / vllm / ollama - 最后更新: 2026-06-30 # 模型管理与推理服务 > 实现源码:模型/推理服务模型 `myapp/models/model_serving.py`,推理服务视图 `myapp/views/view_inferenceserving.py`,端口/域名配置 `myapp/config.py`。 # 模型管理 ## 在"模型管理"中添加模型 模型管理可记录模型所属的项目组、模型版本、算法框架等关键信息,可进行模型的版本管理。在"服务化"-"模型管理"-"添加模型"可添加模型,在每个模型的"更多"中,可以查看更多详情,也可以删除和修改模型信息。 ![模型管理列表](https://i-blog.csdnimg.cn/img_convert/8f7067b750bcbeecfe503938810bd823.png) ![添加模型](https://i-blog.csdnimg.cn/img_convert/c28b0f24a28ccdecd2494ca4f80886cd.png) ## 通过 pipeline 中的"模型注册"模板添加模型 除了手动在模型管理中添加模型,还可以在模型训练的 pipeline 中,通过"模型服务化"类别下的 `model-register` 模板来自动注册模型,将模型元数据添加到"模型管理"中来。 ## 子模型 如果在模型管理中注册的 `模型地址` 填写的为 json 格式,那么表示该模型是由多个子模型构成。每个 key 都表示一个子模型,这种情况下,模型拉取时可以直接拉取子模型。 ## 模型指标 模型指标可填写字符串或者 json 格式,json 格式时,在 list 列表页面展示的时候会展开成 `key1=value1,key2=value2` 的格式。 --- # 推理服务 ## 服务发布 想要将模型发布成推理服务,可以分两步: 1. 在"模型管理"中添加模型,并且点击"发布",自动为模型创建推理服务,或者在"推理服务"中,手动添加服务; 2. 在"推理服务"中,点击已发布的推理服务的"部署测试",将模型部署到测试环境,测试通过后,点击"部署生产",将模型部署到生产环境。 ![发布推理服务](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/f988dacadf0747c58ed315c26f16d19d.png) ![推理服务列表](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/9099ef99360c40c385f0432c12c606eb.png) ## 推理服务类型 `service_type` 当前支持以下类型(见 `myapp/views/view_inferenceserving.py:214`,实际可见类型还会被全局配置 `ENABLE_INFERENCE` 过滤): `serving`、`ml-server`、`tfserving`、`torch-server`、`triton-server`、`vllm`、`vllm-distributed`、`triton-llm`、`ollama`、`mindie`、`mindie-distributed`。 其中 `tfserving / torch-server / triton-server` 等可做到 0 代码推理发布(自动生成配置/端口/环境变量);`serving` 为自定义镜像服务(见下文"自定义镜像服务");`vllm / triton-llm / ollama / mindie` 等用于大模型推理。 ## 域名访问 第一种方式:公司申请泛域名,并将泛域名解析地址配置到 `svc/istio-ingressgateway` 的服务地址上。通过域名访问,在 istio-ingressgateway 中进行转发到对应的服务上。 第二种方式:配置本地 host 文件,以产生域名解析的效果,不过因为这种方式需要在每个人电脑上配置,所以仅适用于测试。 第三种方式:客户端的请求中在 header 中配置 Host,istio-ingressgateway 检测 http 请求中的 Host 来进行转发。不过这种方式需要侵入性修改客户端请求,适用于仅提供 api 的下层服务。 流量流向:客户端 -> istio-ingressgateway(VirtualService)-> k8s service -> k8s pod。 泛域名的配置:`config.py` 中配置 `SERVICE_DOMAIN` 变量为泛域名后缀。 > 注意:`SERVICE_DOMAIN` 在 `myapp/config.py:1378` 与各集群 `CLUSTERS[*].SERVICE_DOMAIN`(如 `config.py:1408`)默认值为 `service.svc.cluster.local`(集群内域名)。文中"例如 `local.com`""`*.cube-studio.local.com`"等仅为对外泛域名示例,实际泛域名后缀以你的部署配置为准。 ## ip:port 访问 平台会为每个 Service / 推理服务 / Notebook 生成一个 `ip:port` 形式的访问入口。 代理 IP 的取值优先级(从高到低,见 `myapp/views/view_inferenceserving.py:1635-1663` 与 `myapp/models/model_serving.py:382-413`): 1. 项目组扩展字段 `expand` 里配置的 `SERVICE_EXTERNAL_IP` 2. 集群配置 `CLUSTERS[$env].HOST` 3. 全局配置 `SERVICE_EXTERNAL_IP` 4. 浏览器访问时的 `request.host`(仅当是合法 IP) `SERVICE_EXTERNAL_IP` 支持 `["内网IP|外网IP"]` 这种写法: - 用于 k8s service 代理绑定(externalIP)时取 `|` **左侧**(内网 IP,见 `view_inferenceserving.py:1667`,注释"代理需要配置内网 ip"); - 用于界面展示 / 对外访问 URL 时取 `|` **右侧**(外网 IP/域名,见 `model_serving.py:112`、`156`,`split('|')[-1]`)。 端口规则(以 `myapp/config.py` 为准,可被修改,见 `config.py:1105-1107`): - Notebook:`NOTEBOOK_PORT`,默认 `10000+2*ID` - 内部服务(Service):`SERVICE_PORT`,默认 `30000+2*ID` - 推理服务(InferenceService):`INFERENCE_PORT`,默认 `20000+2*ID` (`ID` 为对应资源的数据库 id。开放两个端口时,第二个端口取第一个端口之后首个未被屏蔽的端口,见 `core.get_not_black_port`。) > 注意:代码中 `conf.get('INFERENCE_PORT', '20000+10*ID')` 的硬编码兜底为 `20000+10*ID`(`view_inferenceserving.py:1668`、`model_serving.py:384`),仅在 config 未设置该项时生效;随仓库发布的 `config.py` 已设为 `20000+2*ID`。请以 `config.py` 实际取值为准。 流量流向:客户端 -> k8s service external ip -> k8s pod。 ## 版本/域名/pod/ip 的关系 `$服务名 = $模型名-$模型版本(版本会做归一化处理)` 推理服务的 `name` 会根据 `model_name` 与 `model_version` 生成:把 `model_name` 中的 `/ : .` 替换为 `-`、`model_version` 中的 `v . :` 去掉后用 `-` 拼接,截断到 60 字符并把 `_` 换成 `-`(见 `view_inferenceserving.py:608`、`764-787`),用于生成 k8s deployment/service 等资源名。 服务名归一化 - `$k8s-deployment名称 = $服务名` deployment - `$k8s-hpa名称 = $服务名`,在最大最小副本数不一致时创建 hpa - `$k8s-service名称 = $服务名` 用于域名的代理 - `$k8s-service名称 = $服务名-external` 用于 ip 的代理 - `$ip:port = $代理服务ip:(INFERENCE_PORT 按 id 计算)` ,端口取值见上文"端口规则" ![资源关系](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/c9b38fe549404c189d81e536fbe8345c.png) ## 系统自带域名 需要泛域名支持,这里假设泛域名为 `*.cube-studio.local.com`: - 生产域名:`http://$服务名.service.cube-studio.local.com` - 测试环境域名:`http://test.$服务名.service.cube-studio.local.com` - 调试环境域名:`http://debug.$服务名.service.cube-studio.local.com` ## 自定义域名 用户可通过 `host` 字段配置服务的访问域名: 1. 配置域名,会使用该域名作为 istio-ingressgateway 的代理; 2. 配置 url,会使用其中的域名作为代理,但是打开域名自动进入完整的 url; 3. 配置 url path,自动生成域名,但是打开会自动进入完整 url。 多个服务可以配置相同的域名,相同域名的服务只能有一个在线,最新发布的模型会接替同域名的其他模型服务。 ## 流量复制和分流 多个服务(可以是相同模型或者不同模型间)配置相同的域名: 1. "分流"字段控制分配多少流量到其他服务上,剩余流量归属于当前服务; 2. "流量复制"字段控制复制多少流量到其他服务上,但只会将当前服务的响应返回给客户端。 ![流量分流](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/dc6b21a55fec48b9b44ddceaa96ef89f.png) ## 灰度升级 1. 同一个服务灰度升级,只需要修改服务的配置,重新部署,服务会自动滚动升级 pod; 2. 不同服务进行灰度升级(比如同一个模型的不同版本之间),多个服务使用相同的域名,新部署的服务上线正常后,会自动下线同域名的旧服务。 ## 弹性伸缩容 "弹性伸缩容"字段可配置触发条件,可使用自定义指标,使用其中一个或多个指标,示例:`cpu:50%,mem:50%,gpu:50%`。 ## 服务优先级 "优先级"字段可配置服务优先级,优先满足高优先级的资源需求。 ## sidecar 通过"Sidecar"字段配置,通过 sidecar 的配置,推理服务将自动添加伴随容器,使得 IP 形式访问的推理服务也能获得负载统计数据。 ## 环境变量 系统会向推理服务容器注入以下环境变量(见 `view_inferenceserving.py:1122-1136`): ``` KUBEFLOW_ENV= # 当前部署环境 KUBEFLOW_MODEL_PATH= KUBEFLOW_MODEL_VERSION= KUBEFLOW_MODEL_IMAGES= KUBEFLOW_MODEL_NAME= KUBEFLOW_INFERENCE_ID= # 推理服务 id KUBEFLOW_RUN_ID= # 本次部署随机 id RESOURCE_CPU= RESOURCE_MEMORY= RESOURCE_MIN_REPLICAS= RESOURCE_MAX_REPLICAS= RESOURCE_GPU= MODEL_PATH= MODEL_NAME= INFERENCE_NAME= ``` 以及由 k8s downward API 注入的 pod 信息(见 `myapp/utils/py/py_k8s.py:1122-1126`): ``` K8S_NODE_NAME= # spec.nodeName K8S_POD_NAMESPACE= # metadata.namespace K8S_POD_IP= # status.podIP K8S_HOST_IP= # status.hostIP K8S_POD_NAME= # metadata.name ``` ## 内存、CPU、GPU、VGPU 推理服务中,允许用户调整推理服务的内存、CPU、GPU 占用以及选择 GPU 卡型。其中 GPU 的占用支持独占、共享、VGPU。可以设置 GPU 占用方式为虚拟 GPU,比如设置 GPU 时填写 `0.2(T4)`,表示一个推理服务占 0.2 张 T4 卡,从而实现单卡上部署多个推理服务的 pod。 ![GPU/VGPU 配置](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/e49a38d36e9843c5b5fe4ef6d0297286.png) 推理服务的内存、GPU、CPU 都可以在"更多"中修改。 ## 配置文件,启动目录,启动命令 1. 配置文件以 configmap 形式挂载进去,挂载到容器 `/config/` 目录下。留空时将被自动重置,格式: ``` ---文件名 多行文件内容 ---文件名 多行文件内容 ``` ![配置文件](https://i-blog.csdnimg.cn/img_convert/6e16c98ffd15816e797689e30dae89ed.png) 代码中需要读取 `/config` 目录下挂载进去的文件。 2. 启动目录和启动命令会覆盖镜像中的启动目录和命令。注意如果之前的环境中使用 `~/.bashrc` 进行了环境初始化,在使用 k8s 时不存在这个文件,需要在代码中手动 `source` 环境。 ## 端口 端口最多只能设置 2 个,用逗号分隔,比如 `PORT1,PORT2`。 ![端口配置](https://i-blog.csdnimg.cn/img_convert/b600312551e726bdc52993a51087cfd0.png) 开放的端口会启动两种代理方式: 1. 通过配置的泛域名生成的服务域名进行访问:第一个端口由 istio-ingressgateway 的 80 端口代理,第二个端口由 istio-ingressgateway 的 8080 端口代理。访问地址为 `service1.example.oa.com:80` 和 `service1.example.oa.com:8080`。 2. 生成 ip 和端口的访问形式 `xx.xx.xx.xx:EXPORT_PORT1` 和 `xx.xx.xx.xx:EXPORT_PORT2`,其中 `EXPORT_PORT1`/`EXPORT_PORT2` 按上文"端口规则"中的 `INFERENCE_PORT`(默认 `20000+2*ID`)及其后续未屏蔽端口计算。 ## 指标 请求指标采集,配置端口 + url,示例:`8080:/metrics`。 按照 prometheus 采集数据的要求提供 `/metrics`,然后在此处配置端口和地址,配置后会自动被 prometheus 采集,需要自行配置看板,解析自己的指标进行查看。 ## 健康检查 需要业务在代码中提供可用于健康检查的接口,用于阻隔损坏的容器或重启损坏的容器。接口返回 200 表示正常,其他会阻隔流量或重启容器。检查周期为 60s。 ## 调试环境/测试环境/生产环境 三者的主要区别: 1. 调试环境会重置启动命令为 `sleep infinity`,会自动进入命令行,自己手动启动命令,查看日志; 2. 调试环境和测试环境不会启动 hpa; 3. 调试环境会自动在生产环境域名前添加 `debug.`,测试环境会自动在生产环境域名前添加 `test.`。 ## 服务负载监控 在每个推理服务后面点击监控按钮,可以查看每个服务的资源使用和流量负载情况。 ![服务负载监控](https://i-blog.csdnimg.cn/img_convert/e52ed0b05dbaee991a0b27a6d7829cb8.png) ## 自定义镜像服务 往往后端推理服务需要特殊的业务处理逻辑。这个时候我们可以选择 `serving` 类型的推理服务,自己配置镜像和其他参数。 `tfserving / torch-server / triton` 的服务类型也可以修改镜像名,但是其他的配置(比如配置文件、端口、环境变量等)会自动生成,以实现 0 代码推理发布的目的。 ## 服务测试 可以在推理服务列表对已部署的服务发起测试。 ![服务测试](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/356251c0917948f096fb547d59c24d84.png) 大模型(LLM)测试使用对话界面;`ml-server`、`tfserving`、`torch-server`、`triton-server` 类型测试会打开 notebook,使用测试脚本测试(见 `view_inferenceserving.py:2111` 起的测试接口)。 --- # 推理框架导航 不同推理框架的 0 代码发布细节、模型目录约定与测试方式,可参考本目录下各专题文档: - ml-server(sklearn 等)推理服务:[推理服务-ml.md](推理服务-ml.md) - tfserving 推理服务:[推理服务-tfserving.md](推理服务-tfserving.md) - torch-server 推理服务:[推理服务-torchserve.md](推理服务-torchserve.md) - triton 推理服务:[推理服务-triton.md](推理服务-triton.md) - 内部服务(非推理类的常驻服务):[内部服务.md](内部服务.md) onnxruntime 暂无独立专题文档;开源仓库 wiki 总览见 。 > 大模型 OpenAI 兼容网关的认证、限流等见同目录 [服务网关.md](服务网关.md)。 --- ### 内部服务(数据库 Web 管理端 / 桌面等) - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/07-%E6%9C%8D%E5%8A%A1%E5%8C%96%E4%B8%8E%E6%8E%A8%E7%90%86/%E5%86%85%E9%83%A8%E6%9C%8D%E5%8A%A1 - 分类: 平台使用 / 服务化与推理 - 适用场景: 想把数据库 Web 管理端(phpmyadmin/pgadmin/redis-ui)、neo4j 等容器镜像注册成平台内常驻服务、需要知道各自镜像名/环境变量/端口怎么填时读这篇 - 关键词: 内部服务 / internal service / phpmyadmin / mysql web / mysql-ui / pgadmin / dpage/pgadmin4 / postgresql-ui / redis web / redis-ui / patrikx3 / p3x-redis-ui / neo4j / 图数据库 / 环境变量 / 端口 / 镜像 - 最后更新: 2026-06-30 # 内部服务 「内部服务」是把任意容器镜像注册成平台内的常驻服务(例如数据库 Web 管理端、桌面环境等)。 注册方式:先把服务镜像 push 到镜像仓库,再在平台「内部服务」中填写镜像名、环境变量、端口等。 说明: - 其中 `mysql-ui` / `redis-ui` / `postgresql-ui` 是平台初始化时自动创建的内置服务(见 `myapp/init/init-service.json`),下面给出其默认配置。 - `neo4j` 等为常见示例镜像,非平台代码内置,由用户按需注册,请按实际使用的镜像版本调整环境变量与端口。 ## mysql web 服务(mysql-ui) 镜像:`phpmyadmin:5.2.1` 环境变量: ``` PMA_HOST=xx.xx.xx.xx PMA_PORT=xx PMA_USER=xx PMA_PASSWORD=xx ``` 端口:80 > 平台内置 `mysql-ui` 服务默认连接平台自带 MySQL:`PMA_HOST=mysql-service.infra`、`PMA_PORT=3306`、`PMA_USER=root`、`PMA_PASSWORD=admin`(见 `myapp/init/init-service.json:6`-`9`)。 ## postgresql web 服务(postgresql-ui) 镜像:`dpage/pgadmin4` 环境变量: ``` PGADMIN_DEFAULT_EMAIL=admin@tencent.com PGADMIN_DEFAULT_PASSWORD=admin ``` 端口:80 > 与平台内置 `postgresql-ui` 服务一致(见 `myapp/init/init-service.json:30`-`33`)。 ## redis web 服务(redis-ui) 平台内置 `redis-ui` 服务(见 `myapp/init/init-service.json:14`-`25`)使用**环境变量**方式配置连接,无需额外准备连接文件: 镜像:`ccr.ccs.tencentyun.com/cube-studio/patrikx3:latest` 环境变量: ``` REDIS_NAME=default REDIS_HOST=redis-master.infra REDIS_PORT=6379 REDIS_PASSWORD=admin ``` 端口:7843 > 另一种方式(直接使用上游镜像 `patrikx3/p3x-redis-ui:2021.10.262`):在 notebook 中准备连接文件 `$base_dir/.p3xrs-conns.json`: > > ``` > { > "list": [ > { > "name": "default", > "host": "xx.xx.xx.xx", > "port": xx, > "password": "xx", > "id": "unique" > } > ], > "license": "" > } > ``` > > 启动命令:`mkdir /settings/ && cp $base_dir/.p3xrs-conns.json /settings/ && p3x-redis`,端口同样为 7843。 ## neo4j web 服务 镜像:`ccr.ccs.tencentyun.com/cube-studio/neo4j:4.4` 环境变量: ``` NEO4J_AUTH=neo4j/admin ``` 端口:7474、7687 --- > 快速上手版(在新人指南内)见 [新人指南-内部服务](../01-入门与权限/新人用户使用指南/07-内部服务.md),其中还包含服务对外暴露(域名 / IP)的配置说明。 --- ### 推理服务 - 大模型(LLM)推理(vllm / ollama / mindie / triton-llm) - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/07-%E6%9C%8D%E5%8A%A1%E5%8C%96%E4%B8%8E%E6%8E%A8%E7%90%86/%E6%8E%A8%E7%90%86%E6%9C%8D%E5%8A%A1-%E5%A4%A7%E6%A8%A1%E5%9E%8BLLM - 分类: 平台使用 / 服务化与推理 - 适用场景: 需要把 HuggingFace 大模型以 OpenAI 兼容接口部署成推理服务(vllm/ollama/昇腾 mindie/TensorRT-LLM)、或想知道各 LLM 推理框架默认启动命令、端口、并行配置时读这篇 - 关键词: 大模型推理 / LLM推理 / vllm / vllm-distributed / ollama / mindie / mindie-distributed / triton-llm / tensorrt-llm / trtllm / OpenAI兼容 / openai api / tensor-parallel / pipeline-parallel / 张量并行 / 流水并行 / 昇腾 / NPU / service_type / INFERNENCE_COMMAND / 推理服务类型 / 默认启动命令 / 国产GPU - 最后更新: 2026-07-04 # 推理服务 - 大模型(LLM)推理 除了传统的 `ml-server / tfserving / torch-server / triton-server` 之外,CubeStudio 推理服务还内置了一批 **大模型(LLM)推理框架**。它们都对外提供 **OpenAI 兼容接口**(健康检查与模型列表均为 `/v1/models`), 在「服务化 → 推理服务 → 新建」时通过 `service_type` 选择即可,平台会自动生成启动命令、端口、健康检查与配置文件。 > 当前支持的 `service_type` 完整枚举见 `myapp/views/view_inferenceserving.py:214`: > `ml-server / tfserving / torch-server / triton-server / vllm / vllm-distributed / triton-llm / ollama / mindie / mindie-distributed`。 > 可用类型还受配置项 `ENABLE_INFERENCE` 约束(空表示全开放,见 `myapp/config.py:1323`)。 > 各类型的镜像、默认启动命令、端口、健康检查、环境变量集中定义在 > `myapp/views/view_inferenceserving.py:58-134` 与镜像清单 `myapp/config.py:1324-1339`。**具体细节以源码为准。** ## 各 LLM 推理类型一览 | service_type | 适用 | 默认端口 | 默认镜像(示例) | 接口 | |---|---|---|---|---| | `vllm` | 单机 GPU 大模型推理(最常用) | 8000 | `vllm/vllm-openai:v0.8.5.post1` | OpenAI `/v1/...` | | `vllm-distributed` | 多副本/多机分布式 vllm | 8000 | `vllm/vllm-openai:v0.8.5.post1` | OpenAI `/v1/...` | | `ollama` | 轻量本地大模型 | 11434 | `ollama/ollama:latest` | OpenAI `/v1/...` | | `triton-llm` | NVIDIA TensorRT-LLM 高性能推理 | 8000 | `nvcr.io/nvidia/tensorrt-llm/release:1.3.0rc1` | OpenAI `/v1/...` | | `mindie` | 华为昇腾 NPU 大模型推理 | 1025,1026 | `swr.cn-south-1.myhuaweicloud.com/ascendhub/mindie:2.3.0-*` | OpenAI `/v1/...` | | `mindie-distributed` | 昇腾 NPU 多机分布式 | 1025,1026 | 同上 | OpenAI `/v1/...` | ## 各类型关键说明 ### vllm(单机) - 默认启动命令(节选):`python3 -m vllm.entrypoints.openai.api_server --trust-remote-code --max-model-len 8192 --model $KUBEFLOW_MODEL_PATH --host 0.0.0.0 --port 8000 --dtype float16 --tensor-parallel-size $RESOURCE_GPU --served-model-name $KUBEFLOW_MODEL_NAME ...` - **张量并行**:`--tensor-parallel-size` 自动取容器申请的 GPU 卡数 `$RESOURCE_GPU`,即填几张卡就几路张量并行。 - 模型路径用 `$KUBEFLOW_MODEL_PATH`(推理服务表单里填的模型地址),服务名用 `$KUBEFLOW_MODEL_NAME`。 - 默认环境变量含 `HF_ENDPOINT=https://hf-mirror.com`(HuggingFace 国内镜像)。 ### vllm-distributed(分布式) - 在 vllm 基础上增加 `--pipeline-parallel-size $RESOURCE_MIN_REPLICAS`(流水并行规模取最小副本数), 用于多副本/多机分布式部署;额外注入 `NCCL_IB_HCA=mlx5`、`NCCL_DEBUG` 等用于 RoCE/IB 通信。 ### ollama - 启动逻辑:`ollama serve` 后台拉起,再 `ollama pull $model_name` 拉取模型;端口 `11434`。 - 环境变量 `OLLAMA_HOST=0.0.0.0`、`OLLAMA_MODELS=$model_path`。 ### triton-llm(TensorRT-LLM) - 启动命令:`trtllm-serve serve $KUBEFLOW_MODEL_PATH --host 0.0.0.0 --port 8000 --tp_size $RESOURCE_GPU --max_batch_size 4 --max_seq_len 4096 ...`,`--tp_size` 同样取 GPU 卡数。 ### mindie / mindie-distributed(昇腾 NPU) - 面向华为昇腾 NPU 的大模型推理,端口 `1025/1026`。平台会下发一份 `config.json`(含 `ModelConfig` / `ScheduleConfig`,`worldSize` 自动取 NPU 卡数 `$RESOURCE_GPU`),由 `start.sh` 渲染后启动 `mindieservice_daemon`。多机分布式版本走 `generate_config.py` / `generate_rank_table.py` 生成 rank 表。 - 镜像区分 800I-A2 / 800I-A3 / 300I-Duo 等昇腾机型,见 `myapp/config.py:1336-1337`。 > 国产硬件镜像:`myapp/config.py:1330-1333` 注释中还给出了 NPU / 沐曦 / 海光 DCU / 寒武纪 等平台的 > vllm/llama-factory 镜像地址,按硬件替换 `service_type` 对应镜像即可。 ## 使用步骤(界面) 1. 进入「服务化 → 推理服务 → 新建」。 2. `service_type` 选择对应的 LLM 类型(如 `vllm`)。 3. 填写模型名称、版本、**模型地址**(HF 名或挂载路径),按需设置 GPU 卡数(= 张量并行路数)、副本数、资源。 4. 保存后平台自动生成启动命令、端口、健康检查与(如 mindie 的)配置文件并拉起 Pod。 5. 部署成功后通过自动分配的域名/IP 以 **OpenAI 兼容协议** 调用(如 `POST /v1/chat/completions`, `model` 填服务的 `$KUBEFLOW_MODEL_NAME`)。 > 通用能力(灰度/影子流量/限流/HPA 弹性伸缩/优先级等)对 LLM 推理同样适用,见 > [模型服务.md](./模型服务.md) 与 [平台架构-推理服务.md](../../01-架构原理/平台架构-推理服务.md)。 --- ### 推理服务 ml-server(sklearn / xgboost / R-pmml) - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/07-%E6%9C%8D%E5%8A%A1%E5%8C%96%E4%B8%8E%E6%8E%A8%E7%90%86/%E6%8E%A8%E7%90%86%E6%9C%8D%E5%8A%A1-ml - 分类: 平台使用 / 服务化与推理 - 适用场景: 用 ml-server 部署 sklearn/xgboost/R 模型、不知道 config.json 怎么写、各模型格式怎么保存、调用接口路径/方法是什么时读这篇 - 关键词: ml-server / 推理服务 / inference / sklearn / xgboost / xgb / pmml / R 模型 / config.json / model_path / framework / predict / 标准化接口 / model status api / metadata api / predict api / 模型部署 - 最后更新: 2026-06-30 # 推理服务 ml-server `ml-server` 是平台提供的轻量推理服务镜像,统一封装了 sklearn / xgboost / R(pmml) 模型, 并对外暴露与 TFServing 风格一致的标准化 HTTP 接口。 ## 镜像 ``` ccr.ccs.tencentyun.com/cube-studio/ml-server:20251001 ``` > 与代码一致:`myapp/config.py:1325`、`myapp/init/init-inference.json:7`。 ## 配置 config.json ``` [ { "name": "模型英文名", "model_path": "模型地址", "framework": "sklearn", "version": "20231001", "enable": true, "output": [ { "name": "y", "type": "enum", "choices": [0,1] } ], "input": [ { "name": "key1", "type": "int" }, { "name": "key2", "type": "enum", "choices": [0,1,2,3,4,5,6] }, { "name": "key3", "type": "float" } ], "example": [ { "key1": 30, "key2": 0, "key3": -1.8 } ] }, { "name": "模型英文名", "model_path": "模型地址", "framework": "r", "version": "20231001", "enable": true }, { "name": "模型英文名", "model_path": "模型地址", "framework": "xgb", "version": "20231001", "enable": true } ] ``` 字段说明: - `model_path` 支持本地路径,也支持 http/https 在线地址(在线地址会被自动下载,见 `images/serving/ml/server.py:174`)。 - 模型格式约定(见 `images/serving/ml/server.py:175`-`199`): - `xgb`(xgboost)模型保存为 `.model` 格式; - `r`(R 语言)模型保存为 `.pmml` 格式; - `sklearn` 模型保存为 `.pkl`(pickle)或 `.joblib` 格式。 - `enable` 默认 `true`;置 `false` 时该模型不会被加载。 ## 启动命令 ``` python server.py --config_path xxx ``` > 在平台部署时,配置文件会挂载到容器内 `/config/config.json`,平台默认启动命令为 > `python server.py --config_path /config/config.json`(见 `myapp/views/view_inferenceserving.py:86`)。 > 也支持用环境变量 `CONFIG_PATH` 指定配置路径,默认 `config.json`(见 `images/serving/ml/server.py:202`、`:209`)。 > 服务监听端口为 **80**(见 `images/serving/ml/server.py:212`、`myapp/views/view_inferenceserving.py:107`)。 ## 标准化模型接口 > 注意:ml-server 的接口路径全部使用斜杠分隔(`.../predict`、`.../metadata`), > 与 TFServing 的冒号语法(`:predict`)不同(见 `images/serving/ml/server.py:27`-`91`)。 Model status API: ``` GET http://host:port/v1/models/${MODEL_NAME} GET http://host:port/v1/models/${MODEL_NAME}/versions/${VERSION} 示例: http://demo.service.xxx/v1/models/my_model1/versions/20210924 ``` Model Metadata API: ``` GET http://host:port/v1/models/${MODEL_NAME}/metadata GET http://host:port/v1/models/${MODEL_NAME}/versions/${VERSION}/metadata 示例: http://demo.service.xxx/v1/models/my_model1/versions/20210924/metadata ``` Predict API: ``` POST http://host:port/v1/models/${MODEL_NAME}/predict POST http://host:port/v1/models/${MODEL_NAME}/versions/${VERSION}/predict 示例: http://xx.xx.xx.xx/v1/models/my_model1/versions/20210924/predict ``` 预测返回格式(见 `images/serving/ml/server.py:147`-`156`): ``` { "status": 0, "message": "success", "result": { "y": [...], // 预测类别 / 预测值 "score": [...] // 预测概率(无 predict_proba 时为 null) } } ``` 模型不存在时返回 `{"status": -1, "result": {}, "message": "model not exist"}`。 --- ### 推理服务 TFServing(TensorFlow Serving) - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/07-%E6%9C%8D%E5%8A%A1%E5%8C%96%E4%B8%8E%E6%8E%A8%E7%90%86/%E6%8E%A8%E7%90%86%E6%9C%8D%E5%8A%A1-tfserving - 分类: 平台使用 / 服务化与推理 - 适用场景: 用 TFServing 部署 TensorFlow saved_model、需要知道模型目录结构/配置文件怎么写/启动参数/REST API 路径/最小训练-部署示例时读这篇 - 关键词: tfserving / TensorFlow Serving / saved_model / 服务化签名 / saved_model_cli / models.config / monitoring.config / platform.config / model_config_file / rest_api_port / 8501 / predict api / model status api / metadata api / 模型版本 / mnist / 部署 / 推理 - 最后更新: 2026-07-04 # 推理服务 TFServing TFServing(TensorFlow Serving)用于部署 TensorFlow 的 `saved_model`。 平台仅支持**已添加服务签名**的 `saved_model` 目录地址(例如 `/mnt/xx/.../saved_model/`,见 `myapp/views/view_inferenceserving.py:227`)。 ## 保存 saved_model 模型添加服务化签名 `tf.keras.Model` 会自动指定服务上线签名。 `tf.saved_model.save` 要手动指定: ``` module_with_signature_path = '/xx/' call = module.__call__.get_concrete_function(tf.TensorSpec(None, tf.float32)) # 第一个参数也可以加上 shape,例如 (1,256,32,1) tf.saved_model.save(module, module_with_signature_path, signatures=call) ``` ## 查看网络模型结构 ``` pip3 install tensorflow==x.x.x saved_model_cli show --all --dir=model_Path ``` 可以看到输入签名: ``` signature_def['serving_default']: The given SavedModel SignatureDef contains the following input(s): inputs['a_age'] tensor_info: dtype: DT_INT64 shape: (-1, 1) name: serving_default_a_age:0 ... Method name is: tensorflow/serving/predict ``` ## TFServing 云原生服务部署 ### 镜像 平台提供以下 CubeStudio 镜像(基于上游 `tensorflow/serving` 重新打包,见 `myapp/config.py:1326`、`images/serving/tfserving/build.sh`): ``` ccr.ccs.tencentyun.com/cube-studio/tfserving:2.14.1 ccr.ccs.tencentyun.com/cube-studio/tfserving:2.14.1-gpu ccr.ccs.tencentyun.com/cube-studio/tfserving:2.13.1 (及 -gpu) ccr.ccs.tencentyun.com/cube-studio/tfserving:2.12.2 (及 -gpu) ccr.ccs.tencentyun.com/cube-studio/tfserving:2.11.1 (及 -gpu) ccr.ccs.tencentyun.com/cube-studio/tfserving:2.10.1 (及 -gpu) ccr.ccs.tencentyun.com/cube-studio/tfserving:2.9.3 (及 -gpu) ccr.ccs.tencentyun.com/cube-studio/tfserving:2.8.4 (及 -gpu) ccr.ccs.tencentyun.com/cube-studio/tfserving:2.7.4 (及 -gpu) ccr.ccs.tencentyun.com/cube-studio/tfserving:2.6.5 (及 -gpu) ccr.ccs.tencentyun.com/cube-studio/tfserving:2.5.4 (及 -gpu) ``` > 也可直接使用上游镜像 `tensorflow/serving:`(含 `-gpu`)。原文档中列出的 1.11.0 ~ 2.6.0 等老版本为上游镜像,平台当前默认提供的镜像版本以上面列表为准。 ### 模型文件目录结构 `$model_dir/$model_name/$model_version/saved_model.pb` 如下图所示: ![模型目录结构](https://foruda.gitee.com/images/1700625305268559941/8b388ace_1019082.png "屏幕截图") [官网样例](https://github.com/tensorflow/serving/tree/master/tensorflow_serving/servables/tensorflow/testdata/saved_model_half_plus_two_cpu) ### 编写模型配置文件(必须) `$model_dir/$model_name/models.config` 简单样式(标准的 utf-8 编码的 json 文件): ``` model_config_list { config { name: "$model_name" base_path: "$model_dir/$model_name/" model_platform: "tensorflow" model_version_policy { specific { versions: $version } } } } ``` 替换自己的 `$model_dir`、`$model_name` 和 `$version`。 注意: 1. `model_version_policy` 设置提供服务的版本,不设置则自动选择最新的模型版本。 2. `$version` 只能用 int64 来命名。 建议放在个人目录某个子目录下,配置服务时用启动命令的 `--model_config_file=$model_dir/$model_name/models.config` 参数指定 models.config 的路径。 [其他配置文件可选参数](https://www.tensorflow.org/tfx/serving/serving_config) ### 编写监控配置文件(必须) `$model_dir/$model_name/monitoring.config` 监控配置: ``` prometheus_config { enable: true, path: "/metrics" } ``` 放在同目录下,配置服务时用启动命令的 `--monitoring_config_file=$model_dir/$model_name/monitoring.config` 指定。 ### 编写平台配置文件(可忽略) `$model_dir/$model_name/platform.config` ``` platform_configs { key: "tensorflow" value { source_adapter_config { [type.googleapis.com/tensorflow.serving.SavedModelBundleSourceAdapterConfig] { legacy_config { session_config { gpu_options { allow_growth: true } } } } } } } ``` 放在同目录下,配置服务时用启动命令的 `--platform_config_file=$model_dir/$model_name/platform.config` 指定。 ### 部署服务 启动命令:统一填写 `/usr/bin/tf_serving_entrypoint.sh --model_config_file=xxx`,必须指定部署配置文件的路径 `--model_config_file`。 > 平台部署 TFServing 时,会自动生成 models.config / monitoring.config / platform.config 并挂载到 `/config/` 下,默认启动命令为: > `/usr/bin/tf_serving_entrypoint.sh --model_config_file=/config/models.config --monitoring_config_file=/config/monitoring.config --platform_config_file=/config/platform.config --rest_api_num_threads=300 --enable_batching=true` > (见 `myapp/views/view_inferenceserving.py:87`,配置文件生成逻辑见 `myapp/views/view_inferenceserving.py:495`-`521`)。 后面可选添加其他配置项,常用如监听端口、服务线程数、配置更新间隔、启用缓存、证书鉴权等,详见: ``` --model_config_file 模型配置文件 --monitoring_config_file 监控配置文件 --enable_batching 是否启动批处理 --batching_parameters_file 批处理配置文件 --platform_config_file 平台配置文件 --port 监听 gRPC API 的端口 --rest_api_port 监听 HTTP/REST API 的端口 --rest_api_num_threads=64 # 并发线程数,会默认配置 --rest_api_timeout_in_ms HTTP/REST API 调用超时 --file_system_poll_wait_seconds 服务器轮询文件系统以获取每个模型各自 model_base_path 处的新模型版本的时间段 --enable_model_warmup 使用 assets.extra/ 目录中用户提供的 PredictionLogs 启用模型预热 --tensorflow_intra_op_parallelism=10 建议设置为申请的 cpu 核数目 --tensorflow_inter_op_parallelism=10 建议设置为申请的 cpu 核数目 ``` 日志跟踪: ``` TF_CPP_MIN_VLOG_LEVEL=1 详细日志 TF_CPP_VMODULE=http_server=1 api 请求日志 ``` 支持的启动参数:https://github.com/tensorflow/serving/blob/master/tensorflow_serving/model_servers/main.cc#L59 内存申请、cpu 申请、gpu 申请:按需申请。 域名:按具体业务填写。 镜像:选取合适版本镜像。 端口:**8501**(REST API;gRPC 默认 8500。平台中 TFServing 服务端口与健康检查端口均为 8501,见 `myapp/views/view_inferenceserving.py:108`、`:125`)。 ## TFServing API 访问 官方文档:https://github.com/tensorflow/serving/blob/master/tensorflow_serving/g3doc/api_rest.md Model status API: ``` GET http://host:port/v1/models/${MODEL_NAME}[/versions/${VERSION}|/labels/${LABEL}] 示例: https://demo.service.xxx/v1/models/my_model1/versions/20210924 ``` Model Metadata API: ``` GET http://host:port/v1/models/${MODEL_NAME}[/versions/${VERSION}|/labels/${LABEL}]/metadata 示例: https://demo.service.xxx/v1/models/my_model1/versions/20210924/metadata ``` Classify and Regress API: ``` POST http://host:port/v1/models/${MODEL_NAME}[/versions/${VERSION}]:(classify|regress) ``` Predict API: ``` POST http://host:port/v1/models/${MODEL_NAME}[/versions/${VERSION}|/labels/${LABEL}]:predict 示例: http://xx.xx.xx.xx/v1/models/my_model1/versions/20210924:predict ``` 生产中建议 api 调用不使用版本,这样能做到无缝切换版本: ``` http://xx.xx.xx.xx/v1/models/my_model1:predict ``` shell 示例: ``` curl -d '{"instances": [1.0, 2.0, 5.0]}' -X POST http://xx.xx.xx/v1/models/my_model1/versions/20210924:predict ``` python 示例 json: ``` req_json = { "instances":[ { 'input_name1':xx, 'input_name2':xx, ... } ] } predict_request = json.dumps(req_json) response = requests.post(SERVER_URL, data=predict_request) response.raise_for_status() print(response.json()) ``` python 推理图片: ``` jpeg_rgb = Image.open(io.BytesIO(open(IMAGE_PATH,"rb").read())) jpeg_rgb = np.expand_dims(np.array(jpeg_rgb) / 255.0, 0).tolist() predict_request = json.dumps({'instances': jpeg_rgb}) response = requests.post(SERVER_URL, data=predict_request) response.raise_for_status() print(response.json()) ``` ## 最小示例(mnist 训练 → 检查 → 启动服务) 以下是从训练保存模型到本地起服务的最小命令链(见 `images/serving/tfserving/example/`,含 `mnist_saved_model.py`、`mnist_client.py` 等脚本): 启动训练,保存模型: ``` python mnist_saved_model.py --training_iteration 10 --model_version 1 export_dir ``` 检查模型(确认服务签名): ``` saved_model_cli show --dir export_dir/1 --all ``` 启动服务(本地裸跑 tensorflow_model_server,REST 端口 8501): ``` tensorflow_model_server --rest_api_port=8501 --model_name=fashion_model --model_base_path=export_dir ``` > 该示例直接用 `--model_base_path` 指向模型目录裸跑;平台云原生部署则通过上文的 `models.config` 等配置文件指定模型,二选一。 --- ### TorchServe 推理服务 - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/07-%E6%9C%8D%E5%8A%A1%E5%8C%96%E4%B8%8E%E6%8E%A8%E7%90%86/%E6%8E%A8%E7%90%86%E6%9C%8D%E5%8A%A1-torchserve - 分类: 平台使用 / 服务化与推理 - 适用场景: 把 PyTorch 模型(.pt / .mar)部署成在线推理服务,需要了解打包、配置、启动命令与调用接口时读这篇 - 关键词: TorchServe / torch-server / torchserve / PyTorch / pt模型 / mar / torch-model-archiver / handler / config.properties / 推理服务 / inference / model serving / 模型部署 - 最后更新: 2026-06-30 # TorchServe 推理服务 本文介绍如何把 PyTorch 模型通过 TorchServe 部署为在线推理服务。在推理服务列表中新建服务时,`service_type` 选择 `torch-server`,平台会自动完成模型打包、配置文件生成和启动命令编排。下文标注"(系统完成)"的步骤通常由平台自动处理,用户只需准备好模型文件。 > 事实核对依据:服务类型、镜像、配置、端口、命令等来自 `myapp/views/view_inferenceserving.py` 与 `myapp/config.py`(`INFERENCE_IMAGES` 段)。 ## 镜像 平台内置可选的 TorchServe 镜像(`myapp/config.py:1327` `torch-server`): ``` ccr.ccs.tencentyun.com/cube-studio/torchserve:0.9.0-gpu ccr.ccs.tencentyun.com/cube-studio/torchserve:0.9.0-cpu ccr.ccs.tencentyun.com/cube-studio/torchserve:0.8.2-gpu ccr.ccs.tencentyun.com/cube-studio/torchserve:0.8.2-cpu ccr.ccs.tencentyun.com/cube-studio/torchserve:0.7.1-gpu ccr.ccs.tencentyun.com/cube-studio/torchserve:0.7.1-cpu ``` CPU 镜像用于无 GPU 场景,GPU 镜像需配合资源里的 `resource_gpu`。各版本对 Torch / CUDA 的兼容关系以 TorchServe 官方发布说明为准:https://github.com/pytorch/serve/releases ## 模型导出 **一定要导出完整的模型,包括模型结构和模型参数。** 只保存 `state_dict`(权重)而不保存结构,TorchServe 无法直接加载。 ```python # 仅保存/加载权重(不推荐单独用于部署) # torch.save(model.state_dict(), PATH) # model.load_state_dict(torch.load(PATH)) # 保存完整模型 torch.save(model, PATH) model = torch.load(PATH) model.eval() # 转为推理模式 example_input = torch.rand(1, 3, 224, 224) traced_model = torch.jit.trace(model, example_input) # TorchScript 序列化优化 traced_model.save('./model.pt') # 保存完整模型 ``` ## pt 模型打包(系统完成) 平台在部署时会自动调用 `torch-model-archiver` 把 `.pt` 等模型文件打包成 `.mar`(`view_inferenceserving.py:695`): ```bash pip3 install torch-model-archiver torch-model-archiver \ --model-name $model_name \ --version $model_version \ --handler $handler \ --serialized-file $model_path \ --export-path /models -f ``` 其中 `--handler` 在平台中取自服务的 transformer 字段,未填写时回退到 `model_type`(`view_inferenceserving.py:695` 的 `item.transformer or item.model_type`)。TorchServe 内置 handler 包括 `image_classifier`、`image_segmenter`、`object_detector`、`text_classifier` 等;其他类型见 https://pytorch.org/serve/default_handlers.html 。自定义 handler 见文末「自定义 handler」。 如果模型文件本身已经是 `.mar`,平台不再重复打包,直接拷贝到 `/models/` 后启动。在「模型地址」(`model_path`)中填写的规则:torch-model-archiver 编译后的 `.mar` 文件,或 TorchScript 保存的模型文件(`view_inferenceserving.py:228`)。 ## 配置文件 config.properties(系统完成) 平台自动生成 `config.properties`(`view_inferenceserving.py:543` `torch_config()`),内容如下: ```properties inference_address=http://0.0.0.0:8080 management_address=http://0.0.0.0:8081 metrics_address=http://0.0.0.0:8082 cors_allowed_origin=* cors_allowed_methods=GET, POST, PUT, OPTIONS cors_allowed_headers=X-Custom-Header number_of_netty_threads=32 enable_metrics_api=true job_queue_size=1000 enable_envvars_config=true async_logging=true default_response_timeout=120 max_request_size=6553500 ``` 说明: - `inference_address` / `management_address` / `metrics_address` 分别对应推理、管理、监控三个端口(8080 / 8081 / 8082)。 - 这些属性也可通过环境变量 `TS_` 注入(`view_inferenceserving.py:542` 注释)。 - 与早期版本相比,当前配置启用了 `enable_envvars_config=true`、`async_logging=true`,并新增 `default_response_timeout=120`、`max_request_size=6553500`。 > 注意:早期文档中的 `log4j.properties` 日志配置文件与启动命令里的 `---log-config` 参数,在当前平台自动生成的配置与启动命令中已不存在(`view_inferenceserving.py:704` 的启动命令只挂载 `--ts-config=/config/config.properties`,未含 `--log-config`)。如需自定义日志,请参考 TorchServe 原生 logging 配置自行加入。 ## 部署服务(系统完成) 平台自动编排的启动命令大致为(`view_inferenceserving.py:704`): ```bash # 工作目录:/models(系统自动设置) cp /config/* /models/ \ && \ && torchserve --start --model-store /models \ --models $model_name=$model_name.mar \ --foreground \ --ts-config=/config/config.properties ``` 无需手动填写启动命令;如需自定义,可在服务的「启动命令」字段覆盖默认值。 ## API 访问 端口(`view_inferenceserving.py:106-127`): - 推理:`8080` - 管理:`8081`(暴露端口为 `8080,8081`) - 监控:`8082`(指标 `8082:/metrics`) - 健康检查:`8080:/ping` 推理接口(8080 端口): ``` POST /v1/models/{model_name}:predict 推荐接口,兼容 KServe(kfserving) POST /predictions/{model_name} TorchServe 原生接口 POST /predictions/{model_name}/{version} ``` 管理接口(8081):`GET /models`(平台的访问域名 host 默认指向 `:8081/models`,`view_inferenceserving.py:69`)。 监控接口(8082):`/metrics`。 平台在服务列表的「推理测试」会打开 Notebook 示例 `pipeline/example/inference/torch-client.ipynb`(`view_inferenceserving.py:2202`)。 `image_classifier` 调用示例: ```python # pytorch SERVER_URL = 'http://<推理服务域名>/predictions/resnet50' IMAGE_PATH = 'smallcat.jpg' files = {'data': open(IMAGE_PATH, 'rb')} response = requests.post(SERVER_URL, files=files) print(response.json()) print(response.status_code) response.raise_for_status() # curl http://<推理服务域名>/predictions/resnet50 -T smallcat.jpg # curl http://<推理服务域名>/predictions/resnet50 -F "data=@smallcat.jpg" ``` 其他类型接口参考 https://pytorch.org/serve/default_handlers.html 。 ## 自定义 handler 示例 `MNISTDigitClassifier`:根据用户输入的图片地址先下载图片再推理,并回传请求中的 `image_id`。 生成 `handler.py`: ```python from torchvision import transforms from ts.torch_handler.image_classifier import ImageClassifier import base64, time, json import torch from PIL import Image import io import requests import pysnooper class MNISTDigitClassifier(ImageClassifier): image_processing = transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,)) ]) # @pysnooper.snoop() def handle(self, data, context): # 输入输出为 list start_time = time.time() self.context = context metrics = self.context.metrics data_preprocess = self.preprocess(data) if not self._is_explain(): output = self.inference(data_preprocess) output = self.postprocess(output) else: output = self.explain_handle(data_preprocess, data) stop_time = time.time() metrics.add_time('HandlerTime', round( (stop_time - start_time) * 1000, 2), None, 'ms') back = [] for index in range(len(output)): back.append({ "predict": output[index], "image_id": data[index]['body']['image_id'] }) return back # @pysnooper.snoop() def preprocess(self, data): des_images = [] for row in data: image_url = row.get("body")['image_url'] image = requests.get(image_url).content if isinstance(image, (bytearray, bytes)): image = Image.open(io.BytesIO(image)) image = self.image_processing(image) else: # 如果传入的是 list 形式的图片数据 image = torch.FloatTensor(image) des_images.append(image) return torch.stack(des_images).to(self.device) # @pysnooper.snoop() def postprocess(self, data): return data.argmax(1).tolist() ``` 将 `handler.py` 一起打入 `.mar`(系统可自动完成),再把生成的 `.mar` 文件路径填入界面: ```bash torch-model-archiver --model-name xx --version 1.0 --handler handler.py --serialized-file xx.pt --export-path ./ -f ``` `client.py` 调用: ```python data = { "image_url": "http://xx.xx.xx/xx", "image_id": "11111" } url = 'http://127.0.0.1:8080/v1/models/mnist:predict' res = requests.post(url, json=data) print(res.status_code) result = res.content.decode() print(result) ``` --- ### Triton 推理服务 - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/07-%E6%9C%8D%E5%8A%A1%E5%8C%96%E4%B8%8E%E6%8E%A8%E7%90%86/%E6%8E%A8%E7%90%86%E6%9C%8D%E5%8A%A1-triton - 分类: 平台使用 / 服务化与推理 - 适用场景: 用 NVIDIA Triton 部署 ONNX / TensorRT / TorchScript / SavedModel 模型做高性能推理,或把 PyTorch/TF 转成 ONNX 加速时读这篇 - 关键词: Triton / triton-server / tritonserver / TensorRT / ONNX / onnxruntime / TorchScript / config.pbtxt / model.plan / model.onnx / 推理服务 / inference / model serving / 模型加速 - 最后更新: 2026-06-30 # Triton 推理服务 本文介绍如何用 NVIDIA Triton Inference Server 部署模型。在推理服务列表中新建服务时,`service_type` 选择 `triton-server`,平台会根据模型框架自动生成 `config.pbtxt` 与启动命令。Triton 支持 ONNX、TensorRT(plan)、TorchScript(PyTorch libtorch)、TensorFlow SavedModel 等多种后端。 > 事实核对依据:镜像、目录、配置、端口、命令来自 `myapp/views/view_inferenceserving.py` 与 `myapp/config.py`(`INFERENCE_IMAGES` 段)。 ## 镜像 平台内置可选的 Triton 镜像(`myapp/config.py:1328` `triton-server`): ``` ccr.ccs.tencentyun.com/cube-studio/tritonserver:24.01-py3 ccr.ccs.tencentyun.com/cube-studio/tritonserver:23.12-py3 ccr.ccs.tencentyun.com/cube-studio/tritonserver:22.12-py3 ccr.ccs.tencentyun.com/cube-studio/tritonserver:21.12-py3 ccr.ccs.tencentyun.com/cube-studio/tritonserver:20.12-py3 ``` > 注意:原文档使用的 `nvcr.io/nvidia/tensorrtserver:19.05-py3`、`nvcr.io/nvidia/tritonserver:21.09-py3` 已不在当前平台内置镜像列表中,上方列表按 `myapp/config.py:1328` 更新。镜像版本与 ONNX/TensorRT/CUDA 算子兼容性相关,转换模型时注意对齐版本。 ## 模型地址与目录结构 在「模型地址」(`model_path`)中按 `框架:地址` 填写(`view_inferenceserving.py:229`): - `onnx`:模型文件地址,如 `model.onnx` - `pytorch`:TorchScript 模型文件地址,如 `model.pt` - `tf`:SavedModel 目录地址,如 `saved_model` - `tensorrt`:plan 模型文件地址,如 `model.plan` 平台会自动识别后缀(`.onnx` / `.plan` / `.pt` / `.pth`,否则按 tf 处理,`view_inferenceserving.py:719-724`),并按 Triton 要求自动整理为如下仓库结构(`view_inferenceserving.py:728-731`): ``` /models/ / config.pbtxt / model.onnx | model.plan | model.pt | model.savedmodel/ ``` > 说明:模型文件名必须符合 Triton 约定(如 `model.onnx`、`model.plan`),平台在拷贝时会自动重命名为 `model.<后缀>`(TF 模型则放入 `model.savedmodel/` 目录),用户无需手动改名。 ## 配置 config.pbtxt(系统自动生成) 平台根据模型框架自动生成 `config.pbtxt`(`view_inferenceserving.py:562` `triton_config()`),框架到 `platform` 的映射为: | 框架(model_type) | platform | |---|---| | onnx | `onnxruntime_onnx` | | tensorrt | `tensorrt_plan` | | pytorch / torch | `pytorch_libtorch` | | tf | `tensorflow_savedmodel` | 自动生成的基本结构(`max_batch_size` 默认 0,input/output 为示例占位,需按实际模型修改): ```protobuf name: "resnet50" platform: "onnxruntime_onnx" max_batch_size: 0 input [ { name: "input_name" data_type: TYPE_FP32 format: FORMAT_NCHW dims: [ 3, 224, 224 ] reshape: { shape: [ 1, 3, 224, 224 ] } } ] output [ { name: "output_name" data_type: TYPE_FP32 dims: [ 1000 ] reshape: { shape: [ 1, 1000 ] } } ] ... 框架相关优化参数 ``` 不同框架平台会追加不同的优化参数(`triton_config()`): - tf:`optimization { execution_accelerators { gpu_execution_accelerator: [{ name: "tensorrt" precision_mode=FP16 }] } }` - onnx:`intra_op_thread_count` / `execution_mode` / `inter_op_thread_count` 等线程参数 - pytorch:`DISABLE_OPTIMIZED_EXECUTION` / `INFERENCE_MODE` 修改 `config.pbtxt` 时主要关注 input / output 的 `name`、`data_type`、`dims`,使其与实际模型一致。在线查看模型结构可用 https://netron.app/ 。 > 提示:原文档建议「不确定就先不填,系统会自动识别」。当前平台启动参数为 `--strict-model-config=true`(见下文),即由平台自动生成 `config.pbtxt`,而非依赖 Triton 运行时自动推断。部署后可用 `curl localhost:8000/v2/models/<模型名称>/config` 查看 Triton 实际加载的配置。 TorchScript 模型注意:TorchScript 不携带输入输出端口命名,配置文件中 input/output 的 `name` 必须按约定写为 `"INPUT__0"`, `"INPUT__1"` 与 `"OUTPUT__0"`, `"OUTPUT__1"`。 ## 启动命令(系统完成) 平台自动编排的启动命令(`view_inferenceserving.py:728-731`,以非 TF 模型为例): ```bash mkdir -p /models/// \ && cp /config/* /models// \ && cp -r /models///model. \ && tritonserver --model-repository=/models --strict-model-config=true --log-verbose=1 ``` > 注意:原文档启动命令曾为 `--strict-model-config=false`(依赖运行时自动识别),当前代码统一使用 `--strict-model-config=true --log-verbose=1`(`INFERNENCE_COMMAND['triton-server']`,`myapp/views/view_inferenceserving.py:89`,以及 `use_expand` 中实际拼接的启动命令)。 ## API 访问 端口(`view_inferenceserving.py:110-127`): - HTTP 推理:`8000` - 指标:`8002`(`8002:/metrics`),暴露端口为 `8000,8002` - 健康检查:`8000:/v2/health/ready` Triton 采用 KServe v2 协议,平台的访问域名 host 默认指向 `/v2/models/$model_name`(`view_inferenceserving.py:70`)。常用接口: ``` GET /v2/models/{model_name} 模型元数据 GET /v2/models/{model_name}/versions/{version} 指定版本元数据 POST /v2/models/{model_name}/infer 推理 GET /v2/health/ready 健康检查 GET /v2/models/{model_name}/config 查看已加载配置 ``` > 注意:原文档「标准化模型接口」一节列出的是 `/v1/model/$model_name`、`/v1/model/$model_name/version/$version_name` 等形式,与 Triton 实际使用的 KServe v2 协议不一致。Triton 的访问域名 host 默认指向 `/v2/models/$model_name`(`INFERNENCE_HOST['triton-server']`,`view_inferenceserving.py:70`),健康检查为 `/v2/health/ready`,故以上述 v2 接口为准;其余框架(tfserving 等)的接口请见对应文档。 建议使用 Triton 官方客户端包调用: ```bash pip3 install tritonclient[all] pip3 install attrdict ``` 平台在服务列表的「推理测试」会打开 Notebook 示例 `pipeline/example/inference/triton-client.ipynb`(`view_inferenceserving.py:2204`)。 ## ONNX 模型推理加速 ### TF / PyTorch 转 ONNX PyTorch 模型转 ONNX: ```python model.eval() # 设置模型为推理模式 dummy_input = torch.randn(1, 3, 224, 224) # 输入样本 export_onnx_file = "resnet50.onnx" # 目的 ONNX 文件名 torch.onnx.export( model, dummy_input, export_onnx_file, opset_version=13, # 转为 onnx 的版本 do_constant_folding=True, # 是否执行常量折叠优化 input_names=["input_name"], # 输入名 output_names=["output_name"], # 输出名 # dynamic_axes={ # "input": {0: "batch_size"}, # 批处理变量 # "output": {0: "batch_size"} # }, dynamic_axes={'input_name': [2, 3], 'output_name': [2, 3]} # 动态 size 的输入输出维度 ) ``` TF 模型转 ONNX: ```bash # pip install tensorflow-onnx tf2onnx python -m tf2onnx.convert --saved-model ./saved_model --output ./model.onnx --opset 13 ``` 按模型结构填写 `config.pbtxt`,主要是 input / output 信息(可用 https://netron.app/ 查看)。 ### PyTorch 模型加速(TorchScript) PyTorch 模型在 Triton 上加速,需要导出 TorchScript(下例方法 4): ```python # 方法1:保存完整模型 # torch.save(model, 'mnist.pt') # # 方法2:保存网络参数 # torch.save(model.state_dict(), './cifar_net.pth') # # 方法3:导出到 ONNX # dummy_input = torch.randn(1, 1, 28, 28).to(device) # torch.onnx.export(model, dummy_input, "torch.onnx") # 方法4:保存 TORCHSCRIPT(用于 Triton pytorch_libtorch 后端) # dummy_input = torch.randn(1, 1, 28, 28).to(device) # traced_cell = torch.jit.trace(model, dummy_input) # traced_cell.save("torchscript.pt") ``` TorchScript 模型的 input/output 端口名按前文约定写为 `INPUT__0` / `OUTPUT__0` 等。 --- ### 标注平台功能介绍与操作流程 - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/08-%E6%95%B0%E6%8D%AE%E6%A0%87%E6%B3%A8/%E6%A0%87%E6%B3%A8%E5%B9%B3%E5%8F%B0/01-%E5%8A%9F%E8%83%BD%E4%B8%8E%E6%93%8D%E4%BD%9C%E6%B5%81%E7%A8%8B - 分类: 平台使用 / 数据标注 - 适用场景: 要在标注平台上创建项目、导入数据、配置模板、人工或自动标注、同步云存储、导出结果时,按本篇操作 - 关键词: 标注平台 / Label Studio / 创建项目 / 数据管理 / 人工标注 / 标注模板 / 自动化标注 / 预标注 / 预测结果 / 云存储 / Source Storage / Target Storage / 导出 / 网络钩子 / webhook / 标注协作 - 最后更新: 2026-07-04 # 标注平台功能介绍与操作流程 点击「数据资产」->「标注平台」,进入基于 Label Studio 的自动化标注平台。 ![标注平台入口](https://foruda.gitee.com/images/1698386967112077094/73b43e55_1019082.png) 本篇介绍项目创建、数据管理、人工标注、自动化标注、云存储、导出和协作等常用功能。平台围绕「创建项目、导入数据、配置标注模板、人工标注、自动化标注、数据同步、结果导出、成员协作」组织工作流,适用于图像、文本、音频、视频、结构化数据、时间序列等多类型数据标注。 ## 1. 项目列表 进入标注平台后,首先看到项目列表,展示当前用户可访问的标注项目,包含项目名称、任务完成情况、标注数量、预测数量、创建时间和创建人等信息。 ![项目列表](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/ce01aadaf0dfc3684c0ae880f97e3725.png) 常用操作: - 查看已有项目:页面中会列出视觉、文本、语音、结构化数据、时间序列等类型的示例项目。 - 新建项目:点击右上角「创建」按钮进入项目创建流程。 - 进入项目:点击项目卡片或项目名称,进入该项目的数据管理页。 - 权限隔离:用户只能看到自己有权限访问的项目空间下的标注项目。(实现上按项目组 ID 过滤,见总览文档。) ## 2. 创建项目 点击「创建」后出现创建项目弹窗,流程分为「项目名称」「标注配置」「数据导入」三个步骤。可以创建空白项目,也可以在创建过程中直接导入数据生成任务。对于大批量文件,建议导入数据每行一个媒体 URL。 ### 2.1 填写项目基础信息 ![创建项目-基础信息](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/b605e0b5dba892627beecdb1f4fd3bcf.png) 基础信息包括: - 项目名称:用于在项目列表和任务页中识别项目。 - 描述:补充说明项目用途、数据来源、标注目标等。 - 工作空间:选择项目所属空间,用于和平台侧项目组、权限范围对应。 ### 2.2 选择标注模板 ![创建项目-标注配置](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/ec92741a9da25ae44745b3ddd109681c.png) 标注模板决定后续标注界面和可用工具。平台提供多类模板: - 机器视觉:目标检测、语义分割、多边形、关键点、库存跟踪等。 - 自然语言:文本分类、命名实体识别、问答、阅读理解、摘要、翻译等。 - 音频/语音处理:语音识别、说话人分离、多说话人识别等。 - 对话式 AI:聊天、意图识别、对话评估等。 - 结构化数据解析:表格、分类、排序等。 - 时间序列分析:时序片段、区域标注等。 - 视频:视频目标跟踪、视频片段标注等。 - 生成式 AI:大模型相关数据构造和评估场景。 - 自定义模板:使用自定义配置满足特殊标注任务。 选择模板后,可根据业务调整标签名称。例如目标检测场景可以删除默认类别,改为 `face`、`hand`、`person`、`vehicle` 等业务类别。如果进入标注界面后内容为空白,通常需要先到模板配置中选择或调整合适的标注模板。 ### 2.3 导入初始数据 ![创建项目-数据导入](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/0928b1fa41e12670ded76837361eff37.png) 创建项目时可以直接导入数据,也可以先创建空项目后续再导入。适合直接导入的小批量数据格式(详细见 [02-数据导入格式说明](02-数据导入格式说明.md)): - 文本:`txt` - 图片:`jpg`、`jpeg`、`png`、`gif`、`bmp`、`svg`、`webp` - 音频:`wav`、`mp3`、`flac`、`m4a`、`ogg` - 视频:`mpeg4/H.264`、`webp`、`webm` - HTML:`html`、`htm`、`xml` - 时间序列:`csv`、`tsv` - 常用结构化格式:`csv`、`tsv`、`txt`、`json` 导入数据统一建议只上传文件 URL,而不是把整个媒体文件传上来。比如 `txt` 每行一个图片 URL。 ## 3. 数据管理 进入项目后默认打开数据管理页,它是项目日常操作的核心入口,用于查看任务、筛选任务、切换视图、导入数据、导出结果和进入标注。 ![数据管理-列表视图](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/524d30fc388955cc6e724d25a31ae78b.png) 数据管理页提供以下能力: - 任务统计:右上方显示任务总数、已标注数量、预测数量。 - 项目状态:可以将项目设为「标注中」「标记为完成」或「暂停」。 - 列管理:选择要显示的字段,例如完成时间、标注人、指派人、图片字段、草稿状态等。 - 筛选:按字段过滤任务,方便定位未标注、已标注、有草稿或特定数据。 - 排序:按字段调整任务展示顺序。 - 数据导入:在当前项目中追加新任务。 - 数据导出:导出当前项目的标注结果。 - 列表/网格切换:表格适合批量查看字段,网格适合图片类数据快速浏览。 ### 3.1 网格视图 图片、视频等媒体数据可以切换到网格视图,更适合快速检查数据质量和标注覆盖情况。 当图片类数据在列表中显示为空白时,通常是字段类型没有设置正确。例如图片 URL 被识别成普通字符串时,列表中可能只显示空白或文本字段,需要在字段列中把对应字段切换为 `img` / `image` 类型,确认数据以图片形式渲染。 ## 4. 项目内导入数据 在数据管理页点击「导入」,可以向已有项目追加任务。 ![项目导入数据](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/ac658a1b47f1d70bd0560a33f93c46fe.png) 导入方式包括: - 搜索 Cube 数据集:输入关键词搜索平台中的数据集,并导入到当前标注项目。 - 上传文件:上传本地文件,支持文本、图片、音频、视频、CSV、TSV、JSON 等格式。 - 拖拽上传:将文件拖到上传区域,适合少量文件快速导入。 使用建议: - 小批量数据:直接上传文件。 - Cube 平台已有数据集:优先使用「搜索 Cube 数据集」。 - 大批量文件:可以上传每行一个图片地址的 `txt`,或上传任务数组形式的 `json`。 ## 5. 人工标注 在数据管理页点击单条任务,或使用「标注全部任务」,可进入标注编辑器。新项目如果还没有配置标注模板,通常会先进入设置流程,需要先选择或编辑标注模板后再开始标注。 ![标注编辑器](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/889454ed56a2362fdb7069589964c492.png) 标注编辑器通常包含以下区域: - 数据预览区:展示当前任务的图片、文本、音频、视频或表格内容。 - 标签区:展示当前模板配置的标签,支持快捷键选择。 - 标注工具区:根据模板不同,提供矩形框、多边形、关键点、分类、文本选择、音频片段等工具。 - 结果区:显示当前任务已创建的标注区域、标签和预测结果。 - 提交操作:完成标注后提交,任务状态会同步到数据管理页。 常见操作流程: 1. 选择标签。 2. 在数据上创建标注区域或选择分类结果。例如目标检测任务中,选择标签后在目标区域拖拽即可生成标注框。 3. 检查标注结果。 4. 提交标注。 5. 自动进入下一条任务或返回数据管理页。 ## 6. 标注模板设置 项目创建后仍可在「设置 -> 标签接口」中调整标注模板。如果模板不符合当前数据类型,可以通过 Browse Template 选择预置模板,也可以在配置中修改标签名称、字段绑定和控件类型。 ![标注模板设置](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/65f15b20818e3a14ba740b92612ed3e2.png) 模板设置适合以下场景: - 新项目创建后补充标注配置。 - 修改标签名称、颜色或类别集合。 - 从预置模板切换到自定义模板。 - 调整图片、文本、音频等数据字段和标注控件的绑定关系。 - 增加或减少标注任务需要的控件。 注意事项: - 模板中的数据字段要和导入任务中的字段一致。 - 图片标注模板通常需要把图片字段绑定到 `Image` 控件。 - 文本分类、命名实体识别、问答等任务需要确认文本字段名称。 - 项目已经有大量标注结果后,修改模板可能影响后续结果一致性,建议先确认变更范围。 ## 7. 自动化标注与模型配置 在「设置 -> 模型」中可以配置自动化标注模型(ML 后端)。标注平台本身主要提供任务管理、标注界面和结果管理能力;自动化标注通过 ML 后端为未标注任务生成预测结果。 ![模型配置](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/90547fcebd4a6091c230fe6139ca146d.png) 自动化标注的作用: - 对未标注任务生成预测结果。 - 为人工标注提供预标注,提高标注效率。 - 结合人工修正,形成「模型预标注 + 人工审核」的工作流。 - 支持主动学习或模型训练触发流程。 ML 后端有两类来源: - 平台内置 NLP 自动标注后端(核对自 `myapp/views/view_labelstudio.py`):平台在 `/proxy/labelstudio///predict` 暴露了固定的 ML 后端接口,由平台配置的大模型(`CHATGPT_CHAT_URL` / `CHATGPT_ARGS`)驱动,支持文本分类(classification)、摘要(summary)、翻译(translaton)、命名实体识别(ner)、问答(faq)、答案排序(rank)、意图识别(intent)、对话(chat)等 NLP 任务(`view_labelstudio.py:74-93`)。在标注项目的模型设置中,把对应的 ML 后端 URL 接入即可使用。 - 外部模型服务:例如 AIHub 训练完成后发布的推理服务,把服务 URL 配置到标注平台。模型服务需要按标注平台要求适配输入和输出格式,否则即使服务可访问,也可能无法生成可展示的预测结果。 页面中可以查看模型连接状态、模型名称、服务地址和创建时间。 常见自动化标注类型: - 视觉:目标检测、图像分类、关键点检测、实例分割、语义分割、OCR、图片描述、视频目标跟踪。 - 文本:文本分类、命名实体识别、阅读理解、问答、摘要、翻译、答案排序。 - 对话:意图识别、聊天数据构造。 - 语音:语音识别、说话人分离、多说话人识别。 ## 8. 预测结果管理 在「设置 -> 预测」中可以查看和管理项目中的预测结果。 ![预测设置](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/61e9cf22bf25d0289e013b36a57b34c1.png) 预测结果通常来自: - 自动化标注模型在线推理。 - 批量导入的预测文件(导入格式见 [02-数据导入格式说明](02-数据导入格式说明.md) 的「预标注结果」)。 - 外部模型服务生成的预标注结果。 使用建议: - 如果希望人工标注时看到模型建议,需要在项目设置中开启预测展示。 - 如果预测质量较高,可以把预测作为预标注,再由人工确认或修正。 - 如果预测质量不稳定,建议先抽样检查,再决定是否用于批量任务。 ## 9. 云存储同步 在「设置 -> 云存储」中可以配置数据来源和结果回写位置。 ![云存储](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/fc6cfc9714557bd4a013ba78852259be.png) 云存储用于管理大批量待标注数据和标注结果,通常分为两类: - 原始文件云存储:作为待标注数据来源,用于同步未标注任务,也称 Source Storage。 - 结果文件云存储:作为标注结果目标,用于保存标注输出,也称 Target Storage。 典型使用方式: - 从 `/mnt/$username`、对象存储或其他可访问存储目录同步待标注图片、音频、视频等文件。 - 使用 Source Storage 扫描并创建标注任务。 - 使用 Target Storage 将标注结果写回个人目录或共享存储。 - 每次新增数据或完成标注后,通过 Sync Storage 同步任务和结果。 标注平台已和 CubeStudio 底层分布式存储打通。常见做法是先通过 Notebook 或其他流程把数据放到 `/mnt/$username` 目录,再在标注项目中配置该目录作为数据来源。目录中的文件也可以通过静态 URL 访问,例如 `/mnt/admin/aa.jpg` 可对应为 `http://服务器地址/static/mnt/admin/aa.jpg`(`/static/mnt/` 前缀由后端映射到分布式存储工作目录,核对自 `myapp/views/view_dataset.py:1024`)。对于大批量文件,建议使用 URL 形式,也更适合和后续 Pipeline、Notebook 或训练流程衔接。 ## 10. 导出标注结果 在数据管理页点击「导出」可以导出项目标注结果。也可以在云存储中配置结果保存目录,将标注结果同步写回 CubeStudio 个人目录或共享存储。 ![导出结果](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/5787deb38d4b187fede4f44309d60616.png) 导出功能支持: - 选择导出格式。 - 下载标注结果文件。 - 将结果注册或导出回 Cube 数据集。 - 仅导出已完成任务的结果。 常见用途: - 交付标注结果文件。 - 将标注结果用于模型训练。 - 把结果同步回 Cube 数据资产,供 Pipeline 或 Notebook 继续处理。若使用 Target Storage,建议先在 Notebook 中创建结果目录,再在标注项目中配置保存地址;标注提交或同步后,结果会写入该目录。 - 归档不同批次的标注结果。 ## 11. 项目通用设置 在「设置 -> 通用」中可以查看和调整项目基础设置。 ![通用设置](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/e89e33ab94555ef1fc65803d6c7fe2de.png) 通用设置通常包括: - 项目名称和描述。 - 项目状态管理。 - 标注行为选项。 - 任务展示和协作相关选项。 项目状态说明: - 标注中:正常进行任务导入、配置和标注。 - 暂停:临时停止标注,适合等待数据或模板确认。 - 标记为完成:项目进入完成状态,适合冻结当前标注批次。 当项目被标记为完成后,一般不建议继续修改标注模板或追加任务,避免影响结果一致性。 ## 12. 网络钩子 在「设置 -> 网络钩子」中可以配置事件通知。 ![网络钩子](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/3d5bcc6980d518d084a29bc6c0bfc8c1.png) 网络钩子适合将标注平台和外部系统联动,例如: - 新任务导入后通知外部服务。 - 标注提交后触发质量检查。 - 项目完成后通知后续数据处理流程。 - 与内部消息系统或任务调度系统集成。 使用网络钩子前,需要准备可访问的回调地址,并确认外部服务能够处理平台发送的事件数据。 ## 13. 常见问题 ### 图片数据导入后不显示 通常是字段类型不匹配。检查数据字段是否是图片 URL 或图片文件路径,并在数据管理页把对应列设置为图片类型。如果字段仍按字符串显示,图片可能不会正常渲染。 ### 点击项目后看不到任务 可能是项目没有导入数据、当前筛选条件隐藏了任务,或用户没有当前工作空间权限。可以先清空筛选条件,再确认项目任务数量。 ### 自动化标注没有预测结果 检查模型是否已连接、服务地址是否可访问、模型输入输出是否匹配当前模板。外部模型服务需要按标注平台的请求和响应格式适配,也可以先在少量任务上测试预测效果。 ### 大批量文件上传慢或失败 建议先把数据放到 `/mnt/$username`、共享目录或对象存储,再配置成 URL 的 `txt` 上传到平台。 ### 标注结果怎么回到 Cube 可以在导出页选择导出到数据集,也可以配置结果文件云存储,把标注结果写入个人目录或共享存储。结果写入分布式存储后,可继续通过 Pipeline、Notebook 或训练任务处理。 --- ### 标注平台数据导入格式说明 - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/08-%E6%95%B0%E6%8D%AE%E6%A0%87%E6%B3%A8/%E6%A0%87%E6%B3%A8%E5%B9%B3%E5%8F%B0/02-%E6%95%B0%E6%8D%AE%E5%AF%BC%E5%85%A5%E6%A0%BC%E5%BC%8F%E8%AF%B4%E6%98%8E - 分类: 平台使用 / 数据标注 - 适用场景: 准备上传到标注平台的数据文件、确认字段名、按标注类型选格式时查这篇参考 - 关键词: 标注平台 / 数据导入 / 导入格式 / 字段名 / List of tasks / Time Series / CSV / TSV / JSON / TXT / 图片标注 / 音频 / 视频 / 文本 / 问答 / 阅读理解 / 翻译 / 答案排序 / 对话 / 结构化数据 / 时间序列 / HTML / XML / 预标注 / predictions - 最后更新: 2026-06-30 # 标注平台数据导入格式说明 本篇说明导入数据时如何选择文件格式、确认字段名,以及不同标注类型对应的文件内容示例。下方示例均为可上传文件内容示例,可根据实际字段名和文件地址替换。字段名最终以页面列名或标注界面模板配置(`value="$xxx"`)为准。 ## 1. 在页面查看支持格式 进入项目后,在数据管理页点击右上角「导入」,打开「导入数据」窗口。上传区域会展示当前支持的文件类型。 ![项目导入数据](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/ac658a1b47f1d70bd0560a33f93c46fe.png) | 类型 | 支持格式 | 使用建议 | |---|---|---| | 文本 | `txt` | 每行一条文本 | | 图片 | `jpg`、`jpeg`、`png`、`gif`、`bmp`、`svg`、`webp` | 少量可直接上传,批量建议使用 URL 文件 | | 音频 | `wav`、`mp3`、`flac`、`m4a`、`ogg` | 少量可直接上传,批量建议使用 URL 文件 | | 视频 | `mp4`、`webp`、`webm` | 少量可直接上传,批量建议使用 URL 文件 | | 富文本 | `html`、`htm`、`xml` | 用于网页片段、XML 内容标注 | | 表格 / 时间序列 | `csv`、`tsv` | 可按行生成任务,也可作为时间序列文件 | | 通用任务文件 | `json`、`csv`、`tsv`、`txt` | 适合批量导入和多字段任务 | ## 2. 按标注类型选择文件 导入前先确认项目的数据字段。字段名应与数据管理页中的字段保持一致。 ![数据管理-列表视图](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/csdn_image/524d30fc388955cc6e724d25a31ae78b.png) 字段名可以通过以下方式确认: - 已经导入过数据的项目:在数据管理页查看表格列名,导入文件中的字段名应与列名一致。例如页面显示 `image` 列,图片数据就应写在 `image` 字段中。 - 还没有导入数据的项目:进入项目的设置或标注界面配置页,查看数据对象控件中的 `value`。例如 `value="$image"` 表示导入字段名应为 `image`,`value="$text"` 表示导入字段名应为 `text`。 - 多字段任务需要同时准备多个字段。例如阅读理解项目如果配置中使用了 `$text` 和 `$question`,导入文件中就需要同时包含 `text` 和 `question`。 常见字段名如下表。实际项目如有不同,以页面列名或标注界面配置为准。 | 标注类型 | 推荐格式 | 常用字段 | 内容 | |---|---|---|---| | 图片分类、目标检测、分割、OCR、图片描述 | `txt`、`json`、`csv` | `image` / `img` / `ocr` / `captioning` | 图片 URL | | 视频目标跟踪、视频片段标注 | `json`、`csv` | `video` | 视频 URL | | 语音识别、说话人分离、音频分类 | `txt`、`json`、`csv` | `audio` | 音频 URL | | 文本分类、摘要、命名实体识别、代码生成 | `txt`、`json`、`csv` | `text` | 待标注文本 | | 翻译 | `txt`、`json`、`csv` | `chinese` / `text` | 待翻译文本 | | 问答 | `txt`、`json`、`csv` | `question` | 问题 | | 阅读理解 | `json`、`csv` | `text`、`question` | 上下文和问题 | | 答案排序 / 奖励模型数据 | `json` | `question`、`annotations`、`rank` | 问题、候选答案、排序 | | 多轮对话 / 意图识别 | `json` | `dialogue` / `humanMachineDialogue` | 对话轮次 | | 结构化数据分类 | `csv`、`tsv`、`json` | 业务字段 | 每列一个业务字段 | | 时间序列区域标注 | `csv`、`tsv`、`txt` | 时间列、数值列 | 时序数据或时序文件 URL | | HTML / XML 富文本标注 | `html`、`htm`、`xml`、`json` | `html` | 富文本内容 | 建议: - 新建项目时,可优先使用通用字段名:图片 `image`,音频 `audio`,视频 `video`,文本 `text`。 - 已有项目以数据管理页显示的字段名为准。导入后页面不显示数据时,优先检查字段名。 - `json` 适合多字段任务;`csv/tsv` 适合表格化任务;`txt` 适合一行一条文本或一行一个 URL。 > 字段名与内置自动标注后端的对应(核对自 `myapp/views/view_labelstudio.py`):文本类任务读取 `text`(`view_labelstudio.py:99`);问答(faq)读取 `text` 与 `question`(:346-347);翻译读取模板中 `TextArea` 的 `toName` 字段(默认 `chinese`,:215-223);意图识别/对话读取模板中 `Paragraphs` 的 `value` 变量(默认 `humanMachineDialogue` / `dialogue`,:454-461、:518-525)。即字段名最终由模板配置决定。 ## 3. CSV/TSV 导入方式 上传 `csv` 或 `tsv` 时,页面可能要求选择处理方式。 | 选项 | 含义 | 适用场景 | |---|---|---| | List of tasks | 每一行是一条任务 | 文本列表、图片 URL 列表、音频 URL 列表、结构化记录 | | Time Series or Whole Text File | 整个文件作为一条任务 | 时间序列曲线、整份 CSV/TSV 作为一个对象标注 | 大多数分类、检测、文本、问答任务选择 `List of tasks`。时间序列标注选择 `Time Series or Whole Text File`。 ## 4. 图片类任务 适用于图片分类、目标检测、边界识别、遮罩识别、关键点检测、OCR、图片描述等任务。批量导入时建议上传图片 URL 列表。 TXT 示例:每行一个图片 URL。 ```txt http://example.com/static/mnt/admin/images/cat-001.jpg http://example.com/static/mnt/admin/images/dog-002.jpg http://example.com/static/mnt/admin/images/invoice-003.jpeg ``` JSON 示例:字段名按项目实际字段填写。 ```json [ { "image": "http://example.com/static/mnt/admin/images/cat-001.jpg" }, { "image": "http://example.com/static/mnt/admin/images/dog-002.jpg" } ] ``` OCR 项目如果字段为 `ocr`,可写为: ```json [ { "ocr": "http://example.com/static/mnt/admin/images/receipt-001.jpg" } ] ``` CSV 示例: ```csv image http://example.com/static/mnt/admin/images/cat-001.jpg http://example.com/static/mnt/admin/images/dog-002.jpg ``` ## 5. 音频和视频任务 适用于语音识别、说话人分离、音频分类、视频目标跟踪、视频片段标注等任务。批量导入时建议上传音视频 URL 列表。 音频 JSON 示例: ```json [ { "audio": "http://example.com/static/mnt/admin/audio/speech-001.wav" }, { "audio": "http://example.com/static/mnt/admin/audio/meeting-002.mp3" } ] ``` 视频 JSON 示例: ```json [ { "video": "http://example.com/static/mnt/admin/video/traffic-001.mp4" }, { "video": "http://example.com/static/mnt/admin/video/factory-002.webm" } ] ``` 也可以使用 `txt` 文件,每行一个音频或视频 URL。 ## 6. 文本类任务 适用于文本分类、摘要、命名实体识别、代码生成、普通文本审核等任务。 TXT 示例:每行一条文本。 ```txt 这家餐厅服务很好,菜品也很新鲜。 物流太慢了,包装也破损了。 客服回复及时,问题解决得很快。 ``` JSON 示例: ```json [ { "text": "这家餐厅服务很好,菜品也很新鲜。" }, { "text": "物流太慢了,包装也破损了。" } ] ``` CSV 示例:可增加来源、优先级等辅助字段。 ```csv text,source,priority 这家餐厅服务很好,菜品也很新鲜。,评论,high 物流太慢了,包装也破损了。,售后反馈,medium ``` ## 7. 问答、阅读理解和翻译 这类任务通常包含多个字段,推荐使用 `json` 或 `csv`。 翻译示例(字段名默认 `chinese`,即待翻译文本): ```json [ { "chinese": "今天天气很好,我们一起去公园吧。" }, { "chinese": "这个模型可以帮助我们完成自动化标注。" } ] ``` 问答示例: ```json [ { "question": "如何创建一个标注项目?" }, { "question": "标注结果如何导出?" } ] ``` 阅读理解示例: ```json [ { "text": "昨天,我去公园待了大约两个小时,然后回家吃晚餐。", "question": "我在公园待了多久?" }, { "text": "汤姆每天早晨都会跑步5公里来保持健康。", "question": "汤姆为什么每天早晨跑步?" } ] ``` CSV 示例: ```csv text,question 昨天,我去公园待了大约两个小时,然后回家吃晚餐。,我在公园待了多久? 汤姆每天早晨都会跑步5公里来保持健康。,汤姆为什么每天早晨跑步? ``` ## 8. 答案排序和对话任务 这类任务字段结构较复杂,推荐使用 `json`。 答案排序示例: ```json [ { "question": "如何导出标注结果?", "annotations": [ { "text": "在项目数据页点击导出,选择格式后下载。" }, { "text": "在云存储中配置结果路径后同步。" } ], "rank": [1, 2] } ] ``` > 注意:上面的 `annotations` + `rank` 是常见的答案排序导入/预标注结构。但平台内置的 rank 自动标注后端实际读取的是 `task['data']['items']`(每个元素含 `id` / `title` / `body`)和 `question` 字段(`myapp/views/view_labelstudio.py:396-401`)。具体字段名取决于所选标注模板配置,使用内置自动排序时请以模板中的字段为准。 多轮对话示例: ```json [ { "dialogue": [ { "author": "Human", "text": "你好,我想了解一下最近的电影推荐。" }, { "author": "AI", "text": "当然。你喜欢什么类型的电影?" } ] } ] ``` 如果项目字段名是 `humanMachineDialogue`,请将 `dialogue` 替换为 `humanMachineDialogue`。 ## 9. 结构化数据 结构化数据通常来自业务表格,推荐使用 `csv` 或 `tsv`。第一行是列名,每一行是一条任务。 ```csv part,method,lesion,location,morphology,size,conclusion 胸部,X光平片,无,无,无,无,心肺膈未见明显异常 胸部,CT平扫,磨玻璃结节,右肺上叶,磨玻璃状,边缘尚光整,直径约6mm,右肺上叶磨玻璃结节,建议随访 ``` 导入时选择 `List of tasks`。 ## 10. 时间序列 时间序列数据通常使用 `csv` 或 `tsv`。 ```csv time,temperature,pressure 2026-06-09 10:00:00,23.5,101.2 2026-06-09 10:00:01,23.6,101.3 2026-06-09 10:00:02,23.7,101.1 ``` 导入时选择 `Time Series or Whole Text File`。 如果时间序列文件已经在服务器上,也可以上传 URL 列表: ```txt http://example.com/static/mnt/admin/timeseries/sensor-001.csv http://example.com/static/mnt/admin/timeseries/sensor-002.csv ``` ## 11. HTML / XML 富文本 适用于富文本实体识别、网页内容审核、XML 内容抽取等任务。 HTML 示例: ```html

产品说明

这是一段需要进行实体识别或内容审核的 HTML 文本。

联系人:张三,电话:13800000000。

``` XML 示例: ```xml 设备巡检记录 设备 A 在 2026-06-09 出现温度异常。 ``` JSON 中也可以包含 HTML 内容: ```json [ { "html": "

联系人:张三,电话:13800000000。

", "source": "网页表单" } ] ``` ## 12. 预标注结果 如果已有模型预测结果,可以使用 `json` 导入预标注。原始数据放在 `data` 中,预测结果放在 `predictions` 中。 ```json [ { "data": { "text": "这条评论整体是正向的。" }, "predictions": [ { "model_version": "demo-v1", "score": 0.93, "result": [ { "from_name": "sentiment", "to_name": "text", "type": "choices", "value": { "choices": ["正向"] } } ] } ] } ] ``` > 说明:上述 `result` 中的 `from_name` / `to_name` / `type` / `value` 结构与平台内置自动标注后端返回的预测结构一致(参见 `view_labelstudio.py` 各 `nlp_*` 方法),需与模板控件命名对应。 ## 13. 常见检查项 CSV 建议保留表头: ```csv image http://example.com/a.jpg http://example.com/b.jpg ``` 字段名应与页面字段一致。例如项目字段为 `image` 时,建议写为: ```json [ { "image": "http://example.com/a.jpg" } ] ``` CSV/TSV 导入方式选择: - 每行是一条任务时,选择 `List of tasks`。 - 整个文件是一条时间序列或整文件任务时,选择 `Time Series or Whole Text File`。 ## 14. 快速选择表 | 标注类型 | 推荐文件 | |---|---| | 图片分类、目标检测、分割、OCR、图片描述 | `txt/json/csv`,字段为 `image`、`img`、`ocr` 或 `captioning` | | 视频目标跟踪 | `json/csv`,字段为 `video` | | 音频识别、说话人分离 | `txt/json/csv`,字段为 `audio` | | 文本分类、摘要、NER、代码生成 | `txt/json/csv`,字段为 `text` | | 翻译 | `txt/json/csv`,字段为 `chinese` 或 `text` | | 问答 | `txt/json/csv`,字段为 `question` | | 阅读理解 | `json/csv`,字段为 `text` + `question` | | 答案排序 | `json`,字段为 `question` + `annotations` + `rank` | | 多轮对话 | `json`,字段为 `dialogue` 或 `humanMachineDialogue` | | 结构化数据 | `csv/tsv`,第一行是业务字段名 | | 时间序列 | `csv/tsv`,选择时间序列导入方式 | | HTML/XML 标注 | `html/htm/xml`,或包含 `html` 字段的 `json` | --- ### 标注平台 - 内置 LLM 自动标注后端接入 - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/08-%E6%95%B0%E6%8D%AE%E6%A0%87%E6%B3%A8/%E6%A0%87%E6%B3%A8%E5%B9%B3%E5%8F%B0/03-%E5%86%85%E7%BD%AELLM%E8%87%AA%E5%8A%A8%E6%A0%87%E6%B3%A8%E5%90%8E%E7%AB%AF - 分类: 平台使用 / 数据标注 - 适用场景: 想用平台自带的大模型给 Label Studio 标注任务做自动预标注(文本分类/摘要/翻译/NER/问答/意图等)、需要在标注项目里配置内置 ML 后端时读这篇 - 关键词: 自动标注 / 自动化标注 / Label Studio / labelstudio / ML Backend / 机器学习后端 / LLM标注 / 大模型标注 / predict / 预测接口 / 文本分类 / 摘要 / 翻译 / NER / 命名实体 / 问答 / faq / 答案排序 / rank / 意图识别 / intent / 对话 / chat / proxy/labelstudio / CHATGPT_CHAT_URL / 自动预标注 - 最后更新: 2026-06-30 # 标注平台 - 内置 LLM 自动标注后端 除了对接外部模型服务做自动标注外,平台**内置了一套由平台大模型驱动的自动标注 ML 后端**, 直接对接 Label Studio 的「Machine Learning Backend」机制,对标注任务做自动预标注,无需自己额外部署模型服务。 > 后端实现:`myapp/views/view_labelstudio.py`,`route_base = /proxy/labelstudio`。 > 底层调用平台大模型(由配置项 `CHATGPT_CHAT_URL` / `CHATGPT_ARGS` 指向的 OpenAI 兼容大模型)完成各类 NLP 标注。 > **具体字段映射、提示词与返回结构以源码为准。** ## 支持的标注类型(model_type) 内置后端按 `model_type` 区分能力,覆盖常见 NLP 标注: | model_type | 用途 | |---|---| | `nlp_classification` | 文本分类 | | `summary` | 文本摘要 | | `translaton` | 翻译(注意:代码中拼写为 `translaton`) | | `ner` | 命名实体识别 | | `faq` | 问答 | | `rank` | 答案排序 | | `intent` | 意图识别 | | `chat` | 对话 | ## 固定接口 后端实现了 Label Studio ML Backend 要求的一组固定接口,路径形如 `/proxy/labelstudio///<动作>`: | 接口 | 方法 | 作用 | |---|---|---| | `///health` | GET/POST | 健康检查 | | `///setup` | GET/POST | 初始化,接收 `access_token` / `hostname` / `project` | | `///predict` | GET/POST | **预测(自动标注核心)**,返回 Label Studio 标准 `result` 结构 | | `///train` | GET/POST | 训练(占位,返回空) | | `///webhook` | GET/POST | 事件回调(占位) | | `///delete` | GET/POST | 删除(占位) | 其中 `` 为标注任务对应的数据字段名,`` 为上表中的标注类型。 ## 接入步骤 1. 确保平台已配置可用的大模型:配置项 `CHATGPT_CHAT_URL`(OpenAI 兼容地址)与 `CHATGPT_ARGS` (模型/参数),见配置文件。 2. 在 Label Studio 标注项目的「Settings → Machine Learning → Add Model」中,把 **Backend URL** 填为 平台内置后端地址:`<平台域名>/proxy/labelstudio//` (例如文本分类:`.../proxy/labelstudio/text/nlp_classification`)。 3. 保存后 Label Studio 会调用 `setup` 完成握手;标注时调用 `predict` 获取自动预标注结果。 4. 标注人员在自动预标注基础上做人工校正,提升标注效率。 > 不同 `model_type` 对标注模板(Labeling Config)的字段/控件有相应要求(如分类需 `Choices`、NER 需 `Labels`)。 > 具体每种类型的输入字段与返回 `result` 格式以 `myapp/views/view_labelstudio.py` 中对应分支为准。 --- ### 标注平台总览 - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/08-%E6%95%B0%E6%8D%AE%E6%A0%87%E6%B3%A8/%E6%A0%87%E6%B3%A8%E5%B9%B3%E5%8F%B0/README - 分类: 平台使用 / 数据标注 - 适用场景: 了解 CubeStudio 标注平台(基于 Label Studio)能做什么、从哪进入、如何选子文档时读这篇 - 关键词: 标注平台 / Label Studio / labelstudio / 数据标注 / annotation / labeling / 自动化标注 / 预标注 / 图像标注 / 文本标注 / 语音标注 / 视频标注 / 时间序列 / 数据导入格式 - 最后更新: 2026-07-04 # 标注平台总览 CubeStudio 的标注平台基于 Label Studio,覆盖图像、文本、音频、视频、结构化数据、时间序列等多类型数据标注场景。平台围绕「创建项目、导入数据、配置标注模板、人工标注、自动化标注、数据同步、结果导出、成员协作」组织工作流。 入口:点击「数据资产」->「标注平台」进入。 ![标注平台入口](https://foruda.gitee.com/images/1698386967112077094/73b43e55_1019082.png) > 实现说明(核对自代码):平台通过 `myapp/views/view_labelstudio.py`(路由前缀 `/proxy/labelstudio`)与 Label Studio 集成;标注项目元数据存放在独立的 PostgreSQL 库(配置项 `LABEL_STUDIO_DAT`,默认 `postgresql+psycopg2://...@postgresql.kubeflow:5432/labelstudio`,`myapp/config.py:1119`),其中 `project.workspace` 字段保存的是 CubeStudio 项目组 ID,用于按项目组做权限隔离(`view_labelstudio.py:646-692`)。 ## 文档目录 | 子文档 | 内容 | |---|---| | [01-功能与操作流程](01-功能与操作流程.md) | 项目列表、创建项目、数据管理、项目内导入、人工标注、标注模板设置、自动化标注与模型配置、预测结果管理、云存储同步、导出、通用设置、网络钩子、常见问题 | | [02-数据导入格式说明](02-数据导入格式说明.md) | 各标注类型应准备的文件格式与字段:支持格式、按类型选文件、CSV/TSV 导入方式、图片/音视频/文本/问答阅读理解翻译/答案排序对话/结构化/时间序列/HTML-XML 富文本、预标注、检查项、快速选择表 | ## 关键概念速览 - 项目(Project):一组同类型标注任务的集合,归属某个工作空间(对应 CubeStudio 项目组)。 - 标注模板(Label Config):决定标注界面、可用工具与数据字段绑定。 - 任务(Task):一条待标注数据,字段名需与模板配置一致。 - 自动化标注:通过 ML 后端为未标注任务生成预测,作为预标注供人工审核。平台内置基于大模型的 NLP 自动标注后端(文本分类、摘要、翻译、NER、问答、答案排序、意图识别、对话),也可接入外部模型服务。详见 01 文档「自动化标注与模型配置」。 - 云存储(Source / Target Storage):待标注数据来源与标注结果回写位置,已与 CubeStudio 分布式存储(`/mnt/$username`)打通。 --- ### 私有知识库使用说明 - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/09-%E6%95%B0%E6%8D%AE%E6%99%BA%E8%83%BD%E4%B8%8E%E5%B8%82%E5%9C%BA/%E7%A7%81%E6%9C%89%E7%9F%A5%E8%AF%86%E5%BA%93 - 分类: 平台使用 / 数据智能与市场 - 适用场景: 想配置私有知识库场景(先验知识/提示词/多轮对话/召回调试/接口类型/微信钉钉/文生图)时读这篇 - 关键词: 私有知识库 / knowledge base / 知识库 / 场景配置 / 提示词模板 / prompt / 多轮对话 / 召回 / recall / recall_url / upload_url / RAG / 接口类型 / service_type / openai / aihub / chatgpt3.5 / AIGC / 文生图 / history / query / 微信 / 钉钉 / 智能聊天 / 大模型 / LLM - 最后更新: 2026-07-04 # 私有知识库使用说明 ## 场景配置 知识库可以进行配置,点击 CubeStudio 右上角的 “AI” 图标,再进入私有知识库,即可配置知识库的场景。基础的大模型,配上自己的先验知识文件,或者不同的提示词模板,可以配置成不同的场景。 ### 提示词模板中提供先验知识 比如下图中,我们就是将规模较大的先验知识库配置成 `upload_url`,再把召回的相关性最大的小知识库配置成 `recall_url`,就可以把相关性最大的知识库放到提示词模板中,提高大模型回答问题的准确性。 ![输入图片说明](https://foruda.gitee.com/images/1698658589779219545/36f0df19_1019082.png "屏幕截图") ### 多轮对话配置 再比如下图中,我们可以通过在原生大模型中修改提示词模板,传入之前对话的 `history` 和 `query` 参数,完成多轮对话提示。由于大模型的使用存在提示词长度的限制,这里我们也可以限制上下文的长度。 ![输入图片说明](https://foruda.gitee.com/images/1698658084551056263/a5b8d758_1019082.png "屏幕截图") ### 接口类型配置 还需要配置「服务类型」(`service_type`),可选 `openai` 与 `aihub`,默认 `openai`;接口并不一定是 OpenAI,只要符合 HTTP 请求/响应格式即可(见 `myapp/views/view_chat.py:339-344`、`341`)。其中 `openai` 对应大模型对话接口,`aihub` 用于调用 AIHub 类型接口(文生图 AIGC 等通过该类型调用)。 在构建知识库的过程中,会先配置一个大的先验知识库,然后通过匹配用户的 query,召回一批最为相关的先验知识,再把召回的先验知识放到提示词中,和用户的 query 一起提给大模型,得到答案。如果答案离预期差太远,想要调试召回效果,可以通过知识库配置里的召回地址(`recall_url`,见 `view_chat.py:217`)来实现。 ![输入图片说明](https://foruda.gitee.com/images/1698658301279909997/48b82f4f_1019082.png "屏幕截图") ### 微信、钉钉智能聊天 私有知识库模块已经和微信、钉钉打通,如果想要在微信或钉钉中实现智能聊天,可以配置用户自身微信或钉钉的后台 AppID、秘钥、Token 等。 ![输入图片说明](https://foruda.gitee.com/images/1698658943913911685/4a630214_1019082.png "屏幕截图") ### AIGC(文生图) 首先需要在 AIHUB 中部署文生图模型(参见 [AIHub模型市场.md](AIHub模型市场.md))。 ![在这里插入图片描述](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/aigc1.jpg) 在某个场景中配置 AIGC 服务接口。 ![在这里插入图片描述](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/aigc2.jpg) 然后就可以在聊天中进行文生图应用了。 ![在这里插入图片描述](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/aigc3.jpg) ## 场景对话 通过以上的几种配置,平台已经实现了以下几种智能聊天的场景。图示给出了使用 python 聊天窗的效果。 ![输入图片说明](https://foruda.gitee.com/images/1698659258881592242/64601c8c_1019082.png "屏幕截图") 在聊天窗中直接新建会话场景,上传知识库文件,可以取得和后台配置知识库文件一样的效果。 ![输入图片说明](https://foruda.gitee.com/images/1698659313831510389/55d8454e_1019082.png "屏幕截图") --- ### AIHUB 模型市场使用指南 - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/09-%E6%95%B0%E6%8D%AE%E6%99%BA%E8%83%BD%E4%B8%8E%E5%B8%82%E5%9C%BA/AIHub%E6%A8%A1%E5%9E%8B%E5%B8%82%E5%9C%BA - 分类: 平台使用 / 数据智能与市场 - 适用场景: 想了解如何在平台 AIHUB 模型市场中浏览/部署开源模型、调用推理接口(同步/异步)、做自动标注、微调或二次开发时读这篇 - 关键词: AIHUB / aihub / 模型市场 / model market / 开源模型 / 一键部署 / 在线推理 / 异步推理 / async inference / Celery / LabelStudio / 自动化标注 / 模型微调 / fine-tune / 模型应用 / Web应用 - 最后更新: 2026-07-04 # AIHUB 模型市场使用指南 ## 1. 概述 **AIHUB** 是 CubeStudio 平台提供的**开源模型仓库**,集成了大量可商用的开源 AI 模型,覆盖以下领域: - **计算机视觉**:图像分类、目标检测、图像生成、人脸识别等 - **自然语言处理**:文本分类、情感分析、机器翻译、对话系统等 - **语音处理**:语音识别、语音合成、声纹识别等 - **多模态模型**:图文理解、图文生成、视频分析等 AIHUB 旨在为用户提供一站式模型服务,支持模型的**快速部署、在线推理、自动化标注、微调训练和二次开发**,大幅降低 AI 模型的应用门槛。 ![](https://foruda.gitee.com/images/1698291930477634616/984df1de_1019082.png) > 注意:文中“400+ 可商用开源模型”为总览性数字,实际可用模型数量随平台版本与上架情况变化,请以平台模型市场页面展示为准。 ## 2. 快速入门 ### 2.1 前提条件 - 已部署 CubeStudio 平台并拥有有效账户 - 具备相应项目空间的访问权限 - 确保集群有足够的计算资源(CPU/GPU、内存) ### 2.2 部署第一个模型 1. **进入模型市场**:在 CubeStudio 导航栏中选择“AIHUB” 2. **浏览模型**:通过分类、搜索或标签筛选找到目标模型 3. **一键部署**:点击模型卡片上的“部署 Web”按钮 4. **等待启动**:系统将自动创建推理服务 Pod,状态变为 **Running** 即表示部署成功 5. **体验效果**:点击模型图片进入 Web 界面 ## 3. 模型部署 ### 3.1 部署流程 1. **选择模型**:在模型市场中找到适合的模型 ![](https://foruda.gitee.com/images/1698292158139263163/6d4267d0_1019082.png) 2. **启动部署**:点击“部署 Web”,系统将自动跳转到 Pod 部署页面 ![](https://foruda.gitee.com/images/1698296897390276231/57c76f04_1019082.png) 3. **监控状态**:等待 Pod 状态变为 **Running**(通常包括镜像拉取、健康检查等步骤,约需 1-3 分钟) 4. **访问应用**:部署成功后,可通过 Web 界面体验模型效果 ![](https://foruda.gitee.com/images/1698297206985970691/6378ae80_1019082.png) ### 3.2 资源管理 - **释放资源**:对于不再需要的模型,点击“卸载 Web”即可释放相关资源 - **资源监控**:若部署失败,请检查集群资源是否充足,可释放其他闲置应用后重试 ## 4. 模型推理 ### 4.1 推理接口 模型部署成功后,系统会自动提供以下接口: - **HTTP API 接口**:用于程序化调用模型推理服务 - **自动化标注接口**:与 LabelStudio 等标注平台集成,支持自动标注(部分模型) ![](https://foruda.gitee.com/images/1698297663742803815/1219fd2e_1019082.png) ### 4.2 使用方式 #### 4.2.1 Web 界面推理 - 直接通过浏览器访问部署后的 Web 界面,上传数据并查看推理结果 - 支持实时交互,适合演示和快速验证 #### 4.2.2 同步 API 调用 每个 AIHUB 应用的同步推理接口路径形如 `/aihub//api/model//version//`,使用 POST 方法,请求体为该模型的推理参数(JSON),字段名与模型在 Web 界面中暴露的输入项一致(例如图像类模型常用 `image`,文本类常用 `text`)。 ```bash # 示例:调用同步推理接口(参数字段依模型而定) curl -X POST \ 'http:///aihub//api/model//version//' \ -H 'Content-Type: application/json' \ -d '{"image": "https://your-host/your_image.jpg"}' ``` > 说明:同步推理端点路径由应用服务自动注册,见 `aihub/src/cubestudio/aihub/web/server.py:628`(`inference_url`)与 `aihub/src/cubestudio/aihub/web/celery_app.py:63`。早期文档中出现的 `/predict` 仅为示意,并非实际路径。 #### 4.2.3 异步调用 异步推理适用于**大批量数据处理、非实时决策**等无需立即获取结果的场景。系统通过 Celery + Redis 任务队列有序调度推理任务,避免高并发时服务卡顿。 > 前提:异步接口仅在应用容器配置了有效的 `REDIS_URL` 环境变量时才启用(非本地默认值)。启用后服务会自动拉起一个 Celery Worker 消费按 `APPNAME` 命名的队列。见 `aihub/src/cubestudio/aihub/web/server.py:449`。 统一接口地址:`/aihub//api/async/`,通过 HTTP 方法区分操作: | 方法 | 用途 | 参数 | |------|------|------| | POST | 提交推理任务 | Body:推理参数或 `{"tasks": [...]}` | | GET | 查询任务状态 | Query:`?task_ids=id1,id2` | | DELETE | 取消任务 | Body:`{"task_ids": ["id1","id2"]}` | **提交任务(POST)** 单条提交:直接传推理参数,和同步接口入参一致。批量提交:用 `tasks` 数组包裹多组参数。可选传 `callback_url`,推理完成后系统会主动 POST 通知。 ```bash # 单条提交 curl -X POST \ http:///aihub//api/async/ \ -H 'Content-Type: application/json' \ -d '{"text": "your_data_here"}' # 批量提交(带回调) curl -X POST \ http:///aihub//api/async/ \ -H 'Content-Type: application/json' \ -d '{ "tasks": [ {"text": "data_1"}, {"text": "data_2"} ], "callback_url": "http://your-server/callback" }' ``` 返回示例: ```json {"status": 0, "task_ids": ["abc123", "def456"], "message": "已提交 2 个异步推理任务"} ``` **查询状态(GET)** 通过 `task_ids` 查询参数(逗号分隔)轮询任务进度,状态值包括 `PENDING`(排队中)、`PROCESSING`(推理中)、`SUCCESS`(完成)、`FAILURE`(失败)。其中 `PROCESSING` 为任务开始执行时主动设置的自定义状态(见 `aihub/src/cubestudio/aihub/web/celery_app.py:60`)。 ```bash curl "http:///aihub//api/async/?task_ids=abc123,def456" ``` 返回示例: ```json { "status": 0, "data": [ {"task_id": "abc123", "state": "SUCCESS", "result": {"status": 0, "result": [{"text": "推理结果"}]}}, {"task_id": "def456", "state": "PROCESSING"} ] } ``` **取消任务(DELETE)** 仅非终态(即 `SUCCESS` / `FAILURE` 以外)的任务可取消;已终态的任务会返回“无法取消”。 ```bash curl -X DELETE \ http:///aihub//api/async/ \ -H 'Content-Type: application/json' \ -d '{"task_ids": ["abc123"]}' ``` **回调通知** 提交任务时若指定了 `callback_url`,推理完成或失败后系统会向该地址 POST 通知(成功带 `result`,失败带 `error`): ```json {"task_id": "abc123", "state": "SUCCESS", "result": {"status": 0, "result": [{"text": "推理结果"}]}} ``` #### 4.2.4 自动化标注 - 配置 LabelStudio 等标注工具,将 AIHUB 模型作为预测后端 - 支持批量数据自动预标注,提升标注效率 ## 5. 模型微调 ### 5.1 微调流程 对于预训练模型无法直接满足需求的场景,部分模型支持**一键微调**功能: 1. **选择模型**:在模型市场点击目标模型的“训练”按钮 ![](https://foruda.gitee.com/images/1698297815019707648/a7cc1e27_1019082.png) 2. **进入微调界面**:系统自动跳转到模型训练 Pipeline 配置页面 3. **配置数据**:在 Task 节点处配置训练数据和评估数据 - 支持从本地、对象存储、数据库等多种数据源导入 - 提供示例数据集供快速体验 4. **启动训练**:点击“运行 Pipeline”,系统自动创建训练任务 ![](https://foruda.gitee.com/images/1698297952331075810/870cc915_1019082.png) 5. **监控进度**:通过 Pipeline 可视化界面实时监控训练状态和指标 > 注意:支持一键微调的模型清单随平台版本变化,请以模型市场中各模型是否提供“训练”按钮为准。 ### 5.2 注意事项 - **数据格式**:确保训练数据符合模型要求的格式 - **资源需求**:微调通常需要更多计算资源(尤其是 GPU) - **超参数调整**:可根据需求调整学习率、批量大小等超参数 - **模型保存**:微调后的模型会自动保存,可用于后续部署 ## 6. 模型开发 ### 6.1 开发流程 当 AIHUB 应用无法满足你的需求,可进行应用的**二次开发**: 1. **进入开发界面**:点击模型的“开发”按钮 ![](https://foruda.gitee.com/images/1698298487941626206/ae4dd9de_1019082.png) 2. **获取代码**:系统提供完整的模型应用代码,包括 Dockerfile、启动脚本等 ![](https://foruda.gitee.com/images/1698298529793335310/f5da7089_1019082.png) 3. **修改代码**:基于业务需求修改模型逻辑、添加新功能,在 notebook 中运行 4. 若你想把修正后的代码更新到平台的 AIHUB 应用市场,需要参考下面的开发文档和视频教程 ### 6.2 开发指南 - **开发文档**:参见「06-二次开发」段的 AIHUB 应用开发指南(AIHUB 算法应用开发) - **视频教程**:[AIHUB 应用开发视频教程](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/video/aihub-dev.mp4) ## 7. 故障排查 ### 7.1 日志查看 - **Pod 日志**:通过 Kubernetes Dashboard 或 `kubectl logs` 查看 - **应用日志**:在容器内的 `/log.txt` 查看应用(Gradio)相关日志 --- ### 计量计费与资源账单 - 链接: https://www.cubestudio.vip/docs/03-%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8/10-%E8%AE%A1%E9%87%8F%E8%AE%A1%E8%B4%B9/%E8%AE%A1%E9%87%8F%E8%AE%A1%E8%B4%B9 - 分类: 平台使用 / 计量计费 - 适用场景: 想了解平台如何记录各用户/各场景下 Pod 的资源占用并计费、如何自定义计价函数时读这篇 - 关键词: 计量计费 / 计费 / 账单 / billing / metering / 资源占用 / pod / watch_pod / PRICE_FUN / 价格 / price / 成本 / 自定义计价 / kubeflow-watch / supervisord - 最后更新: 2026-06-30 # 计量计费与资源账单 ## 简介 计量计费用于完整记录平台所有用户在任何时间、任何场景下使用的 Pod 所占用的资源信息,并据此核算成本。 ## 实现代码 - 监听采集进程:`myapp/tools/watch_pod.py`。该进程运行在 `infra` 命名空间下的 `kubeflow-watch` Deployment(Pod)中,通过 **supervisord** 启动。 - 容器启动命令为 `supervisord -c /home/myapp/myapp/tools/supervisord.conf`(见 `install/kubernetes/cube/base/deploy-watch.yaml:55`)。 - `supervisord.conf` 中以 `[program:watch-pod] command=python myapp/tools/watch_pod.py` 拉起该进程(见 `myapp/tools/supervisord.conf:35`)。 - 历史 Pod 信息通过 `myapp/views/view_pod.py` 实现。 - Pod 特殊字段通过 `myapp/models/model_pod.py` 设置(原文笔误 `myall`,正确为 `myapp`)。 ## 数据库存储 保存在 `kubeflow` 数据库的 `pod` 表中(表名见 `myapp/models/model_pod.py:23`,`__tablename__ = 'pod'`)。 ## 自定义价格信息 在 `myapp/models/model_pod.py` 中,`Pod.price` 属性负责计算单个 Pod 的总价格:先从配置文件读取 `PRICE_FUN` 函数得到**每小时单价**,再根据起止时间计算运行时长,折算出该任务的总价格。若配置中没有 `PRICE_FUN`,或计算异常,则价格为 0。 ```python # 获取总价(myapp/models/model_pod.py:54) @property def price(self): price_fun = conf.get('PRICE_FUN', None) if price_fun: try: price = price_fun(self) # 获取每个小时的价格 end_time = datetime.datetime.strptime(self.end_time, '%Y-%m-%d %H:%M:%S') if self.end_time else datetime.datetime.now() start_time = datetime.datetime.strptime(self.start_time, '%Y-%m-%d %H:%M:%S') if self.start_time else datetime.datetime.now() duration = (end_time - start_time).total_seconds() price = round(duration * price / 3600, 2) # 单价 × 时长(秒)/3600 = 总价 return price except Exception as e: print(e) return 0 ``` `PRICE_FUN` 在配置文件 `config.py` 中定义,用于返回 Pod 资源的**每小时单价**。需要自定义价格时,可在配置文件中按集群实际资源单价改写该函数。 > 说明:原文称“默认函数不存在,所以价格为 0”。当前代码中 `config.py` 已内置了一个非零的默认 `PRICE_FUN`(见 `myapp/config.py:947` 与 `install/docker/config.py:947`),按 CPU / 内存 / GPU 的资源量计价。已据此更正。 ```python # 自定义任务计价函数(myapp/config.py:947,返回每小时价格) import pysnooper, datetime, math # @pysnooper.snoop(watch_explode=('pod')) def PRICE_FUN(pod): resource = json.loads(pod.resource) # 每核 cpu 0.075 元/h 每 G 内存 0.035 元/h gpu v100 16 元/h T4 9 元/h price = 16 * float(resource.get('gpu', 0)) + 0.075 * float(resource.get('cpu', 0)) + 0.035 * float(resource.get('memory', 0)) return price # 返回每个小时的价格 ``` 传入 `PRICE_FUN` 的 `pod` 对象包含如下字段(可据此自定义计价逻辑),示例(通过 pysnooper 打印): ```text pod.end_time = '2024-03-03 19:27:39' pod.host = '192.168.3.7' pod.id = 1 pod.name = 'admin-098b' pod.namespace = 'jupyter' pod.node_selector = '{"cpu": "true", "notebook": "true", "org": "public"}' pod.org = 'public' pod.pod_type = 'notebook' pod.project = public pod.project_id = 1 pod.resource = '{"memory": 0, "cpu": 0.0}' # 计价主要依据此字段(含 cpu/memory/gpu) pod.start_time = '2024-02-29 20:48:44' pod.status = 'Failed' pod.user = admin pod.user_id = 1 ``` > 提示:计价单价属于运维侧策略配置,落在配置文件中,相关说明见「04-运维管理」的[配置文件管理](../../04-运维管理/配置文件管理.md)。 --- ## 运维管理(18 篇) ### 运维注意事项与通用约定 - 链接: https://www.cubestudio.vip/docs/04-%E8%BF%90%E7%BB%B4%E7%AE%A1%E7%90%86/%E8%BF%90%E7%BB%B4%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9 - 分类: 04-运维管理 / 日常运维 - 适用场景: 日常运维平台、排查 pod 起不来 / 资源不足 / Prometheus OOM / 备份等问题时,先读这份通用提醒清单 - 关键词: 运维 / 注意事项 / ops / checklist / 换行符 / CRLF / arm64 / amd64 / 架构 / prometheus清理 / OOM / mysql备份 / 备份 / pod pending / 资源不足 / 机器混用 / 控制面 / 标签 / label / terminating / 审计日志 / audit / 镜像秘钥 / gpt token / 自动更新 / 初始化脚本 - 最后更新: 2026-07-04 # 运维注意事项与通用约定 本篇汇总日常运维 CubeStudio 平台时的通用约定与高频踩坑点,建议上线前后通读一遍,并据此建立基础运维 SOP。 ## 通用约定 1. **换行符问题**:代码或文件经过 Windows 打开后再传到 Linux,换行符编码会变(CRLF 与 LF)。shell 脚本之类尽量在 Mac / Linux 系统下打开编辑;Windows 下载的 zip 直接传到服务器上,不要在 Windows 里二次编辑。 2. **CPU 架构差异**:新版本 Mac 芯片是 arm64,服务器一般是 amd64。在新版 Mac 上构建镜像时要注意指定目标架构(例如 `docker buildx --platform linux/amd64`),与服务器架构保持一致,否则镜像在服务器上无法运行。 3. **回退到原始配置**:平台在摸索过程中难免操作混乱,或操作后未改回原始配置。如果过程中某些部分或某些任务模板不能使用了,可跟官方体验环境做对比,将配置改回原始配置,或重新部署一遍。 ## 注意事项清单 ### 1. 机器尽可能不要混用(控制面与计算分离) 平台控制部分和用户计算机器最好不要在同一批机器上。 CubeStudio 通过机器 label 管理任务调度,建议平台本身(控制组件)保留 1~2 台机器、不做任务计算;用户的 notebook、pipeline、service 使用单独的机器。因为用户任务资源使用比较多,和控制组件混部容易造成平台宕机。 > 机器标签(`cpu=true` / `gpu=true` / `train=true` / `notebook=true` / `service=true` / `org=xx` 等)与控制面标签(`mysql=true` / `redis=true` / `istio=true` / `kubeflow=true` / `kubeflow-dashboard=true` / `monitoring=true` / `logging=true`)的具体含义见 [管理员操作指南](管理员操作指南.md) 的「机器标签管理」一节;打标签的命令与资源组划分见 [02-部署安装 / 多机多集群多资源组](../02-部署安装/部署方式/多机多集群多资源组.md)。 ### 2. Prometheus 数据清理 Prometheus 如果存储时间过久,机器资源不足时被 OOM,会造成重启一直 OOM。可以删除分布式存储中 Prometheus 的历史数据,重启 `monitoring/prometheus-k8s-0`;或者干脆不将监控数据持久化。 > 监控组件部署、数据持久化与看板配置见 [监控部署与看板](监控部署与看板.md)。 ### 3. MySQL 数据备份 MySQL 数据做好备份,**至少每天备份一次**。 > 平台元数据库(MySQL / PostgreSQL / 达梦)的连接配置与备份相关见 [元数据库配置](元数据库配置.md) 与 [达梦数据库部署与迁移](达梦数据库部署与迁移.md)。 ### 4. 分布式存储重要数据备份 分布式存储系统建议连接公司内部 git,代码数据用 git 管理;每天备份个人目录下的"重要数据"目录。 ### 5. 机器资源不足可能的问题(pod pending 排查) 先在"服务"页面查看总体资源,再判断设置多少资源合适。如果出现 pod pending,几个可能的原因: - 机器标签是否正常添加;GPU 机器查看 GPU 插件是否正常运行,机器可分配资源里是否能看到 GPU 资源; - 分布式存储在机器上是否正常挂载; - 资源是否足够,目标机器现在剩余多少资源。 ### 6. 网络可能的问题 打开 Jupyter 界面时若 Jupyter 反应缓慢,界面会提示让清理空间——**不要清理**,这通常是网络问题导致的误报。 ### 7. 集群缩容(reset docker) `reset docker` 前一定要保障机器已经从 k8s 集群去掉,并且分布式存储已经 `umount`,再执行,否则会造成数据/挂载残留。 ### 8. k8s dashboard 管理权限问题 如果使用集群版本的 k8s dashboard 会方便很多,但有权限/安全风险;如果使用 user 受限版本,使用起来没那么方便。按安全要求权衡选择。 ### 9. aihub 大模型申请版本 aihub 大模型需自己下载,仅提供商业化使用方法,不提供商业化版本的大模型本体。 ### 10. k8s 开启审计日志 自建 k8s 建议开启审计日志(audit log),便于事件排查与安全审计。 ### 11. Terminating 的 pod 需要手动处理 如果有分布式存储未卸载或子进程未关闭,pod 会 Terminating 失败卡住,需要手动处理(强制删除 / 清理挂载)。 ### 12. 维表远程更新失败 维表不一定能正常更新到远程表,因为字段类型不一定能正常转换。不能自动更新的,需要人工更新。 ### 13. 镜像秘钥 / GPT token / GPT URL 换成自己的 镜像拉取秘钥(hubsecret)换成自己的;GPT token 换成自己的,GPT URL 换成自己的。 ### 14. 禁用系统自动更新 禁用掉操作系统的自动更新,避免内核 / Docker / 驱动版本被意外升级导致集群异常。 ### 15. 做好基础机器运维 例如:磁盘满了告警;分布式存储服务状态、数据库服务状态、利用率频繁过高的报警等。注意机器可能存在的定制配置(如机器 DNS、防火墙),以及机器重启后基础存储服务和数据库服务是否正常恢复。 ### 16. 代码二开后谨慎合并新功能 如果自己做了代码二次开发,要自己做好代码测试和升级测试,根据情况决定是否升级。代码是开放给客户的。 ### 17. 机器初始化脚本,避免机器重启后环境复原 为每台机器准备重启后的初始化脚本(如重新打标签、挂载、设置环境变量等),避免机器重启后环境被复原。 --- ### 管理员操作指南 - 链接: https://www.cubestudio.vip/docs/04-%E8%BF%90%E7%BB%B4%E7%AE%A1%E7%90%86/%E7%AE%A1%E7%90%86%E5%91%98%E6%93%8D%E4%BD%9C%E6%8C%87%E5%8D%97 - 分类: 04-运维管理 / 管理员配置 - 适用场景: 作为平台管理员,需要配置机器标签调度 / 权限 / LDAP 认证 / 项目组 / 任务模板 / 任务流后台行为时读这篇 - 关键词: 管理员 / admin / 运维配置 / 机器标签 / label / node selector / nodeSelector / 权限 / RBAC / 认证 / LDAP / ldap3 / 项目组 / org / 模板分类 / expand / CLUSTERS / 多集群 / 跨集群调度 / notebook清理 / 镜像调试 / hubsecret / 任务模板 / 环境变量 / k8s账号 / ServiceAccount / 任务流 / run-id / demo / 定时调度 - 最后更新: 2026-07-04 # 管理员操作指南 本篇从管理员视角说明平台的调度、权限、认证与各功能模块的后台行为配置。事实性内容已对照源码核实,关键差异处给出 `文件:行号` 依据。 ## 机器标签管理 机器通过 label 进行管理,所有的调度机器由平台控制,不由用户直接控制。 ### 开发训练服务机器管理 - 对于 CPU 的 train/notebook/service 会选择 `cpu=true` 的机器 - 对于 GPU 的 train/notebook/service 会选择 `gpu=true` 的机器 - 对于 vGPU 的 service 会选择 `vgpu=true` 的机器 - 训练任务会选择 `train=true` 的机器 - notebook 会选择 `notebook=true` 的机器 - 服务化会选择 `service=true` 的机器 - 不同项目的任务会选择对应 `org=xx` 的机器,默认为 `org=public` - 可以通过 `gpu-type=xx` 表示 GPU 的型号,比如 `gpu-type=V100` 或 `gpu-type=T4`。在配置 GPU 算力时也可以同步配置 GPU 型号,例如 `2(T4)` 表示 2 张 T4 卡。 > 默认的 node_selector:notebook 默认 `cpu=true;notebook=true`(见 `myapp/views/view_notebook.py:171`);pipeline 任务默认 `cpu=true;train=true;org=public`(见 `myapp/views/view_pipeline.py:161`)。 ### 控制器机器管理 平台部署脚本 `install/kubernetes/start.sh` 中给控制面机器统一打的标签如下(每个标签对应一类控制组件,按需拆分到不同机器): - `mysql=true`:部署 MySQL 服务的机器 - `redis=true`:部署 Redis 服务的机器 - `kubeflow-dashboard=true`:部署 CubeStudio 服务(kubeflow-dashboard)的机器 - `kubeflow=true`:部署 kubeflow 的机器 - `istio=true`:部署 istio 的机器 - `monitoring=true`:部署 prometheus 的机器 - `logging=true`:部署日志组件的机器 > ⚠️ 原文档此处有笔误,已按 `install/kubernetes/start.sh:25` 的实际标签纠正:应为 `istio=true`(非 isito)、`kubeflow-dashboard=true`(非 kubeflow-dashobard),`redis=true` 对应 Redis(原文误写成"部署 mysql 服务")。`start.sh` 实际还包含 `logging=true`。 > > 打标签命令示例(详见 [02-部署安装 / 多机多集群多资源组](../02-部署安装/部署方式/多机多集群多资源组.md)): > ```bash > kubectl label node $node train=true cpu=true notebook=true service=true org=public \ > istio=true kubeflow=true kubeflow-dashboard=true mysql=true redis=true monitoring=true logging=true --overwrite > ``` ## 权限管理 - OA 登录开发:登录方式可通过 `project.py` 文件定义的方式自行修改,或自行添加管理员专用接口。 - RBAC 的权限管理方式:所有菜单 / 模块的增删改查以及所有后端接口都有权限控制,可以在 Security 中自由控制。 - 用户登录后会自动创建并绑定与用户名同名的角色,同时绑定 gamma 角色,加入 public 项目组。 ## 认证方式 CubeStudio 支持多种认证方式,默认使用 MySQL 的账号密码验证。用户也可以根据实际环境对接 LDAP。 **当前 LDAP 兜底机制**:用户走 `/login/db/` 登录时,先用本地 `ab_user` 表的密码校验;本地密码不匹配且配置了 `AUTH_LDAP_SERVER` 时,会尝试 LDAP bind 兜底(见 `myapp/views/view_login.py:226-231`)。bind 用户名拼接为 `username@AUTH_LDAP_BASE_DN`(见 `view_login.py:133`)。若用户在本地不存在且 LDAP bind 成功,会自动注册到本地。 `config.py` 中的相关配置项(见 `myapp/config.py:154-158`): ```python AUTH_LDAP_SERVER = "" # LDAP 服务地址,如 ldap://xx.xx.xx.xx;为空则不启用 LDAP 兜底 AUTH_LDAP_PORT = "xx" # LDAP 端口 AUTH_LDAP_USE_TLS = False # 是否使用 TLS AUTH_LDAP_BASE_DN = 'cpcnet.local' # 基准 DN,会与用户名拼成 username@BASE_DN 做 bind ``` 依赖 `ldap3` 库(`from ldap3 import ALL, Connection, Server`),后端镜像需安装该包,更好的方式是在构建镜像时通过 Dockerfile 安装。 ## 项目组 -> 模板分类 项目组(模板分组)的 `expand` 字段: ```json { "index": 2 } ``` `index` 控制该分组下面的 job 模板在 pipeline 编排界面左侧的显示顺序(见 `myapp/views/view_job_template.py:270`,分组 index 会乘以 1000 参与排序)。 ## 项目组 -> 项目分组 ### 跨 k8s 集群调度的支持 需要在 `config.py` 中配置 `CLUSTERS`,并通过 `ENVIRONMENT` 环境变量指定控制台所在的集群,其他集群为训练集群(见 `myapp/config.py:1403`,`ENVIRONMENT` 见 `config.py:461`,默认 `DEV`)。多集群部署与资源组划分的完整步骤见 [02-部署安装 / 多机多集群多资源组](../02-部署安装/部署方式/多机多集群多资源组.md)。 `CLUSTERS` 结构示例(每个 key 与 project expand 里的 `cluster` 名称一致): ```python CLUSTERS = { "dev": { "NAME": "dev", "KUBECONFIG": "/home/myapp/kubeconfig/dev-kubeconfig", "SERVICE_DOMAIN": "service.svc.cluster.local", "HOST": "192.168.3.22", }, } ``` 在项目组 / 项目分组中,可通过项目组的 `expand` 字段控制其调度集群: ```json { "cluster": "dev" } ``` ### 资源划分项目组 机器通过 label 进行管理,所有调度机器由平台控制。在标注好哪些机器属于哪些项目后,可通过项目组的 `expand` 字段控制调度机器(见 `myapp/models/model_team.py:63-70`,`org` 会被拼接成 `org=xx` 加入 node_selector): ```json { "org": "public" } ``` 控制该项目自动挂载什么 pvc,可通过项目组的 `expand` 字段配置: ```json { "volume_mount": "kubeflow-user-workspace(pvc):/mnt" } ``` ## 在线开发 -> notebook 定时任务中配置了 notebook 的定时清理和提醒用户续期,没有及时续期的 notebook 会被删除,容器消失后环境丢失。 > 实现:清理逻辑在 `myapp/tasks/schedules.py` 的 `delete_notebook` celery 任务(见 `schedules.py:185`)。过期时长由 `ENABLE_JUPYTER_EXPIRY` 控制,默认 `60*60*24*3`(3 天,见 `myapp/config.py:989`);每次续期有效期 3 天。续期接口 `/renew/`(见 `view_notebook.py:1002`)。 ## 在线开发 -> 镜像调试 在线调试镜像时,保存按钮会自动 commit/push 到仓库,当晚也会自动释放调试容器。 > 实现:调试容器的释放在 `myapp/tasks/schedules.py` 的 `delete_debug_docker` celery 任务(见 `schedules.py:220`)。 ## 训练 -> 仓库 仓库中的 k8s hubsecret 以及账号密码,在保存时会更新到所配置的所有集群的各个命名空间下。当用户拉起 pod 时,也会附带上用户配置的 k8s hubsecret 以及 `config.py` 中配置的公共 k8s hubsecret(拉取秘钥的合并见 `myapp/views/view_docker.py:283`、`view_docker.py:427`)。 **建议仓库拉取秘钥均在 `config.py` 中全局配置。** ## 训练 -> 任务模板 > 任务模板的字段定义见 `myapp/views/view_job_template.py`。模板挂载 / 环境变量 / k8s 账号等更详细的说明见 05-任务模板 段。 ### 版本 模板的 release 版本才能被用户看到(开发者能看到所有模板,见 `view_job_template.py:42`、`:101`)。 ### 工作目录 / 启动命令 如果配置,则会覆盖镜像的启动目录和启动命令。 ### 挂载目录 会在 task 创建时添加模板的挂载项,一般用户需要固定挂载的模板会配置该参数(比如 docker in docker 需要 `docker.sock`)。目前支持 hostpath / pvc / memory / configmap / storage 几种挂载方式: ```bash kubeflow-user-workspace(pvc):/mnt # pvc 挂载方式,会自动在 pvc 下挂载个人 username 子目录 /data/k8s/kubeflow/pipeline/workspace/xxxx(hostpath):/mnt # 挂载主机目录 4G(memory):/dev/shm # 内存挂载为磁盘 kubernetes-config(configmap):/root/.kube # 挂载 configmap 成文件夹 ``` ### 环境变量 会附加给每个使用该模板的 task。书写格式:每行一个环境变量 `env_key=env_value`(见 `view_job_template.py:131-134`)。 模板中特殊的环境变量(见 `myapp/views/view_pipeline.py:664-668`、`myapp/views/view_task.py:641-644`、`myapp/tools/watch_workflow.py:180`): ```bash NO_RESOURCE_CHECK=true # 使用该模板的 task 不会进行资源配置的自动校验(也不参与近 10 次资源动态调整) TASK_RESOURCE_CPU=4 # 忽略用户的资源配置,cpu 固定配置为 4 核 TASK_RESOURCE_MEMORY=4G # 忽略用户的资源配置,mem 固定配置为 4G TASK_RESOURCE_GPU=0 # 忽略用户的资源配置,gpu 固定配置为 0 卡 ``` > 补充:init 模板中还可见 `TASK_RESOURCE_RDMA=0`(见 `myapp/init/init-job-template.json`),用法同上,用于固定 RDMA 资源。 ### k8s 账号 为模板配置 k8s 账号(ServiceAccount),主要为那些需要操控 k8s 集群的模板设定,比如临时分布式训练集群的 launcher 端(见 `view_job_template.py:152`)。 ### 扩展(expand) ```json { "index": 7, "help_url": "http://xx.xx.xx.xx/xx" } ``` `index` 控制在 pipeline 编排界面同一个模板分组中每个模板的显示顺序;`help_url` 为 pipeline 编排界面每个模板的帮助文档地址(见 `view_job_template.py:160-163`,该 expand 还支持 `"HostNetwork": true` 启动主机端口监听)。 ## 训练 -> 任务流 > 任务流的使用细节见 03-平台使用 段(任务流)。以下为后台调度行为: - 先调试单独的 task,再调试 pipeline 的原则。 - task 包含 debug/run/log/clear 等功能,通过 run-id 串联对应的 pod 和 crd。 - pipeline 包含 run/log/运行实例/定时调度记录/pod 等功能,使用 run-id 串联所有的 task。 - 手动运行 pipeline 会先清空之前手动运行的 pipeline 实例(workflow)。 - 定时任务会定时清理运行结束的 pod,避免 pod 堆积过多(实现在 `myapp/tasks/schedules.py` 的 `delete_debug_docker`/`delete_workflow` 任务,见 `schedules.py:220`、`:133`)。 > ⚠️ 原文档此处写的是 `myapp/task/scheduler.py`,当前代码中并无此文件,清理逻辑在 `myapp/tasks/schedules.py`,已更正。 - 在 pipeline 正常运行 10 次以后,定时任务会取其中真实使用的资源最大值,再预留一定空间,动态修改用户配置的资源项,防止资源配置不合理而浪费算力(实现见 `myapp/tools/watch_workflow.py:176`,按近 10 次最大值 `ceil(max*1.4)+2` 计算,cpu 上限 150、内存上限 350)。 ## 训练 -> demo 任务流 首页会显示所有的 demo pipeline,即 pipeline 扩展字段 `expand`(dict)中包含(见 `myapp/views/view_pipeline.py:1524`,按 `parameter` 含 `"demo": "true"` 过滤): ```json { "demo": "true", "img": "https://xx.xx.xx.xx/xx.png" } ``` ## 训练 -> 定时调度记录 手动运行和定时运行同一个 pipeline,相互之间不干扰。 --- ### 平台配置文件管理(config.py / entrypoint.sh / project.py / kubeconfig) - 链接: https://www.cubestudio.vip/docs/04-%E8%BF%90%E7%BB%B4%E7%AE%A1%E7%90%86/%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E7%AE%A1%E7%90%86 - 分类: 04-运维管理 / 配置 - 适用场景: 需要知道平台配置文件放在哪、本地与线上分别在哪改、改完怎么生效(升级/重启)时读这篇 - 关键词: config.py / entrypoint.sh / project.py / kubeconfig / configmap / kubeflow-dashboard-config / kustomize / overlays / docker-compose / 配置文件 / 升级配置 / 挂载 / infra命名空间 / configMapGenerator - 最后更新: 2026-06-30 # 平台配置文件管理 平台运行依赖 4 个核心配置文件。它们在「本地 docker-compose」和「线上 kustomize/k8s」两种部署形态下存在于不同位置,但内容(尤其是 `config.py`)应保持一致。 | 文件 | 作用 | |---|---| | `config.py` | 平台主配置(数据库、Redis、Celery、鉴权方式、特性开关、集群信息、存储路径等) | | `entrypoint.sh` | 容器启动脚本(初始化软链、编译翻译、建库、`db upgrade`、创建 admin、按 `STAGE` 启动服务) | | `project.py` | 用户自定义模块(自定义登录中转 / SSO 跳转、推送等) | | `kubeconfig` | 平台要纳管的 k8s 集群的 kubeconfig 文件(多集群时多份) | > 说明:`config.py` 三处位置(本地、kustomize overlays、线上 configmap)内容相同,改一处后需同步到其余位置。 --- ## 一、本地开发(docker-compose) 启动方式:在 `install/docker/` 目录下执行 `docker-compose up`(详见 [02-部署安装 / docker-compose 本地部署](../02-部署安装/部署方式/单机部署-docker-compose/02-docker-compose本地部署.md))。 配置文件源在 `install/docker/` 下,由 `docker-compose.yml` 以挂载(volume)方式注入容器: | 宿主机源文件(`install/docker/`) | 容器内挂载路径 | |---|---| | `config.py` | `/home/myapp/myapp/config.py` | | `entrypoint.sh` | `/entrypoint.sh` | | `project.py` | `/home/myapp/myapp/project.py` | | `kubeconfig/`(目录) | `/home/myapp/kubeconfig` | 依据:`install/docker/docker-compose.yml:71-74`。 `install/docker/kubeconfig/` 下已带多份示例:`dev-kubeconfig`、`prod-kubeconfig`、`cloud-kubeconfig`、`npu-kubeconfig`。`config.py` 里通过 `CLUSTERS` 配置引用,例如 `"KUBECONFIG": '/home/myapp/kubeconfig/dev-kubeconfig'`(见 `install/docker/config.py` 的 `CLUSTERS` 段)。 本地改配置后,重启对应容器即可生效(挂载方式,无需重建镜像)。 --- ## 二、线上部署(kustomize overlays) 启动方式:在 `install/kubernetes/` 目录下执行 `kubectl apply -k cube/overlays`(或 `kustomize build cube/overlays | kubectl apply -f -`,详见 [02-部署安装](../02-部署安装/))。 ### 2.1 config.py / entrypoint.sh / project.py → configmap `kubeflow-dashboard-config` 源文件目录:`install/kubernetes/cube/overlays/config/`,包含 `config.py`、`entrypoint.sh`、`project.py`。 `install/kubernetes/cube/overlays/kustomization.yml` 用 `configMapGenerator` 把这三个文件打包成 `infra` 命名空间下的 configmap `kubeflow-dashboard-config`: ```yaml # install/kubernetes/cube/overlays/kustomization.yml namespace: infra configMapGenerator: - name: kubeflow-dashboard-config files: - config/config.py - config/entrypoint.sh - config/project.py ``` 后端 Pod 把该 configmap 挂载到容器(`install/kubernetes/cube/base/deploy-backend.yaml:103-111`,均用 `subPath` 单文件挂载): | configmap key | 容器内路径 | |---|---| | `config.py` | `/home/myapp/myapp/config.py` | | `entrypoint.sh` | `/entrypoint.sh` | | `project.py` | `/home/myapp/myapp/project.py` | > 注意:kustomize 的 `configMapGenerator` 默认会给 configmap 名字追加一段内容哈希后缀,集群里实际名字形如 `kubeflow-dashboard-config-xxxxxxx`,并会自动滚动更新引用它的 Deployment。`kustomization.yml` 注释里给出了不带哈希、手动创建的等价命令: > ```bash > kubectl delete configmap kubeflow-dashboard-config -n infra > kubectl create configmap kubeflow-dashboard-config --from-file=config -n infra > ``` ### 2.2 kubeconfig → 单独的 configmap `kubernetes-config` 线上 kubeconfig 不属于 `kubeflow-dashboard-config`,而是单独打成 configmap `kubernetes-config`。源目录为 `install/kubernetes/kubeconfig/`,部署脚本据此在多个命名空间创建该 configmap(`install/kubernetes/start.sh:146-153`): ```bash kubectl delete configmap kubernetes-config -n infra kubectl create configmap kubernetes-config --from-file=kubeconfig -n infra # 同样在 pipeline、automl 命名空间各创建一份 ``` 后端 / worker / watch Pod 都把 `kubernetes-config` 挂载到 `/home/myapp/kubeconfig`(`install/kubernetes/cube/base/deploy-backend.yaml:118-119` 等)。 > 注意:仓库中的 `install/kubernetes/kubeconfig/` 目录当前为空,`start.sh:10` 会用 `mkdir -p kubeconfig && echo "" > kubeconfig/dev-kubeconfig` 占位(已核对)。实际部署时需把目标集群真实的 kubeconfig 放进该目录后再创建 configmap,见 `install/kubernetes/start.sh:10,146-153`。 --- ## 三、配置升级(改完怎么生效) 线上有两种等价的更新方式: 1. 改源文件后重新部署 - 改 `install/kubernetes/cube/overlays/config/` 下的 `config.py` / `entrypoint.sh` / `project.py`; - 改 kubeconfig 则改 `install/kubernetes/kubeconfig/`; - 在 `install/kubernetes/` 下重新执行 `kubectl apply -k cube/overlays`(kubeconfig 用 `start.sh` 里的 `create configmap kubernetes-config` 命令重建)。 2. 直接改线上 configmap 后重启 Pod - 直接编辑 `infra` 命名空间下的 `kubeflow-dashboard-config*`(或 `kubernetes-config`)configmap; - 改完重启 `infra` 命名空间下 `kubeflow-dashboard*` 相关 Pod 使其重新读取。 本地(docker-compose)改完源文件后,重启对应容器即可。 --- ## 相关 - 数据库连接串(`MYSQL_SERVICE` / `POSTGRESQL_SERVICE` 等)属于 `config.py`/部署环境变量,详见 [元数据库配置.md](元数据库配置.md)。 - HTTPS 场景下 `config.py` 外网地址、前端 nginx scheme 改写等,见 [平台HTTPS配置.md](平台HTTPS配置.md)。 - `config.py` 各字段含义与速查,参见 [06-二次开发](../06-二次开发/) 与 [07-参考速查](../07-参考速查/)。 - 部署方式(docker-compose / kubernetes)详见 [02-部署安装](../02-部署安装/)。 > 配置项繁多,具体字段含义以源码 `install/docker/config.py` / `install/kubernetes/cube/overlays/config/config.py` 为准,本篇仅作位置与升级方式导航。 --- ### CubeStudio 端口使用情况 - 链接: https://www.cubestudio.vip/docs/04-%E8%BF%90%E7%BB%B4%E7%AE%A1%E7%90%86/%E7%AB%AF%E5%8F%A3%E4%BD%BF%E7%94%A8%E6%83%85%E5%86%B5 - 分类: 04-运维管理 / 端口与网络 - 适用场景: 需要知道平台各功能占用哪些端口、端口怎么算出来、或者环境只能放开一个端口时怎么代理 - 关键词: 端口 / port / 443 / 80 / 8080 / notebook ssh / 推理服务端口 / 内部服务端口 / NOTEBOOK_PORT / SERVICE_PORT / INFERENCE_PORT / 单端口代理 / 域名代理 / rancher 443 / nodePort / 泛域名 - 最后更新: 2026-07-04 # CubeStudio 端口使用情况 本篇说明 CubeStudio 各组件/功能占用的端口区间、端口计算公式,以及只能开放单端口/域名时的代理方案。 > 端口公式来源:`myapp/config.py:1105-1107`(`NOTEBOOK_PORT` / `SERVICE_PORT` / `INFERENCE_PORT`),动态端口在 `myapp/models/model_serving.py`、`myapp/models/model_notebook.py` 中按公式计算。 ## 端口一览表 | 端口区间 | 描述 | 作用 / 计算方式 | |---|---|---| | `443` | rancher server 管理端口 | 管理员通过 rancher server 管理集群和扩缩容。注意 rancher web 是 https 协议。 | | `80` | CubeStudio 平台端口 | CubeStudio 平台前后端入口端口。 | | `8080` | 内部服务/推理服务代理端口 | 部署的服务可以通过泛域名或端口访问;对于需要多端口的服务,使用 `80` 和 `8080` 作为代理。 | | `10000~20000` | notebook ssh 链接端口 | 公式 `10000+2*ID`(`ID` 为 notebook 实例 id)。可从本地通过该端口 ssh 远程连接对应 notebook,也可经一台代理机器跳转连接。 | | `20000~30000` | 推理服务开放端口 | 公式 `20000+2*ID`(`ID` 为推理服务 `InferenceService` 实例 id)。通过该端口访问自己创建的推理服务。 | | `30000~40000` | 内部服务(云原生服务)开放端口 | 公式 `30000+2*ID`(`ID` 为内部服务 `Service` 实例 id)。通过该端口访问自己创建的内部服务。 | > 说明(与代码核对): > - 原文档把 notebook 端口写作 `10000+2*notebook_id`、推理写作 `20000+2*service_id`,与代码一致。 > - 原文档把内部服务端口写作 `10000+2*inference_id`,**有误**:内部服务对应配置项 `SERVICE_PORT='30000+2*ID'`(`myapp/config.py:1106`,模型 `Service`,见 `myapp/models/model_serving.py:87`),即 `30000+2*ID`,已在上表中改正。 > - 这三个端口公式都可以在配置文件中改(`NOTEBOOK_PORT` / `SERVICE_PORT` / `INFERENCE_PORT`,`myapp/config.py:1105-1107`)。`config.py` 注释提示:notebook 端口“至少间隔 4”(web 一个、ssh 一个,大数据版本还要两个端口做 spark driver)。 > - 平台还有端口黑名单 `BLACK_PORT=[10250]`(`myapp/config.py:818`,`10250` 是 kubelet 端口),分配端口时会跳过黑名单端口。 ## 无法开放多端口时的代理方案 某些网络环境(云上安全组、内网防火墙)只允许放开有限端口。两类动态端口可以这样收敛: 1. **`10000~20000` 的 notebook ssh 服务**:可以用 ssh 隧道只开放一个端口。具体见 [在线 IDE](../03-平台使用/03-在线开发/在线IDE.md) 中“单端口代理 jupyter 内部 ssh server”部分。 2. **`20000~30000` 的推理服务和 `30000~40000` 的内部服务**:可以用域名进行代理。具体见 [模型服务](../03-平台使用/07-服务化与推理/模型服务.md) 与 [内部服务](../03-平台使用/07-服务化与推理/内部服务.md) 中的“域名访问”部分。 > 本端口表同时是 [07-参考速查](../07-参考速查/)(端口速查)的核心素材。 --- ### 平台元数据库配置(MySQL / PostgreSQL) - 链接: https://www.cubestudio.vip/docs/04-%E8%BF%90%E7%BB%B4%E7%AE%A1%E7%90%86/%E5%85%83%E6%95%B0%E6%8D%AE%E5%BA%93%E9%85%8D%E7%BD%AE - 分类: 04-运维管理 / 数据库 - 适用场景: 配置/切换平台元数据库连接串、初始化数据库表、Postgres 适配、定时备份时读这篇 - 关键词: 元数据库 / metadata db / MySQL / PostgreSQL / pg / MYSQL_SERVICE / POSTGRESQL_SERVICE / KINGBASE_SERVICE / SQLALCHEMY_DATABASE_URI / 连接串 / pymysql / psycopg2 / migrations / versions / versions-postgres / alembic / db upgrade / 数据库备份 / crontab / sa.Text - 最后更新: 2026-06-30 # 平台元数据库配置 平台用一个关系型数据库存储所有元数据(项目、任务流、模型、数据集、用户权限等)。元数据库类型由后端 Pod 的环境变量决定,默认数据库名为 `kubeflow`。 ## 连接串与选型优先级 后端在 `config.py` 中按以下优先级解析连接串到 `SQLALCHEMY_DATABASE_URI`(`install/docker/config.py:476-488`): ``` MYSQL_SERVICE → POSTGRESQL_SERVICE → KINGBASE_SERVICE → DM_SERVICE ``` 即:配了 `MYSQL_SERVICE` 就用 MySQL;否则看 `POSTGRESQL_SERVICE`,再否则 `KINGBASE_SERVICE`(人大金仓),最后 `DM_SERVICE`(达梦)。这些环境变量配置在 `infra` 命名空间下 `kubeflow-dashboard` 的 Deployment 上(线上由 `deploy-config` configmap 注入,见 [配置文件管理.md](配置文件管理.md))。 > 用 PostgreSQL(或人大金仓)时,不要再配置 `MYSQL_SERVICE`,否则会优先走 MySQL。 --- ## 一、MySQL 环境变量: ```bash MYSQL_SERVICE = mysql+pymysql://$user:$password@$host:$port/kubeflow?charset=utf8mb4 ``` 其中 `$user`/`$password`/`$host`/`$port` 为 MySQL 的用户名、密码、ip、端口。 > 线上 kustomize 默认值(`install/kubernetes/cube/overlays/kustomization.yml:20`): > `mysql+pymysql://root:admin@mysql-service.infra:3306/kubeflow?charset=utf8mb4` MySQL 的数据库表迁移文件在 `myapp/migrations/versions`(默认即 MySQL 版本;仓库另存了一份 `myapp/migrations/versions-mysql` 作为来源)。 --- ## 二、PostgreSQL 环境变量: ```bash POSTGRESQL_SERVICE = postgresql+psycopg2://$user:$password@$host:$port/kubeflow ``` 测试/内网连接串示例: ```bash postgresql+psycopg2://postgres:postgres@postgresql.kubeflow:5432/kubeflow ``` ### 迁移目录会自动切换(无需手动改) PostgreSQL 的迁移文件在 `myapp/migrations/versions-postgres`。**当检测到配置了 `POSTGRESQL_SERVICE`(或 `KINGBASE_SERVICE`)时,`config.py` 会自动**删除 `versions` 目录并把 `versions-postgres` 拷贝过去(`install/docker/config.py:480-482`): ```python shutil.rmtree('/home/myapp/myapp/migrations/versions', ignore_errors=True) shutil.copytree('/home/myapp/myapp/migrations/versions-postgres', '/home/myapp/myapp/migrations/versions') ``` > ⚠️ 与旧文档差异:早期文档要求「手动把 versions-postgres 改名为 versions、并自行备份原 MySQL 结构」。当前版本已由 `config.py` 在启动时自动完成该切换,**不需要手动改目录**。这是一次性覆盖 `versions` 目录的操作,源在 `versions-postgres`,无需也不应手动备份运行目录里的 `versions`。依据 `install/docker/config.py:478-482`。 ### Postgres 不支持 `sa.Text(length=65536)` PostgreSQL 无法识别 `sa.Text(length=65536)` 这类带长度的 Text,需改为 `sa.Text()`。也就是说,用作 Postgres 元数据库时,迁移/模型里不能出现 `sa.Text(length=65536)` 这种列类型。 ### 人大金仓 KingBase(PostgreSQL 兼容) 人大金仓(KingBase)兼容 PostgreSQL 协议,平台把它当作 PG 使用: - 连接串配 `KINGBASE_SERVICE`,**格式与 PG 相同**(驱动仍是 `postgresql+psycopg2`),端口默认 `54321`: ```bash KINGBASE_SERVICE = postgresql+psycopg2://$user:$password@$host:54321/kubeflow ``` - 选型优先级上 `KINGBASE_SERVICE` 在 `POSTGRESQL_SERVICE` 之后(见本文开头);配了它就和 PG 一样自动切到 `versions-postgres` 迁移目录、走 Alembic 建表,上面 PG 的 `sa.Text(length=...)` 限制同样适用。 - 平台对 KingBase 有一段**兼容补丁**:`myapp/__init__.py:8-17` 会在任何 SQLAlchemy 连接建立前执行, 按 `KingbaseES Vxx Rxx` 版本号做适配,因此 `KINGBASE_SERVICE` 必须在启动时就配好。 - schema 初始化与 PG 一致(`myapp/create_db.py`、`install/docker/README.md:230` 对 postgres/kingbase/达梦做了兼容)。 --- ## 三、数据库初始化(建表) 容器启动脚本 `entrypoint.sh` 负责初始化(`install/docker/entrypoint.sh:21-32`): ```bash export FLASK_APP=myapp:app python myapp/create_db.py # 建库 / db.create_all() 兜底 # 非达梦时执行 Alembic 迁移(MySQL/PostgreSQL 走这里) if [ -z "$DM_SERVICE" ]; then myapp db upgrade # 按 versions 目录把表结构同步到数据库 fi myapp fab create-admin ... # 创建 admin 用户/角色/权限 myapp init # 初始化默认角色、权限、自定义 menu ``` > 达梦(`DM_SERVICE`)不走 Alembic 迁移,靠 `create_db.py` 里的 `db.create_all()` 建表,并在 `config.py` 中清空 `versions` 目录(`install/docker/config.py:484-488`)。达梦的部署与迁移另见 [达梦数据库部署与迁移.md](达梦数据库部署与迁移.md)。 --- ## 四、数据库定时备份 通过 crontab 定时备份数据库数据目录(按月清理旧备份、按天打快照): ```bash # 添加到 crontab mkdir -p /data/back/ rm -rf /data/back/mysql-$(date +%Y%m)* cp -r /data/k8s/infra/mysql /data/back/mysql-$(date +%Y%m%d) ``` > 该示例针对 MySQL 数据目录 `/data/k8s/infra/mysql`(hostpath 部署)。PostgreSQL/达梦请按其数据目录与官方备份工具(如 `pg_dump`)调整。 --- ## 相关 - 连接串环境变量配在哪、如何升级:[配置文件管理.md](配置文件管理.md)。 - 达梦数据库:[达梦数据库部署与迁移.md](达梦数据库部署与迁移.md)。 - 数据库选型 / 连接串速查:[07-参考速查](../07-参考速查/)。 > 具体连接行为以源码 `install/docker/config.py` 与 `install/docker/entrypoint.sh` 为准。 --- ### 分布式存储目录结构(/data/k8s) - 链接: https://www.cubestudio.vip/docs/04-%E8%BF%90%E7%BB%B4%E7%AE%A1%E7%90%86/%E5%88%86%E5%B8%83%E5%BC%8F%E5%AD%98%E5%82%A8%E7%9B%AE%E5%BD%95 - 分类: 04-运维管理 / 存储 - 适用场景: 想知道平台在主机/共享存储 /data/k8s 下各子目录分别存什么、排查空间占用或迁移数据时 - 关键词: 分布式存储 / 存储目录 / /data/k8s / hostPath / NFS / 共享存储 / pipeline / workspace / archives / minio / dataset / labelstudio / postgresql / grafana / prometheus / 目录层级 - 最后更新: 2026-07-04 # 分布式存储目录结构(/data/k8s) 平台所有需要持久化的数据都落在主机(或共享/分布式存储挂载点)的 `/data/k8s` 目录下,按命名空间组织。共享存储的准备方式(NFS / hostPath / 其他分布式存储)见「02-部署安装」段的存储准备文档。 ## 目录层级 ``` 主机 /data/k8s 目录下使用层级 ├── infra # infra 命名空间下面 │ └── mysql # mysql 数据库的存储 ├── kubeflow │ ├── dataset # 用户通过 sdk 上传的数据集的数据存储 │ ├── global │ │ ├── cube-studio # CubeStudio 源码的存储 │ │ ├── sqllab # sqllab 查询结果下载地址 │ │ └── datatse # 数据集的备份地址 │ ├── labelstudio # 标注平台的数据存储 │ ├── minio # pipeline 中任务日志和输出指标的存储 │ ├── pipeline # 用户空间存储 │ │ ├── archives # 每个人的归档目录 │ │ │ └── admin │ │ └── workspace # 每个人的工作目录 │ │ └── admin │ └── postgresql # 标注平台的 postgresql 数据库存储 └── monitoring ├── grafana # grafana 看板数据存储 └── prometheus # prometheus 监控数据存储,每个 k8s 集群要是不一样的目录 ``` > 说明:`kubeflow/global/datatse` 按原文保留(注释为「数据集的备份地址」,目录名疑似 `dataset` 的笔误,以实际部署创建的目录为准)。 ## 各目录用途速查 | 路径 | 命名空间 | 用途 | |---|---|---| | `/data/k8s/infra/mysql` | infra | MySQL 元数据库数据 | | `/data/k8s/kubeflow/dataset` | kubeflow | 用户通过 SDK 上传的数据集数据 | | `/data/k8s/kubeflow/global/cube-studio` | kubeflow | CubeStudio 源码 | | `/data/k8s/kubeflow/global/sqllab` | kubeflow | SQLLab 查询结果下载目录 | | `/data/k8s/kubeflow/global/datatse` | kubeflow | 数据集备份目录 | | `/data/k8s/kubeflow/labelstudio` | kubeflow | 标注平台数据 | | `/data/k8s/kubeflow/minio` | kubeflow | pipeline 任务日志与输出指标 | | `/data/k8s/kubeflow/pipeline/archives/` | kubeflow | 每个用户的归档目录 | | `/data/k8s/kubeflow/pipeline/workspace/` | kubeflow | 每个用户的工作目录 | | `/data/k8s/kubeflow/postgresql` | kubeflow | 标注平台 PostgreSQL 数据 | | `/data/k8s/monitoring/grafana` | monitoring | Grafana 看板数据 | | `/data/k8s/monitoring/prometheus` | monitoring | Prometheus 监控数据(多集群需分目录) | ## 相关运维提示 - **多集群的 Prometheus 目录必须分开**:每个 K8s 集群的监控数据要落在不同目录,避免互相覆盖。 - **Prometheus 历史数据清理**:监控数据会持续增长,定期清理见本段「[运维注意事项.md](运维注意事项.md)」。 - **存储准备前置**:`/data/k8s` 的共享存储如何挂载、用什么后端(NFS / hostPath / 分布式存储),见「02-部署安装」段的存储准备说明。 - 其它中间件也复用 `/data/k8s` 约定,例如 Redis 哨兵的 PV 落在 `/data/k8s/infra/redis/pv-*`(见「[Redis哨兵部署.md](Redis哨兵部署.md)」)。 --- ### 私有镜像仓库 Harbor 安装 - 链接: https://www.cubestudio.vip/docs/04-%E8%BF%90%E7%BB%B4%E7%AE%A1%E7%90%86/%E7%A7%81%E6%9C%89%E9%95%9C%E5%83%8F%E4%BB%93%E5%BA%93Harbor - 分类: 运维管理 / 私有仓库 - 适用场景: 在内网/离线环境搭建 Harbor 私有镜像仓库(docker http、nerdctl、https 证书三种方式)时阅读 - 关键词: harbor / 私有镜像仓库 / registry / 镜像仓库 / 离线安装 / docker / nerdctl / containerd / https / insecure-registries / 证书 / harbor.yml / 开机自启 - 最后更新: 2026-06-30 # 私有镜像仓库 Harbor 安装 本文汇总 Harbor 私有镜像仓库的三种安装方式: - **docker + http 离线安装**:有 docker / docker-compose 环境,最常用,仓库走 http。 - **nerdctl 离线安装**:containerd 环境(无 docker),用 nerdctl 替代 docker/docker-compose。 - **https 安装**:自签证书,仓库走 https,并配置开机自启。 安装文件位于 `install/kubernetes/harbor/`。Harbor 安装后 admin 默认密码为 `Harbor12345`(在 `harbor.yml` 中可改 `harbor_admin_password`)。 ## 一、docker + http 离线安装 ### 1. 离线下载安装包 ```bash # github地址 # amd64版本 wget https://githubfast.com/goharbor/harbor/releases/download/v2.11.1/harbor-offline-installer-v2.11.1.tgz # wget https://cube-studio.oss-cn-hangzhou.aliyuncs.com/install/harbor-offline-installer-v2.11.1.tgz # arm64版本 wget https://githubfast.com/wise2c-devops/build-harbor-aarch64/releases/download/v2.13.0/harbor-offline-installer-aarch64-v2.13.0.tgz # 解压 rm -rf /usr/local/harbor tar xf harbor-offline-installer-v2.11.1.tgz -C /usr/local/ cd /usr/local/harbor cp harbor.yml.tmpl harbor.yml ``` ### 2. 修改 harbor.yml(hostname、登录密码、关闭 https) `vim harbor.yml`,主要涉及:hostname 改为 ip,http 端口可以换掉,https 块去掉: ```yaml hostname: xx.xx.xx.xx harbor_admin_password: admin http: # port for http, default is 80. If https enabled, this port will redirect to https port port: 88 #https: # https port for harbor, default is 443 # port: 443 # The path of cert and key files for nginx # certificate: /your/certificate/path # private_key: /your/private/key/path data_volume: /data #这个路径是宿主机的路径,根据实际情况修改成空间大的地方 # external_url: http://xx.xx.xx.xx:88 # 如果有公网地址,这里填写 ``` ### 3. 执行安装 安装 Harbor 前需要先安装 docker 和 docker-compose,并启动它们。Docker 安装参考 [02-部署安装/节点准备/安装Docker](../02-部署安装/节点准备/安装Docker.md)。 ```bash cd /usr/local/harbor # 每次修改了配置文件都要删除之前的配置,重新安装 rm -rf ./common/config ./install.sh ``` 用 docker-compose 查看 Harbor 容器运行状态: ```bash docker-compose ps ``` ### 4. 客户端使用 http 仓库服务 http(非 https)仓库需要在 docker 客户端把仓库地址加入 `insecure-registries`。`vi /etc/docker/daemon.json`: ```json { "insecure-registries":["xx.xx.xx.xx:88"] } ``` 重启 docker 生效: ```bash systemctl stop docker systemctl daemon-reload systemctl start docker ``` ## 二、nerdctl 离线安装(containerd 环境,无 docker) 无 docker 环境下,用 nerdctl 替换安装脚本中的 docker/docker-compose 命令。 ```bash # 下载离线安装包 wget https://cube-studio.oss-cn-hangzhou.aliyuncs.com/harbor/harbor-offline-installer-v2.3.4.tgz # 解压并拷贝至 /usr/local/ 目录下 tar xf harbor-offline-installer-v2.3.4.tgz -C /usr/local/ # 进入 /usr/local/harbor 目录 cd /usr/local/harbor # 复制 harbor 配置文件 cp harbor.yml.tmpl harbor.yml # 注释配置文件中的 https,修改 http 端口,并设置 hostname 为主机 ip vi harbor.yml # 默认密码 Harbor12345 # 将 install.sh、common.sh、prepare 文件中的 docker-compose 改为 nerdctl compose,docker 改为 nerdctl sed -i 's/docker-compose/nerdctl compose/g' install.sh sed -i 's/docker/nerdctl/g' install.sh sed -i 's/docker-compose/nerdctl compose/g' common.sh sed -i 's/docker/nerdctl/g' common.sh sed -i 's/docker-compose/nerdctl compose/g' prepare sed -i 's/docker/nerdctl/g' prepare # 执行安装 # 1、vi install.sh 中去除 check_nerdctl、check_nerdctlcompose 等命令 # 2、执行安装 bash ./install.sh ``` ### 卸载 ```bash cd /usr/local/harbor nerdctl compose down rm -rf `find / -name harbor` # 将运行的容器全部停止 nerdctl stop `nerdctl ps -q` # 将容器全部删除 nerdctl rm `nerdctl ps -qa` # 将镜像全部删除 nerdctl rmi `nerdctl images -q` ``` ## 三、https 安装(自签证书) 参考 https://blog.csdn.net/networken/article/details/107502461 ### 1. 生成 https 证书 以 `registry.harbor.com` 域名为例: ```bash mkdir /root/ssl cd /root/ssl # 生成 CA 证书私钥 openssl genrsa -out ca.key 4096 # 生成 ca 证书 openssl req -x509 -new -nodes -sha512 -days 3650 \ -subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=registry.harbor.com" \ -key ca.key \ -out ca.crt # 生成服务器证书私钥 openssl genrsa -out registry.harbor.com.key 4096 # 生成证书签名请求(CSR) openssl req -sha512 -new \ -subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=registry.harbor.com" \ -key registry.harbor.com.key \ -out registry.harbor.com.csr # 生成一个 x509 v3 扩展文件 cat > v3.ext <<-EOF authorityKeyIdentifier=keyid,issuer basicConstraints=CA:FALSE keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment extendedKeyUsage = serverAuth subjectAltName = @alt_names [alt_names] DNS.1=registry.harbor.com DNS.2=registry.harbor DNS.3=harbor EOF # 使用该 v3.ext 文件为 Harbor 主机生成证书 openssl x509 -req -sha512 -days 3650 \ -extfile v3.ext \ -CA ca.crt -CAkey ca.key -CAcreateserial \ -in registry.harbor.com.csr \ -out registry.harbor.com.crt # 转换 registry.harbor.com.crt 为 registry.harbor.com.cert,供 Docker 使用 openssl x509 -inform PEM -in registry.harbor.com.crt -out registry.harbor.com.cert # 将服务器证书、密钥和 CA 文件复制到 Harbor 主机上的 Docker 证书文件夹中 mkdir -p /etc/docker/certs.d/registry.harbor.com/ cp registry.harbor.com.cert /etc/docker/certs.d/registry.harbor.com/ cp registry.harbor.com.key /etc/docker/certs.d/registry.harbor.com/ cp ca.crt /etc/docker/certs.d/registry.harbor.com/ systemctl restart docker ``` ### 2. 离线下载包 ```bash # github地址 wget https://githubfast.com/goharbor/harbor/releases/download/v2.11.1/harbor-offline-installer-v2.11.1.tgz # wget https://cube-studio.oss-cn-hangzhou.aliyuncs.com/install/harbor-offline-installer-v2.11.1.tgz # 解压 tar xf harbor-offline-installer-v2.11.1.tgz -C /usr/local/ cd /usr/local/harbor cp harbor.yml.tmpl harbor.yml ``` ### 3. 修改 harbor.yml(hostname、登录密码、https 证书位置) `vim harbor.yml`: ```yaml hostname: registry.harbor.com # http related config #http: # port for http, default is 80. If https enabled, this port will redirect to https port #port: 80 # https related config https: # https port for harbor, default is 443 port: 443 # The path of cert and key files for nginx certificate: /root/ssl/registry.harbor.com.crt private_key: /root/ssl/registry.harbor.com.key # enable strong ssl ciphers (default: false) # strong_ssl_ciphers: false data_volume: /data #这个路径是宿主机的路径,根据实际情况修改成空间大的地方 # external_url: http://xx.xx.xx.xx:88 # 如果有公网地址,这里填写 ``` ### 4. 执行部署 ```bash ./install.sh # 每次修改了配置文件都要删除之前的配置,重新安装 cd /usr/local/harbor rm -rf ./common/config ./install.sh ``` ### 5. 配置 Harbor 开机自启 ```bash cat > /usr/lib/systemd/system/harbor.service << 'EOF' [Unit] Description=Harbor After=docker.service systemd-networkd.service systemd-resolved.service Requires=docker.service Documentation=http://github.com/vmware/harbor [Service] Type=simple Restart=on-failure RestartSec=5 Environment=harbor_install_path=/data/packages ExecStart=/usr/local/bin/docker-compose -f ${harbor_install_path}/harbor/docker-compose.yml up ExecStop=/usr/local/bin/docker-compose -f ${harbor_install_path}/harbor/docker-compose.yml down [Install] WantedBy=multi-user.target EOF ``` > 注意:上面 systemd 单元里的 `harbor_install_path=/data/packages`(即 `docker-compose.yml` 路径为 `/data/packages/harbor/docker-compose.yml`)与前文解压目录 `/usr/local/harbor` 不一致,请根据实际安装路径调整,见 `install/kubernetes/harbor/https-harbor.md:136-138`。 --- ### Redis 哨兵模式部署与故障切换验证 - 链接: https://www.cubestudio.vip/docs/04-%E8%BF%90%E7%BB%B4%E7%AE%A1%E7%90%86/Redis%E5%93%A8%E5%85%B5%E9%83%A8%E7%BD%B2 - 分类: 04-运维管理 / 中间件 - 适用场景: 需要在 K8s 上为平台部署高可用(哨兵模式)Redis,或验证主节点故障自动切换、配置平台连接哨兵时 - 关键词: Redis / 哨兵 / sentinel / 哨兵模式 / 高可用 / HA / failover / 故障转移 / 主从切换 / redis-cluster / redis-sentinel / pv-pvc / mymaster / 26379 / SENTINEL_NODES / REDIS_SENTINEL_PASSWORD - 最后更新: 2026-06-30 # Redis 哨兵模式部署与故障切换验证 在 K8s 上部署一套哨兵(Sentinel)模式 Redis,实现主从高可用与主节点故障自动切换,供平台做缓存 / Celery broker 使用。相关清单在 `install/kubernetes/redis/sentinel/` 目录下。 ## 一、组件构成 | 清单文件 | 作用 | 关键参数(以源码为准) | |---|---|---| | `pv-pvc.yaml` | 为 3 个 Redis Pod 各准备 1 个 PV+PVC | hostPath `/data/k8s/infra/redis/pv-0..2`,`storageClassName: manual`,每个 1Gi,`Retain` 回收策略 | | `redis-cluster.yaml` | Redis 主从(StatefulSet,3 副本) | 镜像 `redis:6.0-alpine`,端口 6379;`redis-0` 为主,其余 `replicaof redis-0.redis 6379` | | `redis-sentinel.yaml` | 哨兵(Deployment,3 副本) | 镜像 `redis:6.0-alpine`,端口 26379;ConfigMap `sentinel monitor mymaster redis-0.redis 6379 2` | | `test-sentinel.py` | Python 连通性与故障切换测试脚本 | 需改 `SENTINEL_NODES`,`SERVICE_NAME=mymaster` | 要点: - Redis 主从用 **StatefulSet**(稳定网络标识 `redis-0/1/2`),主节点固定为 `redis-0`,其余 Pod 启动时 `replicaof redis-0.redis 6379`;Service 名为 `redis`(headless,`clusterIP: None`)。 - 哨兵用 **Deployment**(3 副本),监听 `26379`,配置 `sentinel monitor mymaster redis-0.redis 6379 2`(quorum=2)、`down-after-milliseconds 5000`、`failover-timeout 60000`。哨兵配置从只读 ConfigMap 复制到可写 `/data` 后再启动,运行态数据用 `emptyDir`(Pod 重启会丢,但状态可重建)。 - 如果 Redis 设了密码,需在哨兵 ConfigMap 里放开 `sentinel auth-pass mymaster <密码>` 与 `requirepass <密码>`。 ## 二、部署步骤 ```bash # 1) 部署 pv-pvc 存储 kubectl apply -f pv-pvc.yaml # 2) 部署 redis-cluster 主从 kubectl apply -f redis-cluster.yaml # 查看 redis-cluster pod 是否 running kubectl get pod # 3) 部署 redis-sentinel 哨兵 kubectl apply -f redis-sentinel.yaml # 查看 redis-sentinel pod 是否 running kubectl get pod ``` ## 三、连通性测试(Python 哨兵客户端) ```bash # 修改 test-sentinel.py 中 SENTINEL_NODES 的主机列表,改为 redis-sentinel pod 的 IP 地址 python test-sentinel.py ``` `test-sentinel.py` 行为(见 `install/kubernetes/redis/sentinel/test-sentinel.py`): - 用 `redis.sentinel.Sentinel` 连接哨兵列表,`SERVICE_NAME='mymaster'`; - 每 5 秒(`WRITE_INTERVAL`)向主节点写一次 `sentinel_test:data`,并分别从主、从节点读取,演示读写分离; - 通过 `sentinel.discover_master('mymaster')` 打印当前主节点地址;写失败时自动用 `master_for(...)` 重新发现新主节点(验证自动切换)。 > 注意:脚本里 `PASSWORD = 'None'` 是字符串 `'None'` 而非 Python `None`;如果你的 Redis 无密码,按脚本默认即可,有密码则改成真实口令。 ## 四、主节点故障切换验证 ```bash # 1) 获取一个哨兵 Pod 名称 SENTINEL_POD=$(kubectl get pods -l app=redis-sentinel -o jsonpath='{.items[0].metadata.name}') # 2) 通过哨兵查询当前主节点地址 kubectl exec -it $SENTINEL_POD -- redis-cli -p 26379 sentinel get-master-addr-by-name mymaster # 3) 找到该 IP 对应的 Pod 并删除,模拟主节点宕机 kubectl get pod -owide kubectl delete pod redis-x # 把 redis-x 换成上一步主节点 IP 对应的 pod ``` 删除主节点 Pod 后,哨兵应在 `down-after-milliseconds`(5s) + 选举时间内把某个从节点提升为新主;再次执行第 2 步的 `get-master-addr-by-name` 应返回新的主节点地址,`test-sentinel.py` 也会自动写入新主节点。 ## 五、平台侧连接哨兵 平台默认连单实例 Redis(`REDIS_HOST/REDIS_PORT/REDIS_PASSWORD`)。切换到哨兵模式需在配置里改用哨兵相关项(`myapp/config.py:495-504`,默认被注释): ```python # 哨兵模式 redis 配置 REDIS_PASSWORD = 'wenwang' # Redis 没有密码则填 None REDIS_SENTINEL_PASSWORD = 'wenwangsentinel' # 哨兵没有密码填 None SENTINEL_SERVICE_NAME = 'mymaster' # Sentinel master 名称,与上面 monitor 的名字一致 SENTINEL_NODES = [ # 哨兵节点列表 ('10.42.0.88', 26379), ('10.42.0.89', 26379), ('10.42.0.90', 26379), ] ``` > 单实例与哨兵两套配置项是互斥的:启用 `SENTINEL_NODES` 等哨兵项时,确保 `SENTINEL_SERVICE_NAME` 与哨兵 ConfigMap 里 `sentinel monitor ` 的名字(示例为 `mymaster`)一致。具体生效逻辑以 `myapp/config.py` 及读取该配置的代码为准。 ## 相关 - 哨兵 Redis 的 PV 落在 `/data/k8s/infra/redis/pv-*`,目录约定见「[分布式存储目录.md](分布式存储目录.md)」。 --- ### 达梦数据库(DM8)部署与 MySQL 迁移 - 链接: https://www.cubestudio.vip/docs/04-%E8%BF%90%E7%BB%B4%E7%AE%A1%E7%90%86/%E8%BE%BE%E6%A2%A6%E6%95%B0%E6%8D%AE%E5%BA%93%E9%83%A8%E7%BD%B2%E4%B8%8E%E8%BF%81%E7%A7%BB - 分类: 04-运维管理 / 元数据库 - 适用场景: 需要用达梦数据库(DM8)替换 MySQL 作为平台元数据库时,如何部署达梦、配置客户端、把 MySQL 建表语句迁移到达梦 - 关键词: 达梦 / 达梦数据库 / DM8 / DM / dameng / dmPython / dmSQLAlchemy / 国产数据库 / 信创 / 兼容模式 / COMPATIBLE_MODE / LENGTH_IN_CHAR / DM_SERVICE / MySQL迁移 / DDL转换 / to_dm.py / 序列 / SEQUENCE - 最后更新: 2026-06-30 # 达梦数据库(DM8)部署与 MySQL 迁移 本文覆盖两件事: 1. **部署**——用 Docker(本地或阿里云 ECS)跑起一个达梦 DM8 实例,并完成兼容模式、客户端驱动、连通性配置; 2. **MySQL 迁移到达梦**——把平台原有的 MySQL 建表 DDL 通过正则批量转换成达梦 SQL,并用脚本灌库。 > 平台的元数据库连接统一通过 `DM_SERVICE` 环境变量配置,URI 形如 > `dm+dmPython://SYSDBA:<密码>@:?schema=kubeflow` > (见 `install/docker/docker-compose.yml:57`、`myapp/config.py:484`)。 > 三类元数据库(MySQL / PostgreSQL / 达梦)的总体选型与切换说明见本段「[元数据库配置.md](元数据库配置.md)」。 --- ## 一、部署 推荐两种方式,**生产优先用阿里云上常驻实例**:阿里云上的参数已调优、性能好,部署完只要给服务器开外网 IP、安全组放开端口即可,不建议用本地自建实例顶生产。 ### 1.1 本地 Docker 运行(测试用) > 容器内端口固定为 `5236`,**不能改**(参考 https://blog.csdn.net/chou342175867/article/details/145902563 )。对外可映射成任意 NodePort,下例映射到 `30226`。 ```bash # 清理旧数据与旧容器 rm -rf /opt/data docker rm dm8_test -f # 启动 DM8(容器内 5236 -> 宿主 30226) docker run -d -p 30226:5236 --restart=always --name=dm8_test --privileged=true \ -v /opt/data:/opt/dmdbms/data \ -e LD_LIBRARY_PATH=/opt/dmdbms/bin \ -e PAGE_SIZE=16 -e EXTENT_SIZE=32 -e LOG_SIZE=1024 -e UNICODE_FLAG=1 \ -e INSTANCE_NAME=dm8_test \ ccr.ccs.tencentyun.com/cube-studio/dm8:dm8_20250206_rev257733_x86_rh6_64 ``` ### 1.2 阿里云上运行(生产) 阿里云镜像启动时直接挂载配置文件会失败,只能起来后再进容器改(见下文兼容模式)。 ```bash docker run -d -p 30226:5236 --restart=always --name=dm8_test --privileged=true \ -v /opt/data:/opt/dmdbms/data \ -e SYSDBA_PWD=19910101a \ -e COMPATIBLE_MODE=4 \ -e LD_LIBRARY_PATH=/opt/dmdbms/bin \ -e PAGE_SIZE=16 -e EXTENT_SIZE=32 -e LOG_SIZE=1024 -e UNICODE_FLAG=1 \ -e INSTANCE_NAME=dm8_test \ -e PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \ -e CASE_SENSITIVE=0 -e LENGTH_IN_CHAR=0 -e BUFFER=30000 -e MODE=dmsingle \ -e CHG_PASSWD=dameng777 -e DM_USER_PWD=dameng777 -e BLANK_PAD_MODE=0 \ -e LANG=en_US.UTF-8 \ ccr.ccs.tencentyun.com/cube-studio/dm8:dm8_20241022_rev244896_x86_rh6_64 /opt/startup.sh ``` 常用启动参数说明: | 环境变量 | 含义 | |---|---| | `SYSDBA_PWD` / `CHG_PASSWD` / `DM_USER_PWD` | SYSDBA / 修改后口令 / 业务用户口令 | | `COMPATIBLE_MODE=4` | 兼容模式,`4` 为兼容 MySQL(迁移 MySQL DDL 必须开) | | `CASE_SENSITIVE=0` | 大小写不敏感(对象名不区分大小写) | | `LENGTH_IN_CHAR=0` / `1` | varchar 长度按字节(0)还是按字符(1)计 | | `PAGE_SIZE` / `EXTENT_SIZE` / `LOG_SIZE` / `BUFFER` | 页大小/簇大小/日志大小/缓冲,性能相关 | | `UNICODE_FLAG=1` | 启用 Unicode | | `MODE=dmsingle` | 单机模式 | > 注意:源 `install/kubernetes/mysql/dm/kubeflow/readme.md:10` 的阿里云示例里 `-e COMPATIBLE_MODE=4` 写了两次,是冗余笔误(已核对源文件),本文已合并为一个,效果不变。 ### 1.3 兼容模式(进容器改 dm.ini) 如果启动时没设或要调整兼容模式,进容器改配置文件后重启: ```bash docker exec -it dm8_test /bin/bash vi /opt/dmdbms/data/DAMENG/dm.ini # 修改/确认以下两项 COMPATIBLE_MODE = 4 LENGTH_IN_CHAR = 1 # 或者 NVARCHAR_LENGTH_IN_CHAR = 1 ``` ```bash docker restart dm8_test ``` ### 1.4 查看日志与口令 ```bash docker logs -f dm8_test # 看日志里是否 success docker inspect dm8_test | grep PWD # 注意:口令可能被改写,例如变成 SYSDBA_dm001 ``` 进容器用 disql 连: ```bash docker exec -it dm8_test bash source /etc/profile cd /opt/dmdbms/bin/ ./disql SYSDBA/SYSDBA_dm001 # 用 docker inspect 看到的真实口令 ``` ### 1.5 客户端驱动安装 平台后端通过 `dm+dmPython` 方言连接达梦,需要两个 Python 包: | 包 | 平台镜像内版本(以 `install/docker/requirements.txt` 为准) | |---|---| | `dmPython` | `2.5.30`(`requirements.txt:64`,达梦驱动) | | `dmSQLAlchemy` | `1.4.46`(`requirements.txt:65`,达梦 SQLAlchemy 方言) | 安装方式: ```bash # Linux(有 wheel,直接 pip) pip install dmPython==2.5.30 pip install dmSQLAlchemy==1.4.46 # 其他平台(无 wheel,源码安装) # 1) 到 https://eco.dameng.com/download/ 下载“达梦 Python 接口源码” # 2) dmPython:在解压出的 dmPython 目录下执行 python setup.py install # 3) dmSQLAlchemy:在 dmSQLAlchemy/dmSQLAlchemy1.4 目录下执行 python setup.py install ``` > 注意:源 `readme.md:32` 写的是 `pip install dmSQLAlchemy==1.4.39`,而平台镜像 `install/docker/requirements.txt:65` 钉的是 `1.4.46`(已核对)。本文以 `requirements.txt` 为准写成 `1.4.46`,与服务端版本保持一致。 > > 注:PC(非 Linux)上 `dmPython==2.5.30` 没有 wheel 装不上。不需要达梦的开发者可临时绕过(见 `install/docker/README.md:144`): > ```bash > grep -vE "^(dmPython|dmSQLAlchemy)" install/docker/requirements.txt > /tmp/req.txt > pip install -r /tmp/req.txt > ``` ### 1.6 连通性测试(DBeaver / disql) 用 DBeaver 等客户端连上后,建 schema、建测试表验证: ```sql create schema KUBEFLOW AUTHORIZATION SYSDBA; CREATE TABLE KUBEFLOW.ACCOUNTS ( ACCOUNT_ID INT PRIMARY KEY, ACCOUNT_NAME VARCHAR(100), BALANCE DECIMAL(15,2) ); ``` > 注意 schema 大小写:`readme.md` 用大写 `KUBEFLOW` 建 schema,而平台连接串 `docker-compose.yml:57` 用的是小写 `schema=kubeflow`,迁移脚本 `to_dm.md` 也以小写 `"kubeflow"` 建 schema。配合启动参数 `CASE_SENSITIVE=0`(大小写不敏感)时二者等价;若实例区分大小写,务必让 schema 名与 `DM_SERVICE` 里的 `schema=` 完全一致。 ### 1.7 平台侧行为差异(重要) 达梦作为元数据库时,平台**不走 Alembic 迁移**,而是用 `db.create_all()` 直接建表: - `myapp/config.py:484-488`:检测到 `DM_SERVICE` 后清空 `migrations/versions` 目录; - `install/docker/entrypoint.sh:25-28`:仅当 `DM_SERVICE` 为空时才执行 `myapp db upgrade`;达梦走 `myapp/create_db.py` 里的 `db.create_all()` 建表。 这也是为什么从 MySQL 迁移到达梦时,需要手工把 DDL 转换好(下一节),而不是依赖迁移文件。 --- ## 二、MySQL 迁移到达梦 思路:把平台原有的 MySQL 建表脚本(`kubeflow.sql`)用编辑器/IDE 的正则替换,按下列规则批量改写成达梦语法,再用 `to_dm.py` 灌进达梦。涉及文件都在 `install/kubernetes/mysql/dm/kubeflow/` 目录下(`kubeflow.sql` 建表、`data.sql` 初始数据、`to_dm.py` 执行器)。 ### 2.1 正则批量转换规则 按顺序在编辑器里做正则「查找→替换」(`$1`/`$2` 为捕获组): **清理无关语句与注释** | 查找(正则) | 替换为 | |---|---| | `^SET.*` 开头的行 | 删除 | | `^DROP.*` 开头的行 | 删除 | | `` ` ``(反引号) | `"`(双引号) | | `BEGIN;` | 空 | | `COMMIT;` | 空 | | `INSERT INTO.*` | 空 | | `^--.*`(行注释) | 空 | | `COMMENT.*?,\n` | `,\n` | **类型与子句改写** | 查找(正则) | 替换为 | |---|---| | `ENGINE=InnoD.*` | `STORAGE(ON "MAIN", CLUSTERBTR) ;` | | `AUTO_INCREMENT` | `IDENTITY(1,1)` | | `UNIQUE KEY "(.*?)" ` | `CONSTRAINT TABLE1_$1 UNIQUE ` | | ` COLLATE utf8mb4_general_ci` | 空 | | `tinyint(1)` | `TINYINT` | | `mediumtext` | `CLOB` | | `datetime DEFAULT NULL` | `TIMESTAMP(0)` | | `enum.*?\)` | `varchar(100)` | | `varchar(64)`(可选) | `VARCHAR(64 CHAR)` | **主键 / 外键改写** | 查找(正则) | 替换为 | |---|---| | `PRIMARY KEY` | `CONSTRAINT "TABLE1_PRIMARY" NOT CLUSTER PRIMARY KEY` | | `FOREIGN KEY(.*?),` | `FOREIGN KEY$1 WITH INDEX,` | | `FOREIGN KEY(.*?)\n\)` | `FOREIGN KEY$1 WITH INDEX\n)` | **把每个表压成一行(便于后续整表替换)** 需要执行很多遍,直到没有可匹配的行——目标是把跨多行的 `CREATE TABLE` 折叠成一行: | 查找(正则) | 替换为 | |---|---| | `CREATE TABLE (.*)\n ` | `CREATE TABLE $1` | 再执行一遍把表末尾的右括号接上: | 查找(正则) | 替换为 | |---|---| | `CREATE TABLE (.*)\n\)` | `CREATE TABLE $1 )` | **把占位表名 `TABLE1` 换回真实表名** | 查找(正则) | 替换为 | |---|---| | `CREATE TABLE "(.*?)" (.*)TABLE1` | `CREATE TABLE "$1" $2$1` | **把索引创建从表内提取到表外** | 查找(正则) | 替换为 | |---|---| | `, *KEY` | `, KEY` | | `CREATE TABLE "(.*?)" (.*?), KEY "(.*?)" (.*?),(.*)` | `CREATE TABLE "$1" $2, $5\nCREATE OR REPLACE INDEX "$1_$3" ON "$1"$4 STORAGE(ON "MAIN", CLUSTERBTR) ;` | **幂等与达梦保留字处理** | 查找(正则) | 替换为 | |---|---| | `CREATE TABLE` | `CREATE TABLE IF NOT EXISTS` | | ` user ` | ` "user" ` | | ` public ` | ` "public" ` | | ` table `(区分大小写) | ` "table" ` | | ` cluster ` | ` "cluster" ` | | ` resource ` | ` "resource" ` | | ` date ` | ` "date" ` | | ` skip ` | ` "skip" ` | | `kubeflow.dimension `(维表,转小写) | `kubeflow."dimension" ` | | `kubeflow.model `(训练模型表,转小写) | `kubeflow."model" ` | | `\n\n`(连续空行) | `\n` | ### 2.2 重建 schema 并设置当前 schema 在转换好的 SQL 顶部加上: ```sql DROP SCHEMA "kubeflow" CASCADE; CREATE SCHEMA "kubeflow" AUTHORIZATION "SYSDBA"; SET SCHEMA "kubeflow"; ``` ### 2.3 批量灌库 用 `to_dm.py` 逐行执行转换后的 `kubeflow.sql` 与 `data.sql`: ```bash python to_dm.py ``` `to_dm.py` 要点(见 `install/kubernetes/mysql/dm/kubeflow/to_dm.py`): - 连接串为 `dm+dmPython://SYSDBA:<密码>@:?schema=KUBEFLOW`(脚本里是写死的示例值,实际请改成你的实例); - 用 `dmPython.connect(... autoCommit=True)` 建连接,逐行 `cursor.execute(sql)`; - 单行执行失败会被 `try/except` 吞掉继续(容忍重复建表等报错),先执行 `kubeflow.sql` 再执行 `data.sql`。 > 注意:`to_dm.py:2` 写死的示例端口是 `30236`,而部署小节 `docker run` 映射的是 `30226`。这两个都是示例值,实际以你映射的 NodePort 为准。 ### 2.4 为 ab_ 开头的权限表建序列 达梦下自增主键改成了 `IDENTITY` 或序列。Flask-AppBuilder 的权限/用户表(`ab_` 前缀)需要手工补建序列: ```sql CREATE SEQUENCE "kubeflow"."ab_user_id_seq" INCREMENT BY 1 MAXVALUE 9223372036854775807 MINVALUE 1; CREATE SEQUENCE "kubeflow"."ab_role_id_seq" INCREMENT BY 1 MAXVALUE 9223372036854775807 MINVALUE 1; CREATE SEQUENCE "kubeflow"."ab_user_role_id_seq" INCREMENT BY 1 MAXVALUE 9223372036854775807 MINVALUE 1; CREATE SEQUENCE "kubeflow"."ab_permission_id_seq" INCREMENT BY 1 MAXVALUE 9223372036854775807 MINVALUE 1; CREATE SEQUENCE "kubeflow"."ab_view_menu_id_seq" INCREMENT BY 1 MAXVALUE 9223372036854775807 MINVALUE 1; CREATE SEQUENCE "kubeflow"."ab_permission_view_id_seq" INCREMENT BY 1 MAXVALUE 9223372036854775807 MINVALUE 1; CREATE SEQUENCE "kubeflow"."ab_permission_view_role_id_seq" INCREMENT BY 1 MAXVALUE 9223372036854775807 MINVALUE 1; ``` ### 2.5 禁掉 fab 自动建权限的部分 迁移完成后,`fab` 创建权限的那些初始化步骤需要禁掉(否则会与已迁移的权限数据冲突)。 > ⚠️ 待核实:原文 `to_dm.md:84` 只写了「fab 创建权限的那些部分还要禁掉」,未给出具体改哪段代码。结合 `install/docker/entrypoint.sh` 里的 `myapp fab create-admin` 与 `myapp init`,禁用范围以实际代码为准,请确认。 --- ## 三、连接配置回填 迁移完成后,平台通过 `DM_SERVICE` 连接达梦(在 `docker-compose.yml` 或 K8s 环境变量里设置): ```yaml # install/docker/docker-compose.yml 示例(注意去掉行首注释启用) DM_SERVICE: 'dm+dmPython://SYSDBA:Sysdba001@192.168.3.22:5236?schema=kubeflow' ``` 三类元数据库的优先级(`MYSQL_SERVICE` > `POSTGRESQL_SERVICE`/`KINGBASE_SERVICE` > `DM_SERVICE`)与切换细节见本段「[元数据库配置.md](元数据库配置.md)」。 --- ### 认证与单点登录(SSO)配置 - 链接: https://www.cubestudio.vip/docs/04-%E8%BF%90%E7%BB%B4%E7%AE%A1%E7%90%86/%E8%AE%A4%E8%AF%81%E4%B8%8E%E5%8D%95%E7%82%B9%E7%99%BB%E5%BD%95%E9%85%8D%E7%BD%AE - 分类: 运维管理 / 认证与登录 - 适用场景: 部署/运维时需要配置平台登录方式——启用 LDAP 兜底或某种第三方单点登录(OAuth2/CAS/飞书/企微/钉钉/微信),需要知道各自的配置项、回调地址、启用方式与对接步骤时读这篇 - 关键词: 登录 / 认证 / SSO / 单点登录 / OAuth2 / OIDC / OpenID / CAS / 飞书 / feishu / 企业微信 / wecom / 钉钉 / dingtalk / 微信 / wechat / LDAP / AUTH_LDAP / 账号密码登录 / 自动注册 / AUTH_USER_REGISTRATION_ROLE / view_login / project.py / MyCustomRemoteUserView / callback / 回调地址 - 最后更新: 2026-06-30 # 认证与单点登录(SSO)配置 平台支持多种登录方式,全部由 `myapp/views/view_login.py` 实现,配置集中在 `myapp/config.py`。 默认是账号密码登录(`/login/db`,密码不匹配时可回退 LDAP bind);另支持 6 种第三方单点登录。 **各端点细节、回调流程与自动注册逻辑以 `myapp/views/view_login.py`、`myapp/config.py` 为准。** ## 支持的登录方式 | 方式 | 登录入口 | 对应视图类 | 配置块 | |---|---|---|---| | 账号密码(+LDAP 兜底) | `/login/db` | `Myauthdbview` | `AUTH_LDAP_*` | | OAuth2 / OIDC | `/login/oauth2/` | `OAuth2LoginView` | `OAUTH2_*` | | CAS | `/login/cas/` | `CASLoginView` | `CAS_*` | | 飞书 | `/login/feishu/` | `FeishuLoginView` | `FEISHU_*` | | 企业微信 | `/login/wecom/` | `WeComLoginView` | `WECOM_*` | | 钉钉 | `/login/dingtalk/` | `DingTalkLoginView` | `DINGTALK_*` | | 微信开放平台 | `/login/wechat/` | `WeChatLoginView` | `WECHAT_*` | ## 启用某种登录方式 平台默认入口跳转由 `project.py` 的 `MyCustomRemoteUserView.login()` 控制。启用某种 SSO 时, 把该方法的跳转目标改为对应入口即可(见 `myapp/config.py:107-110` 的说明): ```python # project.py MyCustomRemoteUserView.login() return redirect('/login/oauth2/') # 例:启用 OAuth2;CAS 改为 /login/cas/,飞书 /login/feishu/ ... ``` ## 各方式配置项(config.py) > 以下配置项默认在 `myapp/config.py` 中以注释给出模板(约 `:112-152`),按需取消注释并填写。 > 各 SSO 的 `*_REDIRECT_URI` **留空时会自动拼接** `/(login)//callback`,一般无需手填。 - **OAuth2 / OIDC**:`OAUTH2_PROVIDER`(填 `github` / `google` 可自动补全各端点 URL;其他 IdP 如 Keycloak/Okta/Azure AD 留空并手填)、`OAUTH2_CLIENT_ID` / `OAUTH2_CLIENT_SECRET`、 `OAUTH2_AUTHORIZE_URL` / `OAUTH2_TOKEN_URL` / `OAUTH2_USERINFO_URL`、`OAUTH2_SCOPES`、 `OAUTH2_USERNAME_FIELD` / `OAUTH2_EMAIL_FIELD`(从 userinfo 取用户名/邮箱的字段)、`OAUTH2_LOGOUT_URL`。 - **CAS**:`CAS_SERVER_URL`、`CAS_SERVICE_URL`(回调,留空自动拼)、`CAS_LOGOUT_URL`。 - **飞书**:`FEISHU_APP_ID`、`FEISHU_APP_SECRET`、`FEISHU_REDIRECT_URI`。 - **企业微信**:`WECOM_CORPID`、`WECOM_AGENTID`、`WECOM_CORPSECRET`、`WECOM_REDIRECT_URI`。 - **钉钉**:`DINGTALK_APP_KEY`、`DINGTALK_APP_SECRET`、`DINGTALK_REDIRECT_URI`。 - **微信开放平台**:需先在 open.weixin.qq.com 创建「网站应用」并过审;`WECHAT_APP_ID`、 `WECHAT_APP_SECRET`、`WECHAT_REDIRECT_URI`。 - **LDAP 兜底**(账号密码登录时密码不匹配则尝试 LDAP bind):`AUTH_LDAP_SERVER`、`AUTH_LDAP_PORT`、 `AUTH_LDAP_USE_TLS`、`AUTH_LDAP_BASE_DN`。 ## 通用对接步骤 1. 在对应 IdP / 三方开放平台创建应用,拿到 `client_id` / `secret`(或 CAS server 地址)。 2. 在三方平台配置**回调地址**为 `<平台域名>/login//callback`(与留空自动拼接的地址一致)。 3. 在 `config.py` 填写对应配置块(上一节)。 4. 修改 `project.py` 的 `MyCustomRemoteUserView.login()` 跳转到该方式入口。 5. 重启后端生效。首次通过 SSO 登录的用户会**自动注册**,默认角色由 `AUTH_USER_REGISTRATION_ROLE` 决定(默认 `Gamma`,见 `myapp/config.py:94`)。 > 三方登录的回调与「自动注册或登录」由 `view_login.py` 中通用函数 `_sso_login_or_register` 完成; > 角色到平台权限的映射、用户名取值规则等以代码为准。 --- ### 平台 HTTPS 配置(istio gateway / nginx 代理 / 自签证书) - 链接: https://www.cubestudio.vip/docs/04-%E8%BF%90%E7%BB%B4%E7%AE%A1%E7%90%86/%E5%B9%B3%E5%8F%B0HTTPS%E9%85%8D%E7%BD%AE - 分类: 04-运维管理 / 网络与证书 - 适用场景: 给平台启用 HTTPS / 配置 TLS 证书 / 解决 https 下前端跳转回 http 的问题时读这篇 - 关键词: https / tls / ssl / istio / gateway / kubeflow-gateway / ingress / nginx / 反向代理 / 证书 / self-signed / openssl / server.crt / server.key / tls-secret / X-Forwarded-Proto / scheme / 443 / labelstudio - 最后更新: 2026-07-04 # 平台 HTTPS 配置 平台默认通过 istio ingressgateway 以 HTTP(80 端口)对外提供服务。要启用 HTTPS,有两条路线: - istio 侧:直接给 `kubeflow-gateway` 配 TLS(当前不可用,见下)。 - nginx 侧(推荐 / 实际可用):在 istio 前面加一层 nginx 做 TLS 终止,nginx 处理证书并把明文流量转发给 istio ingressgateway。 最后还需要生成(或替换)证书,并在前端做 scheme 改写避免 https 页面跳回 http。下面分「istio 侧 / nginx 侧 / 证书生成」三部分。 --- ## 一、istio 侧:直接给 gateway 配 TLS(方式一,目前不行) > 说明:此方式来自原文档,标注「目前不行」,仅作背景了解,请勿据此作为生产方案。 在对应命名空间创建 TLS secret: ```bash kubectl create secret tls tls-secret --cert=server.crt --key=server.key -n kubeflow ``` 修改 `kubeflow` 命名空间的 `kubeflow-gateway`,新增 443/HTTPS server 并引用该 secret: ```yaml apiVersion: networking.istio.io/v1beta1 kind: Gateway metadata: name: kubeflow-gateway namespace: kubeflow spec: selector: istio: ingressgateway servers: - hosts: - '*' port: name: http-port number: 80 protocol: HTTP # 使用 https 添加这部分,并让 istio-ingressgateway 开放 443 端口 # 注意不要和 rancher 等已占用 443 的服务端口冲突 - hosts: - '*' port: name: https-port number: 443 protocol: HTTPS tls: credentialName: tls-secret mode: SIMPLE ``` 经过该 gateway 的所有 VirtualService 理论上即可用 https 访问。 --- ## 二、nginx 侧:nginx 代理 + 前端 scheme 改写(方式二,推荐) 思路:新增一层 nginx 做 TLS 终止,把流量代理到 istio ingressgateway;istio 本身不做任何 TLS 配置。相关清单在 `install/kubernetes/nginx-https/`。 ### 2.1 部署 https nginx(接管 TLS) nginx 的 `default-https.conf` 监听 443(k8s 形态)做 TLS 终止,转发到 `http://istio-ingressgateway.istio-system:80/`,并已带上 `proxy_set_header X-Forwarded-Proto https;`(`install/kubernetes/nginx-https/default-https.conf`)。 k8s 部署(把证书与配置打成 configmap `ssl-config`,再起一个 nginx Deployment + NodePort Service,对外 443): ```bash # 先确认 default-https.conf 中转发地址为 http://istio-ingressgateway.istio-system:80/ kubectl delete configmap ssl-config --namespace=istio-system kubectl create configmap ssl-config \ --from-file=server.crt --from-file=server.csr --from-file=server.key --from-file=default-https.conf \ --namespace=istio-system kubectl apply -f ingress-nginx.yaml ``` > `ingress-nginx.yaml` 创建:`istio-system` 下名为 `ingress-nginx` 的 NodePort Service(443)和同名 Deployment,挂载 `ssl-config` 到 `/etc/nginx/conf.d/default-https.conf` 与 `/etc/nginx/ssl/`。依据 `install/kubernetes/nginx-https/ingress-nginx.yaml`。 docker 部署(docker-compose / 单机形态): ```bash # 修改 default-https.conf 的监听端口(作为 https 暴露端口)与转发到 istio ingressgateway 的内网地址 docker run --name https-nginx -d -p 8443:8443 \ -v $PWD:/etc/nginx/ssl/ \ -v $PWD/default-https.conf:/etc/nginx/conf.d/default-https.conf \ nginx ``` 如只需 http 代理(不加密,用于调试): ```bash docker run --name nginx -it --network=host \ -v $PWD/default-http.conf:/etc/nginx/conf.d/default-http.conf nginx ``` ### 2.2 修改平台外网地址与 labelstudio host - 把 CubeStudio 的「外网 ip/域名」配置改为该 nginx 的 ip:端口(`config.py` 中 `CLUSTERS` 的 `HOST` 等,见 [配置文件管理.md](配置文件管理.md))。 - 把数据标注 labelstudio 的 host 环境变量改为该 nginx 的 ip:端口 + https 协议。该环境变量为 `LABEL_STUDIO_HOST`,正常部署时形如 `http://$ip/labelstudio`(同时设置在 labelstudio Deployment 的 frontend 与 backend 两个容器上),https 场景应改为 `https://$ip/labelstudio`。依据 `install/kubernetes/start.sh:169-170`(patch frontend/backend 两个容器的 `LABEL_STUDIO_HOST`)、`install/kubernetes/labelstudio/labelstudio.yaml:81,135`。详见 [03-平台使用 / 数据标注](../03-平台使用/08-数据标注/)。 ### 2.3 前端 nginx 改 scheme(关键,避免 https 跳回 http) CubeStudio 前端 Pod 的 nginx 配置里有一条把根路径重定向到 `/frontend/` 的规则,默认用 `$scheme`(会回填成 http)。https 下需写死成 `https`,并打开 `X-Forwarded-Proto https`: ```nginx # 原:rewrite ^(.*) $scheme://$http_host/frontend/ permanent; # 改为: rewrite ^(.*) https://$http_host/frontend/ permanent; # 同时取消注释: proxy_set_header X-Forwarded-Proto https; ``` 改完重启前端 Pod。 该 nginx 配置在前端 Deployment 的内嵌 configmap 中:`install/kubernetes/cube/base/deploy-frontend.yaml:19`(重写规则)与 `deploy-frontend-more.yaml:18,66`;本地形态对应 `install/docker/dockerFrontend/nginx.80.conf:9,53`。 --- ## 三、证书生成(openssl 自签) 使用 openssl 生成自签证书(`install/kubernetes/nginx-https/readme.md`,参考腾讯云文档 ): ```bash # 1. 生成 server.key openssl genrsa -aes256 -out server.key 2048 # 2. 去掉私钥密码(生成无密码的 server.key) openssl rsa -in server.key -out server.key # 3. 创建证书申请文件 server.csr openssl req -new -key server.key -out server.csr # 交互式填写示例: # Country Name (2 letter code): CN # State or Province Name: Zhejiang # Locality Name: HangZhou # Organization Name: kaiqiao # Organizational Unit Name: kaiqiao # Common Name: * # 填你的域名或访问 ip;通配符域名似乎不行,可直接用 * # Email Address: xxx@xx.com # 4. 生成 crt 证书文件 server.crt(自签,有效期 10 年) openssl x509 -in server.csr -out server.crt -req -signkey server.key -days 3650 ``` 生成的 `server.crt` / `server.key` / `server.csr` 即上文 nginx 部署中引用的证书文件(`install/kubernetes/nginx-https/` 目录下已带一套示例)。生产环境应替换为受信任 CA 签发的正式证书。 --- ## 相关 - 平台外网地址、前端/配置文件位置:[配置文件管理.md](配置文件管理.md)。 - labelstudio host 改 https 属数据标注功能配置:[03-平台使用 / 数据标注](../03-平台使用/08-数据标注/)。 --- ### 加密与安全加固(交付加固清单 + containerd 镜像加密) - 链接: https://www.cubestudio.vip/docs/04-%E8%BF%90%E7%BB%B4%E7%AE%A1%E7%90%86/%E5%8A%A0%E5%AF%86%E4%B8%8E%E5%AE%89%E5%85%A8%E5%8A%A0%E5%9B%BA - 分类: 04-运维管理 / 安全加固 - 适用场景: 商业版/私有化交付前给系统做加固(去外网仓库、清源码、删kubeconfig),或需要对镜像做存储加密时读这篇 - 关键词: 加密 / 安全加固 / 商业化交付 / 镜像加密 / containerd / imgcrypt / ocicrypt / ctr-enc / 镜像存储加密 / encrypted image / image encryption / kubeconfig / history / 私有化部署 / security hardening - 最后更新: 2026-07-04 # 加密与安全加固 本篇汇总两类加固工作: - 商业化/私有化**交付加固清单**:交付前对系统、镜像、凭据、源码做的一次性收尾操作。 - **containerd 镜像存储加密**:基于 containerd `imgcrypt`/`ocicrypt` 的镜像层加密,保护镜像在仓库与磁盘上的存储安全。 > 来源:`install/kubernetes/rancher/加密/系统加密.md`、`install/kubernetes/rancher/加密/镜像存储加密.md`。 --- ## 一、交付加固清单 商业版交付(私有化、内网环境)前,按以下清单逐项收尾,目的是不泄露源码、不残留可被反向利用的凭据与外网仓库通道。 1. **编译加密版本代码,构建加密代码版本的镜像。** 即使用加密后的代码产出业务镜像,避免容器内可直接读到明文源码。镜像构建流程见 [06-二次开发 / 镜像构建总览](../06-二次开发/镜像构建/镜像构建总览.md)。 2. **对关键镜像做加密。** 需要加密的镜像包括:镜像名后缀含 `encryption` 的镜像,以及 `labelstudio`、`jupyter`、`vscode` 等镜像。加密方式见下文「containerd 镜像存储加密」。 3. **关闭外网仓库通道、收紧权限。** - 不使用外网仓库镜像,不在平台中配置仓库账号密码; - 仅下发**有限权限的 token**; - 去除 cluster 版本的 dashboard(避免暴露集群级管理面)。 4. **清理本地拉取的源码,并登出镜像仓库。** ```bash docker logout ccr.ccs.tencentyun.com ``` > `ccr.ccs.tencentyun.com/cube-studio/` 是 CubeStudio 的官方镜像仓库前缀(见 `myapp/config.py:978` `REPOSITORY_ORG`)。交付环境登出后即无法再从该仓库拉取。 5. **清空 shell 历史记录。** ```bash history -c && history -w ``` 6. **删除 kubeconfig,断开对集群的本地管理入口。** ```bash rm -rf ~/.kube/config ``` > kubekey 部署的 config 文件在 `/etc/kubernetes/admin.conf`,如需彻底收紧也要一并处理(注意:删除后本机将无法再用 `kubectl` 管理集群,请确认已无后续运维需求)。 7. **删除所有下载到本机的代码。** --- ## 二、containerd 镜像存储加密 > ⚠️ 重要前提:containerd 镜像加密**只能加密存储**(仓库里、磁盘上的镜像层是密文)。但镜像一旦在 k8s 中运行起来,仍然可以 `kubectl exec` 进入容器查看其中内容。因此它防的是“镜像被下载/落盘后被窃取源码或资产”,不防“运行态容器内查看”。 加密方案基于 containerd 官方的 [`imgcrypt`](https://github.com/containerd/imgcrypt)(`ocicrypt` 体系),命令行工具为 `ctr-enc`。 ### 2.1 为 containerd 安装 imgcrypt 插件 先安装指定版本 Go(按 CPU 架构二选一): ```bash # amd64 apt update wget https://mirrors.aliyun.com/golang/go1.23.0.linux-amd64.tar.gz sudo tar -C /usr/local -xzf go1.23.0.linux-amd64.tar.gz export PATH=/usr/local/go/bin:$PATH go version # arm64 apt update wget https://mirrors.aliyun.com/golang/go1.23.0.linux-arm64.tar.gz sudo tar -C /usr/local -xzf go1.23.0.linux-arm64.tar.gz export PATH=/usr/local/go/bin:$PATH go version ``` 从源码构建 imgcrypt(使用官方 `containerd.io` 包时通常需要这样自行构建): ```bash git clone -b v2.0.0 https://github.com/containerd/imgcrypt.git cd imgcrypt go env -w GOPROXY=https://goproxy.cn,direct make sudo make install ``` ### 2.2 配置 containerd 解密策略 编辑 `/etc/containerd/config.toml`: ```bash vi /etc/containerd/config.toml ``` 配置解密策略(如果类型是 pod,则需要在 k8s pod 上添加注释并挂载秘钥): ```toml [plugins."io.containerd.grpc.v1.cri".image_decryption] key_model = "node" ``` 配置解密步骤(stream processors): ```toml [stream_processors] [stream_processors."io.containerd.ocicrypt.decoder.v1.tar.gzip"] accepts = ["application/vnd.oci.image.layer.v1.tar+gzip+encrypted"] returns = "application/vnd.oci.image.layer.v1.tar+gzip" path = "ctd-decoder" args = ["--decryption-keys-path", "/etc/containerd/ocicrypt/keys"] env= ["OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf"] [stream_processors."io.containerd.ocicrypt.decoder.v1.tar"] accepts = ["application/vnd.oci.image.layer.v1.tar+encrypted"] returns = "application/vnd.oci.image.layer.v1.tar" path = "ctd-decoder" args = ["--decryption-keys-path", "/etc/containerd/ocicrypt/keys"] env= ["OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf"] ``` 重载并重启 containerd: ```bash systemctl daemon-reload systemctl restart containerd ``` ### 2.3 生成密钥对 ```bash openssl genrsa -out mykey.pem openssl rsa -in mykey.pem -pubout -out mypubkey.pem ``` - `mypubkey.pem`:公钥,用于**加密**镜像(推送方持有即可)。 - `mykey.pem`:私钥,用于**解密**镜像(运行节点持有,须保密)。 ### 2.4 加密镜像并推送到仓库 ```bash # 拉取原始镜像 ctr-enc --namespace k8s.io images pull ccr.ccs.tencentyun.com/cube-studio/kubeflow-dashboard:2026.07.01 # 用公钥加密镜像,输出一个 -encrypted 标签的镜像 ctr-enc --namespace k8s.io images encrypt \ --recipient=jwe:mypubkey.pem \ ccr.ccs.tencentyun.com/cube-studio/kubeflow-dashboard:2026.07.01 \ ccr.ccs.tencentyun.com/cube-studio/kubeflow-dashboard:2026.07.01-encrypted # 推送加密镜像 nerdctl --namespace k8s.io push ccr.ccs.tencentyun.com/cube-studio/kubeflow-dashboard:2026.07.01-encrypted ``` > 上面的镜像名/标签(`ccr.ccs.tencentyun.com/cube-studio/kubeflow-dashboard:2026.07.01`)只是示例,按实际镜像替换。 ### 2.5 验证加解密 ```bash # 用私钥解密回明文镜像 ctr-enc --namespace k8s.io images decrypt --key=mykey.pem \ ccr.ccs.tencentyun.com/cube-studio/kubeflow-dashboard:2026.07.01-encrypted \ ccr.ccs.tencentyun.com/cube-studio/kubeflow-dashboard:2026.07.01 # 不提供秘钥直接运行加密镜像 —— 会报错 ctr-enc --namespace k8s.io run --rm \ ccr.ccs.tencentyun.com/cube-studio/kubeflow-dashboard:2026.07.01-encrypted test ls # 提供秘钥运行加密镜像 —— 正常 ctr-enc --namespace k8s.io run --rm --key mykey.pem \ ccr.ccs.tencentyun.com/cube-studio/kubeflow-dashboard:2026.07.01-encrypted test echo 'Hello World!' ``` ### 2.6 k8s 节点侧解密配置 在需要运行加密镜像的节点上,把秘钥放到 containerd 约定目录并重启: ```bash mkdir -p /etc/containerd/ocicrypt/keys /run/containerd/ocicrypt/keys/ cp mykey.pem /etc/containerd/ocicrypt/keys/ cp mypubkey.pem /etc/containerd/ocicrypt/keys/ cp -r /etc/containerd/ocicrypt/keys/* /run/containerd/ocicrypt/keys/ systemctl restart containerd # 节点拉取加密镜像(带私钥) ctr-enc --namespace k8s.io images pull --key mykey.pem \ ccr.ccs.tencentyun.com/cube-studio/kubeflow-dashboard:2026.07.01-encrypted ``` ### 2.7 k8s Deployment 示例 节点完成解密配置后,直接像普通镜像一样在 Deployment 中引用加密镜像即可: ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: myapp spec: replicas: 1 selector: matchLabels: app: myapp template: metadata: labels: app: myapp spec: containers: - name: main image: ccr.ccs.tencentyun.com/cube-studio/kubeflow-dashboard:2026.07.01-encrypted imagePullPolicy: IfNotPresent command: ["sleep","1000000"] ``` --- ### 多租户隔离(ENABLE_MULTI_TENANT) - 链接: https://www.cubestudio.vip/docs/04-%E8%BF%90%E7%BB%B4%E7%AE%A1%E7%90%86/%E5%A4%9A%E7%A7%9F%E6%88%B7%E9%9A%94%E7%A6%BB - 分类: 运维管理 / 多租户 - 适用场景: 需要让平台按"组织/租户"隔离数据(不同组织看不到彼此的项目组/任务/机器/存储等)、或想了解多租户开启后谁能看到什么时读这篇 - 关键词: 多租户 / multi-tenant / ENABLE_MULTI_TENANT / 租户隔离 / org / 组织 / 租户管理员 / 系统管理员 / is_system / is_admin / 数据隔离 / 项目组隔离 / 机器隔离 / 存储隔离 / SaaS / 私有化多组织 - 最后更新: 2026-06-30 # 多租户隔离(ENABLE_MULTI_TENANT) 平台支持多租户模式:开启后,不同"租户(组织)"之间的数据互相隔离,适合一套平台给多个组织/团队使用。 默认**关闭**(`ENABLE_MULTI_TENANT=False`,见 `myapp/config.py:766`)。 ## 租户怎么划分 - 租户由用户的 **`org`(组织标识)** 字段决定:**`org` 相同的用户属于同一租户**(见 `myapp/security.py:64`)。 - `org` 在「用户列表」里维护;多租户开启后,非系统用户的 `org` 字段在表单中只读,默认就是自己的 `org` (`myapp/security.py:334-343`)。 ## 三种可见范围 多租户开启后,几乎所有业务列表都会按下面的规则过滤(每个视图各有一个 `*_Filter`,逻辑一致, 可参考 `myapp/views/view_notebook.py:51-54`、`view_inferenceserving.py` 等): | 身份 | 判定 | 能看到 | |---|---|---| | **系统管理员** | `username=='admin'` 或 `org=='system'` 或 `org` 为空(`is_system()`,`myapp/security.py:144`) | **全部租户**的数据 | | **租户管理员** | 该租户内的 admin 角色(`is_admin()`) | **本租户(同 org)**的数据 | | 普通用户 | 其余 | 主要是**自己**的数据(叠加项目组/责任人等既有权限) | > 即:`org='system'` 或用户名 `admin` 是跨租户的"超级管理员";每个租户内再设自己的 admin 作为"租户管理员"。 ## 影响范围 多租户过滤覆盖几乎所有资源视图(约 35 个),包括:项目组、机器/节点资源、存储资源、Notebook、 任务流/任务、推理服务/内部服务、模型、数据集/维表/库表、镜像、消息、账单、整体资源等 (即 `myapp/views/` 下大量 `view_*.py` 都引用了 `ENABLE_MULTI_TENANT`)。**具体每个模块的过滤细节以对应 `view_*.py` 中的 `*_Filter` 为准。** ## 启用步骤 1. 在 `config.py` 设 `ENABLE_MULTI_TENANT=True`。 2. 给各用户设置 `org`(同组织同值);跨租户的超级管理员用 `admin` 或把 `org` 设为 `system`。 3. 每个租户内指定该租户的 admin 角色用户作为租户管理员。 4. 重启后端生效。 > 相关:项目组专属命名空间 `ENABLE_SPECIFY_NAMESPACE`(`config.py:784`)可与多租户配合做更强的 > K8s 命名空间级隔离,见 [配置项速查.md](../07-参考速查/配置项速查.md)。 --- ### 平台定时任务与自动清理(Celery beat) - 链接: https://www.cubestudio.vip/docs/04-%E8%BF%90%E7%BB%B4%E7%AE%A1%E7%90%86/%E5%AE%9A%E6%97%B6%E4%BB%BB%E5%8A%A1%E4%B8%8E%E8%87%AA%E5%8A%A8%E6%B8%85%E7%90%86 - 分类: 运维管理 / 定时任务 - 适用场景: 想知道平台有哪些后台定时任务(自动清理/资源均衡/账单/伸缩)、它们什么时间跑、默认是否启用,或排查"我的 pod/调试镜像/数据为什么被自动清理"时读这篇 - 关键词: 定时任务 / celery / celery beat / crontab / 自动清理 / 资源回收 / 自动维护 / 定时调度 / delete_workflow / delete_old_data / delete_debug_docker / check_pod_terminating / watch_pod_utilization / day_bill / cronhpa / make_timerun_config / adjust_node_resource / 为什么pod被清理 / 自动停止notebook - 最后更新: 2026-06-30 # 平台定时任务与自动清理(Celery beat) 平台用 Celery beat 跑一批后台定时任务(自动清理、资源调度、账单等)。调度表定义在 `myapp/config.py` 的 `CeleryConfig.beat_schedule`(约 `:691-755`),任务实现在 `myapp/tasks/`。 **这些任务需要 Celery beat + worker 进程在运行**(容器/部署中通常随后端一起启动)。 ## 默认启用的定时任务 | 任务 | 调度(crontab) | 作用 | |---|---|---| | `task.delete_workflow` | 每小时第 1 分 | 删除旧的 Argo workflow 记录 | | `task.make_timerun_config` | 每 5 分钟 | 生成 pipeline 定时调度的 yaml(让定时任务流按时触发) | | `task.cronhpa` | 每 5 分钟 | 定时弹性伸缩(cronhpa,按时间段对服务扩缩容) | | `task.delete_old_data` | 每天 01:01 | 删除数据库中的旧数据/历史记录 | | `task.check_pipeline_run` | 每天 11:10 | 检查 pipeline 运行时长(超时提醒) | | `task.delete_debug_docker` | 每天 23:30 | **删除镜像调试的 debug pod**(调试镜像不会一直留着) | | `task.watch_pod_utilization` | 每天 11:10 | 推送低负载利用率的 pod(提醒释放资源) | | `task.check_pod_terminating` | 每 30 分钟 | 检查并处理卡在 terminating 的 pod | | `task.day_bill` | 每天 03:10 | 生成每日资源账单(计量计费) | > 排障提示:如果发现「调试镜像 pod 半夜消失」「旧 workflow/数据被清掉」「收到低负载 pod 提醒」, > 通常就是上面这些定时任务的正常行为,不是故障。 ## 默认禁用的定时任务(在 config.py 中被注释) 需要时在 `beat_schedule` 中取消注释即可启用: | 任务 | 调度(crontab) | 作用 | |---|---|---| | `task.delete_notebook` | 每天 04:01 | 定时停止 notebook,释放资源 | | `task.push_workspace_size` | 每天 10:10 | 推送用户工作目录文件大小 | | `task.watch_gpu` | 8-23 点每 2 小时 | 推送 GPU 使用情况 | | `task.adjust_node_resource` | 每 10 分钟 | 在多项目组间做节点资源均衡 | | `task.adjust_service_resource` | 每 10 分钟 | 把资源释放给高优先级推理服务 | | `task.adjust_pipeline_resource` | 每 10 分钟 | 把资源释放给高优先级训练任务 | > `myapp/tasks/` 下还有更多任务函数(异步/被动触发,不一定在 beat 调度里)。要确认某任务的确切行为, > 直接看 `myapp/tasks/` 对应实现;调度时间以 `myapp/config.py` 的 `beat_schedule` 为准。 --- ### 监控部署与看板(Prometheus + Grafana) - 链接: https://www.cubestudio.vip/docs/04-%E8%BF%90%E7%BB%B4%E7%AE%A1%E7%90%86/%E7%9B%91%E6%8E%A7%E9%83%A8%E7%BD%B2%E4%B8%8E%E7%9C%8B%E6%9D%BF - 分类: 运维管理 / 监控 - 适用场景: 在 Kubernetes 集群上从零部署 Prometheus/Grafana 监控体系,更新 Grafana 配置,或查看平台各类监控看板时阅读 - 关键词: 监控 / monitoring / prometheus / prometheus-operator / grafana / alertmanager / node-exporter / kube-state-metrics / servicemonitor / dcgm / gpu监控 / prometheus-adapter / 看板 / dashboard / configmap - 最后更新: 2026-07-04 # 监控部署与看板(Prometheus + Grafana) CubeStudio 的监控体系基于 prometheus-operator 搭建,组件包含: - prometheus-operator:以 CRD 方式管理 Prometheus/Alertmanager 实例 - Alertmanager:报警分发 - node-exporter:采集节点(机器)层指标 - kube-state-metrics:采集 K8s 对象状态指标 - ServiceMonitor:声明 Prometheus 的采集目标 - DCGM exporter:采集 GPU 指标 - prometheus-adapter:把 Prometheus 指标暴露为 K8s custom metrics(供 HPA 使用) - Grafana:监控看板展示 所有部署文件位于 `install/kubernetes/prometheus/` 目录下。下文所有 `kubectl apply -f ./xxx` 命令均以该目录为工作目录,执行前请先: ```bash cd install/kubernetes/prometheus ``` > 注意:仓库中报警相关目录名为 `alertmanater`(拼写如此),下文命令保持与实际目录一致。 ## 1. 前置准备 为需要部署监控组件(node-exporter、pushgateway 等)的机器打 label。监控组件通过 `monitoring=true` 的节点亲和性进行调度,机器准备/打 label 的相关说明见 [02-部署安装](../02-部署安装/)(集群准备)。 ```bash kubectl label node xxx monitoring=true ``` 创建命名空间: ```bash kubectl create ns monitoring ``` ## 2. 部署 prometheus-operator ```bash kubectl apply -f ./operator/operator-rbac.yml kubectl apply -f ./operator/operator-dp.yml kubectl apply -f ./operator/operator-crd.yml ``` ## 3. Alertmanager、node-exporter、kube-state-metrics 创建 Alertmanager 配置(定义报警方式)、node-exporter(节点指标)、kube-state-metrics(K8s 对象指标): ```bash kubectl apply -f ./alertmanater/alertmanager-main-sa.yml kubectl apply -f ./alertmanater/alertmanager-main-secret.yml kubectl apply -f ./alertmanater/alertmanager-main-svc.yml kubectl apply -f ./alertmanater/alertmanager-main.yml kubectl apply -f ./node-exporter/node-exporter-sa.yml kubectl apply -f ./node-exporter/node-exporter-rbac.yml kubectl apply -f ./node-exporter/node-exporter-svc.yml kubectl apply -f ./node-exporter/node-exporter-ds.yml kubectl apply -f ./kube-state-metrics/kube-state-metrics-sa.yml kubectl apply -f ./kube-state-metrics/kube-state-metrics-rbac.yml kubectl apply -f ./kube-state-metrics/kube-state-metrics-svc.yml kubectl apply -f ./kube-state-metrics/kube-state-metrics-dp.yml ``` ### 配置报警接收方(邮件 / 企业微信) 上面 apply 的 `alertmanager-main-secret.yml` 里存的是 Alertmanager 配置(base64 编码)。要配置邮件或企业微信报警接收方,用仓库 `install/kubernetes/prometheus/alertmanater/` 下的两个脚本生成这段 base64: - **邮件**:编辑 `make-alert-email-config.py` 里的 `config`——全局 `smtp_smarthost` / `smtp_from` / `smtp_auth_username` / `smtp_auth_password`,以及 `receivers` 下 `email_configs` 的收件人 `to`;运行 `python make-alert-email-config.py`,把打印出的 base64 串填入 `alertmanager-main-secret.yml` 的 secret data,再 `kubectl apply` 一次。 - **企业微信 / webhook**:`make-alert-wechat-config.py` 同理,但用的是 `webhook_configs`(`url` 指向企业微信机器人或自建的报警转发 webhook);改好 `url` 后运行、取 base64、填 secret、apply。 > `route.routes` 里的 `match` / `match_re`(如按 `namespace` 匹配)决定哪些告警走哪个 receiver;`inhibit_rules` 做告警抑制避免重复告警。改完重新 apply secret 后 Alertmanager 会重载配置。 ## 4. 部署 Grafana 按照自己的分布式存储创建 PV,再部署 Grafana 相关资源(定义数据源、显示方式): ```bash # 按照自己的分布式存储创建pv kubectl apply -f ./grafana/pv-pvc-hostpath.yml kubectl apply -f ./grafana/grafana-sa.yml kubectl apply -f ./grafana/grafana-source.yml kubectl apply -f ./grafana/grafana-datasources.yml kubectl apply -f ./grafana/grafana-admin-secret.yml kubectl apply -f ./grafana/grafana-svc.yml ``` 创建 Grafana 配置与看板的 configmap,然后部署 Grafana 及服务发现 svc: ```bash kubectl create configmap grafana-config --from-file=./grafana/grafana.ini --namespace=monitoring kubectl create configmap all-grafana-dashboards --from-file=./grafana/dashboard --namespace=monitoring kubectl apply -f ./grafana/grafana-dp.yml kubectl apply -f ./service-discovery/kube-controller-manager-svc.yml kubectl apply -f ./service-discovery/kube-scheduler-svc.yml ``` Grafana 默认管理员账号/密码均为 `admin / admin`(定义于 `grafana/grafana-admin-secret.yml`,base64 编码的 `admin`,通过 `GF_SECURITY_ADMIN_USER`/`GF_SECURITY_ADMIN_PASSWORD` 注入)。Service 端口为 `8080`;如需从集群外访问,可在 `grafana/grafana-svc.yml` 中放开 `type: NodePort` 与 `nodePort`(默认被注释)。 ## 5. 部署 Prometheus 自定义配置文件,定义采集和报警规则: ```bash kubectl apply -f ./prometheus/prometheus-secret.yml kubectl apply -f ./prometheus/prometheus-rules.yml kubectl apply -f ./prometheus/prometheus-rbac.yml kubectl apply -f ./prometheus/prometheus-svc.yml ``` prometheus-operator 部署成功后才能成功创建 Prometheus 实例: ```bash kubectl apply -f ./prometheus/pv-pvc-hostpath.yaml kubectl apply -f ./prometheus/prometheus-main.yml ``` ## 6. 配置监控目标 ServiceMonitor ServiceMonitor 声明 Prometheus 的采集目标。注意:采集目标的 label 必须是 `k8s-app`,因为 Prometheus 按这个标签查找,否则采集不到该资源。 ```bash # kubelet监控,请先确保每个节点的kubelet 添加了 authentication-token-webhook=true 和 authorization-mode=Webhook 参数 kubectl apply -f ./servicemonitor/alertmanager-sm.yml kubectl apply -f ./servicemonitor/coredns-sm.yml kubectl apply -f ./servicemonitor/kube-apiserver-sm.yml kubectl apply -f ./servicemonitor/kube-controller-manager-sm.yml kubectl apply -f ./servicemonitor/kube-scheduler-sm.yml kubectl apply -f ./servicemonitor/kubelet-sm.yml kubectl apply -f ./servicemonitor/kubestate-metrics-sm.yml kubectl apply -f ./servicemonitor/node-exporter-sm.yml kubectl apply -f ./servicemonitor/prometheus-operator-sm.yml kubectl apply -f ./servicemonitor/prometheus-sm.yml kubectl apply -f ./servicemonitor/pushgateway-sm.yml ``` ## 7. 部署 GPU 监控 GPU 指标由 DCGM exporter(DaemonSet)采集,配套的 Grafana GPU 看板模板为 `install/kubernetes/prometheus/grafana/dashboard/dcgm.json`。 ```bash # 注意:源 readme 写的是 ./gpu/dcgm-exporter.yaml,但 prometheus/ 下并无 gpu 子目录, # 实际部署文件在上一级的 install/kubernetes/gpu/dcgm-exporter.yaml,因此从 prometheus 目录执行时用 ../gpu kubectl apply -f ../gpu/dcgm-exporter.yaml ``` DCGM exporter 部署详情(DaemonSet,命名空间 `monitoring`,镜像 `nvidia/dcgm-exporter:3.1.7-3.1.4-ubuntu20.04`)见 `install/kubernetes/gpu/dcgm-exporter.yaml`。GPU 节点接入与驱动准备见 [02-部署安装/GPU与异构算力](../02-部署安装/GPU与异构算力/)。 ## 8. 部署 prometheus-adapter prometheus-adapter 将 Prometheus 指标转换为 K8s custom metrics,供 HPA 等组件按自定义指标扩缩容: ```bash kubectl apply -f ./prometheus_adapter/metric_rule.yaml kubectl apply -f ./prometheus_adapter/prometheus_adapter.yaml ``` adapter 目录还提供: - `metric_rule.yaml`:把 Prometheus 指标映射为 `custom.metrics` 的规则;`metric_rule_more.yaml` 是更多指标规则的扩展,按需追加 apply。 - `prometheus_adapter-arm64.yaml`:arm64 架构的 adapter 部署变体(国产化/ARM 集群用它替代 `prometheus_adapter.yaml`)。 - `hpa-demo.yaml`:基于**自定义指标**做 HPA 的示例——对一个 Deployment 按 Pods 指标 `container_gpu_usage` 扩缩容(所有 pod 该指标均值超过 `targetAverageValue` 就加一个副本)。 这样推理服务/任务就能按 GPU 利用率、QPS 等自定义指标弹性伸缩(与 [平台架构-推理服务](../01-架构原理/平台架构-推理服务.md) 的 HPA 一节配合)。custom.metrics 是否生效可用 `kubectl get --raw /apis/custom.metrics.k8s.io/v1beta1` 验证。 ## 9. Grafana 配置更新 修改 `grafana.ini` 后需要删除旧 configmap 再重建(在 `install/kubernetes/prometheus/grafana/` 目录下执行),重建后重启 Grafana Deployment 生效: ```bash cd install/kubernetes/prometheus/grafana kubectl delete -n monitoring configmaps grafana-config kubectl create configmap grafana-config --from-file=./grafana.ini --namespace=monitoring kubectl delete -n monitoring configmaps grafana-defaults-config kubectl create configmap grafana-defaults-config --from-file=./defaults.ini --namespace=monitoring ``` > ⚠️ 待核实:`grafana-defaults-config --from-file=./defaults.ini` 中的 `defaults.ini` 在仓库 `grafana/` 目录下不存在,且 `grafana-dp.yml` 只挂载了 `grafana-config`、`grafana-datasources`、`grafana-dashboards`、`all-grafana-dashboards` 四个 configmap,未引用 `grafana-defaults-config`。该命令可能为历史遗留或可选项,见 `install/kubernetes/prometheus/grafana/readme.md:4-5`,请确认。 ## 10. 看板查看 部署完成后,登录 Grafana 即可查看以下内置看板。 ### 所有机器的负载情况 ![所有机器负载1](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/grafana-allnode1.png) ![所有机器负载2](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/grafana-allnode2.png) ### 单个机器的资源和应用使用情况 ![单机资源1](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/grafana-node1.png) ![单机资源2](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/grafana-node2.png) ### GPU 资源的使用情况 ![GPU资源](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/grafana-gpu.png) ### Pod 的资源使用情况 ![Pod资源](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/grafana-pod.png) ### 推理服务的流量负载和资源使用情况 ![推理服务](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/docs/image/grafana-service.png) ## 相关文档 - 监控体系的架构与原理(Prometheus/Operator、机器与容器监控、ServiceMonitor、告警与 Grafana)见 [01-架构原理/监控体系](../01-架构原理/监控体系/)。 - 自定义指标推送与报警代理见 [监控指标推送-pushgateway](监控指标推送-pushgateway.md)。 --- ### 监控指标推送与报警代理(cloud-pushgateway) - 链接: https://www.cubestudio.vip/docs/04-%E8%BF%90%E7%BB%B4%E7%AE%A1%E7%90%86/%E7%9B%91%E6%8E%A7%E6%8C%87%E6%A0%87%E6%8E%A8%E9%80%81-pushgateway - 分类: 运维管理 / 监控 - 适用场景: 需要把自定义业务指标推送给 Prometheus,或把报警转发到微信/企业微信群时阅读 - 关键词: pushgateway / cloud-pushgateway / 自定义指标 / custom metrics / prometheus / 指标推送 / 报警代理 / webhook / 企业微信 / wechat / alertmanager / grafana webhook - 最后更新: 2026-06-30 # 监控指标推送与报警代理(cloud-pushgateway) cloud-pushgateway 是平台自研的指标网关服务(非官方 prometheus pushgateway),提供两类能力: 1. 接收自定义指标的 POST 推送,按策略合并后以 Prometheus 文本格式对外暴露 `/metrics` 供采集; 2. 作为报警推送代理,把外部系统(Grafana / Alertmanager / Rancher 等)的 webhook 报警转发到微信或企业微信群。 部署相关文件在 `install/kubernetes/prometheus/pushgateway/`: - 镜像:`ccr.ccs.tencentyun.com/cube-studio/prometheus:pushgateway` - 服务监听端口:`80`(`util/config.py` 中 `LOCAL_SERVER_PORT=80`,容器 `containerPort: 80`) - 默认 sender:环境变量 `sender`,默认 `TME_DataInfra`;默认推送类型 `Sender_type` 默认 `wechat` - 调度:通过节点亲和性 `monitoring=true` 调度(与监控组件同机器,部署见 [监控部署与看板](监控部署与看板.md)) ## 1. Prometheus 指标推送 向 `POST /metrics` 推送数据,请求体为 JSON,外层含 `type` 与 `metrics` 两个字段(服务端读取 `data['metrics']`)。 post 数据格式: ``` type:'prometheus' metrics: { 'metric_name1':{ 'lables':['method', 'clientip'], 'describe':'this is test', 'exist_not_update_type':'clear', 'exist_update_type':'update', 'not_exist_update_type':'add', 'pull_finish_deal_type':'clear', 'data':[ [['get','192.168.11.127'],4], [['get','192.168.12.49'],3], [['post','192.168.11.127'],5] ] }, 'metric_name2':{ } } ``` > 说明:源 README 示例中此处写的是 `push_deal_type`,与服务端代码不符,已按代码改正为 `pull_finish_deal_type`(见 `install/kubernetes/prometheus/pushgateway/util/prometheus_util.py:39`,服务端读取的 key 为 `pull_finish_deal_type`)。 各策略字段含义: - `exist_not_update_type`(已存在但本次未更新的数据) - `exist_update_type`(已存在且本次更新的数据) - `not_exist_update_type`(本次新出现的数据) - `pull_finish_deal_type`(数据被拉取以后的处理行为) 可选取值: ``` # update 覆盖原有值 # clear 删除属性 # keep 保留原状态 # add 属性的 value 累加 # reset 属性的值设置为 0 ``` > 说明:服务端对 `exist_not_update_type` 实现了 `clear`/`reset`;对 `exist_update_type` 实现了 `update`/`add`/`clear`/`reset`;对 `not_exist_update_type` 实现了 `reset`/`add`/`update`;对 `pull_finish_deal_type` 实现了 `clear`/`reset`。`keep`(保留原状态)即不命中上述分支时的默认行为。详见 `install/kubernetes/prometheus/pushgateway/util/prometheus_util.py:72-156`。 服务端(Python)内部存储结构(`data` 由数组转为按 label 元组索引的字典): ``` { 'metric_name1':{ 'lables':['method', 'clientip'], 'describe':'this is test', 'exist_not_update_type':'clear', 'exist_update_type':'update', 'not_exist_update_type':'add', 'data':{ ('get','192.168.11.127'):4, ('get','192.168.12.49'):3, ('post','192.168.11.127'):5 } }, 'metric_name2':{ } } ``` Prometheus 通过 `GET /metrics` 拉取(返回 `text/plain` 文本格式),拉取后会按 `pull_finish_deal_type` 对数据做后处理。 ## 2. 报警推送代理 POST 访问接口 `/{client}/webhook`,其中 `{client}` 为来源系统标识(如 `grafana`、`alertmanager`、`rancher`、`superset` 等,会做来源特定的消息格式化;其他值按通用方式处理)。 参数(可放在 query 或 JSON body 中): - `sender_type`:字符串。推送类型,目前支持 `wechat` 和 `username_group`(企业微信群)。 - `sender`:字符串。推送者(微信场景为 `TME_DataInfra` 之类的发送方;企业微信群场景为群机器人 key)。 - `username`:字符串。接收用户(逗号分隔多用户)。微信推送时为接收人 username;企业微信群推送时为空。 - `message`:推送字符串。若带 `message` 字段则仅推送 `message`;否则除上述参数外的所有字段会 JSON 序列化为 message 推送。 示例(向 `juno` 来源推送一条微信消息): ```bash curl -H 'Content-type: application/json' -X POST \ -d '{"message":"'"${MY_POD_NAME}"' juno restart"}' \ 'http:///juno/webhook?username=pengluan&sender_type=wechat' ``` 推送实现说明(见 `install/kubernetes/prometheus/pushgateway/server.py:40-80`): - `sender_type=wechat`:调用微信公众号告警接口,按 `username`(接收人)做个人推送,需要同时有 sender、receiver、message。 - `sender_type=username_group`:向企业微信群机器人 webhook 推送,`sender` 为群机器人 key,`message` 为文本内容(此时 username 为空)。 > 备注:除 `/{client}/webhook` 外,服务端还提供 `POST /junopodstop/customwebhook`(按 `username`+`message` 直接推送),以及 `GET /`(健康检查,返回 `OK`)。 ## 相关文档 - 自定义指标与 pushgateway 的设计原理见 [01-架构原理/监控体系/04-自定义指标与pushgateway](../01-架构原理/监控体系/04-自定义指标与pushgateway.md)。 - 监控整体部署、Grafana 看板见 [监控部署与看板](监控部署与看板.md)。 --- ### 故障恢复 - Rancher RKE 集群时间回拨 - 链接: https://www.cubestudio.vip/docs/04-%E8%BF%90%E7%BB%B4%E7%AE%A1%E7%90%86/%E6%95%85%E9%9A%9C%E6%81%A2%E5%A4%8D-%E9%9B%86%E7%BE%A4%E6%97%B6%E9%97%B4%E5%9B%9E%E6%8B%A8 - 分类: 04-运维管理 / 故障恢复 - 适用场景: 服务器重启后大量 Pod 异常、apiserver 报 token "未来签发"、docker ps 显示控制面容器 "Up Less than a second" 时读这篇 - 关键词: 时间回拨 / time skew / clock skew / 时钟 / RTC / set-local-rtc / timedatectl / Rancher / RKE / token not valid yet / service account token is not valid yet / apiserver 拒绝认证 / 双系统 / UTC / NTP / kubelet / k8s 容器 / 故障恢复 / 重启异常 - 最后更新: 2026-06-30 # Rancher RKE 集群时间回拨恢复 > 来源:`install/kubernetes/rancher/rancher-rke-time-skew-recovery.md`。本篇为故障恢复运维文档,命令均针对 Rancher RKE 部署(容器化控制面 + RKE kubeconfig 路径)。 ## 现象 服务器重启后,`docker ps` 控制面容器显示 `Up Less than a second`,大量 Pod 异常,kube-apiserver 报 `service account token is not valid yet`。 ## 原因 双系统(Windows + Linux)或 BIOS 用本地时间存 RTC,Linux 默认按 UTC 读取,导致开机时系统时间多 8 小时。Docker/K8s 在错误时间下启动,NTP 修正后 token 变成"未来签发",apiserver 拒绝认证。 ## 根治:防止再次发生 ```bash # 告诉 Linux 硬件时钟存的是本地时间,只需执行一次 sudo timedatectl set-local-rtc 1 ``` ## 恢复步骤 ```bash # 1. 用 RKE kubeconfig 查看集群状态 sudo kubectl --kubeconfig /etc/kubernetes/ssl/kubecfg-kube-node.yaml get node -o wide sudo kubectl --kubeconfig /etc/kubernetes/ssl/kubecfg-kube-node.yaml get pod -A # 2. 备份 k8s 容器列表 sudo docker ps -a --format "{{.ID}} {{.Names}} {{.Status}}" | awk '$2 ~ /^k8s_/ {print}' | sudo tee /tmp/k8s-containers-before-cleanup.txt # 3. 停 kubelet → 清理 k8s_ 容器 → 启 kubelet sudo docker stop kubelet sudo docker ps -a --format "{{.ID}} {{.Names}}" | awk '$2 ~ /^k8s_/ {print $1}' | xargs -r sudo docker rm -f sudo docker start kubelet # 4. 等待 Pod 重建 sleep 60 sudo kubectl --kubeconfig /etc/kubernetes/ssl/kubecfg-kube-node.yaml get pod -A # 5. 修正控制面容器的时间显示(可选,仅解决 docker ps 显示问题) sudo docker restart etcd && sleep 8 sudo docker restart kube-apiserver && sleep 8 sudo docker restart kube-controller-manager kube-scheduler kube-proxy # 6. 验证 sudo kubectl --kubeconfig /etc/kubernetes/ssl/kubecfg-kube-node.yaml get pod -A | awk 'NR==1 || ($4 != "Running" && $4 != "Completed") {print}' sudo docker ps --format "{{.Names}} {{.Status}}" | egrep "^(etcd|kube-apiserver|kubelet|kube-proxy|kube-scheduler|kube-controller-manager|myrancher) " ``` ## 注意 - 只删 `k8s_` 开头的 Pod 容器,不要 `docker rm -f $(docker ps -aq)`,会误删控制面容器。 - 不会删除 etcd 数据、Docker volume、PVC、镜像,MySQL/PostgreSQL/MinIO 等数据不受影响。 - 宿主机直接 `kubectl` 报 `localhost:8080 refused` 是因为没加 `--kubeconfig`,不代表集群挂了。 --- ### 常见问题 FAQ - 链接: https://www.cubestudio.vip/docs/04-%E8%BF%90%E7%BB%B4%E7%AE%A1%E7%90%86/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98FAQ - 分类: 04-运维管理 / 常见问题 - 适用场景: 部署、构建、网络、GPU、功能使用、配置运维等遇到报错或疑问时,先在这里按问题域查 - 关键词: FAQ / 常见问题 / 故障排查 / troubleshooting / 部署问题 / 镜像拉取失败 / istio / 网关 / 证书 / GPU / vgpu / notebook / pipeline / 服务化 / 数据ETL / 配置文件 / config.py / 商业版 / 开源版 / 502 / 301 / 404 / no healthy upstream - 最后更新: 2026-07-09 # 常见问题 FAQ 本篇由社区常见问答整理而来,按问题域分组。每条以 `Q:` 提问、随后给出答复。涉及具体配置项/路径处已对照当前代码核实,发现与代码不一致的地方用 ⚠️ 标出。 > 来源:`docs/运维/常见问题.csv`(约 150 条)。 --- ## 一、部署与安装 ### Q: 单机部署 rancher 之后进不去 web 页面 如果是刚部署完就进不去 web 界面,可能是 rancher server 还没启动起来,稍等片刻。如果是运行一段时间后突然进不去,或因 docker 重启、机器重启等原因进不去,可参考 wiki 中 rancher 部署 k8s 部分的文章,配置 rancher 的单机高可用。 ### Q: rancher 单集群多机一直卡在 "Waiting to register with Kubernetes" 机器需要先把镜像拉取好,再加入 k8s 集群,这样加入集群会快很多。 ### Q: rancher 主机注册的时候一直卡在 "[remove/etcd-fix-perm] Successfully removed container on host" rancher 部署时会自动在机器上部署 agent 来完成 k8s 节点初始化。部署需要提前拉取好镜像,准备至少 16 核的机器;如果部署失败,使用 `reset_docker` 脚本重置 docker 后重启,再重新部署。 ### Q: rancher 创建失败,等了好久也不成功,"Cluster health check failed: cluster agent is not ready" 同上:rancher 部署会自动部署 agent 完成节点初始化。需提前拉取镜像、准备至少 16 核机器,失败则用 `reset_docker` 脚本重置 docker 后重启重新部署。 ### Q: 搭建单机版出现 "cluster health check failed cluster agent is not ready" 机器资源问题。提前拉取镜像,`reset_docker` 重置 docker 重启后重试。 ### Q: myrancher 运行 docker 启动后不断重启 可能是资源不足造成,建议扩大资源至少 16 核,然后按 wiki 中 rancher 单机高可用方案部署。 ### Q: 机器重启或机器上的 docker 服务重启后,rancher web 界面打不开了 这是 rancher 的一个 bug,需参考 wiki 部署 rancher 文章中的单机高可用方案来解决。 ### Q: 单机版部署 rancher 后无法访问 web 页面,日志出现 "error syncing 'validating-webhook-configuration': handler need-a-cert" 建议提前拉取镜像后重新部署,并把 iptables 放开。 ### Q: rancher 部署的时候不成功,等了很久一直失败 需提前拉取好镜像、准备至少 16 核机器,失败则用 `reset_docker` 脚本重置 docker 后重启重新部署。 ### Q: rancher 443 拒绝访问 rancher server 是第一个运行的容器(即 rancher web 界面),部署可能需要等待几秒钟;并且打开 web 界面时要跳过 https 限制。 ### Q: 目前最新版用哪个 rancher 和 kubernetes 版本好? rancher 2.6.2、k8s 1.21 最好。 ### Q: K8S 高版本的支持 目前支持 1.18 到 1.24 的 k8s 版本。高低版本部分组件要微调,可参考 start 脚本中的内容。 ### Q: sudo sh start.sh x.x.x.x 这种安装方式是不是只适用单机通过 rancher 安装?已有 k8s 集群能用吗? 已有的 k8s 集群也是这种安装方式。 ### Q: 运行 start.sh 安装时报错 如果报“删除对象不存在”可以忽略;如果报“api server 服务不可达”,检查 config 文件是否正常、是否能正常下载 kubectl。start 脚本会先拉取镜像和基础软件,然后按步骤安装云原生基础组件,最后配置 istio ingressgateway 代理。详见 `start.sh` 脚本内容。 ### Q: start 脚本部署不完整,缺部分组件(本地虚拟机资源不足?connection refused) start 脚本可以重复多次运行,多运行几次即可;部署前提前把镜像拉取好。 ### Q: worker 节点的机器上是否需要 pull_image_kubeflow.sh 里的镜像? 是的,worker 节点上需要拉取镜像,并为机器打上对应的 tag。 ### Q: 多机器部署时,worker 需不需要运行 start.sh? worker 节点不需要运行 start.sh,只需要把 worker 节点加入到 k8s 集群即可。 ### Q: 部署后 kubeflow dashboard 报错 mysql 数据库链接不上,域名无法解析 应该是机器防火墙的问题,可用以下命令放开防火墙;由于各家公司网络可能会自动恢复,iptables 的放开可以设为定时任务: ```bash iptables -P FORWARD ACCEPT iptables -P INPUT ACCEPT iptables -P OUTPUT ACCEPT ``` ### Q: core-dns 出错,service name 无法解析,集群启动但 pod 之间无法通信 同样是机器防火墙的问题,用上面的 `iptables -P ... ACCEPT` 放开防火墙,并把放开设为定时任务防止被自动恢复。 ### Q: myapp-1 docker 运行启动后不断重启 myapp 容器不断重启有可能是连不上数据库,可根据日志信息提供更多内容排查。 ### Q: myapp fab create-admin 报错 `create-admin` 是初始化阶段创建数据库 admin 账户,如果之前已经存在 admin 会报错,可以忽略。 ### Q: 单机部署 myapp/home 无法进入 / 访问 http://xxxx/mysqpp/home 进不去 新版本首页不是 `myapp/home`,直接用 `http + ip` 访问会自动跳转到首页。如果进不去,按 wiki “单机部署”文章末尾的部署后排查流程逐步排查。 ### Q: 部署后 some namespaces without pods `pipeline`、`service`、`jupyter`、`automl` 这些命名空间是预留给用户应用的,并非系统应用占用,所以刚部署起来后是没有 pod 的,属正常现象。 ### Q: 平台部署完成后 ml-pipeline-viewer-crd 起不来,demo 跑不起来 新版本已不再需要 `ml-pipeline-viewer-crd`,建议部署新版本。 ### Q: metadata-grpc-deployment 报错 "mysql_real_connect failed ... Unknown MySQL server host 'mysql-service.infra'" 新版本已不再使用 metadata-grpc 服务,建议升级到新版本。 ### Q: 部署后 kubeflow-dashboard 一直报错缺 ab_user_role 表 如果是新部署的集群,可从主机 `/data/k8s/infra/mysql` 删除 mysql 的存储,然后重新用 start 脚本部署 CubeStudio。 ### Q: stat /data/k8s/kubeflow/pipeline/workspace: no such file or directory `/data/k8s/` 是分布式存储目录,单机部署时可以是主机目录。先确保主机该目录存在,并且 `docker start kubelet` 后保证 kubelet 容器中该目录也存在。 ### Q: metric-server 默认镜像拉取是 Always,rancher 中改不动 yaml 怎么办? rancher 的 metric-server 默认拉取策略确实是 Always。如果 rancher web 界面上改不成功,可直接用 `kubectl` 命令去修改。 ### Q: 部署最后的 CubeStudio 组件时,kubernetes-config 配置是否必须?报错找不到 kubernetes-config start 脚本最开始会创建 kubeconfig 目录,并将该目录内容创建为 configmap。虽然 configmap 内容为空,但 kubeconfig 目录是必须存在的。 ### Q: kubernetes 1.22.16 版本 kubeflow-batch 部署报错,只部署 volcano 可以吗? 现在平台不依赖 kube-batch,替代方案使用 volcano。 ### Q: master 节点打哪些服务的 label?worker 上哪些 label 是 true? 机器通过 label 进行管理,所有调度机器由平台控制,不由用户直接控制。 - 开发训练服务机器:cpu 的 train/notebook/service 选 `cpu=true`;gpu 的选 `gpu=true`;vgpu 的 service 选 `vgpu=true`;训练任务选 `train=true`;notebook 选 `notebook=true`;服务化选 `service=true`;不同项目任务选对应 `org=xx`(默认 `org=public`)。 - gpu 型号用 `gpu-type=xx` 标识,如 `gpu-type=V100`、`gpu-type=T4`,配置 gpu 算力时可同步配置型号(如 `2(T4)` 表示 2 张 T4 卡)。 - 控制器机器:`mysql=true`(部署 mysql)、`redis=true`(部署 redis)、`kubeflow-dashboard=true`(部署 CubeStudio 服务)、`kubeflow=true`(部署 kubeflow)、`istio=true`(部署 istio)、`monitoring=true`(部署 prometheus)。 ### Q: 部署 k8s 集群,在某个 worker 节点执行了 start.sh 本地 ip 后,此节点与其他节点 ip 不通了 可能是 k8s 使用的网络 ip 域与主机本身网络 ip 域重复了,可在 rancher 中修改节点和服务 pod 的 ip 范围,参考 wiki rancher 章节。 ### Q: 服务发布之后 ExternalIP 为 master ip 导致集群故障 主要出现在平台入口使用 nodeport 模式时,端口相互冲突占用导致。 ### Q: 如何部署 CubeStudio 平台?是否有完整详细的部署文档? wiki 文档有详细的部署文档:先部署 k8s 集群,再部署 CubeStudio 平台,再把多台机器加入集群。 ### Q: 能否提供一个一键部署的 docker-compose? 在 `install/docker` 中提供了本地一键启动的 docker-compose,但因为 CubeStudio 平台很多地方需要 k8s 作为基底,本地启动后部分功能仍需连接远程 k8s 才能正常运行。 ### Q: 开始部署前需要准备哪些镜像? 主要为 rancher 的镜像和 CubeStudio 的镜像,可参考部署文档中的 `all_image.py` 文件一次性生成镜像列表。 ### Q: 怎么卸载 CubeStudio? `install/kubernetes/rancher` 中包含 `reset_docker.sh` 脚本,可以快速把 k8s 集群卸载掉。 ### Q: 默认下载 master 分支代码就可以吗? 用最新的 release 版本会更稳一些。 ### Q: 有升级文档吗? 每个版本发布可能涉及架构变更,统一可以把原平台的数据库导出,然后在新数据库的基础上部署新版本的平台。 ### Q: 部署 triton-server 的教程 wiki 中有 triton 服务部署的相关资料。 ### Q: 服务器的 IP 地址换了怎么改? 如果服务器上部署了 rancher server,需要按 wiki “部署 rancher”章节内容更换 master 服务器。 ### Q: 报错 cannot connect to MySQL server on 'host.docker.internal' `host.docker.internal` 是 mac/windows 上 docker 容器中“本机 ip”的域名表示。可换成自己机器的内网 ip,但不要使用 `127.0.0.1`。 --- ## 二、镜像与打包构建 ### Q: Dockerfile-base 打包出错 / 构建 dockerfile-base 时报错 基础环境镜像打包失败可能是网络问题,可以配置国内 apt 源(或相应的软件源),多构建几次;也可以直接基于 base 镜像再次构建自己的环境镜像。 ### Q: 构建 vision 和 visionPlus 失败 前端代码构建失败可能是网络问题,建议添加国内 node 源后再构建,可多试几次。 ### Q: when frontend run yarn & yarn build, an error happens! / vision 前端页面运行不起来 可联系社区管理员协助。 ### Q: 总有一个镜像拉取有问题 / 总有一个镜像拉取不到 可以先在主机上把该镜像拉取好。 ### Q: 似乎没有找到这个镜像,哪里需要这个镜像? 如果是 CubeStudio 的镜像,可联系管理员;如果是其他开源项目或自己的镜像,先尝试在机器上能否拉取,再排查平台拉不到的原因。可能是账号密码问题,也可能是镜像名错误。 ### Q: 更新到最新版后还是拉取镜像失败 / 拉取镜像失败的原因 可能原因:镜像名写错、镜像在仓库中不存在、镜像没有设为 public、未配置拉取账号密码,或国内网络问题无法拉取。 ### Q: 拉取 rancher 依赖镜像很多都失败,需要换源吗? 不需要。rancher 镜像是 docker hub 官方镜像,拉取失败主要是 docker hub 做了限频。可以先 `docker login` 登录,再多试几次。 ### Q: 镜像太大传不上 docker hub 怎么办? 可以自己部署内网 harbor,或尝试把镜像每一层减小一些。 ### Q: 希望作者更新 cuda11 的镜像 已经支持 cuda11 的 gpu 镜像。 ### Q: 如何在之前的 notebook 镜像上添加插件并重启后生效? / 如何修改 notebook 的镜像? 在本地机器上用容器运行 notebook,浏览器打开后安装插件,再把容器 `commit` 成镜像并推送到仓库,这样线上就能用新的 notebook 镜像了。 --- ## 三、网络、网关与证书 ### Q: 路由增加 https 反代后,login 跳转返回 http 协议 目前仅支持 http 协议,代码中做了限制。 ### Q: istio-ingressgateway 报错,无法通过健康检查 需看具体日志才能定位。可能原因:istiod 没有正常启动导致 ingressgateway 连不上 istiod;使用了第三方证书;或证书过期。可根据具体日志信息搜索解决。 ### Q: 部署以后 cert-manager pod 不正常,导致 istio 组件缺少挂载 现在 CubeStudio 使用第一个证书(自带证书),不需要 cert-manager。 ### Q: 80 端口被占用,如何修改为其他端口? 可以使用 nodePort 模式,把 `istio-system` 命名空间下的 `istio-ingressgateway` 服务的服务类型配置为 nodeport。 ### Q: 所有服务都没问题,可输入本机 ip 还是进入 rancher,进不去 CubeStudio 界面 rancher 界面是 https 协议,CubeStudio 界面是 http 协议,浏览器会记忆之前的网址。手动在浏览器中输入 `http://ip` 来打开 CubeStudio。 ### Q: kubectl patch svc istio-ingressgateway 设置 externalIP 后创建了和物理机冲突的 ip,集群崩了 可能是 rancher 创建的 k8s 集群网络和主机内网 ip 网络重叠了,可参考 wiki 部署 rancher 章节里的 rancher 集群配置。 ### Q: 安装 CubeStudio 后访问 web 端返回 301? 301 是重定向,一般是用户没有登录,所以重定向到登录地址。 ### Q: 用内外网双网卡安装,外网安装顺利但打不开 CubeStudio 界面,内网很多服务一直 pending? 先保证所有 pod 正常 running,再排查外网 ip 打开问题。部署时使用内网 ip,浏览器打开时使用外网 ip,并且云上安全组需要放开权限。 ### Q: 502 Bad Gateway,nginx 报错 CubeStudio 只在前端界面上使用 nginx(前端镜像基于 `nginx:latest`,版本随构建时间变化,见 `myapp/frontend/Dockerfile:1`,不是固定版本)。如果能打开前端界面 logo 但 nginx 报错,说明后端 pod 启动异常,排查后端 pod;如果报错的 nginx 不是前端镜像里的版本,可能是自己额外添加的 nginx 代理导致。 --- ## 四、服务化与推理部署 ### Q: 服务化 -> 服务上线部署之后无法访问服务 内部服务和推理服务部署后访问不了,几个可能原因(按此顺序排查):pod 没有正常启动、pod 端口配置错误、ip 端口被网络限制、域名和 ip 混用。 ### Q: CubeStudio 的服务化在内网中根据 ip 和端口访问不到? 内部服务和推理服务的端口是自动生成的。部署后无法访问,首先确认 pod 是否正常启动。端口规则见 [端口使用情况](端口使用情况.md)。 ### Q: 内部服务添加云原生服务,把默认端口 80 改为 30021 后首页打不开 内部服务和推理服务的端口配置是**业务代码的监听端口**,不是客户端访问的 ip 和端口。客户端可访问的端口是自动生成的,会转发到容器的业务监听端口。改成 80 会和平台入口冲突,导致首页打不开。 ### Q: 开源版能部署 tfserving 吗? 开源版本可以部署 tfserving、torch-server、triton 等推理框架,或自定义推理镜像。 ### Q: 推理服务部署上线,接口入参在哪里配置? 推理服务有启动命令,可统一配置在启动命令中。 ### Q: 是否支持 CV 项目的线上推理可视化? 支持。 ### Q: 自定义模板报错 "OCI runtime create failed ... exec: images: executable file not found" 说明自定义模板中的镜像没有配置启动命令,所以容器运行时找不到可执行文件。 ### Q: 创建自定义模板后无法正常调用,修改原有模板后也无法使用? 模板修改要配合镜像一起改才能正常使用;自定义镜像的模板不能直接改。 --- ## 五、平台功能使用(notebook / pipeline / 数据ETL / 大数据 / aihub) ### Q: 在平台部署 notebook 直接提示 unknown,选 reset 会报错 notebook unknown 说明 notebook 没有运行;reset 报错需要提供进一步信息排查。 ### Q: notebook 模块进入报错 notebook 进不去可以通过 notebook 记录后面的 reset 按钮重启、配置 notebook。 ### Q: notebook 到期后进行 reset 会出现 404 404 多出现在多域名、或域名与 ip 混用的场景。建议只使用一个,在 config 文件中配置好域名。 ### Q: 部署完成后创建 notebook 后无法进入,提示 "no healthy upstream" 管理员可在状态按钮中进入 k8s dashboard,查看 pod 拉取是否正常、运行是否正常等。 ### Q: 启动 jupyter-ubuntu-deeplearning 无法调用 cuda? / jupyter 调不了 GPU 只有 gpu 版本的 jupyter 可以调用 gpu,其他版本的 jupyter 均是 cpu 版本。 ### Q: 在 jupyter lab 中加入大数据功能 提供了大数据版本的 jupyter,配置好 hadoop 和 spark 集群信息后,就可以在 notebook 中查询大数据平台数据做 etl 和数据分析;大数据版本的 notebook 还集成了常用数据分析工具。 ### Q: 模型训练结果可视化(类似 tensorboard)打算怎么实现? 任务结果可视化目前是商业版功能。不过 tensorboard 在 jupyter 中做了集成:打开深度学习版本的 jupyter,在左侧文件目录先打开训练日志目录,再点 tensorboard 图标按钮,即可查看实时/离线训练结果。 ### Q: 如何进行算子的编排? 分任务级别和函数级别。任务级别要求前一个结束才运行下一个,主要在训练菜单的“任务流”模块拖拉拽算子实现。如果只做编排(定义上下游逻辑关系),可用“数据 ETL”中的任务流编排(通用能力,不一定用在数据 ETL 场景),不过要进行二次开发。 ### Q: 如何自定义算子? 部署平台后,参考首页的“自定义模板”视频,或参考 CubeStudio 视频号中的部分视频教程。 ### Q: 样例任务流运行完成后,中间过程(如 yolov3)的容器没有被清除? pipeline 实例运行结束后会在三个小时后删除,并不是立刻删除。 ### Q: pipeline 容器启动时可以加参数指定端口映射吗? pipeline 中的任务都是离线任务,不是服务,所以不能也不需要配置端口映射。 ### Q: 怎样启动 volcano 调度? 使用 volcano 任务模板,任务启动时会现场部署一个服务要求的分布式集群,这个集群由 volcano-controller 部署。 ### Q: 工作任务流里,任务之间的变量传递有什么方式? 开源版本不提供任务之间输入输出参数变量的传递,只有商业版本支持。 ### Q: 数据 ETL 模块不可用 / 任务 ETL 开源能用吗? 开源版本数据 ETL 只提供了算子模板化、拖拉拽编排的能力,使用者需要二开对接自己公司的调度系统才能正常运行。 ### Q: 有没有在线开发里数据 ETL 的例子? 目前还没有现成示例。 ### Q: 怎么对接已有的数据中台? 对接数据中台包含计算引擎(sqllab)、调度引擎(数据 ETL)、元数据(离线库表/指标/维表)、血缘关系(血缘链路)、存储(任务模板)等各部分。 ### Q: 使用 datax 时,job.json 文件是外部传入还是打包进镜像? 不需要打进镜像。在 notebook 里写就可以,pipeline 里写上地址即可。 ### Q: 怎么支持大数据组件(hive/spark 等)的定时调度任务?pipeline 可以直接调吗? pipeline 中包含提交 hive、spark 任务,可参考 hadoop 模板,该模板用于提交大数据生态相关任务。 ### Q: 做增量训练怎么使用 huggingface 上下载的开源模型? huggingface 模型在其介绍页一般会说明如何微调,可在 notebook 或 pipeline 中运行你的微调代码。 ### Q: aihub 运行中存在的前端 bug aihub 前端 bug 仍在修复中,有 bug 也可在 github 提出。 ### Q: aihub deeplearning 的算法包,有可以直接跑的吗? 目前 aihub 的功能只能在商业版中正常使用。 ### Q: 操作中通过“更多”里的删除无法删除,但批量操作中的删除可以? “更多”菜单中的删除是单条目删除,与批量操作中的删除应是一样的。如果删不掉,建议查看是否有其他类型条目的绑定。 ### Q: 有从数据导入到模型部署完整任务流的案例吗? 可参考 CubeStudio 视频号,里面有各种教程和示例。 ### Q: 页面有些功能不可点击 部分功能尚未补齐,或为商业版功能,所以不可点击。 --- ## 六、GPU、硬件与架构兼容 ### Q: 有没有类似 TKE vCUDA、阿里 cGPU 的 cuda 劫持虚拟 GPU 计划? / VGPU 目前支持 vgpu 能力,可参考 wiki “加入 gpu 机器”这篇文章。 ### Q: CubeStudio 的 VGPU 需要授权许可 license 吗? 不需要。 ### Q: 如何支持更多型号的 GPU? / 怎么支持 gpu 机器加入集群被正常调度? / 集群加入 gpu 后服务报错 参考 wiki “添加 GPU 节点 / 加入 gpu 机器”文章。流程:机器上安装 gpu 驱动 → 加入 k8s 集群 → 打对应标签(主要是 `gpu=true` 和 `gpu-type=V100` 等卡型)→ 在 k8s 中安装对应驱动插件 → 在业务镜像中安装驱动调用库(如 cuda),这样才能在平台里使用机器上的 gpu。 ### Q: CubeStudio 支持 A10 这款显卡吗? 支持。 ### Q: CubeStudio 是否支持 arm64 架构、国产芯片、华为麒麟服务器? CubeStudio 类似 ai 中台,架构相对复杂,目前只有商业版本支持 arm64 架构。 ### Q: 平台支持 arm 吗? 开源版支持 amd64,商业版支持 arm64 和 amd64。 ### Q: 有边缘计算部署到车机/手机端的案例吗? 目前还没有边缘计算到车载/手机端的案例。平台支持 arm64 架构,可联系管理员一同测试。 ### Q: windows 下基于 wsl2 的 ubuntu,cpu 长期打满? wsl2 只能开 gpu docker,用不了 nvidia k8s plugins。也可以扩内存或用 ssd。 --- ## 七、配置与运维 ### Q: 关于将 CubeStudio 嵌入其他云平台的 cookie 作用域问题 可以在配置文件 `config.py` 中配置 `COOKIE_DOMAIN` 参数(`myapp/config.py:1377`),它是你想共享给其他平台的域名后缀。 ### Q: 如何配置内网运行时镜像拉取不使用 Always 而用 IfNotPresent? 平台通过配置文件中的 `IMAGE_PULL_POLICY` 参数控制调度任务容器时是否拉取(`myapp/config.py:968`,默认 `Always`,可改为 `IfNotPresent`)。可参考 wiki “自定义配置文件”。 ### Q: 能否隔离部署,让各服务镜像不会自动拉取更新? 内网部署需先把所需镜像拉到内网机器,最好配置内网镜像仓库。同时需修改 `config.py` 中的镜像拉取策略(`IMAGE_PULL_POLICY` 改为 `IfNotPresent`),并更新到 k8s 集群。 ### Q: 配置文件在哪里?如何修改并在生产上生效? 配置文件位于 `install/docker/config.py`(本地开发)和 `install/kubernetes/cube/overlays/config/config.py`(线上配置)。线上也可以直接修改 `infra` 命名空间下的 `kubeflow-dashboard-config` 这个 configmap。 > 已核实:`install/kubernetes/cube/overlays/config/config.py` 存在;configmap 名 `kubeflow-dashboard-config`(`install/kubernetes/cube/overlays/kustomization.yml:6`),在 `infra` 命名空间。 ### Q: 本地部署,项目配置的 expand 字段里公网 ip 和内网 ip 指哪个? 配置一个内网 ip 就行;有公网 ip 或域名的才配置公网 ip。 ### Q: 平台有资源审核模块吗? 目前平台限制普通用户最高可配置 50 核 CPU、100G 内存、8 卡 GPU(`MAX_TASK_CPU=50` / `MAX_TASK_MEM=100`(单位 G)/ `MAX_TASK_GPU=8`,见 `myapp/config.py:1126-1128`),更高配置只有管理员可设置,但并没有单独的资源审核模块。 --- ## 八、数据与存储 ### Q: CubeStudio 是否提供共享存储功能(包括前端页面展示)? CubeStudio 依赖分布式存储,但并没有提供分布式存储的管理能力。 ### Q: juicefs 需要其他的文件存储吗? juicefs 本身就是分布式存储文件,不需要更底层的分布式存储了。 ### Q: k8s 集群里删不掉 PVC? PVC 删不掉一般是因为有 pod 挂载该 pvc,需要先找到对应 pod,删除 pod 后才能删除 pvc。 --- ## 九、账号与认证 ### Q: 登录失败 如果能打开页面但登录失败,可点右上角退出按钮重新进入登录界面。系统默认自动注册新用户,自带账户密码 `admin/admin`。忘记密码可联系管理员修改或进入数据库修改。 ### Q: 安装完 pod 都正常,但登录 web 提示 Internal Server Error? 右上角退出后重新登录试试。 ### Q: 如何去掉登录验证? 无法去除登录验证。很多界面都要验证用户后才能获取数据,去掉验证这些界面将无法正常访问。 ### Q: 用户认证系统支持哪些? 现在 CubeStudio 支持 `AUTH_OID` / `AUTH_LDAP` / `AUTH_REMOTE_USER` 等登录注册方式。 ### Q: 有认证/多用户/用户空间这些功能吗? 有。 ### Q: 目前支持多租户吗? 支持多租户、多项目组、RBAC 权限划分。 ### Q: 体验账户和密码在哪里获取? / 体验账号是什么? 体验账户密码为 `admin/admin`。 --- ## 十、监控与资源排查 ### Q: 没有运行的作业,但 cpu 居高不下,如何释放资源? 不确定是什么任务占用资源时,可先在 k8s dashboard 进入主机界面,看主机上有什么 pod;或在 prometheus 上查看所有 pod 的 cpu/内存/gpu 资源。如果没发现 pod,再到机器上查看什么进程占用资源。 ### Q: Grafana 模块监控异常 - 打不开 grafana 页面:先排查 `monitoring` 命名空间下 grafana pod 是否正常,浏览器是否为 http 协议。 - 能打开但页面显示不正常:强制刷新浏览器、清空缓存。 - 页面正常但指标查询异常:看 prometheus pod 是否正常,进入 prometheus 页面手动查询指标,确认指标是否被正常采集,以及 rule、service discovery、target 等是否正常。 ### Q: 一主三从,前端页面当前负载只显示一台机器? 负载界面显示的机器与机器标签有关,需要按项目分组和功能分类配置好机器的 label 标签。 --- ## 十一、架构与技术栈 ### Q: CubeStudio 是基于 kubeflow 开发的吗? CubeStudio 和 kubeflow 生态目前没有太多关系,最开始基于 kubeflow 开发,现在只使用了 kubeflow 的 train-operator。 ### Q: CubeStudio 项目有用到 go 吗? CubeStudio 自己的代码前端是 react、后端是 python,没有 go 代码;但依赖的相关组件(k8s 基础组件)是用 go 写的开源组件。 ### Q: argo 中的数据存到 etcd 吗?etcd 存储有限制吗? argo 是云原生调度系统,定义 workflow 等 crd,crd 实例存储在 etcd 中。etcd 的存储限制属于 k8s 基础架构范畴,不在 CubeStudio 的技术范围内。 ### Q: pipeline 用的原生 kfp 吗? pipeline 目前与 kfp 没有关系。 ### Q: pipeline 调度底层用的是什么? 训练 pipeline 的底层调度是 argo;数据 etl 的 pipeline 没有定义底层调度,需要用户二开对接自己公司的调度系统。 ### Q: CubeStudio 和 KubeSphere 是什么关系?多租户/资源管理是自己做的还是依赖 KubeSphere? CubeStudio 的账号密码是自己的一套;kubesphere/rancher 是容器编排产品,有自己独立的账号密码,与 CubeStudio 的账号体系无关。 --- ## 十二、商业版、社区与通用咨询 ### Q: 二次开发 二次开发需要进一步学习源码,或购买商业版二开咨询服务。 ### Q: 定制化二次开发是腾讯的人吗?能驻场开发吗? 定制化二次开发不是腾讯的人,是由社区开发者组成,详细情况可联系社区管理员栾鹏。 ### Q: 商业版和开源版的主要区别是什么? / 商业版定价多少? / 报价是按项目收费吗? 可联系社区管理员。项目报价收费比较灵活。 ### Q: demo 演示环境的问题,有公共体验环境吗? 社区用 docker-compose 部署了开源版 demo 体验环境 www.data-master.net,但因为没有 k8s 集群,公共体验环境中与 k8s 相关的功能无法正常体验。想体验完整开源版或商业版功能可联系管理员。 ### Q: CubeStudio 社区见面会 目前还没有定时的社区见面会,可随时关注群里消息。 ### Q: 全部功能支持私有化部署吗? 目前所有功能均支持私有化部署。 ### Q: 哪个版本支持数据血缘? 目前只有商业版支持血缘链路。 ### Q: 是否考虑把 HPC 场景加进来? 目前只有商业版支持 HPC 的任务模板。 ### Q: 对 AIGC 大模型训练与推理(SFT/Megatron/Deepspeed/prompt 等)有支持计划吗? 目前商业版支持大模型的一键微调、多机多卡训练和服务部署。 ### Q: Wiki 上的公司使用的是开源版还是商业版? github 中的公司示例是部署开源版本的公司示例。 ### Q: github 和 gitee 上的文档版本有什么差异? 看 github,维护更好。 ### Q: CubeStudio 用的什么开源协议? MIT。 ### Q: 哪里有详细教程或 wiki 文档地址? github 上有 wiki 文档:https://github.com/data-infra/cube-studio/wiki 。 --- ## 任务模板(22 篇) ### 任务模板/算子总览索引 - 链接: https://www.cubestudio.vip/docs/05-%E4%BB%BB%E5%8A%A1%E6%A8%A1%E6%9D%BF/00-%E6%A8%A1%E6%9D%BF%E6%80%BB%E8%A7%88 - 分类: 05-任务模板 / 总览 - 适用场景: 想知道平台内置了哪些 pipeline 算子/任务模板、各算子用途及对应详情文档时,先读这篇做导航。 - 关键词: 任务模板 / 算子 / operator / job-template / pipeline / 流水线 / 模板总览 / 模板索引 / 算子列表 / ML算子 / 训练算子 - 最后更新: 2026-07-04 # 任务模板 / 算子总览 CubeStudio 的「任务模板」(也叫**算子**)是 pipeline(流水线)中可被拖拽编排的最小执行单元。每个算子在仓库 `job-template/job/<算子目录>` 下,以一个独立镜像 + 入口脚本(多为 `launcher.py` / `start.sh`)实现;平台通过 `myapp/init/init-job-template.json` 把它们注册为「任务模板」,用户在流水线里选择模板、填参数即可运行。 - 想了解**如何开发/注册一个新模板** → 见 [开发任务模板.md](开发任务模板.md)。 - 想了解**在 pipeline 中如何使用这些算子**(编排、参数填写、逐项预处理/特征处理用法)→ 见 [模板使用/](模板使用/)。 - 各算子的**参数、设计、命令**详情,见下表「详情文档」列链接的家族文档。 > 下表按家族分组,覆盖 `job-template/job` 下全部算子目录(已排除 `__init__.py`/`pkgs`/`test`/`demo`/`window`/`aihub` 等非算子项;`model_offline_predict` 目录为空已跳过)。具体参数与行为以源码为准,本页仅供导航。 --- ## 数据导入导出 详情文档:[01-数据导入导出.md](01-数据导入导出.md) | 算子目录 | 平台任务模板名 | 一句话用途 | 详情 | |---|---|---|---| | `datax` | datax / datax-import | 基于阿里 DataX 的异构数据源同步与导入(datax 原生手写 job.json;datax-import 表单化导出数据库表为 CSV) | [→](01-数据导入导出.md#datax) | | `dataset` | dataset | 从当前平台 / Hugging Face / 魔塔(ModelScope) 下载数据集到目录 | [→](01-数据导入导出.md#dataset) | | `model_download` | model-download | 从模型管理 / 推理服务 / Hugging Face / 魔塔下载模型到目录 | [→](01-数据导入导出.md#model-download) | | `label-studio-import` | label-studio-import | 从 Label Studio 标注库导出标注数据(JSON/COCO/YOLO/YOLOv8-OBB) | [→](01-数据导入导出.md#label-studio-import) | ## 数据处理 详情文档:[02-数据处理.md](02-数据处理.md) | 算子目录 | 平台任务模板名 | 一句话用途 | 详情 | |---|---|---|---| | `data-process` | data-process | CSV 通用预处理(去重/填充/降维/异常检测/划分等 process_type) | [→](02-数据处理.md#data-process) | | `hadoop` | hadoop | 对接客户已有 Hadoop/YARN/Hive/Spark 集群的客户端镜像(平台不自带集群) | [→](02-数据处理.md#hadoop) | | `spark` | spark | 通过 spark-operator 提交 SparkApplication 跑 Spark 作业 | [→](02-数据处理.md#spark) | | `ray` | ray | 在 K8s 上按需拉起 Ray 集群跑分布式 Python | [→](02-数据处理.md#ray) | | `volcano` | volcano | 用 Volcano Job CRD 起多副本分布式计算任务 | [→](02-数据处理.md#volcano) | | `nlp-process` | nlp-clean-data / nlp-replace-private-data / nlp-filter-data / nlp-analyze-data / markdown-to-qa / expand-qa | 文本清洗、脱敏、质量过滤、数据集分析、Markdown 转 QA、QA 数据扩展 | [→](02-数据处理.md#nlp-process) | | `feature-process` | feature-combine / hadamard-multiply / calculate-correlation / feature-importance / union-join-data / feature-process-all | 特征组合、相关性、重要性、Hadamard 积、合并连接,及一体化特征工程 | [→](02-数据处理.md#feature-process) | ## 机器学习 详情文档:本段「机器学习」家族文档(文件名以本段实际为准,见 [05-任务模板/](.))。 | 算子目录 | 平台任务模板名 | 一句话用途 | |---|---|---| | `sklearn` | sklearn 系列 | sklearn 算法训练/评估/推理(adaboost、ar、arima、bayesian、decision-tree、gbdt、kmeans、knn、lightgbm、lr、random-forest、rf-regression、xgb 及通用模板) | | `ray-sklearn` | ray-sklearn | 基于 Ray + Joblib 的分布式 sklearn | ## 深度学习 详情文档:本段「深度学习」家族文档(见 [05-任务模板/](.))。 | 算子目录 | 平台任务模板名 | 一句话用途 | |---|---|---| | `tf` | tfjob | 基于 Kubeflow TFJob 的 TensorFlow 分布式训练 | | `pytorch` | pytorchjob | 基于 Kubeflow PyTorchJob 的 PyTorch 分布式训练 | | `deep-learning-framework` | deep-learning-framework | 多框架分布式训练(colossalai/deepspeed/horovod/megatron/mindformers/mindspore/mpi/mxnet/paddle) | ## 大模型 详情文档:本段「大模型」家族文档(见 [05-任务模板/](.))。 | 算子目录 | 平台任务模板名 | 一句话用途 | |---|---|---| | `llama-factory` | llama-factory | 基于 LLaMA-Factory 的大模型训练 / SFT / PPO / reward / eval | | `llm-benchmark` | llm-benchmark | 大模型推理性能压测 | | `llm-distillation` | llm-distillation | 大模型知识蒸馏 | | `llm-prune` | llm-prune | 基于 LLM-Pruner 的大模型剪枝 | | `llm-quantization` | llm-quantization | 大模型量化 | | `llm-safety-eval` | llm-safety-eval | 大模型安全性 / 越狱评估 | | `opencompass` | opencompass | 基于 OpenCompass 的大模型评测 | ## 模型服务化 详情文档:本段「模型服务化」家族文档(见 [05-任务模板/](.))。 | 算子目录 | 平台任务模板名 | 一句话用途 | |---|---|---| | `model-convert` | model-convert | PyTorch/YOLO 转 ONNX 及边缘多格式(OpenVINO/NCNN/MNN/TFLite/RKNN/TensorRT) | | `model_register` | model-register | 把模型注册到平台「模型管理」 | | `deploy-service` | deploy-service | 在 pipeline 内一键创建/更新推理服务 | | `model_evaluation` | model-evaluation | 传统 ML 离线推理结果对比真值算指标 | | `offline-predict` | offline-predict | 基于 RabbitMQ 的分布式离线推理 | ## 多媒体 / CV / 语音 详情文档:本段「多媒体CV语音」家族文档(见 [05-任务模板/](.))。 | 算子目录 | 平台任务模板名 | 一句话用途 | |---|---|---| | `video-audio` | video-audio(3 子模板) | Ray 分布式媒体下载 / 视频抽帧 / 提取音频 | | `vision-process` | vision-process | 图像处理与图片质量评估 | | `voice-process` | voice-process | 音频清洗 / 增强 / 评估 | | `yolo26` | yolo26 | YOLO26 目标检测训练 / 评估 / 服务 | | `yolov8` | yolov8 | YOLOv8(仅 Dockerfile/脚本,无 README,疑似被 yolo26 取代) | | `paddleocr-vl` | paddleocr-vl | PaddleOCR-VL 文档/图片转 Markdown | ## 超参搜索 详情文档:本段「超参搜索」家族文档(见 [05-任务模板/](.))。 | 算子目录 | 平台任务模板名 | 一句话用途 | |---|---|---| | `hyperparameter-search-nni` | hyperparameter-search-nni | 基于 NNI 的超参搜索 | | `hyperparameter-search-ray` | hyperparameter-search-ray | 基于 Ray Tune 的超参搜索 | --- > 说明:本页为导航总览,算子的**镜像版本、参数默认值、命令行行为**可能随版本变化,**具体以 `job-template/job/<算子目录>` 下源码与各家族详情文档为准,仅供导航**。 --- ### 数据导入导出类任务模板(datax / dataset / model-download / label-studio-import) - 链接: https://www.cubestudio.vip/docs/05-%E4%BB%BB%E5%8A%A1%E6%A8%A1%E6%9D%BF/01-%E6%95%B0%E6%8D%AE%E5%AF%BC%E5%85%A5%E5%AF%BC%E5%87%BA - 分类: 05-任务模板 / 数据导入导出 - 适用场景: 需要把外部数据源/数据集/模型/标注结果导入或导出到平台目录时,查这些算子的参数与行为。 - 关键词: datax / datax-import / dataset / 数据集下载 / model-download / 模型下载 / label-studio-import / 标注导出 / huggingface / modelscope / 魔塔 / DataX / COCO / YOLO / 数据导入 / 数据导出 - 最后更新: 2026-06-30 # 数据导入导出类任务模板 本家族包含 4 个算子,统一解决「外部 → 平台目录」「平台 → 目录」的数据/模型/标注搬运问题: | 算子 | 平台模板 | 用途 | |---|---|---| | [datax](#datax) | datax / datax-import | 异构数据源同步与数据库表导出 CSV | | [dataset](#dataset) | dataset | 下载数据集到目录 | | [model-download](#model-download) | model-download | 下载模型到目录 | | [label-studio-import](#label-studio-import) | label-studio-import | 导出 Label Studio 标注数据 | > 交叉引用:`dataset` / `model-download` 与平台「数据集」「模型管理」「推理服务」功能配套使用,平台侧功能见 [数据资产与处理](../03-平台使用/05-数据资产与处理/) 与 [服务化与推理](../03-平台使用/07-服务化与推理/);`label-studio-import` 与 [数据标注](../03-平台使用/08-数据标注/) 配套。 --- ## datax 基于 [阿里巴巴 DataX](https://github.com/alibaba/DataX) 的异构数据源同步/导入算子,提供两个子模板。 - **镜像**:`ccr.ccs.tencentyun.com/cube-studio/datax:20240501` - **实现目录**:`job-template/job/datax` - **镜像默认入口**:Dockerfile 的 `ENTRYPOINT` 为 `python start.py`(即 datax-import 子模板);datax 原生子模板由模板的启动命令改用 `start.sh`。 ### 子模板一:datax(手写 job.json) - **入口**:`start.sh`,解析 `-f` 后执行 `python datax.py `。 - **适用**:需要完整 DataX 能力(任意 Reader/Writer、复杂映射/过滤),愿意手写 DataX job JSON。 | 参数 | 类型 | 必填 | 说明 | |---|---|---|---| | `-f` | 文件路径 | 是 | DataX job.json 文件地址(如 `/mnt/{{creator}}/pipeline/example/ml/mysql-csv.json`)。JSON 写法见 [DataX 官方文档](https://github.com/alibaba/DataX) | 镜像内自带若干示例 job 配置:`mysql-csv.json`、`postgresql-csv.json`、`clickhouse-csv.json`、`hive-csv.json`、`hive-stream.json`,可参考改写。 ### 子模板二:datax-import(表单化导出数据库表为 CSV) - **入口**:`start.py`,读取内置模板 `to-csv.json`,把表单参数替换进占位符(`READER`/`USERNAME`/`PASSWORD`/`HOST`/`DATABASE`/`TABLE`/`COLUMNS`/`OUTDIR`/`OUTNAME`),生成临时 DataX 配置 `_csv.json` 再执行 `python datax.py`,最后把带随机后缀的输出文件重命名为 `--save_path`。 - **适用**:从数据库表导出为 CSV,免写 JSON。 | 参数 | 类型 | 必填 | 说明 | |---|---|---|---| | `--db_type` | str | 是 | 数据库类型,对应 DataX reader 名(如 `mysql`→mysqlreader、`postgresql`、`clickhouse`) | | `--host` | str | 是 | 数据库地址含端口(如 `mysql-service.infra:3306`),拼进 jdbcUrl | | `--username` | str | 是 | 数据库用户名 | | `--password` | str | 是 | 数据库密码 | | `--database` | str | 是 | 库名 | | `--table` | str | 是 | 表名 | | `--columns` | str | 是 | 要导出的列名,逗号分隔(如 `id,name,age`) | | `--save_path` | 文件路径 | 是 | 导出 CSV 的保存地址 | | `--query_sql` | str | 否 | 自定义查询 SQL | > 注意:`--query_sql` 虽在 `start.py:31` 通过 `argparse` 定义,但在 `to-csv.json` 占位符替换逻辑(`start.py:41-49`)与最终命令拼接(`start.py:55`)里**均未被使用**(脚本中再无 `args.query_sql` 引用);即当前 datax-import 实际只能整表+指定列导出,`query_sql` 不生效。 > 注意:`start.py:45` 中 `config.replace('DATABASE', args.databasen if '?' in args.database else ...)` 引用了不存在的属性 `args.databasen`(应为 `args.database` 笔误,argparse 只定义了 `--database`);当 `--database` 含 `?` 时会走到该分支抛 `AttributeError`,是代码 bug。 ### 选型 | 需求 | 推荐子模板 | |---|---| | 任意 DataX 读写组合 / 复杂配置 | datax(手写 job.json + `start.sh`) | | MySQL/PostgreSQL/ClickHouse 表导出为 CSV、快速配置 | datax-import(表单 + `start.py`) | --- ## dataset 把数据集下载到指定目录,支持三种来源。 - **镜像**:`ccr.ccs.tencentyun.com/cube-studio/dataset:20250301`(`job-template/job/dataset/build.sh` 当前构建版本;README 正文里写的是旧版 `20240501`,以 build.sh 为准) - **实现**:`job-template/job/dataset/launcher.py` - **平台 API 地址**:环境变量 `HOST`(或 `KFJ_MODEL_REPO_API_URL`),默认 `http://kubeflow-dashboard.infra`;请求头 `Authorization` 取环境变量 `SECRET`(默认等于 `KFJ_CREATOR`)。 ### 来源(--src_type) | 取值 | 行为 | |---|---| | `当前平台` / `cube-studio` | 调平台 API `/dataset_modelview/api/` 按 name+version 查询数据集,再按 `/dataset_modelview/api/download/{id}[/{partition}]` 取多个 `download_urls`,**并行 HTTP 下载**,下载后自动解压目录下 `.zip` / `.tar.gz` / `.gz` | | `huggingface` | `huggingface-cli download --repo-type dataset --resume-download {name} --revision {version} --local-dir {save_dir} --local-dir-use-symlinks False` | | `modelscope` / `魔塔` | `modelscope download --dataset {name} --local_dir {save_dir}`(当前实现**未**把 `--version` 传入 ModelScope 命令) | ### 参数 | 参数 | 类型 | 必填 | 默认 | 说明 | |---|---|---|---|---| | `--src_type` | str | 是 | `当前平台` | 来源:`当前平台`/`cube-studio`/`huggingface`/`modelscope`/`魔塔` | | `--name` | str | 是 | - | 数据集名(平台名 / HF 仓库名 / ModelScope 数据集名) | | `--version` | str | 是 | `latest` | 版本/分支(当前平台与 HF 用,HF 映射为 `--revision`;ModelScope 未传) | | `--partition` | str | 否 | `''` | 分区/子集名,**仅当前平台**生效 | | `--save_dir` | str | 否 | 见下 | 本地保存目录 | `save_dir` 默认:无分区 `/mnt/{KFJ_CREATOR}/dataset/{name}/{version}`;有分区 `/mnt/{KFJ_CREATOR}/dataset/{name}/{version}/{partition}`。 ```bash # 当前平台(带分区) python launcher.py --src_type cube-studio --name my-dataset --version v1 --partition train --save_dir /data/dataset/train # Hugging Face python launcher.py --src_type huggingface --name squad --version main --save_dir /data/squad # 魔塔 python launcher.py --src_type modelscope --name 某数据集 --version latest --save_dir /data/ms-dataset ``` --- ## model-download 从多种来源下载模型到指定目录,常用作流水线首节点拉取基线模型。 - **镜像**:`ccr.ccs.tencentyun.com/cube-studio/model_download:20250301` - **实现**:`job-template/job/model_download/launcher.py` - **平台 API / 鉴权**:同 dataset,使用 `HOST`/`KFJ_MODEL_REPO_API_URL`(默认 `http://kubeflow-dashboard.infra`)与 `SECRET`(默认 `KFJ_CREATOR`)。 - Hugging Face 可配 `HF_ENDPOINT`(如 `https://hf-mirror.com`)、`HF_HUB_ENABLE_HF_TRANSFER` 加速。 ### 来源(--from) | 取值 | 行为 | |---|---| | `模型管理`(或含 `model`) | 调 `/training_model_modelview/api/` 按「模型名+版本」查 `path`;path 为 JSON 时用 `--sub_model_name` 取子路径;path 为 URL 则 HTTP 下载、为本地路径则拷贝到 `--save_path`;并把模型元数据写入 `{name}.{version}.json` | | `推理服务`(或含 `inference`) | 调 `/inferenceservice_modelview/api/` 按「模型名+版本(+可选 model_status)」查 `model_path`,同样支持 JSON 子模型与 URL/本地路径下载或拷贝 | | `huggingface` | `huggingface-cli download --repo-type model --resume-download {model_name} [--revision {model_version}] --local-dir {save_path} --local-dir-use-symlinks False` | | `魔塔` / `modelscope` | `modelscope download --model {model_name} --local_dir {save_path}` | ### 参数 | 参数 | 类型 | 必填 | 默认 | 说明 | |---|---|---|---|---| | `--from` | str | 是 | 模板默认 `模型管理`(代码 argparse 默认为 `train_model`,含 `model` 故等同模型管理) | 模型来源:`模型管理`/`推理服务`/`huggingface`/`魔塔` | | `--model_name` | str | 是 | - | 模型名 / HF 仓库名 / ModelScope 模型 ID | | `--sub_model_name` | str | 否 | `''` | 多子模型时指定子模型键名(path 为 JSON 时) | | `--model_version` | str | 否 | `''` | 版本号;HF 时为 revision | | `--model_status` | str | 否 | `''` | `online`/`offline`/`test`,仅来源为推理服务时有效 | | `--save_path` | str | 是 | - | 下载目的目录(需容器内可写,建议挂载持久化路径) | ```bash python3 launcher.py --from 模型管理 --model_name my-model --model_version v1.0 --save_path /mnt/workspace/model python3 launcher.py --from 推理服务 --model_name my-model --model_version v1.0 --model_status online --save_path /mnt/workspace/model python3 launcher.py --from huggingface --model_name bert-base-chinese --model_version main --save_path /mnt/workspace/model python3 launcher.py --from 魔塔 --model_name damo/xxx --save_path /mnt/workspace/model ``` --- ## label-studio-import 从 [Label Studio](https://labelstud.io/) 标注平台的数据库中批量导出指定项目的标注数据,默认导出 JSON,可额外导出 COCO / YOLO / YOLOv8-OBB 数据集格式,便于直接喂给训练任务。 > 该算子在分组上归入「数据导入导出」家族:它把 Label Studio 中的标注结果导入/导出到平台用户目录,是标注 → 训练之间的桥梁。平台标注功能见 [数据标注](../03-平台使用/08-数据标注/)。 - **镜像**:`ccr.ccs.tencentyun.com/cube-studio/label-studio-import:20260601` - **实现**:`job-template/job/label-studio-import/launcher.py`,直接连 Label Studio 使用的 PostgreSQL 库查询。 - **连接配置(环境变量)**: - `POSTGRES_HOST`:Label Studio 数据库连接串,默认 `postgresql+psycopg2://postgres:postgres@postgresql.kubeflow:5432/labelstudio`;自建 Label Studio 时在模板高级配置覆盖。 - `LABELSTUDIO_BASE_URL`:默认 `http://labelstudio.kubeflow:8080`。 - `SECRET`:作为 Label Studio token(`LABELSTUDIO_TOKEN`)。 - **查询逻辑**:先校验 `project` 表中项目存在;再查 `task`(`total_annotations>0` 且符合过滤条件);为每个 task 关联 `task_completion`(标注 `annotations`)、`prediction`(`predictions`),并附上所属 `project` 信息。导出 JSON 为任务字典列表。 ### 参数 | 参数 | 类型 | 必填 | 平台默认 | 说明 | |---|---|---|---|---| | `--project_id` | str | 是 | `2` | Label Studio 项目 ID(`project.id`);不存在则任务失败 | | `--filter` | str | 是 | `updated_at>'2024-02-08'` | task 表过滤条件片段,多条用 `,`/`&`/`;` 分隔,内部用 SQL `AND` 拼接,双引号 `"` 会被替换为单引号 `'` | | `--output_format` | str | 是 | `json` | 输出格式:`json`/`coco`/`yolo`/`yolov8_obb`(值会小写并把 `-` 转 `_`) | | `--save_path` | str(workdir) | 是 | `/mnt/{{creator}}/pipeline/example/label-studio/result.json` | json 时填文件地址,非 json 时填目录 | > 提示:`--project_id` / `--filter` 上述默认值来自平台模板配置;脚本 `argparse` 的代码默认值为空字符串。`--output_format` 为 `json` 时仅导出 JSON;为 `coco`/`yolo`/`yolov8_obb` 时会在目录额外生成对应数据集(COCO 需要 Pillow)。 **过滤条件写法举例**: - 只按更新时间:`updated_at>'2024-02-08'` - 多条件:`updated_at>'2024-02-08', is_labeled=true` → 等价 `... AND updated_at>'2024-02-08' AND is_labeled=true` - ID 集合:`id in (1,2,3)` 请确保过滤条件字段与所用 Label Studio 版本的 `task` 表字段一致,时间/字符串使用引号。 --- ### 数据处理类任务模板(data-process / hadoop / spark / ray / volcano / nlp-process / feature-process) - 链接: https://www.cubestudio.vip/docs/05-%E4%BB%BB%E5%8A%A1%E6%A8%A1%E6%9D%BF/02-%E6%95%B0%E6%8D%AE%E5%A4%84%E7%90%86 - 分类: 05-任务模板 / 数据处理 - 适用场景: 需要做表格预处理、对接大数据集群、分布式计算、NLP 文本清洗/过滤/构造 QA、特征工程时,查这些算子的设计与参数。 - 关键词: data-process / 数据预处理 / hadoop / hive / yarn / spark / spark-operator / ray / ray集群 / volcano / volcanojob / 分布式计算 / nlp-process / 文本清洗 / 脱敏 / 数据过滤 / markdown-to-qa / feature-process / 特征工程 / 特征组合 / 相关性 / 特征重要性 / PCA / one-hot - 最后更新: 2026-07-04 # 数据处理类任务模板 本家族算子最多、文档量最大,覆盖表格预处理、大数据对接、分布式计算、NLP 处理与特征工程: | 算子 | 平台模板 | 用途 | |---|---|---| | [data-process](#data-process) | data-process | CSV 通用预处理 | | [hadoop](#hadoop) | hadoop | 对接外部 Hadoop/YARN/Hive/Spark 集群客户端 | | [spark](#spark) | spark | spark-operator 提交 SparkApplication | | [ray](#ray) | ray | K8s 上拉起 Ray 集群跑分布式 Python | | [volcano](#volcano) | volcano | Volcano Job CRD 多副本分布式计算 | | [nlp-process](#nlp-process) | nlp-clean-data 等 6 个 | 文本清洗/脱敏/过滤/分析/转 QA/扩展 | | [feature-process](#feature-process) | feature-combine 等 6 个 | 特征工程 | > 本文档侧重各算子的**设计、参数与命令定义**。在 pipeline 中逐项预处理/特征处理的**操作用法**已在 [模板使用/](模板使用/) 拆分文档中覆盖,两者互相补充,避免重复。 --- ## data-process 通用 CSV 数据预处理算子,单入口 `launcher.py`,用 `--process_type` 选择功能。 - **镜像**:`ccr.ccs.tencentyun.com/cube-studio/data-process:20230501` - **实现**:`job-template/job/data-process/launcher.py` - **输入**:默认 CSV;所有功能必填 `--process_type`。 ### process_type 功能对照 | process_type | 功能 | 关键参数(除 `--input_dataset_path`/`--save_dataset_path` 外) | |---|---|---| | `drop_duplicates` | 按行去重,保留首次出现 | - | | `drop_high_missing` | 删除缺失率超阈值的列 | `--missing_ratio`(默认 `0.3`) | | `drop_stablize` | 删除单一取值占比过高的列 | `--stable_threshold`(默认 `0.95`) | | `calculate_metric` | 描述性统计输出 CSV(不改原数据) | `--metric_path`(统计结果输出路径) | | `fill_missing` | 缺失值填充 | `--fill_type`:`mean`/`median`/`modes`(默认 `mean`) | | `one_hot` | One-Hot 编码 | `--categorical_cols`(逗号分隔;不填则对所有 object 列编码) | | `outlier_detection` | 异常值检测(可选删除) | `--detection_type`(多选逗号分隔:`stddev`/`box_line`/`Tukey`/`Z-score`)、`--delete_or_not`(`yes`/`no`) | | `pca` | PCA 降维(保留标签列) | `--feature_columns`、`--label_columns`、`--dimension` | | `split` | 划分训练/验证集 | `--split_ratio`(默认 `0.8`) | `split` 的 `--save_dataset_path` 规则:目录 → 生成 `train.csv`/`val.csv`;单 CSV 路径 → 生成 `{basename}_train.csv`/`{basename}_val.csv`;逗号分隔两路径 → 分别作训练/验证集。 ```bash python launcher.py --process_type drop_high_missing --input_dataset_path /data/raw.csv --save_dataset_path /data/cleaned.csv --missing_ratio 0.3 python launcher.py --process_type pca --input_dataset_path /data/raw.csv --save_dataset_path /data/pca.csv --feature_columns "f1,f2,f3,f4,f5" --label_columns label --dimension 2 ``` > 平台模板侧把每种 process_type 注册为独立参数组(过滤重复样本/丢弃缺失值过高的列/…),参数 JSON 见 `job-template/job/data-process/README.md`。 --- ## hadoop 对接**客户已有大数据平台**(Hadoop / YARN / Hive / Spark)的**客户端镜像**算子。CubeStudio **不提供大数据集群本身**,任务实际提交到你公司已有的 HDFS/YARN/Hive 上执行;组件版本不一致时需二次开发改 Dockerfile 重建镜像。 - **默认镜像**:`ccr.ccs.tencentyun.com/cube-studio/hadoop:20240501` - **默认组件版本**(见 `Dockerfile`):Hadoop 3.3.6、Hive 3.1.3、Spark 3.4.3(bin-hadoop3)、JDK 8 - **实现目录**:`job-template/job/hadoop`(入口 `start.sh` 先执行 `set.sh` 再跑 `--command`) ### 参数 | 参数 | 类型 | 必填 | 说明 | |---|---|---|---| | `--command` | str | 是 | 要执行的命令,如 `spark-submit /path/app.py`、`hive -e "SELECT 1"`、`hadoop fs -ls /` | ### 对接集群的环境变量(运行时由 `set.sh` 写入 xml 配置) | 环境变量 | 说明 | |---|---| | `FS_DEFAULTFS` | HDFS defaultFS,如 `hdfs://your-namenode:9000` → 写入 `core-site.xml` | | `YARN_RESOURCEMANAGER_ADDRESS` | YARN RM 地址,如 `your-rm-host:8032` → 写入 `yarn-site.xml` | | `HIVE_METASTORE_URIS` | Hive Metastore thrift 地址,如 `thrift://your-hive-metastore:9083` → 写入 `hive-site.xml`(不用 Hive 可不配) | 当 `spark-submit` Driver 跑在 K8s 内时,`set.sh` 还会从平台注入的 `PORT1`(`spark.driver.port`)、`PORT2`(`spark.blockManager.port`)、`K8S_HOST_IP`(`spark.driver.host`)写入 Spark 配置,一般无需手填。 **二次开发切换 Hadoop 2 栈**:编辑 `Dockerfile`,启用预留的 `HADOOP_VERSION=2.7.2`、`HIVE_VERSION=1.2.2`、`SPARK_VERSION=2.1.3`、`SPARK_HADOOP_VERSION=2.7`,在 `job-template` 目录用 `docker build ... -f job/hadoop/Dockerfile .` 重建并改模板镜像。 --- ## spark 通过 **spark-operator** 提交 `SparkApplication`(`sparkoperator.k8s.io/v1beta2`,见 `job-template/job/spark/launcher.py:118`)跑 Spark 作业。 - **镜像**:`ccr.ccs.tencentyun.com/cube-studio/spark:20260601`(`job-template/job/spark/build.sh` 当前构建版本;README 正文里写的是旧版 `20230701`,以 build.sh 为准) - **K8s 账号**:`kubeflow-pipeline` - **实现**:`job-template/job/spark/launcher.py` ### 参数 | 参数 | 类型 | 必填 | 默认 | 说明 | |---|---|---|---|---| | `--image` | str | 是 | `ccr.ccs.tencentyun.com/cube-studio/spark-operator:spark-v3.1.1` | 执行镜像 | | `--num_worker` | str | 是 | `3` | executor(`instances`)数目 | | `--code_type` | str | 是 | `Python` | 语言:`Java`/`Python`/`Scala`/`R` | | `--code_class` | str | 否 | - | Java/Scala 主类名(`mainClass`),其他语言不填 | | `--code_file` | str | 是 | `local:///opt/spark/examples/src/main/python/pi.py` | 代码文件(`mainApplicationFile`),支持 `local://`/`http://`/`hdfs://`/`s3a://`/`gcs://` | | `--code_arguments` | str | 否 | - | 代码参数 | | `--sparkConf` | text | 否 | - | spark 配置,每行 `xx=yy` | | `--hadoopConf` | text | 否 | - | hadoop 配置,每行 `xx=yy` | > 注意(来自源码与 README):当前版本 spark-operator 无法挂载分布式存储中的代码文件,因此 `code_file` 主要用 http 地址。分布式存储路径 `/mnt/admin/xx/example.py` 对应 http 形如 `http://127.0.0.1/static/mnt/admin/xx/example.py`。`launcher.py` 会自动把以 `local:///mnt/` 开头的 `code_file` 转换为 `/static/mnt/...` 的 http 地址(见 `job-template/job/spark/launcher.py:273-275`)。 --- ## ray 在 Kubernetes 上**按需拉起一套 Ray 集群**并执行用户代码的分布式计算算子,用户无需事先部署 Ray。 - **镜像**:`ccr.ccs.tencentyun.com/cube-studio/ray:gpu-20250301`(以 init-job-template 为准) - **K8s 账号**:`kubeflow-pipeline` - **实现**:`job-template/job/ray/launcher.py` ### 运行机制 Launcher Pod 既是驱动端也是客户端,通过 K8s API 在当前命名空间创建:1 个 Head(Deployment+Service,容器执行 `ray start --head --port=6379 --num-cpus=$MY_CPU_REQUEST --block`)+ N 个 Worker(Deployment replicas=N,执行 `ray start --address=$RAY_HEAD_SERVICE_HOST:6379 --block`)。Head 命名 `ray-header-{KFJ_PIPELINE_NAME}-{KFJ_TASK_ID}`(截断 54 字符)。随后 Launcher 用 `ray.util.connect(:10001)` 连接并轮询直到节点数达到 worker 数,设置环境变量 `RAY_HOST=`,在工作目录下执行用户命令。 ### Head 服务端口 | 端口 | 用途 | |---|---| | `10001` | Ray 客户端连接端口(用户代码用 `:10001` 连接) | | `8265` | Ray Dashboard | | `6379` | Ray 内部 Redis | ### 参数 | 参数 | 类型 | 必填 | 默认 | 说明 | |---|---|---|---|---| | `--workdir` | str | 是 | `/` | 工作目录,用户命令在此执行 | | `--command` | str | 是 | `python3 mnist.py` | 用户启动命令,如 `python demo.py` | | `--num_worker` | int | 是 | `3` | Worker 数量(内部变量 `NUM_WORKER`),决定集群规模 | | `--init` | str | 否 | `''` | 初始化脚本,Head/Worker 启动前及当前驱动 Pod 内各执行一次(装依赖/备环境) | 镜像由平台注入(`KFJ_TASK_IMAGES`)。资源/调度从 `KFJ_TASK_RESOURCE_CPU/MEMORY/GPU`、`KFJ_TASK_NODE_SELECTOR`、`KFJ_TASK_VOLUME_MOUNT` 等环境变量读取。 ### 用户代码写法 ```python import os, ray @ray.remote def fun1(arg): return "back_data" if __name__ == "__main__": head = os.getenv("RAY_HOST", "") if head: ray.util.connect(head + ":10001") # 集群模式 else: ray.init() # 本地调试 ray.get([fun1.remote(i) for i in range(100)]) ``` `job_example.py`、`demo.py` 为目录内示例。 --- ## volcano 通过创建 **Volcano Job** CRD(`batch.volcano.sh/v1alpha1`)发起**多副本分布式计算**:所有 Worker Pod 使用相同镜像与命令,由 Volcano 调度,用环境变量区分副本序号,适合数据并行、批处理。 - **镜像**:`ccr.ccs.tencentyun.com/cube-studio/volcano:20250801`(`job-template/job/volcano/build.sh` 当前构建版本;README 正文里写的是旧版 `20230601`,以 build.sh 为准) - **K8s 账号**:`kubeflow-pipeline` - **实现**:`job-template/job/volcano/launcher.py`(入口 `python3 launcher.py`) ### 运行机制 Launcher 读取参数与 `KFJ_TASK_*` 环境变量,组装 Volcano `Job` 提交到当前命名空间:单个 Task 类型 `worker`,`replicas=num_worker`,`minAvailable=num_worker`,`schedulerName: volcano`,`queue: default`,`cleanPodPolicy: None`,启用 `env`/`svc`/`ssh` 插件;每个 Pod 以 `bash -c ` 执行。Launcher 用 `stern` 实时汇聚所有 Worker 日志(约每小时重启一次 stern),后台线程轮询 Job 状态,`Completed` 退出码 0,`Failed`/`Aborted`/`Terminated` 退出码 1。Pod 间用 Pod 反亲和尽量打散到不同节点(`topologyKey: kubernetes.io/hostname`)。 ### 参数 | 参数 | 类型 | 必填 | 默认 | 说明 | |---|---|---|---|---| | `--working_dir` | str | 是 | `/mnt/` | 运行 job 的工作目录 | | `--command` | str | 是 | `python3 mnist.py` | 运行命令,由 `bash -c` 执行 | | `--num_worker` | int | 是 | `3` | Worker 数量(Pod 副本数 / minAvailable) | | `--image` | str | 否 | `''` | Worker 镜像;不填则用模板默认镜像(`KFJ_TASK_IMAGES`) | 资源/调度来自 `KFJ_TASK_RESOURCE_CPU/MEMORY/GPU`、`GPU_RESOURCE_NAME`、`KFJ_TASK_RESOURCE_RDMA`、`KFJ_TASK_NODE_SELECTOR`、`KFJ_TASK_VOLUME_MOUNT`、`HUBSECRET` 等。 ### 用户代码(数据并行分片) Volcano 为各 Pod 注入 `VC_WORKER_NUM`(Worker 总数)、`VC_TASK_INDEX`(当前序号,0 起),用户据此分片: ```python import os WORLD_SIZE = int(os.getenv('VC_WORKER_NUM', '1')) RANK = int(os.getenv("VC_TASK_INDEX", '0')) local_task = [i for i in range(300) if i % WORLD_SIZE == RANK] # 仅处理本 Worker 分片 ``` --- ## nlp-process NLP 文本处理算子集合,单镜像 + 多运行文件,每个运行文件对应一个平台任务模板。 - **镜像**:`ccr.ccs.tencentyun.com/cube-studio/nlp-process:20260527`(`nlp-analyze-data` 例外,见下) - **实现目录**:`job-template/job/nlp-process` ### 子模板与运行文件 | 平台任务模板 | 运行文件 | 用途 | |---|---|---| | `nlp-clean-data` | `clean-data.py` | 文本清洗:无意义符号、格式规范、去重、异常规则、数值噪声、缺失值 | | `nlp-replace-private-data` | `replace-data.py` | 隐私/敏感信息替换:email、IP、数字串、自定义词 | | `nlp-filter-data` | `filter-data.py` | 文档质量过滤:长度、重复率、特殊字符、敏感词、中文占比 | | `nlp-analyze-data` | `analyze-data.py` | 大模型自动分类(领域/任务/语言)+ 质量指标 | | `markdown-to-qa` | `markdown-to-data.py` | Markdown/TXT 转 Alpaca/ShareGPT QA 数据集 | | `expand-qa` | `expand-dataset.py` | 已有 QA 举一反三扩展 + 规则型数据增强 | **推荐链路**:`replace-data.py`(可选脱敏) → `clean-data.py`(清洗) → `filter-data.py`(过滤) → `analyze-data.py`(可选分析) → `markdown-to-data.py`(生成 QA) → `expand-dataset.py`(可选扩展)。 ### nlp-clean-data(clean-data.py) 支持基础字符清理与高级清理:移除不可见字符/规范空格/去乱码、繁转简、去 HTML/XML/emoji/主题标签、半全角与日期数值规范、行/段/文件去重、规则异常检查、分箱/回归式数值噪声处理、缺失值保留/删除/填充,可输出清理报告 JSON。布尔参数用字符串 `true`/`false`。`--input_file_path` 可为文件或目录(目录递归处理)。 关键参数(共 24 个,完整表见 `job-template/job/nlp-process/README-clean-data.md`): | 参数 | 脚本默认 | 平台默认 | 说明 | |---|---|---|---| | `--input_file_path` / `--save_file_path` | `clean-input.txt` / `result.txt` | 个人空间路径 | 输入/输出文件或目录 | | `--remove_invisible_char` / `--standard_spaces` / `--remove_garbled_char` / `--traditional_to_simplified` | `false` | `true` | 基础字符清理(平台默认开启) | | `--remove_page_identifiers` / `--remove_emoticons` / `--remove_topic_tags` | `false` | `true` | 去 HTML/XML、emoji、`#话题#`/`#tag` | | `--normalize_formats` / `--validate_numeric_content` | `false` | `true` | 半全角/日期数值规范、数值异常检查 | | `--remove_duplicates` / `--dedupe_unit` / `--dedupe_scope` | `false` / `line` / `file` | `true` / `line` / `dataset` | 去重及粒度(`line`/`paragraph`/`file`)、范围(`file`/`dataset`) | | `--validation_rules` / `--drop_patterns` / `--drop_invalid_records` | 空 / 空 / `false` | 同 | 规则 JSON、删除正则、是否删异常段落 | | `--noise_method` / `--bin_count` / `--noise_threshold` | `none` / `5` / `3.0` | 同 | 数值噪声处理(`none`/`binning`/`regression`) | | `--missing_strategy` / `--missing_tokens` / `--fill_dict` | `keep` / `N/A,NULL,null,NaN,无,--,未知` / 空 | 同 | 缺失值策略(`keep`/`remove`/`fill`)、占位符、补全词典 | | `--report_file_path` | 空 | 报告路径 | 清理报告 JSON 输出 | ### nlp-replace-private-data(replace-data.py) > 该子模板在仓库中**无独立 README**(`README-replace-data.md` 不存在),以下据源码 `job-template/job/nlp-process/replace-data.py` 整理。 逐文件(或目录递归)对文本做隐私/敏感信息替换:email→`PI:EMAIL`,IPv4/IPv6→`PI:IP`,数字串(16/11 位、32 位十六进制、4 位、纯数字)→`PI:NUMBER`,以及自定义词替换。空文件跳过不保留。 | 参数 | 类型 | 默认 | 说明 | |---|---|---|---| | `--input_file_path` | str | `replace-input.txt` | 输入文件或目录 | | `--save_file_path` | str | `result.txt` | 输出路径(目录输入时按原文件名写到该路径所在目录) | | `--replace_email` | str | `false` | `true` 时替换邮箱为 `PI:EMAIL` | | `--replace_ip` | str | `false` | `true` 时替换 IPv4/IPv6 为 `PI:IP` | | `--replace_number` | str | `false` | `true` 时替换数字串为 `PI:NUMBER` | | `--replace_spec_word` | str | `''` | 自定义替换,格式 `旧:新` 多组用 `,` 或 `;` 分隔(按正则替换,如 `公司A:某公司,张三:某人`) | ### nlp-filter-data(filter-data.py) > 该子模板在仓库中**无独立 README**(`README-filter-data.md` 不存在),以下据源码 `job-template/job/nlp-process/filter-data.py` 整理。 逐文件按多项质量指标判定是否保留(任一不达标即丢弃,通过的才写出):字数/词数(jieba 分词)在范围内、字重复率/词重复率/特殊字符率/敏感词率不超阈值、中文占比不低于阈值。敏感词表来自镜像内 `keywords.txt`。 | 参数 | 类型 | 默认 | 说明 | |---|---|---|---| | `--input_file_path` | str | `filter-input.txt` | 输入文件或目录 | | `--save_file_path` | str | `result.txt` | 输出路径 | | `--char_num` | str | `1-100000` | 字数范围(用 `,`/`-`/`;`/`~` 分隔上下界) | | `--word_num` | str | `1-50000` | 词数范围(jieba 分词) | | `--char_repetition_rate` | str | `0.2` | 字重复率上限 | | `--word_repetition_rate` | str | `0.4` | 词重复率上限 | | `--special_char_rate` | str | `0.3` | 特殊字符率上限 | | `--sensitive_word_rate` | str | `0.001` | 敏感词率上限 | | `--chinese_word_rate` | str | `0.85` | 中文占比下限 | | `--perplexity` | str | `1110` | 困惑度阈值 | > 注意:`--perplexity` 参数在 `filter-data.py:80` 已定义,但当前过滤逻辑**未调用任何困惑度计算**(`args.perplexity` 在脚本中再无引用,过滤主循环 `filter-data.py:96-145` 也无相关分支),即该阈值实际不参与过滤。 ### nlp-analyze-data(analyze-data.py) 用大模型自动对文本做领域/任务/语言分类,并计算质量指标;输出领域/任务分布统计、质量指标明细/汇总 CSV 及图表。支持 `.txt`/`.csv`/`.jsonl`/`.jsonl.gz`,输入可为文件/目录/逗号列表/glob。大模型走 OpenAI 兼容接口,经环境变量 `API_URL`/`API_KEY`/`MODEL` 配置(也可用 `--api-url`/`--api-key`/`--model` 覆盖)。 | 参数 | 类型 | 默认 | 说明 | |---|---|---|---| | `--input` | str | (空,必填) | 输入数据(每行一句话) | | `--output` | str | `/mnt/{creator}/pipeline/text-dataset` | 输出目录 | | `--plots` | str | `true` | 是否输出图表 | | `--batch-size` | int | `10` | 大模型批处理大小 | | `--domains` / `--tasks` / `--languages` | str | 空 | 领域/任务/语言类别(逗号分隔;不填则模型自动分类) | | `--llm-params` | json | `{"temperature":0.5,"top_p":0.9,"max_tokens":2048}` | 大模型超参数 | > 注意:`README-analyze-data.md` 已过时,与源码存在多处不一致,**以源码 / 总 README 为准**:(1) README 称 `--batch-size` 默认 `5`,源码默认 `10`(`analyze-data.py:1175`);(2) README 的 `--output` 默认带 `/output` 后缀,源码无(`analyze-data.py:1170`);(3) README 示例用 `python start.py`,实际运行文件为 `analyze-data.py`;(4) README 顶部镜像写 `text-dataset-jobs:20251111`,但该脚本随 nlp-process 镜像构建,应以总 README 与 `build.sh` 的 `nlp-process:20260527` 为准。 ### markdown-to-qa(markdown-to-data.py) 把清洗/过滤后的 `.md`/`.txt` 高质量文本转换为 LlamaFactory 可用的 Alpaca/ShareGPT 问答对数据集:分块 → 大模型抽取文档上下文(摘要/关键点/实体等,失败回退规则摘要)→ 按 chunk×模板生成候选问题并去重 → 按质量评分重试/剔除低分样本。 主要参数(完整见 `job-template/job/nlp-process/README-markdown-to-data.md`): | 参数 | 默认 | 说明 | |---|---|---| | `--input` / `--output` | 个人空间路径 | 输入 `.md`/`.txt`(文件/目录/逗号列表/glob)/ 输出数据集 JSON | | `--format` | `alpaca` | `alpaca` 或 `sharegpt` | | `--expand_qa` / `--expand_num` | `false` / `3` | 是否继续举一反三扩展、每条扩展问题数 | | `--api-url` / `--api-key` / `--model` / `--llm-params` | 空 | 大模型 API 与超参(未传则读环境变量 `API_URL`/`API_KEY`/`MODEL`) | | `--chunk_size` / `--chunk_overlap` / `--min_chunk_chars` / `--qa_per_chunk` | `2000` / `200` / `80` / `3` | 分块与生成粒度 | | `--min_quality_score` / `--max_quality_retry` | `0.7` / `2` | 最低保留质量分、质量优化最大次数 | | `--metadata_output` | 空 | metadata 输出路径(为空写 `${output}.metadata.json`) | ### expand-qa(expand-dataset.py) 对已有 QA 数据集做大模型「举一反三」与/或离线规则增强,支持 `llm`/`rule`/`both` 三种模式。规则增强含同义词替换、近音字替换、随机插入、随机交换、随机删除。 主要参数(完整见 `job-template/job/nlp-process/README-expand-dataset.md`): | 参数 | 默认 | 说明 | |---|---|---| | `--input` / `--output` | 个人空间路径 | 输入 QA JSON(Alpaca/ShareGPT 自动识别)/ 输出 JSON | | `--format` | `alpaca` | `alpaca` 或 `sharegpt` | | `--expand_num` | `3` | 每条 QA 大模型扩展问题数 | | `--keep_original` | `true` | 是否保留原始数据 | | `--augment_mode` | `llm` | `llm`/`rule`/`both` | | `--augment_methods` | `synonym_replace,homophone_replace,random_insert,random_swap,random_delete` | 规则增强方法(逗号分隔) | | `--augment_num` / `--augment_fields` | `1` / `instruction` | 每条规则增强数量、增强字段 | | `--synonym_dict` / `--homophone_dict` / `--insert_words` | - | 同义词/近音字词典、可插入词 | | `--replace_prob` / `--insert_prob` / `--swap_prob` / `--delete_prob` / `--random_seed` | - | 各操作概率与随机种子 | | `--llm-params` | - | 大模型 API 与超参 | --- ## feature-process 特征工程算子集合,镜像 `ccr.ccs.tencentyun.com/cube-studio/feature-process:20260601`(`job-template/job/feature-process/build.sh` 当前构建版本;README 正文里写的是旧版 `20250801`,以 build.sh 为准),每个任务对应一个 launcher 脚本,以不同任务模板注册:实际运行哪个脚本由平台下发的 `job_template_command`(如 `python3 launcher-combine.py`)决定。`Dockerfile` 仅把目录拷进 `/app`、设 `WORKDIR /app`,**未设置 ENTRYPOINT/CMD**(见 `job-template/job/feature-process/Dockerfile`),所以必须靠模板命令指定入口;镜像内脚本名即仓库内文件名(`launcher-combine.py`/`launcher-calculate-correlation.py`/`launcher-feature-importance.py`/`launcher-hadamard-multiply.py`/`launcher-union-join-data.py`/`launcher-all.py`)。实现目录 `job-template/job/feature-process`。 > 一体化模板 `feature-process-all` 的入口脚本 `launcher-all.py` 也在该目录内、同属 `feature-process` 镜像,见本节末尾。 ### feature-combine(特征组合,launcher-combine.py) 对指定列两两组合衍生新特征,新列名 `{col1}_{col2}_{method}`。方法:`cross`(逐元素相乘)、`polynomial`(`col1^2+col2^2`)、`statistics`(逐行均值)、`aggregation`(按 col1 分组对 col2 取组内均值)、`hashing`(拼接字符串 hash 对 1000 取模)。 | 参数 | 类型 | 说明 | |---|---|---| | `--input_dataset_path` / `--save_dataset_path` | workdir | 输入/输出 CSV | | `--params` | json | `{"方法名": "列1,列2,列3", ...}`,如 `{"cross":"age,duration","statistics":"age,duration,campaign"}` | ### hadamard-multiply(Hadamard 积,launcher-hadamard-multiply.py) 对两个**同形状** CSV 做逐元素乘积 `result[i,j]=data1[i,j]*data2[i,j]`;shape 不一致则报错退出。 | 参数 | 类型 | 说明 | |---|---|---| | `--data1` / `--data2` | workdir | 两个 CSV,行列数必须一致 | | `--save_dataset_path` | workdir | 结果保存路径 | ### calculate-correlation(相关性,launcher-calculate-correlation.py) 对指定特征列计算相关系数矩阵并写 CSV。 | 参数 | 类型 | 说明 | |---|---|---| | `--input_dataset_path` | workdir | 输入 CSV | | `--result_path` | workdir | 相关性矩阵输出 CSV | | `--corr_type` | str | 相关系数类型,可多选逗号分隔 | | `--feature_columns` | str | 参与计算的特征列(逗号分隔) | `corr_type` 实际只有 `corr` 有效:`corr` 分支用 `DataFrame.corr()`(Pearson)计算相关系数矩阵并写出到 `--result_path`。代码里另有 `kappa`(Cohen's kappa)分支,但**整段被三引号块注释掉了**(`job-template/job/feature-process/launcher-calculate-correlation.py:23-33`),传 `kappa` 不会有任何输出。 ### feature-importance(特征重要性,launcher-feature-importance.py) 用多种方法计算特征重要性,可多 method × 多 target,结果合并为一张表。 | 参数 | 类型 | 说明 | |---|---|---| | `--input_dataset_path` / `--save_dataset_path` | workdir | 输入 / 输出(默认 `feature_importance.csv`)| | `--target` | str | 目标列名,可多列逗号分隔 | | `--method` | str | 评估方法,可多个逗号分隔 | | `--col_name` | str | 参与计算的特征列;不填则用除 target 外全部列 | | `--model_path` | workdir | 可选,用已有模型评估重要性 | `method` 取值:`logistic_regression`、`random_forest`、`xgb`、`mutual_if`(互信息)、`iv`(IV 值)、`chi`(卡方,仅非负特征)、`variance`(归一化方差)。 ### union-join-data(合并/连接,launcher-union-join-data.py) 对多张表按顺序两两合并。 | 参数 | 类型 | 默认 | 说明 | |---|---|---|---| | `--data` | text | - | 多个表路径,用 `\|`/`,`/换行分隔 | | `--merge_type` | str | `row_union` | 合并类型(见下) | | `--ignore_index` | str | `True` | 合并后是否重置索引 | | `--join_columns` | str | - | join 时的连接列(逗号分隔),union 可不填 | | `--save_dataset_path` | workdir | - | 结果保存路径 | `merge_type`:`row_union`(按行/UNION ALL)、`column_union`(按列)、`left_join`/`right_join`/`inner_join`/`outer_join`(需 `join_columns`)。 ### feature-process-all(一体化特征工程,launcher-all.py) 一体化特征工程入口,单入口脚本 `launcher-all.py`(与上面几个 launcher 同在 `feature-process` 镜像内),通过 `--params`(JSON 单对象或对象数组,按顺序执行多步)中的 `process_type` 区分处理类型。 > 注意:`README-feature-process-all.md` 已过时——正文写入口 `python3 launcher.py`、镜像 `feature-process-all:20231128`,但仓库实际文件名是 `launcher-all.py`,且 `feature-process/build.sh` 只构建一个 `feature-process:20260601` 镜像、未单独构建 `feature-process-all`。平台 `myapp/init/init-job-template.json` 中的 feature-process-all 系模板(run-sql、sort 等)已确认统一使用镜像 `feature-process:20260601` + 启动命令 `python3 launcher-all.py`,「单独 feature-process-all 镜像」是历史写法。 | 参数 | 类型 | 必填 | 说明 | |---|---|---|---| | `--input_dataset_path` / `--save_dataset_path` | str | 否 | 输入/输出 CSV | | `--params` | str | 是 | 步骤配置 JSON,每条须含 `process_type`;通用可选字段 `col_name`/`col_map`/`keep`/`y_col` | 支持的 `process_type`(35 种,见 `job-template/job/feature-process/README-feature-process-all.md`): ``` width_dist 等宽离散化、freq_dist 等频离散化、boxcox 变换、pca 主成分、binarization 二值化、 featurehasher 特征哈希、polynomialfeatures 多项式展开、maxabsscaler、minmaxscaler、standardscaler、 normalizer 向量归一化、kbinsdiscretizer 分箱、one_hot 独热、drop_duplicates 去重、col_rename 列重命名、 sort 排序、z_score、dct_transform DCT、chi_ 卡方选择、svd 奇异值分解、random_sample 随机抽样、 weight_sample 加权抽样、level_sample 分层抽样、over_under_sample 过/欠采样、select 选列/删列、 label_encoding 标签编码、type_transfer 类型转换、index_to_col 索引转列、runsql 执行SQL、add_index 增加索引、 time_format 时间格式化、split_column 列拆分、split_data 拆分数据集、func_transfer 函数转换、ma 移动平均 ``` ```bash python3 launcher.py --input_dataset_path in.csv --save_dataset_path out.csv \ --params '[{"process_type":"width_dist","col_name":"age","bins":5},{"process_type":"standardscaler","col_name":"age,duration"}]' ``` --- > 各算子镜像版本、默认值与命令行行为可能随版本变化,具体以 `job-template/job/<算子目录>` 源码为准。 --- ### 机器学习任务模板(sklearn 算法族 / ray-sklearn 分布式) - 链接: https://www.cubestudio.vip/docs/05-%E4%BB%BB%E5%8A%A1%E6%A8%A1%E6%9D%BF/03-%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0 - 分类: 05-任务模板 / 机器学习 - 适用场景: 需要在 cube-studio pipeline 上用 sklearn / xgboost / lightgbm / statsmodels 跑表格类机器学习(分类/回归/聚类/时序)或用 Ray 分布式跑 sklearn 时 - 关键词: 机器学习 / sklearn / scikit-learn / ray-sklearn / ray / joblib / 分布式训练 / adaboost / arima / ar / bayesian / naive-bayes / 朴素贝叶斯 / decision-tree / 决策树 / gbdt / kmeans / 聚类 / knn / lightgbm / lr / logistic-regression / 逻辑回归 / random-forest / 随机森林 / rf-regression / 回归 / xgboost / xgb / launcher / model_params / 超参数 / 训练 / 评估 / 推理 - 最后更新: 2026-06-30 # 机器学习任务模板 本篇覆盖两类「经典机器学习」任务模板: - **sklearn**:单个镜像内含一组 `launcher-*.py` 脚本,覆盖 adaboost / ar / arima / bayesian / decision-tree / gbdt / kmeans / knn / lightgbm / lr / random-forest / rf-regression / xgb 及通用 `launcher-sklearn`,用于表格数据的分类、回归、聚类与时间序列。 - **ray-sklearn**:基于 Ray + Joblib 的分布式 sklearn 训练/推理。 > 任务家族描述里所说的「sklearn 及其算法」即指 sklearn 目录下的多 `launcher-*.py` 算法子模板。 --- ## sklearn 源码目录:`job-template/job/sklearn/`。一个镜像内放了 13+ 个 `launcher-*.py`,每个算法是一个独立子模板,但共享同一套数据约定与参数风格。 ### 共用约定 - **镜像**:`ccr.ccs.tencentyun.com/cube-studio/sklearn:20250801`(见 `job-template/job/sklearn/build.sh:5`)。 - 镜像内依赖(见 `Dockerfile`):`scikit-learn==1.6.1`、`xgboost==2.1.4`、`statsmodels==0.14.5`、`pandas==2.3.2`、`numpy==2.0.2`、`graphviz==0.21`、`matplotlib==3.9.4`、`joblib==1.5.2` 等,基础镜像 `python:3.9`。 > 注意:`job-template/job/sklearn/Dockerfile:14` 的 `ENTRYPOINT` 写的是 `python3 launcher-skearn.py`(拼写少了一个 l,且该文件不存在),实际可用脚本名为 `launcher-sklearn.py`。任务模板里通过「启动命令」覆盖入口(如 `init-job-template.json:4828` 的 `python3 launcher-sklearn.py`),所以正常使用不受该 ENTRYPOINT 影响;但镜像默认入口是坏的(如需可顺手修正 Dockerfile)。 - **启动命令**:在任务模板里配置 `python launcher-xxx.py`,按算法选择对应脚本。 - **三种运行模式**(由传入哪个数据集参数决定,绝大多数脚本一致): - 传 `--train_dataset`:执行训练,输出模型 `.pkl` 与训练/测试评估指标; - 传 `--val_dataset`:执行评估,输出 `val_result*.json`; - 传 `--inference_dataset`:执行推理,输出 `inference_result.csv`。 - **通用参数**(大多数脚本都有,少数算法做了裁剪,见下表「特有/裁剪」列): | 参数 | 含义 | |------|------| | `--train_dataset` | 训练集 CSV 路径 | | `--val_dataset` | 评估集 CSV 路径 | | `--inference_dataset` | 推理集 CSV 路径 | | `--feature_columns` | 特征列名,逗号分隔 | | `--label_columns` | 标签列名,逗号分隔(分类/回归用) | | `--save_model_dir` | 模型与评估结果保存目录或 `.pkl` 路径 | | `--load_model_path` | 从指定 `.pkl` 加载模型(部分脚本支持) | | `--model_params` | JSON 字符串,传给具体模型的超参数,默认 `{}` | 以上参数名已逐一对照各 `launcher-*.py` 的 `argparse` 核实一致(如 `launcher-lr.py:244-251`、`launcher-adaboost.py:246-253`)。 ### 各算法子模板速查 | 子模板 | 脚本 | 底层模型 / 库 | 任务类型 | 特有 / 裁剪参数 | |--------|------|---------------|----------|------------------| | sklearn(通用分类) | `launcher-sklearn.py` | 多种 sklearn 分类器,由 `--model_name` 选择 | 分类 | 多 `--model_name`、`--train_test_split_ratio`(默认`0.8`);无 `--load_model_path` | | adaboost | `launcher-adaboost.py` | `AdaBoostClassifier` | 分类 | 模型文件 `adaboost_model.pkl` | | bayesian | `launcher-bayesian.py` | `MultinomialNB` + `CountVectorizer` | 文本分类 | `--feature_columns` 仅填 1 个文本列;无 `--load_model_path` | | kmeans | `launcher-kmeans.py` | `KMeans` | 聚类 | 输出轮廓系数 + 散点图;`--label_columns` 可空;无 `--load_model_path` | | lr | `launcher-lr.py` | `LogisticRegression` | 分类 | 二分类输出 ROC/AUC | | decision-tree | `launcher-decision-tree.py` | `DecisionTreeClassifier` | 分类 | 额外导出 DOT + graphviz 渲染 `iris_tree.png`(见 `launcher-decision-tree.py:192`) | | knn | `launcher-knn.py` | `KNeighborsClassifier` | 分类 | 适合小数据低维 | | random-forest | `launcher-random-forest.py` | `RandomForestClassifier` | 分类 | 模型文件 `randomForest_model.pkl` | | rf-regression | `launcher-rf-regression.py` | `RandomForestRegressor` | 回归 | 指标为 MSE;无 `--load_model_path` | | xgb | `launcher-xgb.py` | `xgboost.XGBClassifier` | 分类 | `LabelEncoder` + `xgb_label_mapping.json` 反解标签(见 `launcher-xgb.py:201,207`) | | gbdt | `launcher-gbdt.py` | `GradientBoostingClassifier` | 分类 | 中小规模表格数据 | | lightgbm | `launcher-lightgbm.py` | `lightgbm.LGBMClassifier` | 分类 | 高维稀疏/大数据 | | ar | `launcher-ar.py` | `statsmodels` `AutoReg` | 时间序列 | 用 `--feature_col`/`--time_col`/`--start`/`--end`/`--lag`,仅训练,输出 `predict.csv` | | arima | `launcher-arima.py` | `statsmodels` `ARIMA` | 时间序列 | 同 ar,但用 `--order`(字符串元组如 `"(2,1,2)"`)替代 `--lag` | 说明:分类脚本统一逻辑——二分类用 `roc_auc_score` 并绘制 ROC 曲线;多分类输出 accuracy/precision/recall/f1。模型路径由统一逻辑解析,支持「目录」或「`.pkl` 文件路径」两种写法。 > 注意:评估结果文件名实际为 `val_result.json`(把超参数 JSON 拼进文件名,见 `launcher-adaboost.py:205`、`launcher-xgb.py:230`),并非固定的 `val_result.json`。 ### 时间序列(ar / arima)参数 `ar` / `arima` 与分类脚本参数不同,核对 `launcher-ar.py:61-67` / `launcher-arima.py:61-67`: - `--train_dataset`:时间序列 CSV; - `--feature_col`:单一数值列名(注意是 `feature_col` 单数,不是 `feature_columns`); - `--time_col`:时间列名,用于排序; - `--start` / `--end`:预测起止位置(整数索引); - `--lag`(ar):AR 滞后阶数,常用 1–30; - `--order`(arima):`(p,d,q)` 字符串,如 `"(2,1,2)"`; - `--save_model_dir`:结果输出目录。 两者均按时间排序后 8:2 切分 train/test,输出 MSE 与 `predict.csv`。 ### 通用分类模板支持的模型(`launcher-sklearn.py`) 通过 `--model_name` 选择,覆盖(核对自 README 与脚本注释): `RandomForestClassifier`、`GradientBoostingClassifier`、`AdaBoostClassifier`、`ExtraTreesClassifier`、`BaggingClassifier`、`LogisticRegression`、`RidgeClassifier`、`SGDClassifier`、`PassiveAggressiveClassifier`、`SVC`、`LinearSVC`、`GaussianNB`、`BernoulliNB`、`MultinomialNB`、`KNeighborsClassifier`、`DecisionTreeClassifier`、`MLPClassifier`、`LinearDiscriminantAnalysis`、`QuadraticDiscriminantAnalysis`。 训练示例: ```bash python launcher-sklearn.py \ --train_dataset /mnt/admin/pipeline/example/ml/train.csv \ --train_test_split_ratio 0.8 \ --label_columns y \ --feature_columns age,duration,campaign,pdays,previous,emp_var_rate,cons_price_idx,cons_conf_idx,euribor3m,nr_employed \ --save_model_dir /mnt/admin/pipeline/example/ml/sklearn/ \ --model_name RandomForestClassifier \ --model_params '{"n_estimators":200,"max_depth":8,"min_samples_leaf":5}' ``` ### 常用超参数建议(model_params) - `RandomForestClassifier` / `RandomForestRegressor`:`n_estimators` 100–500、`max_depth` 3–20、`min_samples_leaf` 1–20、`max_features` `"sqrt"`/`"log2"`。 - `LogisticRegression`:`C` 0.01–10、`penalty` `"l2"`、`solver` `"lbfgs"`/`"liblinear"`、`max_iter` 100–2000。 - `SVC`/`LinearSVC`:`C` 0.1–10、`kernel` `"linear"`/`"rbf"`、`gamma` `"scale"`/`"auto"`。 - `KNeighborsClassifier`:`n_neighbors` 3–50、`weights` `"uniform"`/`"distance"`。 - `DecisionTreeClassifier`:`max_depth` 3–20、`min_samples_leaf` 1–20、`criterion` `"gini"`/`"entropy"`。 - `AdaBoostClassifier`:`n_estimators` 50–500、`learning_rate` 0.01–1、`algorithm` `"SAMME"`/`"SAMME.R"`。 - `KMeans`:`n_clusters` 2–20、`init` `"k-means++"`、`max_iter` 100–500、`n_init` 10–50。 - `MultinomialNB`(bayesian):`alpha` 0.1–10、`fit_prior` true/false。 - `XGBClassifier`(xgb):典型二分类 `{"n_estimators":200,"max_depth":6,"learning_rate":0.1,"subsample":0.8,"colsample_bytree":0.8,"reg_lambda":1.0,"objective":"binary:logistic","eval_metric":"auc"}`。 - `LGBMClassifier`(lightgbm):典型 `{"n_estimators":300,"learning_rate":0.05,"num_leaves":31,"max_depth":-1,"subsample":0.8,"colsample_bytree":0.8}`。 - `GradientBoostingClassifier`(gbdt):`n_estimators` 100–500、`learning_rate` 0.01–0.2、`max_depth` 3–10、`subsample` 0.6–1.0。 --- ## ray-sklearn 源码目录:`job-template/job/ray-sklearn/`(入口 `launcher.py`,模型映射 `common.py` 由 launcher 内联)。基于 [Ray](https://www.ray.io/) 的分布式能力,通过 **Ray + Joblib** 后端跑 sklearn 的训练与推理,适用于在 Kubernetes 上按需拉起 Ray 集群执行 sklearn 任务。 ### 镜像与运行机制 - **镜像**:`ccr.ccs.tencentyun.com/cube-studio/ray-sklearn:20250301`(见 `build.sh:5`,基于 `cube-studio/ray:nightly`,含 `scikit-learn==1.6.1`、`pandas==1.5.3`、`numpy==1.26.4`、`joblib==1.4.2`)。 - **启动命令**:`python3 launcher.py`。 - **K8s 账号**:需 `kubeflow-pipeline`(launcher 要在命名空间内创建 Ray 集群)。 - **执行流程**(核对 `launcher.py:62-147`): 1. 解析参数,校验「至少做训练或推理之一」、模型路径必填、训练时校验 label/feature 列; 2. `pd.read_csv(..., sep=',', header=0)` 读取数据(逗号分隔、首行列名); 3. `ray_launcher(num_worker, init_file, 'create')` 创建 Ray 集群(1 Head + N Worker),设置 `RAY_ADDRESS`; 4. `register_ray()` + `with joblib.parallel_backend('ray')` 内执行:训练则 `model.fit` 后 `joblib.dump`,推理则 `joblib.load` 后 `model.predict`,每行一个结果写入 `--predict_result_path`; 5. `ray_launcher(..., 'delete')` 销毁集群。 其中 Ray 集群通过 `from job.pkgs.k8s.py_ray import ray_launcher` 创建,`--init_file` 默认 `/app/init.sh`。 ### 支持的模型(`SUPPORT_MODELS`) 核对 `launcher.py:25-37`,模型名不区分大小写与空格: `GaussianNB`、`MultinomialNB`、`BernoulliNB`、`CategoricalNB`、`ComplementNB`、`KNeighborsClassifier`、`LogisticRegression`、`RandomForestClassifier`、`DecisionTreeClassifier`、`GradientBoostingClassifier`、`SVC`、`SVR`。 ### 启动参数(与 `launcher.py:152-162` 一致) | 参数 | 必填 | 说明 | |------|------|------| | `--train_csv_file_path` | 训练时必填 | 训练集 CSV(逗号分隔,首行 header) | | `--feature_columns` | 否 | 特征列名,逗号分隔;不填则除 label 外全部作为特征 | | `--label_columns` | 训练时必填 | 标签列名,逗号分隔 | | `--model_name` | 是 | 见上「支持的模型」 | | `--model_args_dict` | 否 | 模型超参数 JSON,如 `{"max_depth":5,"min_samples_leaf":10}` | | `--model_file_path` | 是 | 模型保存/加载路径(joblib 文件) | | `--predict_csv_file_path` | 推理时必填 | 预测用 CSV | | `--predict_result_path` | 推理时必填 | 预测结果保存路径(每行一个结果) | | `--num_worker` | 是 | Ray Worker 数量,1~10(`launcher.py:62` 校验) | | `--init_file` | 否 | 各节点启动前执行的脚本,默认 `/app/init.sh` | > 提示:`--train_csv_file_path` 的 argparse help 文案写的是「| 分割」,但代码实际用 `sep=','`(逗号分隔,见 `launcher.py:79`)。以逗号为准。 ### 使用示例 仅训练: ```bash python3 launcher.py \ --train_csv_file_path /mnt/admin/pipeline/example/sklearn/ml-label.csv \ --label_columns y \ --feature_columns age,duration,campaign \ --model_name RandomForestClassifier \ --model_args_dict '{"max_depth":5,"min_samples_leaf":10}' \ --model_file_path /mnt/admin/pipeline/example/sklearn/model.joblib \ --num_worker 2 \ --init_file /app/init.sh ``` 仅推理(需已有模型): ```bash python3 launcher.py \ --predict_csv_file_path /mnt/admin/pipeline/example/sklearn/ml-nolabel.csv \ --predict_result_path /mnt/admin/pipeline/example/sklearn/result.txt \ --model_file_path /mnt/admin/pipeline/example/sklearn/model.joblib \ --num_worker 2 ``` 训练 + 推理可在同一任务内先 `fit` 再 `predict`(同时传训练与推理参数)。 --- 具体参数与默认值以各 `launcher-*.py` 源码为准,本篇仅供导航与检索。 --- ### 深度学习分布式训练任务模板(TF / PyTorch / 多框架) - 链接: https://www.cubestudio.vip/docs/05-%E4%BB%BB%E5%8A%A1%E6%A8%A1%E6%9D%BF/04-%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0 - 分类: 05-任务模板 / 深度学习 - 适用场景: 需要在 cube-studio pipeline 上发起 TensorFlow / PyTorch / Paddle / DeepSpeed / Horovod / Megatron / ColossalAI / MindSpore / MindFormers / MXNet 等分布式训练时 - 关键词: 深度学习 / 分布式训练 / tensorflow / tf / tfjob / pytorch / pytorchjob / ddp / kubeflow / training-operator / deep-learning-framework / paddle / paddlejob / deepspeed / horovod / mpi / mpijob / megatron / colossalai / mindformers / mindspore / mxnet / mxjob / volcano / volcano-job / crd / operator / num_worker / num_ps / GPU / RDMA / NCCL / stern / launcher - 最后更新: 2026-06-30 # 深度学习分布式训练任务模板 本篇覆盖三组深度学习分布式训练模板: - **tf**:Kubeflow TFJob 分布式(TensorFlow)。 - **pytorch**:Kubeflow PyTorchJob 分布式。 - **deep-learning-framework**:一个统一镜像内含多框架 launcher,子框架包括 paddle / deepspeed / horovod / megatron / colossalai / mindformers / mindspore / mpi / mxnet。 这些模板都遵循同一套思路:**Launcher 容器只负责按平台下发的环境变量和启动参数组装一个分布式 CRD(TFJob / PyTorchJob / PaddleJob / MPIJob / MXJob / Volcano Job)并提交、用 `stern` 汇聚日志、轮询状态决定退出码,不包含你的训练逻辑**。真正的训练代码跑在你指定的 worker 镜像(`--image` / `--work_images`)里。 > 各分布式模板均依赖对应的 Operator/CRD(TFJob/PyTorchJob/PaddleJob/MPIJob/MXJob 需 Kubeflow training-operator,Volcano Job 需 Volcano 调度器)。集群、GPU、Operator 的准备见 **02-部署安装** 段。 --- ## tf 源码:`job-template/job/tf/launcher.py`。创建 Kubeflow **TFJob**(`kubeflow.org/v1`),发起 TensorFlow 多 Worker 分布式训练。 - **镜像(launcher 镜像)**:`ccr.ccs.tencentyun.com/cube-studio/tf:20230801`(`build.sh:5`)。 - **启动命令**:`python3 launcher.py`。**K8s 账号**:`kubeflow-pipeline`。 - **角色与副本**:仅 Worker 角色(无 PS/Chief),副本数 = `--num_worker`,适配 TF 2.x 的 `tf.distribute` 多 Worker。容器名固定为 `tensorflow`(TFJob 规范要求,见 `launcher.py:211`)。 - **策略**:`cleanPodPolicy: None`(不自动删 Pod 便于排查)、`backoffLimit = num_worker`(`launcher.py:282-283`)。 - **结束**:TFJob 状态为 `Succeeded` 退出码 0,否则 1。 - **启动参数**(核对 `launcher.py:336-339`): | 参数 | 默认值 | 说明 | |------|--------|------| | `--image` | 空 | worker 镜像;为空时用环境变量 `KFJ_TASK_IMAGES` | | `--working_dir` | `/mnt/` | 容器内工作目录 | | `--command` | `python3 mnist.py` | 实际执行命令(`bash -c` 执行) | | `--num_worker` | `3` | Worker 副本数 | TFJob 名称形如 `tfjob--xxxx`。示例训练代码可参考 Kubeflow 官方 `mnist_with_summaries`。 --- ## pytorch 源码:`job-template/job/pytorch/launcher.py`(含分布式示例 `demo.py`)。创建 Kubeflow **PyTorchJob**(`kubeflow.org/v1`,`plural: pytorchjobs`)。 - **镜像(launcher 镜像)**:`ccr.ccs.tencentyun.com/cube-studio/pytorch:20250801`(`build.sh:5`)。 - **角色与副本**:Master + Worker 两个角色(`launcher.py:332-333`);Worker 副本数 = `--num_worker` - 1(因为 Master 也算一个 worker,见 `launcher.py:307`)。容器名为 `pytorch`,PyTorchJob 名称形如 `pytorchjob--xxxx`。 - **策略**:`cleanPodPolicy: None`、`backoffLimit = num_worker`。 - **启动参数**:与 tf 一致 —— `--image` / `--working_dir`(默认`/mnt/`) / `--command`(默认`python3 mnist.py`) / `--num_worker`(默认`3`),见 `launcher.py:389-392`。 ### 分布式代码写法(你的训练脚本需自己改造) 每个 Pod 注入如下环境变量(`MASTER_PORT="23456"`): ```text NCCL_DEBUG=INFO MASTER_PORT=23456 NCCL_SOCKET_IFNAME=eth0 MASTER_ADDR=pytorchjob-xxx-master-0 WORLD_SIZE=3 # worker 总数 RANK=0 # 当前 worker 序号;master=0, worker-0=1, worker-1=2 ... ``` 要点: - 每个进程 rank 唯一,master 必须 rank=0;`WORLD_SIZE>1` 时调 `dist.init_process_group(backend=..., init_method=None)`(系统自动识别 RANK/WORLD_SIZE)。 - 用 `DistributedDataParallel` 封装 model;用 `DistributedSampler` 配合 `DataLoader`,每 epoch `train_sampler.set_epoch(epoch)`。 - 启动可直接 `python your_start.py`,或 `python -m torch.distributed.launch --nproc_per_node=<每worker卡数> --nnodes=$WORLD_SIZE --node_rank=$RANK --master_addr=$MASTER_ADDR --master_port=$MASTER_PORT train.py ...`。 ### GPU 利用率优化(要点) GPU 整卡占用时利用率低,核心原因是「CPU 操作慢阻塞 GPU 计算」(数据加载/预处理/频繁 IO/日志上报等)。常见优化: - 数据加载:数据导入集群存储、合并小文件、提高 `num_workers`、配置 `prefetch_factor`、`pin_memory=true`、增大 `batch_size`; - 数据预处理与训练拆成两个 task,或用 Nvidia DALI 在 GPU 上做预处理; - 减少 checkpoint / tensorboard / 日志的保存频率。 - 多进程共享单卡:用 `start.sh` 或 `start.py` 拉起多个进程,每个进程加 `--process_index xx --process_num xx`,后台运行并 `wait`。 监控可在平台「监控」按钮查看资源使用率,或在容器内 `watch nvidia-smi` / `gpustat`。 --- ## deep-learning-framework 源码目录:`job-template/job/deep-learning-framework/`,内含 `launcher-<框架>.py` 与子目录。**多个子框架共享同一个 launcher 镜像**: - **统一 launcher 镜像**:`ccr.ccs.tencentyun.com/cube-studio/deep-learning-framework:20260419`(多架构 amd64+arm64,见 `build.sh`)。镜像内含 `stern`、`kubernetes==28.1.0` 等,**没有默认 ENTRYPOINT**,因此每个子框架靠任务模板的「启动命令」指定,如 `python3 launcher-paddle.py`、`python3 launcher-deepspeed.py` 等。 > 旧版各子框架 README 里标注的 `paddle:20230801`、`megatron:20230801`、`mxnet:20221010`、`mindspore:20230801`、`mindformers:20250101`、`deepspeed:20230801` 等,是历史上各自独立的 launcher 镜像;当前已统一为上面的 `deep-learning-framework:20260419`。worker 镜像(`--image`/`--work_images`)则各框架不同,见各小节。 - **共用机制**(Volcano 类 launcher:deepspeed/megatron/colossalai/mindspore;Kubeflow CRD 类:paddle/horovod/mpi/mxnet/mindformers): - 从环境变量读取资源与调度:`KFJ_TASK_RESOURCE_CPU/MEMORY/GPU`、`GPU_RESOURCE_NAME`、`KFJ_TASK_NODE_SELECTOR`、`KFJ_TASK_VOLUME_MOUNT`(解析出 volumes/volumeMounts)、`KFJ_TASK_RESOURCE_RDMA`/`RDMA_RESOURCE_NAME`、`KFJ_TASK_IMAGES`、`HUBSECRET`、`IMAGE_PULL_POLICY`(默认`IfNotPresent`) 等; - 容器内注入 `NCCL_DEBUG=INFO`、`GPU_NUM`;无 GPU 时设 `NVIDIA_VISIBLE_DEVICES=none`;有 RDMA 时申请 RDMA 资源并加 `IPC_LOCK` capability; - 节点亲和按 `KFJ_TASK_NODE_SELECTOR`(如 `cpu=true,train=true`),Pod 反亲和尽量把同 Job 的 Worker 分散到不同节点; - 用 `stern` 实时汇聚日志、后台线程轮询状态,结束按状态返回退出码(成功 0 / 失败 1)。 > 说明:任务家族清单里的 `paddle` **不是独立顶层目录**,实际是 `deep-learning-framework/README-paddle.md` + `launcher-paddle.py`(PaddleJob CRD),在本文档以 paddle 子节呈现。 ### paddle `launcher-paddle.py` 创建 Kubeflow **PaddleJob**(`kubeflow.org/v1`)。 - **角色**:Worker(副本 = `--num_worker`)+ 可选 Master/PS(`--num_ps > 0` 时,副本 = `--num_ps`,与 Worker 同镜像/目录/命令)。 - **弹性策略**:`elasticPolicy.minReplicas = maxReplicas = num_worker`,`maxRestarts = 0`(固定副本、不自动重启,见 `launcher-paddle.py:299-302`)。 - **启动参数**(`launcher-paddle.py:370-374`):`--image`、`--working_dir`(默认`/mnt/`)、`--command`(默认`python3 mnist.py`)、`--num_ps`(默认`0`)、`--num_worker`(默认`3`)。 - **worker 镜像**:可用官方 `registry.baidubce.com/paddlepaddle/paddle:2.4.0rc0-gpu-cuda11.2-cudnn8.1-trt8.0`,启动命令如 `python -m paddle.distributed.launch train.py`。PaddleJob 名形如 `paddlejob--xxxx`,状态 `Succeeded`/`Completed` 视为成功。 ### deepspeed `launcher-deepspeed.py` 创建 **Volcano Job**(`batch.volcano.sh/v1alpha1`,`schedulerName: volcano`),一组相同规格的 Worker Pod,名称形如 `{job}-worker-0`、`{job}-worker-1`…。 - **启动参数**(`launcher-deepspeed.py:382-385`):`--working_dir`(默认`/mnt/`)、`--command`(默认`python3 mnist.py`)、`--num_worker`(默认`3`)、`--image`(空则用 `KFJ_TASK_IMAGES`)。 - launcher 跟踪 master Pod(`{job}-worker-0`)日志并等待结束;非 Succeeded 则非 0 退出。 - 多机时 worker 可读 `VC_WORKER_HOSTS`、`VC_TASK_INDEX` 等做节点发现;若用基于 SSH 的 DeepSpeed launcher,镜像内需装 `openssh-server` 并在 `--command` 中先起 sshd 再起 `deepspeed`,hostfile 自行生成。 ### horovod `launcher-horovod.py` 创建 Kubeflow **MPIJob**(`kubeflow.org/v1`),1 个 Launcher + N 个 Worker,Launcher 用 `mpirun -np ` 在 `--working_dir` 下执行 `--command`。 - **启动参数**(`launcher-horovod.py:416-419`):`--num_worker`(默认`2`)、`--command`、`--work_images`(默认 `ccr.ccs.tencentyun.com/cube-studio/horovod:20210401`)、`--working_dir`(默认`/mnt/admin`)。 - 注意 horovod 用的是 **`--work_images`**(不是 `--image`)。 - worker 镜像里需装好深度学习框架 + Horovod/MPI;只要在镜像里 `--command` 能正常跑单机训练,多机多卡封装由模板和 Kubeflow 接管。 ### megatron `launcher-megatron.py` 创建 **Volcano Job**(`batch.volcano.sh/v1alpha1`)。 - **启动参数**(核对 `launcher-megatron.py:379-382`):`--working_dir`(默认`/mnt/`)、`--command`(默认`python3 mnist.py`)、**`--cluster`**(默认`worker=3`)、`--image`。 > ⚠️ 注意:megatron **使用 `--cluster` 而非 `--num_worker`**(与旧 README 里写的 `--num_worker` JSON 不符,已按代码 `launcher-megatron.py:381` 改正)。`--cluster` 是按行的角色规格,每行 `角色=数量` 或 `角色:数量`(用 `:` 或 `=` 分隔,见 `launcher-megatron.py:284-298`),可定义多个角色,如: > > ```text > master=1 > worker=3 > ``` > > 每个角色生成一个 Volcano task,容器内注入 `VC_TASK_ROLE`。 - worker 侧可用 `VC_WORKER_NUM`(总 worker 数)、`VC_TASK_INDEX`(当前序号)做分工。 ### colossalai `launcher-colossalai.py` 创建 **Volcano Job**(`batch.volcano.sh/v1alpha1`,`schedulerName: volcano`,`minAvailable = num_workers` 保证一次性调齐)。Job 名形如 `colossalai--<4hex>`。 - **启动参数**(核对 `launcher-colossalai.py:375-378`):`--working_dir`(默认`/mnt/admin/pipeline/example/colossalai/`)、`--command`(默认`bash start.sh`)、`--num_worker`(默认`2`)、**`--work_images`**(默认 `hpcaitech/colossalai:0.3.0`)。 > ⚠️ 注意:colossalai **镜像参数是 `--work_images`,不是 `--image`**(旧 README 表格里写的是 `--image`,已按代码 `launcher-colossalai.py:378` 改正)。 - 监控:后台线程每 60s 检查 master Pod(`-worker-0`)状态,stern 跟踪日志(每轮约 10s,约 1 小时重启一次),master 为 Succeeded 则 exit(0) 否则 exit(1)。 ### mindspore `launcher-mindspore.py` 创建 **Volcano Job**(`batch.volcano.sh/v1alpha1`,`schedulerName: volcano`,`queue: default`),Job 名形如 `msjob--`。 - **启动参数**(`launcher-mindspore.py:376-379`):`--working_dir`(默认`/mnt/`)、`--command`(默认`python3 mnist.py`)、`--num_worker`(默认`3`)、`--image`(空则用 `KFJ_TASK_IMAGES`)。 - 状态为 `Completed`/`Failed`(或 aborted/terminated) 时退出;`Failed` 则非 0 退出。worker 数需与 MindSpore 的 `device_num`/`rank_size` 等配置一致。 ### mindformers `launcher-mindformers.py` 用于 MindFormers 分布式训练。 > ⚠️ 重要更正:旧 `README-mindformers.md` 称其「launcher 位于 `job/mindspore/launcher.py`,创建 Volcano Job,作业名 `msjob-`」,但当前实际代码 `launcher-mindformers.py` 创建的是 **Kubeflow PyTorchJob**(`kubeflow.org/v1`,`plural: pytorchjobs`,见 `launcher-mindformers.py:48-49`),作业名前缀为 **`mindjob-`**(`launcher-mindformers.py:77`),角色为 Master + Worker(`:333-334`),并非 Volcano Job。本节按代码为准。 - **启动参数**(`launcher-mindformers.py:390-393`):`--working_dir`(默认`/mnt/`)、`--command`(默认`python3 mnist.py`)、`--num_worker`(默认`3`)、`--image`。 - worker 命令会被追加 ` $MASTER_ADDR $MASTER_PORT $RANK` 等参数(见 `launcher-mindformers.py:255`)。worker 数需与 MindFormers 的 `device_num`/`rank_size` 一致。 ### mpi `launcher-mpi.py` 创建 Kubeflow **MPIJob**(`kubeflow.org/v1`,`plural: mpijobs`),实现 Horovod/MPI 等分布式。 - **角色**:Launcher 1 个(通过 `mpirun`/`horovodrun` 启动训练)+ Worker `--num_worker` 个(容器初始长时间 `sleep`,由 Launcher 经 `kubectl exec` 下发训练命令)。 - **启动参数**(`launcher-mpi.py:402-405`):`--num_worker`(默认`2`)、`--command`(默认`python /examples/tensorflow2_mnist.py`)、`--work_images`(默认 `horovod/horovod:0.20.0-tf2.3.0-torch1.6.0-mxnet1.5.0-py3.7-cpu`)、`--working_dir`(默认`/mnt/admin`)。同样用 `--work_images`。 - Launcher Pod 起来后最长等 1 小时拉镜像,再实时跟踪 Launcher 容器日志;结束读 MPIJob `conditions`,最近一次 `type == "Succeeded"` 退出码 0,否则 1。命令里不要写死 Node IP/Pod 名,集群拓扑由 Launcher 发现注入。 ### mxnet `launcher-mxnet.py` 创建 Kubeflow **MXJob**(`kubeflow.org/v1`),支持 Scheduler / Server / Worker 三类角色。 - **launcher 镜像(历史)**:`ccr.ccs.tencentyun.com/cube-studio/mxnet:20221010`(现统一为 `deep-learning-framework:20260419`)。 - **启动参数**(`launcher-mxnet.py:391-395`):`--working_dir`(默认`/mnt/`)、`--command`(默认`python3 mnist.py`)、`--num_ps`(默认`0`,对应 Server 角色 replicas)、`--num_worker`(默认`3`,对应 Worker replicas)、`--image`。 - 所有角色用同一镜像与命令(`bash -c <--command>`)。MXJob 名形如 `mxjob--xxxx`,状态 `Succeeded` 视为成功。 --- 各模板的 CRD 字段、资源组装与默认值以对应 `launcher-*.py` 源码为准,本篇仅供导航与检索。 --- ### 大模型任务模板(训练 / 蒸馏 / 剪枝 / 量化 / 评测) - 链接: https://www.cubestudio.vip/docs/05-%E4%BB%BB%E5%8A%A1%E6%A8%A1%E6%9D%BF/05-%E5%A4%A7%E6%A8%A1%E5%9E%8B - 分类: 05-任务模板 / 大模型 - 适用场景: 需要在 cube-studio pipeline 上对大模型做 SFT/PPO/reward 训练、推理性能压测、知识蒸馏、剪枝、量化、安全评估或 OpenCompass 评测时 - 关键词: 大模型 / LLM / llama-factory / llamafactory / SFT / 微调 / lora / ppo / dpo / reward / 奖励模型 / RLHF / llm-benchmark / 推理性能 / 压测 / throughput / llm-distillation / 知识蒸馏 / 硬标签蒸馏 / distillation / llm-prune / 剪枝 / LLM-Pruner / taylor / llm-quantization / 量化 / gptq / awq / gguf / bitsandbytes / llm-safety-eval / 安全评估 / 越狱 / jailbreak / opencompass / 评测 / benchmark / deepseek / qwen / start.py - 最后更新: 2026-06-30 # 大模型任务模板 本篇覆盖 7 个面向大模型(LLM)的任务模板,均位于 `job-template/job/` 下,入口多为 `start.py`,参数以前端可配置的 JSON 表单形式给出(key 即 `start.py` 的 argparse 参数名)。 | 模板 | 用途 | 入口 | 工作目录 | |------|------|------|----------| | llama-factory | 训练 / SFT / PPO / reward / eval | `start.py` `start-ppo.py` `start-reward.py` `start-eval.py` | `/root/llama_factory` | | llm-benchmark | 推理性能压测 | `start.py` | `/app` | | llm-distillation | 硬标签 / 知识蒸馏 | `start.py` | `/app`(默认) | | llm-prune | LLM-Pruner 剪枝 | `start.py` | `/app` | | llm-quantization | 量化(gptq/awq/gguf/hf) | `start.py` | `/app` | | llm-safety-eval | 越狱安全评估 | `start.py` | — | | opencompass | OpenCompass 评测 | `start.py` | `/app` | --- ## llama-factory 基于开源项目 [LLaMA-Factory](https://github.com/hiyouga/LLaMA-Factory),覆盖训练(SFT)、PPO、reward 模型训练与评估。 - **镜像**:当前 `build.sh` 构建并推送多架构 manifest `ccr.ccs.tencentyun.com/cube-studio/llama-factory:20260320`(由 `20260320-amd64` + `npu-vllm-20251124` 组成,见 `build.sh:5-13`)。 > 注意:`README.md:5` 仍写旧镜像 tag `llama-factory:20251124`,与 `build.sh` 当前推送的 `20260320` 不一致——经核对为 README 未同步更新(`build.sh:5-13` 才是当前构建)。请以实际部署的镜像 tag 为准。 - **工作目录**:`/root/llama_factory`。 - **多硬件 Dockerfile**:`Dockerfile-amd64`、`DockerFile-npu`(昇腾 NPU)、`Dockerfile-cambricon`(寒武纪)、`Dockerfile-dcu`(海光 DCU)、`Dockerfile-mx`(沐曦 MX),另有 `Dockerfile-encryption`、`Dockerfile-eval-amd64`。即同一模板支持多种国产/异构算力。 ### 四个入口脚本 四个脚本共享大部分训练参数,区别在 `--stage` 与少数特有参数(核对各脚本 argparse): | 脚本 | `--stage` | 用途 | 特有 | |------|-----------|------|------| | `start.py` | `sft` | 监督微调 SFT | — | | `start-ppo.py` | `ppo` | PPO 强化学习 | 额外 `--model_rm_lora_path`(reward 模型 lora 路径,`start-ppo.py:51`) | | `start-reward.py` | `rm` | 奖励模型训练 | `--dataset` 默认 `dpo_zh_demo`(`start-reward.py:51`) | | `start-eval.py` | — | 模型评估 | 见下方独立参数 | **SFT 训练参数**(`start.py:47-67`,前端 JSON 见 `README.md`):`--stage`(默认`sft`)、`--do_train`、`--model_name`(默认`deepseek-ai/DeepSeek-R1-Distill-Qwen-7B`)、`--model_path`(配置后忽略 model_name)、`--dataset`、`--template`(默认`deepseek3`)、`--finetuning_type`(`full`/`freeze`/`lora`)、`--lora_target`(默认`all`)、`--output_dir`、`--per_device_train_batch_size`(默认`4`)、`--gradient_accumulation_steps`(默认`4`)、`--lr_scheduler_type`(默认`cosine`)、`--logging_steps`(默认`10`)、`--save_steps`(默认`100`)、`--learning_rate`(默认`5e-5`)、`--num_train_epochs`、`--max_samples`、`--max_grad_norm`(默认`1.0`)、`--quantization_bit`(`4`/`8`/`none`)、`--fp16`(默认`true`)、`--merge_lora`。 > 默认值差异:`--num_train_epochs` 前端 JSON 默认 `5`,`start.py:62` argparse 默认 `3`;`--max_samples` 前端默认 `500`,argparse 默认 `300`。以平台 JSON 配置为准(实际下发会覆盖 argparse 默认)。 **评估参数**(`start-eval.py:26-34`):`--model_path`、`--adapter_model_path`、`--finetuning_type`、`--task`(默认`cmmlu_test`)、`--template`(默认`fewshot`)、`--lang`(默认`zh`)、`--n_shot`(默认`5`)、`--output_dir`、`--batch_size`(默认`4`)。 `--model_name` 提供大量 choice(Baichuan2 / GLM / ChatGLM / DeepSeek-V3/R1 系列 / Llama2/3/3.1/3.2 / Mistral/Mixtral / Qwen2/2.5/3 系列含 VL/Audio/Omni / Yi / Hunyuan / XVERSE / InternLM 等),`--template` 提供近百种对话模板(alpaca/qwen/qwen3/deepseek/deepseek3/llama3/glm4/gemma3 等),完整清单见 `README.md`。 --- ## llm-benchmark 评测大模型或量化大模型的推理性能。加载本地 HuggingFace 模型,按指定 batch/轮数/生成长度压测,输出吞吐、时延与资源消耗。 - **镜像**:`ccr.ccs.tencentyun.com/cube-studio/llm-benchmark:20260427`,工作目录 `/app`,启动 `python start.py`。 - **主要指标**:生成吞吐 `tokens/s`、请求吞吐 `requests/s`、响应时延、资源消耗(CPU/内存/GPU 利用率/显存/CUDA 峰值显存)。 - **启动参数**(`start.py:55-63`): | 参数 | 必填 | 默认 | 说明 | |------|------|------|------| | `--model_path` | 是 | — | 本地 HF 模型路径或名;多个模型用中/英文逗号分隔,逐个 × 每种量化方式评测 | | `--output_dir` | 是 | — | 结果输出目录 | | `--prompts_path` | 否 | 空 | txt/json/jsonl 测试集;不填走内置 4 条默认 prompt | | `--quantization` | 否 | `none` | `none`/`4bit`/`8bit`,多选逗号分隔;4bit/8bit 用 bitsandbytes 加载 | | `--dtype` | 否 | `float16` | `auto`/`float16`/`bfloat16`/`float32`(模型加载精度) | | `--batch_size` | 是 | `1` | 每轮请求数 | | `--iterations` | 是 | `20` | 正式评测轮数 | | `--max_new_tokens` | 是 | `128` | 每条最大生成 token | | `--input_length` | 否 | `512` | 输入 prompt 最大 token | > `--dtype` 在 `start.py` 中存在(`start.py:59`),但 README 的前端 JSON 未列出(属文档遗漏)。 - **输出**:顶层 `summary.json`/`summary_zh.json`(嵌套 `{模型: {量化: 指标}}`)+ 4 张单指标对比 CSV(吞吐 tokens / 吞吐 requests / 时延 / 显存,宽表,列=`<模型>/<量化>`)+ `summary_metrics_detail.csv` 长表;每个 `<模型>/<量化>/` 子目录下有该组合的 summary、`detail.csv`、`resource_samples.jsonl`(中英各一份)。 - **可视化**:另在 `/mnt/{KFJ_CREATOR}/pipeline/example/visualization/llm_benchmark/{KFJ_RUN_ID 或时间戳}/` 下放 4 张 compare CSV 副本,`metric.json` 中 4 条 echart-bar 分别指向(4 张柱状图拆开是因量级差异大)。echart 数据格式见关联文档。 --- ## llm-distillation 硬标签知识蒸馏 / 知识蒸馏。 - **镜像**:`ccr.ccs.tencentyun.com/cube-studio/llm-hard-distillation-knowledge-distillation:20250904`,启动 `python start.py`。 - **启动参数**(`start.py:15-32`): - `--type`:`HardDistillation`(数据蒸馏,推荐)/ `KnowledgeDistillation`(知识蒸馏,显存要求高,建议 >40G); - `--teacher_model_path_or_name` / `--student_model_path_or_name`:教师/学生模型(HF 名或本地路径); - `--student_template`:学生模型对话模板(如 qwen、deepseek); - `--out_model_path`:输出目录(LoRA 或合并后权重); - `--default_prompts_file_name`:默认提示词文件(argparse 默认 `/app/default_prompts.txt`); - `--epochs`(默认`10`)、`--num`(默认`30`,数据生成/采样条数)、`--max_new_tokens`(默认`2048`)、`--temperature`(默认`0.7`)、`--top_p`(默认`0.95`)、`--seed`(默认`42`); - `--min_words` / `--max_words`:样本词数约束(`max_words` 默认 `4096`); - `--data_path`:[知识蒸馏] 数据集路径(argparse 默认 `/app/distillation.jsonl`); - `--lambda_kd`(默认`0.5`,KD 与 CE 混合权重)、`--tau`(默认`2`,蒸馏温度); - `--merge_lora`(默认`false`)。 > 默认值差异:`--min_words` 前端 JSON 默认 `32`,`start.py:27` argparse 默认 `16`。 --- ## llm-prune 基于 [LLM-Pruner](https://github.com/horseee/LLM-Pruner) 的结构化剪枝。 - **镜像**:`ccr.ccs.tencentyun.com/cube-studio/llm-prune:20260123`,工作目录 `/app`,启动 `python start.py`。 - **启动参数**(`start.py:285-313`,与 README 一致): - 基础:`--base_model`(模型路径)、`--output_path`(日志+模型输出目录)、`--pruning_ratio`(默认`0.25`,剪掉比例 0-1)、`--pruner_type`(`random`/`l1`/`l2`/`taylor`,默认`taylor`); - 剪枝模式:`--prune_mode`(`block_wise`(推荐)/`channel_wise`/`layer_wise`)、`--layer`(仅 layer_wise,保留前 n 层,7B 共 32 层); - block_wise 专用:`--block_attention_layer_start`(默认`4`)/`--block_attention_layer_end`(默认`11`)/`--block_mlp_layer_start`(默认`4`)/`--block_mlp_layer_end`(默认`11`)(建议保留前 2-4 层与最后一层,7B 结束层=31、13B=39、70B=79); - block/channel_wise:`--iterative_steps`(默认`1`,多步迭代更好但更慢,1-5)、`--global_pruning`(`true`/`false`,跨层统一比较); - taylor 专用:`--grouping_strategy`(`sum`/`mean`/`max`/`prod`/`first`)、`--taylor`(`vectorize`/`param_second`/`param_first`/`param_mix`,默认`param_first`)、`--num_examples`(默认`1`,计算梯度样本数 1-20)。 --- ## llm-quantization 大模型量化,`--job` 区分量化方式。 - **镜像**:`build.sh:5` 构建 `ccr.ccs.tencentyun.com/cube-studio/llm-quantization:20250801`。 > 注意:`README.md:2` 写的是 `llm-quantization:20250823`,与 `build.sh:5` 实际构建的 `20250801` 不一致——经核对 `build.sh` 当前只构建 `20250801`(README 的 tag 仓库未构建)。请以实际部署的镜像为准。 - **工作目录**:`/app`,启动 `python start.py`。 - **启动参数**(核对 `start.py:18-21`): - `--job`:`gptq` / `awq` / `gguf` / `hf_quantize`(argparse 默认 `hf_quantize`,前端 JSON 默认 `gptq`); - `--model_path`:模型路径; - `--quantization`:量化位数,前端 choice 含 `2`/`3`/`4`/`8`/`q3_K_M`/`q3_K_L`/`q4_K_S`/`q4_K_M`/`q5_K_M`/`q8_0`/`8bit`/`4bit`(按量化类型选),argparse 默认 `4bit`; - `--output_dir`:量化后模型导出目录。 > 说明:早期 `README.md` 的前端 JSON 曾把这两个参数误写作 `--quantify` / `--export_model_dir_name`,与 `start.py:20-21` 的 `--quantization` / `--output_dir` 不一致;**现已改正**为 `--quantization` / `--output_dir`。注:真正的注册源 `myapp/init/init-job-template.json` 一直是正确的,故模板下发本就不受影响。 - 量化时会用 `wikitext-2-raw-v1` 在线校准(拉取失败则退回内置中文样本,见 `start.py:24-37`)。 --- ## llm-safety-eval 对大模型做多策略、多语言安全性压力测试。 - **镜像**:`ccr.ccs.tencentyun.com/cube-studio/llm-safety-eval:20251222`,启动 `python start.py`(含 `Dockerfile` 与 `Dockerfile-npu` 两种硬件)。 - **8 种越狱策略**(中英双语):基线直接提问、角色扮演反派、system 提示词忽略安全策略、法语/西班牙语翻译混淆、假设虚构场景、权威/研究用途诉求、多轮对话逐步引导。统计拒答率、越狱成功率、有害指示率、PII 输出率(邮箱/手机号/身份证号/信用卡号等)。 - **启动参数**(核对 `start.py:1063-1086`): - `--model_path`:模型本地路径(支持文本与 VL 模型,仅评估文本安全,`trust_remote_code` 默认开启); - `--dataset`:jsonl 测试集(字段需含 `prompt`,可选 `category`); - `--output`:输出目录; - `--languages`:逗号分隔语言,前端 choice `zh`/`en`/`all`,argparse 默认 `zh,en`(`all` 表示同时评测中英)。 - **输出**:`output.jsonl` 原始结果 + 中/英字段版 `output_zh/en.jsonl`、`summary_zh/en.json`、`summary_zh/en.csv`,以及中英各 7 张(共 14 个 PNG)可视化图表(最终评估卡片、语言对比、策略越狱率排名、类别×策略热力图、安全雷达图、策略-语言矩阵、累积分布曲线)。主要看 `summary_zh`。 --- ## opencompass 基于 OpenCompass 的模型评测。 - **镜像**:`ccr.ccs.tencentyun.com/cube-studio/opencompass:20260610`(`build.sh:5`),工作目录 `/app`,启动 `python start.py`。 - **启动参数**(核对 `start.py:18-26`): - `--model_path`:模型名或路径,支持多个用英文逗号分隔(如 `/mnt/model_a,/mnt/model_b`); - `--datasets`:数据集名(select2 多选,逗号分隔)。choice 含演示集 `demo_showcase_*`(EM/F1/匹配/BLEU/ROUGE/code/math 各 10 条本地样例)及多种 OpenCompass 配置名(gsm8k/math/cmmlu/humaneval/mbpp/triviaqa/drop/nq 等); - `--hf_type`:`chat`(对话/指令微调)/ `base`(基础因果 LM); - `--output_path`:评估结果与汇总输出目录(argparse 默认 `/mnt/{{creator}}/pipeline/example/export-result`,前端 JSON 默认 `.../output-opencompass`)。 - **内置演示数据集**:`demo_showcase_*` 每个仅 10 条样例,用于快速验证评估流程/冒烟测试,不代表真实评测结果;本地样例在 `demo/data/`,读取器与配置生成在 `demo/demo.py`,镜像构建时自动生成 OpenCompass 入口配置。 --- 各模板参数与默认值以对应 `start.py` / `start-*.py` 源码为准,本篇仅供导航与检索。 --- ### 模型服务化任务模板(转换/注册/部署/评估/离线推理) - 链接: https://www.cubestudio.vip/docs/05-%E4%BB%BB%E5%8A%A1%E6%A8%A1%E6%9D%BF/06-%E6%A8%A1%E5%9E%8B%E6%9C%8D%E5%8A%A1%E5%8C%96 - 分类: 05-任务模板 / 模型服务化 - 适用场景: 训练出模型后要做格式转换、注册到模型管理、一键部署推理服务、离线批量推理或离线评估指标时读这篇 - 关键词: 模型服务化 / model-convert / 模型转换 / ONNX / OpenVINO / NCNN / MNN / TFLite / RKNN / TensorRT / model-register / 模型注册 / deploy-service / 推理服务部署 / model-evaluation / 模型评估 / offline-predict / 离线推理 / 分布式推理 / RabbitMQ / Volcano / Ray / model-offline-predict / edge deploy / 边缘部署 / serving - 最后更新: 2026-06-30 # 模型服务化任务模板 本篇汇总 5 个面向「模型上线/批量推理」环节的 pipeline 任务模板,覆盖从模型转换、注册、部署到离线推理与评估的完整链路: | 任务模板 | 算子目录 | 作用 | |---|---|---| | **model-convert** | `job-template/job/model-convert` | PyTorch/YOLO → ONNX → OpenVINO/NCNN/MNN/TFLite/RKNN/TensorRT 等边缘多格式 | | **model-register** | `job-template/job/model_register` | 把训练产出的模型注册到平台「模型管理」 | | **deploy-service** | `job-template/job/deploy-service` | pipeline 内一键创建/更新推理服务并发布上线 | | **model-evaluation** | `job-template/job/model_evaluation` | 传统 ML 离线推理结果对比真值,算指标并输出 JSON | | **offline-predict** | `job-template/job/offline-predict` | 基于 RabbitMQ 的多 Worker 分布式离线推理 | > 命名提示:任务家族清单里有一个 `model_offline_predict` 目录,但当前为空,已跳过;平台编排界面里显示的任务名是 **model-offline-predict**,其实际算子代码就在 **offline-predict** 目录。其「模板使用」说明见 [05-任务模板/模板使用/README.md](模板使用/README.md)(对应 `08-模型服务化.md` 使用文档),本篇侧重算子设计与参数核对。 --- ## model-convert(模型转换:PyTorch/YOLO → ONNX → 边缘多格式) 将 **PyTorch / YOLO 模型** 统一先转换为 **ONNX**,再按需分发到下列任意组合的边缘部署格式(核对 `job-template/job/model-convert/start.py`、`backends/`、`verify/`): - **ONNX**(基础产物,所有 backend 的前置) - **INT8 动态量化 ONNX**(可选) - **OpenVINO**(Intel CPU/iGPU:`model.xml` + `model.bin`) - **NCNN**(手机/嵌入式:`model.param` + `model.bin`) - **MNN**(阿里 MNN:`.mnn`) - **TFLite**(移动端:`.tflite`,含 FP32 / dynamic range / FP16 多变体 + SavedModel) - **RKNN**(瑞芯微 NPU:`.rknn`,支持 RK3566/3568/3588 等) - **TensorRT Engine**(NVIDIA GPU:`-FP32.engine` + `-FP16.engine`) - **跨平台 SDK 库**(lib):把 ONNX 嵌入 C/C++ 动态库 `.so`/`.dll`,统一 C ABI ### 流程与入口 ``` PyTorch / YOLO ──► ONNX ──► (可选) INT8 动态量化 └► 按 --export_format 分发到各 backend onnx | openvino | ncnn | mnn | tflite | rknn | engine | lib ``` - **入口脚本**:`start.py`,工作目录 `/app`,启动命令 `python start.py`。 - **双模式输入**(`--model_type`,仅允许 `yolo` / `torch`): - **yolo**:调用 `ultralytics` 的 `export(format="onnx")`,固定 `imgsz=640`、`opset=12`、`dynamic=True`、`simplify=True`、`nms=True`(`start.py:69`)。 - **torch**:通过 `generic_loader.load_model_from_file` 加载 TorchScript / 完整 `nn.Module` / state_dict,再经 `torch2onnx_compat.torch_to_onnx` 导出(默认动态轴、图简化、导出后数值校验,`start.py:103-114`)。未指定 `--arch` 时会在有限集合内自动猜测架构。 - **多 backend 分发**:`--export_format` 是逗号分隔的格式列表,`onnx` 始终被自动加入(它是其它 backend 的前置)。各 backend 错误隔离——某个失败不影响其它格式,但只要有失败 backend,进程以**退出码 2** 结束(`start.py:282-283`),便于流水线判定。 - **量化**:`--do_quantize true` 时用 `onnxruntime.quantization.quantize_dynamic`(`QInt8`、`per_channel=True`)生成 `*-int8.onnx`(`start.py:119-124`)。 - **TensorRT**:`--onnx2engine true` 等价于把 `engine` 加进 `--export_format`,必须分配 NVIDIA GPU,且 engine 与构建时 GPU 架构强绑定,建议在与部署目标同型号的 GPU 上构建。 ### 输出路径 设 `BASE` 为 `--export_model_path` 去掉 `.onnx` 后的部分(如 `/out/x.onnx` → `BASE=/out/x`): | 格式 | 输出 | |---|---| | `onnx` | `--export_model_path` 指定的 `.onnx` | | INT8 量化 | `BASE-int8.onnx` | | `openvino` | `BASE_openvino/model.xml` + `model.bin` | | `ncnn` | `BASE_ncnn/model.param` + `model.bin` | | `mnn` | `BASE.mnn` | | `tflite` | `BASE_tflite/`(SavedModel + 多份 `.tflite`) | | `rknn` | `BASE.rknn` | | `engine` | `BASE-FP32.engine` + `BASE-FP16.engine` | | `lib` | `BASE_sdk/linux-x86_64/lib{lib_name}.so` 和/或 `BASE_sdk/windows-x86_64/{lib_name}.dll`,附 `inference.h`、`README.md` | ### 镜像与参数 - **镜像**:`ccr.ccs.tencentyun.com/cube-studio/model-convert:20260506`(核对 `build.sh`、`Dockerfile`,基础镜像 `nvidia/cuda:12.1.0-devel-ubuntu22.04`,内置 PyTorch 2.5 / Ultralytics / ONNX / onnxruntime / TensorRT / OpenVINO / NCNN / MNN / onnx2tf+TF / RKNN-Toolkit2 / cmake+g+++mingw-w64 等全部依赖)。 | 参数 | 适用 | 说明 | 默认值(start.py) | |---|---|---|---| | `--model_type` | 必填 | `yolo` / `torch` | `torch` | | `--model_path` | 必填 | 待转换模型文件路径(.pt/.pth) | 空 | | `--export_model_path` | 必填 | 导出 ONNX 的完整路径,其它产物落同目录 | `/mnt/pipeline/example/export-onnx/export.onnx` | | `--export_format` | 必填 | 逗号分隔,可选 `onnx,openvino,ncnn,mnn,tflite,rknn,engine,lib`;`onnx` 总会自动包含 | `onnx` | | `--arch` | torch | 架构名,可留空自动猜测 | `None` | | `--input_name` / `--output_name` | torch | ONNX 输入/输出名,逗号分隔,`none` 自动推断 | `None` | | `--do_quantize` | 通用 | `true`/`false`,是否生成 INT8 量化 ONNX | `false` | | `--onnx2engine` | 通用 | `true`/`false`,额外生成 TensorRT engine(需 GPU) | `false` | | `--rknn_target_platform` | rknn | `rk3566/rk3568/rk3588/rk3399pro/rv1103/rv1106` 等 | `rk3588` | | `--lib_target` | lib | `linux`/`windows`/`both` | `linux` | | `--lib_precision` | lib | `fp32`/`fp16` | `fp32` | | `--lib_name` | lib | 输出库基础名 | `model_inference` | > 注意:README 的「模板参数 JSON」里 `--lib_target` 默认写的是 `both`(`model-convert/README.md:215`),而 `start.py:38` 中 argparse 默认是 `linux`(已核对)。二者一处是平台注册时的展示默认值、一处是代码默认值;以代码(`linux`)为运行时默认,注册模板时可按需把界面默认改成 `both`。 ### 使用示例 ```bash # YOLO -> ONNX + OpenVINO + NCNN(如 yolo11n) python start.py --model_type yolo --model_path /app/yolo11n.pt \ --export_model_path /app/onnx_model/yolo11n.onnx \ --export_format onnx,openvino,ncnn # 通用 PyTorch -> 全格式(如 deeplabv3_resnet50) python start.py --model_type torch \ --model_path /app/deeplabv3_resnet50_coco-cd0a2569.pth \ --export_model_path /app/onnx_model/deeplabv3.onnx \ --export_format onnx,openvino,ncnn,mnn,tflite,rknn,engine,lib \ --rknn_target_platform rk3588 --lib_target both ``` YOLO 权重来源:。示例 PyTorch 权重:ResNet18 、DeepLabV3-ResNet50 。 ### SDK 库(lib)部署要点 + 模型验证 - 生成的 `.so`/`.dll` **不自带 ONNX Runtime**:部署时需把对应平台的 `libonnxruntime.so` / `onnxruntime.dll`(Windows 须用微软官方 Windows 版)与产物放同目录,运行期 `dlopen`/`LoadLibraryA` 加载,不在编译期链接。 - C ABI(签名见随产物的 `inference.h`):`model_init` → `model_get_input_count`/`model_get_output_count` → `model_infer` → `model_free_outputs` → `model_release`。 - 当前交叉编译仅覆盖 **x86_64**(toolchain `mingw-w64-x86_64.cmake`);arm64 Windows 暂未覆盖。 - 产物目录的 `verify/` 提供三种验证脚本与说明:`dll-verify.py`+`dll-readme.md`、`so-verify.py`+`so-readme.md`、`bin-verify.py`+`bin-readme.md`。Jupyter 内 `.so` 可能被隐藏,在终端中查看。 --- ## model-register(注册模型到模型管理) 将训练完成的模型**注册到平台「模型管理」模块**,便于版本追溯,并为后续转换、离线预测、在线推理提供模型来源(核对 `job-template/job/model_register/launcher.py`)。 ### 设计要点 - **注册/更新策略**:按「模型名 `model_name` + 当前 Run ID `KFJ_RUN_ID`」查询 `training_model_modelview` API;无记录则 **POST 新建**,有记录则 **PUT 更新**(避免同一 Run 重复注册)。 - **API 地址**:`host = HOST 或 KFJ_MODEL_REPO_API_URL`,默认 `http://kubeflow-dashboard.infra`(`launcher.py:17`,会 `strip('/')`)。 - **鉴权**:请求头 `Authorization` 取环境变量 `SECRET`(缺省回退 `KFJ_CREATOR`,再缺省 `admin`,`launcher.py:13`)。 - **校验项目组**:先按 `--project_name` 查 `project_modelview` API,项目不存在则打印「不存在项目组」并直接返回(不注册)。 ### 参数 → 模型管理字段映射 写入 `training_model_modelview` 的 payload(`launcher.py:65-78`): | 启动参数 | 写入字段 | 默认值 | |---|---|---| | `--project_name` | 用于校验并取 `project` 的 id | `public` | | `--model_name` | `name`(a-z0-9- 组成,≤54 字符) | `demo` | | `--model_version` | `version` | 当前日期 `v%Y.%m.%d.1` | | `--model_path` | `path` | 空 | | `--describe` | `describe` | `xx模型` | | `--model_metric` | `metrics`(可为 JSON 字符串) | 空 | | `--framework` | `framework`(lr/xgb/tf/pytorch/onnx/tensorrt/aihub) | `tf` | | `--inference_framework` | `api_type`(serving/ml-server/tfserving/torch-server/onnxruntime/triton-server/aihub) | `tfserving` | | 环境变量 | `run_id`(`KFJ_RUN_ID`)、`pipeline_id`(`KFJ_PIPELINE_ID`)、`run_time`、`md5`(空) | — | - **镜像**:`ccr.ccs.tencentyun.com/cube-studio/model_register:20230501`(核对 `model_register/build.sh`)。 - **命令行示例**: ```bash python launcher.py \ --project_name public --model_name my-model \ --model_version v2022.10.01.1 \ --model_path minio://bucket/path/to/model \ --model_metric '{"accuracy":0.95}' \ --describe "我的模型" --framework pytorch \ --inference_framework torch-server ``` > 注意:`model_path` 必须是任务运行环境可访问的路径;模型管理只存路径与元数据,本步骤不上传文件。同一 Run 内多次用相同 `model_name` 注册会**更新**同一条记录而非新增。 --- ## deploy-service(一键建/更推理服务并发布) 在 pipeline 中**一键创建或更新推理服务并自动发布上线**:按「模型名 + 模型版本」判断新建还是更新,完成后触发生产环境部署(核对 `job-template/job/deploy-service/launcher.py`)。 ### 前置条件 - **项目组已存在**:`--project_name` 指定的项目组必须在平台「项目组」中已创建,否则报「不存在项目组」并退出。 ### 行为流程(与 launcher 一致) 1. **项目组校验**:查 `project_modelview` API,不存在则退出。 2. **查询服务**:按 `model_name` + `model_version` 查 `inferenceservice_modelview` API。 - 不存在 → **POST** `/inferenceservice_modelview/api/` 创建; - 已存在 → **PUT** `/inferenceservice_modelview/api/{id}` 更新。 3. **发布**:成功后 `time.sleep(5)`(等数据落库),再 GET `/inferenceservice_modelview/api/deploy/prod/{id}` 部署到生产;返回 `302` 或 `200` 视为成功,否则打印错误退出(`launcher.py:115-125`)。 API 地址与鉴权同 model-register(`HOST`/`KFJ_MODEL_REPO_API_URL` + `Authorization=SECRET`)。 ### 参数 | 参数 | 说明 | 必填 | 默认值 | |---|---|---|---| | `--project_name` | 项目组(须已存在) | 是 | `public` | | `--label` | 服务中文名/描述 | 是 | `演示服务` | | `--model_name` | 模型名 | 是 | `demo` | | `--model_version` | 版本;同名+同版本→更新,否则新建 | 是 | 当前日期 `v%Y.%m.%d.1` | | `--model_path` | 模型地址 | 否 | 空 | | `--service_type` | 服务类型(serving/ml-server/tfserving/torch-server/onnxruntime/triton-server/vllm 等,以平台支持为准) | 是 | `serving` | | `--images` | 推理服务镜像 | 是 | `nginx` | | `--resource_memory` / `--resource_cpu` / `--resource_gpu` | 每 Pod 内存/CPU/GPU | 是 | `2G` / `2` / `0` | | `--replicas` | 副本数(min/max 均取此值) | 是 | `1` | | `--working_dir` / `--command` / `--args` / `--env` | 容器工作目录/启动命令/启动参数/环境变量 | 否 | 空 | | `--ports` | 暴露端口 | 否 | `80` | | `--host` | 部署域名,留空自动生成 | 否 | 空 | | `--volume_mount` | 挂载,支持 pvc/hostpath/configmap,如 `pvc名(pvc):/容器路径` | 否 | 空 | | `--inference_config` | 配置文件内容,挂到容器 `/config/`,留空被重置 | 否 | 空 | | `--hpa` | 弹性伸缩配置 | 否 | 空 | | `--metrics` | 指标采集,如 `8080:/metrics` | 否 | 空 | | `--health` | 健康检查,如 `8080:/health` 或 `shell:python health.py` | 否 | 空 | - **镜像**:`ccr.ccs.tencentyun.com/cube-studio/deploy-service:20240601`。 - **环境变量小技巧**:在模板环境变量里配 `HOST=http://xx.xx.xx.xx`,可让任务把服务发布到当前访问地址。 推理服务本身的使用、各 server 类型(ml-server / tfserving / torchserve 等)详见 [03-平台使用/07-服务化与推理](../03-平台使用/07-服务化与推理/推理服务-tfserving.md) 目录下相关文档。 --- ## model-evaluation(离线推理结果对比真值算指标) **传统机器学习模型**离线推理后,将**预测结果**与**带真实标签的评估数据集**逐行对比,按指定指标算评估结果并输出 JSON(核对 `job-template/job/model_evaluation/launcher.py`)。常置于「离线推理」之后、可与「模型注册」串联实现「推理 → 评估 → 注册」闭环。 ### 执行流程 1. 从真实数据集 CSV 取 `--true_label_column`(多列取第一列)得 `y_true`;从预测数据集 CSV 取 `--pred_label_column` 得 `y_pred`。 2. 校验 `len(y_true)==len(y_pred)`,不一致直接抛异常退出。 3. 按 `--model_type` 分流并按 `--eval_type` 选算指标,结果以 JSON 写入 `--save_result_path`。 - **分类指标(classify)**:precision、recall、accuracy、f1_score(分类用 `average='macro'`)、auc。 - **回归指标(regression)**:MSE、MAE、R2_Score、Explained_Variance_score。 - **eval_type 前缀处理**:launcher 会去掉界面下拉里的 `分类-`/`回归-`/`classify-`/`regression` 前缀后再匹配(`launcher.py:121`)。 > 注意:README 的 `--eval_type` 下拉 `choice` 只列了分类的 precision/recall/accuracy/f1_score 与回归项,未含 `分类-auc`(见 `model_evaluation/README.md` 的 choice 数组),但 `launcher.py:60-64` 代码里有 `auc` 分支(已核对,`auc` 来自 `from sklearn.metrics import ... auc`,按 `sklearn.metrics.auc(y_true,y_pred)` 计算)。`sklearn.metrics.auc` 是按梯形法对 (x,y) 坐标积分、并非由标签直接算 ROC-AUC,如需用 auc 请先确认数据形态与该函数语义是否匹配。 ### 参数 | 参数 | 说明 | |---|---| | `--true_dataset_path` | 真实标签数据集 CSV 路径 | | `--true_label_column` | 真实标签列名(多列取第一列) | | `--pred_dataset_path` | 预测结果数据集 CSV 路径 | | `--pred_label_column` | 预测值列名(多列取第一列) | | `--save_result_path` | 评估结果 JSON 输出路径 | | `--eval_type` | 评估指标,逗号分隔;可带 `分类-`/`回归-` 前缀 | | `--model_type` | `classify` 或 `regression` | - **镜像**:`ccr.ccs.tencentyun.com/cube-studio/model_evaluation:20230801`(核对 `model_evaluation/build.sh`)。 - **注意**:真实/预测数据集需**按行一一对应**且无缺失;列名要与各自 CSV 完全一致;分类指标配 `classify`、回归指标配 `regression`,否则结果无意义。 --- ## offline-predict(RabbitMQ 分布式离线推理) 面向**大规模离线推理**:多个 Worker 并行消费同一份数据源,对每条数据执行模型推理;适合「数据量大、单条耗时、需水平扩展」的场景(核对 `launcher-rabbitmq.py`、`predict_model.py`、`user_code_demo.py`)。 ### 整体架构 - **调度层**:`launcher-rabbitmq.py` 用 **Volcano Job**(`batch.volcano.sh/v1alpha1`,`queue=default`,`minAvailable=num_worker`)在 K8s 拉起一组 Worker Pod,用 `stern` 跟踪日志,按队列消费情况与 Job 状态判断结束;同时拉起一个单机 **RabbitMQ** Pod+Service(镜像 `rabbitmq:3.9.12-management`,端口 5672/15672,默认账号 `admin/admin`)。 - **任务协调层**:RabbitMQ 做任务队列(`predict_model.py`): - exchange `predict-exchange`(topic),queue `predict-queue`,routing key `predict-key`,消息持久化,`prefetch_count=1` 保证负载均衡。 - **角色划分**(`predict_model.py:277-298`): - `VC_TASK_INDEX==0 且 LOCAL_RANK==0`:**唯一生产者**,执行 `datasource()` 把数据逐条送入队列,再 `wait_finish()` 等待队列消费完。 - 其他进程(其他 Pod / 其他 `LOCAL_RANK`):**消费者**,从队列取消息执行 `predict(value)` 后 ack。 - 本地无 `VC_TASK_INDEX` 时退化为单进程:直接遍历 `datasource()` 逐条 `predict()`。 ### 用户只需实现两个方法 继承 `Offline_Predict`(来自与算子同目录的 `predict_model.py`),实现: - `datasource()`:返回待推理条目列表(如路径字符串列表),仅生产者调用。 - `predict(value)`:单条推理逻辑。 ```python # your_code.py import os, numpy from predict_model import Offline_Predict # 公司内部可改 from di.cube.offline_predict_model import Offline_Predict class My_Offline_Predict(Offline_Predict): def __init__(self): import tensorflow as tf self.model = tf.saved_model.load('/mnt/xx/your_model_path/') def datasource(self): with open('/mnt/xx/list.txt') as f: return [l.strip() for l in f.readlines()] def predict(self, value): return self.model(numpy.load(value)) if __name__ == '__main__': My_Offline_Predict().run() # run() 内部据 VC_TASK_INDEX/LOCAL_RANK 自动选生产者/消费者 ``` 启动脚本 `start.sh` 负责装依赖并按 `LOCAL_RANK` 启多个进程(单机内多进程提利用率): ```bash pip install pika requests numpy psutil --index-url https://mirrors.aliyun.com/pypi/simple for index in $(seq 0 2); do { export LOCAL_RANK=$index; python your_code.py; } & done wait ``` ### Launcher 启动参数 `launcher-rabbitmq.py` 接收(`launcher-rabbitmq.py:493-497`): | 参数 | 说明 | 默认值 | |---|---|---| | `--working_dir` | Worker 工作目录(需能访问代码与数据,如 `/mnt/{{creator}}/...`) | 空 | | `--command` | Worker 启动命令,通常 `bash start.sh` | 空 | | `--num_worker` | Volcano Job 的 Worker Pod 数(其中一个兼任生产者) | `3` | | `--image` | Worker 运行镜像(可与 Launcher 镜像不同) | `ubuntu:18.04`(注册模板时常配 `ccr.ccs.tencentyun.com/cube-studio/ubuntu-gpu:cuda11.8.0-cudnn8-python3.9`) | - **Launcher 镜像**:`ccr.ccs.tencentyun.com/cube-studio/offline-predict:20230801`,`ENTRYPOINT ["python3","launcher-rabbitmq.py"]`。 - **建议环境变量**(任务模板内):`NO_RESOURCE_CHECK=true`、`TASK_RESOURCE_CPU=4`、`TASK_RESOURCE_MEMORY=4G`、`TASK_RESOURCE_GPU=0`、`TASK_RESOURCE_RDMA=0`。 - **账号**:提交 K8s/Volcano 资源使用 `kubeflow-pipeline` 账号。 > 关于命名:平台编排界面里此模板显示为 **model-offline-predict**,实际算子代码就是 **offline-predict** 目录;空目录 `model_offline_predict` 已废弃跳过。其面向使用者的操作说明见 [05-任务模板/模板使用/README.md](模板使用/README.md)(`08-模型服务化.md`)。 --- *本篇为知识库导航/核对稿,具体参数与行为以各算子源码(`job-template/job/...`)为准。* --- ### 多媒体/CV/语音任务模板(视频音频/图像/语音/YOLO/OCR) - 链接: https://www.cubestudio.vip/docs/05-%E4%BB%BB%E5%8A%A1%E6%A8%A1%E6%9D%BF/07-%E5%A4%9A%E5%AA%92%E4%BD%93CV%E8%AF%AD%E9%9F%B3 - 分类: 05-任务模板 / 多媒体CV语音 - 适用场景: 要做视频抽帧/转音频、图像处理与质量评估、音频数据集清洗增强评估、YOLO 目标检测训练/评估/服务、OCR 文档转 Markdown 时读这篇 - 关键词: 多媒体 / 视频处理 / video-audio / media-download / video-img / 抽帧 / 视频提音频 / ffmpeg / Ray / 图像处理 / vision-process / 图片质量评估 / image-data-check / PSNR / SSIM / LPIPS / BRISQUE / 语音处理 / voice-process / 音频清洗 / 音频增强 / 音频评估 / audio clean augment eval / YOLO / yolo26 / yolov8 / 目标检测 / mAP / RTSP / 实时流推理 / PaddleOCR-VL / OCR / PDF转Markdown / NPU - 最后更新: 2026-06-30 # 多媒体 / CV / 语音任务模板 本篇汇总多媒体、计算机视觉与语音方向的 pipeline 任务模板: | 算子目录 | 任务模板 | 作用 | |---|---|---| | `video-audio` | media-download / video-img / video-audio | Ray 分布式:媒体下载、视频抽帧、视频提音频 | | `vision-process` | vision-process / image-data-check | 图像批处理 + 图片质量评估 | | `voice-process` | 音频清洗 / 增强 / 评估 | 音频数据集清洗、增强、质量评估 | | `yolo26` | yolo26 训练 / 评估 / 服务 | YOLO26 目标检测训练、mAP 评估、推理服务(含 RTSP 多路实时流、NPU 变体) | | `yolov8` | (无独立文档) | 旧版 YOLOv8,疑似已被 yolo26 取代 | | `paddleocr-vl` | paddleocr-vl | PaddleOCR-VL 把 PDF/图片/DOCX/HTML 转 Markdown | --- ## video-audio(Ray 分布式视频/多媒体处理) 同一目录下 3 个模板,均基于 **Ray** 在 K8s 拉起多 Worker 并行执行,共用镜像 `ccr.ccs.tencentyun.com/cube-studio/video-audio:20260301`,靠「名称 + 启动命令 + 参数」区分(核对 `start_download.py`、`start_video_img.py`、`start_video_audio.py`): | 任务模板 | 入口脚本 | 启动命令 | 输入文件每行格式 | |---|---|---|---| | **media-download** | `start_download.py` | `python start_download.py` | `$url $local_path` | | **video-img** | `start_video_img.py` | `python start_video_img.py` | `$local_video_path $des_img_dir $frame_rate` | | **video-audio** | `start_video_audio.py` | `python start_video_audio.py` | `$local_video_path $des_audio_path` | 公共机制: - 用 Ray 创建集群(Worker 数由 `--num_worker` 指定,默认 `3`),从 `--input_file` 逐行读任务,按行轮询划分到约 1000 个「任务盒」再作为 Ray 远程任务下发到各 Worker。 - **账号**:`kubeflow-pipeline`;`gitpath` 统一为 `/job-template/job/video-audio`。 各模板要点: - **media-download**:每行 `$url $local_path`,Worker 内 `requests.get` 下载;`local_path` 已存在则跳过,父目录自动创建。参数另有 `--download_type`(当前仅 `url`)。 - **video-img**:每行 `$local_video_path $des_img_dir $frame_rate`,Worker 内用 **ffmpeg** 执行 `ffmpeg -i <视频> -r <帧率> -f image2 <输出目录>/%5d.jpg`,自动建目录(生成 `00001.jpg`...)。 - **video-audio**:每行 `$local_video_path $des_audio_path`,目标 `.mp3` 直接导出;目标 `.wav` 先导 mp3 再转 **16kHz 单声道 pcm_s16le**(常用于语音识别)后删中间 mp3;`des_audio_path` 已存在则跳过。 > 依赖:video-img / video-audio 依赖容器内 **ffmpeg**(镜像已含)。可先用 media-download 下载到本地,再用 video-img/video-audio 处理;保证同一流水线内挂载与路径一致即可。 --- ## vision-process(图像处理 + 图片质量评估) 同一目录承载两类能力(两份 README 合并)。 ### 图像批处理(`launcher.py`) 镜像:`ccr.ccs.tencentyun.com/cube-studio/vision-process:20240601`。对 `--input_dir` 下图像批量处理后存到 `--save_dir`。 | 参数 | 说明 | 默认值 | |---|---|---| | `--input_dir` | 输入图像目录 | `/mnt/{{creator}}/coco_data_sample/images/train2014/` | | `--save_dir` | 保存图像目录 | `.../processed/images/train2014/` | | `--deal_type` | 处理类型:`blur`/`resize`/`normalize`/`equalize`/`cvtcolor`/`augmentation`/`cropping` | `resize` | | `--deal_arg` | 一级参数(如 resize 的目标尺寸 `640`) | `640` | | `--deal_kwarg` | 二级参数 | 空 | ### 图片质量评估(`image-data-check.py`) 镜像:`ccr.ccs.tencentyun.com/cube-studio/vision-process:20260101`(与图像处理 README 标注的 `20240601` 不同——质量评估能力在较新版本镜像)。支持无参考与全参考图像质量评估。 - **基础指标(始终计算)**:分辨率、亮度、清晰度(Laplacian 方差)、对比度、过曝/欠曝比例、图像熵、RGB 通道均值、边缘密度、近似重复检测(aHash,需 `--hash-dup`)。 - **无参考指标**:BRISQUE、NIQE。 - **全参考指标(需 `--reference`)**:PSNR、SSIM、MS-SSIM、LPIPS、CLIP 余弦/欧氏距离。 | 参数 | 说明 | 默认值 | |---|---|---| | `--images` | 待评估图片目录 | `.../yolo/electric-bicycle/dataset/images/train` | | `--reference` | 参考图(用于全参考指标),可选 | `.../reference.jpg` | | `--output` | 输出目录 | `.../image-quality-check` | | `--hash-dup` | 启用近似重复检测(true/false) | `false` | | `--plots` | 是否生成可视化图表(true/false) | `true` | 输出:`quality_report.json`(含 duplicates 分组)、`quality_metrics.csv`(每图明细:`image,img_w,img_h,aspect,brightness_mean,blur_metric,contrast,overexposed_ratio,underexposed_ratio,entropy,r_mean,g_mean,b_mean,edge_density` 及可选无参考/全参考列)、`plots/`(每指标直方图+箱线图,中英文各一份,约 32 张)。 --- ## voice-process(音频数据集清洗/增强/评估) 目录无主 README;3 个独立模板,共用镜像 `ccr.ccs.tencentyun.com/cube-studio/voice-process:20260101`(核对 `clean-audio-dataset.py`、`augment-audio-dataset.py`、`audio-dataset-eval.py`)。 ### 音频清洗(`clean-audio-dataset.py`) 批量清洗标准化:转单声道、重采样、降噪(频谱减法)、VAD 去非语音、去直流偏移、带通滤波、静音裁剪、RMS 响度归一化(防削波)、质量检查(时长/削波率/静音比例/信噪比)。输出统一 **16 位 PCM WAV**,保持原目录结构,并写 `output_dir/metadata_clean.csv`(UTF-8 带 BOM)。 | 参数 | 说明 | 默认值 | |---|---|---| | `--input_dir` / `--output_dir` | 输入/输出目录 | LibriSpeech / cleaned | | `--sr` | 目标采样率(16000/22050/44100/48000) | `16000` | | `--trim_top_db` | 静音裁剪阈值 dB(越大越激进,推荐 30-40) | `35.0` | | `--target_dbfs` | RMS 归一化目标响度 dBFS(负值,常用 -20~-16) | `-20.0` | | `--bp_low_hz` / `--bp_high_hz` | 带通低/高频截止 Hz | `50.0` / `7800.0` | | `--min_dur` / `--max_dur` | 最短/最长时长(秒),超界跳过 | `0.4` / `30.0` | | `--max_clipping_ratio` | 最大削波率(0-1) | `0.01` | | `--max_silence_ratio` | 最大静音比例(0-1) | `0.98` | `metadata_clean.csv` 字段:`rel_path,out_path,sr,duration,peak,rms,clipping_ratio,silence_ratio,snr_db,status,message`。 ### 音频增强(`augment-audio-dataset.py`) 随机数据增强生成变体(随机增益±6dB、时间平移±0.2s、高斯噪声 SNR10-25dB、混响 RT60 0.15-0.6s、时间拉伸 0.9-1.1x、音高±2 半音、动态压缩、频谱遮蔽 SpecAugment、带宽限制、背景噪声、随机削波)。输出 16 位 PCM WAV(扁平化到同一目录),命名 `{原始路径}_aug{序号}.wav`,并写 `output_dir/metadata_aug.csv`。 | 参数 | 说明 | 默认值 | |---|---|---| | `--input_dir` / `--output_dir` | 输入(递归扫描)/输出目录 | LibriSpeech / augmented | | `--num_aug` | 每条音频生成的增强样本数(推荐 2-5) | `2` | | `--seed` | 随机种子(0=用系统时间) | `0` | `metadata_aug.csv` 字段:`rel_path,out_path,sr,duration,aug_id,status,message`。 ### 音频质量评估(`audio-dataset-eval.py`) 递归扫描目录评估音频质量,生成报告与可视化图表。注意参数名用**连字符**风格(`--scan-dir` 等)。 | 参数 | 说明 | 默认值 | |---|---|---| | `--scan-dir` | 音频目录(递归扫描,必需) | `.../voice-datas/LibriSpeech` | | `--sr` | 重采样采样率(None=保持原采样率) | `16000` | | `--output-dir` | 输出目录(已存在会先清空) | `.../voice-datas/result` | | `--audio-ext` | 支持后缀(逗号分隔,不含点) | `flac,wav,mp3,m4a` | | `--clip-threshold` | 削波判定振幅阈值(0-1) | `0.999` | 统计分组含:`duration_stats`(num_clips/total_duration_s/mean_s/std_s/min_s/max_s/p50_s/p90_s/p95_s 等)、`audio_quality_stats`(peak_mean/peak_max/rms_mean/clip_ratio_mean)、`snr_dynamics_stats`(snr_db_mean/snr_db_std/dynamic_range_db_mean/silence_ratio_mean/crest_factor_mean/loudness_lufs_mean)、`spectral_stats`(频谱质心/带宽/滚降/平坦度/对比度)、`audio_features_stats`(过零率/MFCC 方差/色度偏差)。 --- ## yolo26(YOLO26 目标检测:训练/评估/服务) 镜像:`ccr.ccs.tencentyun.com/cube-studio/yolo26:20260331`(核对 `train.py`、`eval-yolo.py`、`server.py`、`app.py`;含 `Dockerfile-npu` 的 ARM64/NPU 变体)。 ### 训练(`train.py`) `ENTRYPOINT`/启动命令为 `python train.py`,训练完成后把 best 权重拷到 `--save_model_path`,并把指标写入 `/metric.json`(供平台展示)。 | 启动参数(界面) | 代码 argparse 名 | 说明 | 默认值 | |---|---|---|---| | `--train` | `--train` | 训练数据集 txt 配置地址 | 空 | | `--val` | `--val` | 验证数据集 txt 配置地址 | 空 | | `--classes` | `--classes` | 目标分类,逗号分隔(默认 COCO 80 类) | COCO 80 类 | | `--batch_size` | `--batch_size` | batch size | `16` | | `--epoch` | `--epochs` | 训练轮数 | `300` | | `--weights` | `--weights` | 权重文件(`/yolo26/yolo26{n,s,m,l,x}.pt` 或自有微调模型) | `/yolo26/yolo26n.pt` | | `--save_model_path` | `--save_model_path` | 模型保存地址 | 空 | | —(界面未列) | `--worker` | 数据加载并发数 | `8` | | —(界面未列) | `--img_size` | 训练/测试图像尺寸 | `640` | > 注意:界面模板里轮数参数写作 `--epoch`,而 `train.py:65` argparse 定义的是 `--epochs`、默认 `300`(界面默认却是 `1`,已核对 README JSON)。argparse 默认允许唯一前缀缩写,`--epoch` 能匹配到 `--epochs`,故一般可正常工作;如关闭 `allow_abbrev` 则会出错。建议注册模板时统一用 `--epochs`。`train.py:66` 的 `--batch_size` 代码默认 `16`、界面默认 `1`。 ### 评估(`eval-yolo.py`,README-eval-yolo) 对 YOLO 检测模型自动算 mAP / Precision / Recall / F1。`--root` 自动发现 `images/` 与 `labels/`,或用 `--images_dir` + `--labels_dir` 显式指定(二选一,`--root` 支持逗号分隔多目录)。 | 参数 | 说明 | 默认值 | |---|---|---| | `--model` | YOLO 模型文件路径(支持 yolo26 等 ultralytics 格式) | `.../electric-bicycle-new.pt` | | `--root` | 数据集根目录(自动发现 images/labels) | `.../dataset` | | `--images_dir` / `--labels_dir` | 测试图片 / YOLO 标注目录(与 root 二选一) | 空 | | `--imgsz` | 推理短边尺寸 | `640` | | `--conf_thres` | 置信度阈值(0-1) | `0.25` | | `--iou_thres` | mAP 计算的 IoU 阈值(0-1) | `0.5` | | `--output` | 输出目录(留空仅控制台显示) | `.../yolo-eval/output` | 输出:`evaluation_results.csv`、`evaluation_results.json`、`evaluation_charts.png`、`/metric.json`(平台元数据)。指标含 mAP@IoU、Precision、Recall、F1-score、各类别 AP(VOC 2010+ 插值)。 ### 推理服务(`server.py` + `app.py`) FastAPI 服务,监听端口 **8080**(`uvicorn.run(host="0.0.0.0", port=8080)`,`server.py:563`)。常规接口(API 详见 `yolo26_api.md`): | 路径 | 方法 | 作用 | |---|---|---| | `/v1/models/{MODEL_NAME}/versions/{MODEL_VERSION}/predict` | POST | 主推理接口;body `{"image": }`,返回 `{labels,scores,xywhs,orig_shape}` | | `/demo/predict` | POST | 示例推理,body `{"image": }`,返回 `{results:[]}` | | `/labelstudio/predict` `/labelstudio/setup` `/labelstudio/health` | POST/POST/GET | 自动化标注接口(Label Studio ML Backend) | | `/` | GET | 重定向到 `/gradio`(Gradio 上传图片推理页) | 请求/响应示例: ```python import requests, base64, json url = "http://xx.xx.xx.xx/v1/models/MODEL_NAME/versions/MODEL_VERSION/predict" data = {"image": base64.b64encode(open("a.jpg","rb").read()).decode()} r = requests.post(url, headers={'Content-Type':'application/json'}, data=json.dumps(data)) print(r.json()) # {"labels":[],"scores":[],"xywhs":[],"orig_shape":[w,h]} ``` #### RTSP/RTMP 多路实时流推理(`--rtsp` / `RTSP_URLS`) 传 `--rtsp` 参数或环境变量 `RTSP_URLS` 即启用;不传则完全退化为 Gradio 图片推理(零影响)。RTSP 相关代码在 `rtsp.py`。 - 启动:`python server.py --rtsp demo`(内置两路示例流,容器内自动拉起 MediaMTX + ffmpeg 循环推流);`--rtsp rtsp://a,rtsp://b,rtmp://c/live/x`(外部多路,逗号分隔);`RTSP_URLS=demo python server.py` 等价。 - token `demo`(大小写不敏感)展开成两条内置 RTSP 地址并自动去重;其它 token 为任意 `cv2.VideoCapture` 可识别 URL。 - 启用后额外端点:`/`(网格 HTML 页)、`/rtsp/stream/{idx}`(multipart/x-mixed-replace MJPEG 流)、`/rtsp/health`(JSON 健康检查);原有接口不变。 - demo 模式额外占用端口:`8554`(RTSP)、`1935`(RTMP)、`8888`(HLS)、`8889`(WebRTC);非 demo 模式只占 `8080`。 - 关键设计:每路流独立子进程各自加载 YOLO(规避 GIL/CUDA 冲突);reader 线程丢旧帧防解码缓冲堆积;JPEG 只编码一次共享缓存;MJPEG over `` 取代 Gradio streaming(720p 实测从 ~0.1fps 提到 15fps+);`mp.set_start_method('spawn')` 须在 torch/cv2 之前。 - 排障:白屏→`curl http://:8080/rtsp/health` 看 `has_frame`;`corrupted macroblock`→降采样 `max_side=720`。 --- ## yolov8(旧版,建议优先用 yolo26) `job-template/job/yolov8` 目录**无独立 README**,仅含 `Dockerfile`、`build.sh`、`install-cube-studio.sh`、`npu/`。从这些文件推断: - 镜像 `ccr.ccs.tencentyun.com/cube-studio/yolov8:20250901`(`build.sh`;`Dockerfile` 顶部注释与 manifest 命令里用带架构后缀的 `:20250901-amd64` / `-npu`),基础镜像 `ubuntu-gpu:cuda11.8.0-cudnn8-python3.9`,装 `torch==2.5.1 torchvision==0.20.1 ultralytics==8.2.55 gradio==4.43.0`,预下载 `yolov8{n,s,m,l,x}.pt`(来自 ultralytics assets v8.2.0)。 - `Dockerfile` 的 `ENTRYPOINT ["python","train.py"]` 指向 `train.py`,但**该目录下并无 `train.py`/`server.py`/`app.py` 等源码**(仅构建脚本与 npu 目录)。 > 注意(旧产物):yolov8 目录功能等价代码已缺失(仅余 `Dockerfile`/`build.sh`/`install-cube-studio.sh`/`npu/`,已核对),已被 **yolo26** 取代(yolo26 目录完整含 train/eval/server)。本节仅作存档说明,**新项目建议直接用 yolo26**;是否删除 yolov8 目录由维护者决定。 --- ## paddleocr-vl(文档/图片转 Markdown) 基于 **PaddleOCR-VL**,把 PDF/图片/DOCX/HTML 识别为文本并输出 **Markdown**(含版面/表格/公式)。镜像 `ccr.ccs.tencentyun.com/cube-studio/paddleocr-vl:20251126`,工作目录 `/app`,启动命令 `python start.py`(核对 `start.py`)。 ### 支持格式与流程 | 格式 | 扩展名 | 处理 | 依赖 | |---|---|---|---| | 图片 | png/jpg/jpeg | `PaddleOCRVL.predict(image_path)`,含防 OOM 自动缩放重试 | — | | PDF | pdf | 直接 `predict`,多页拼接为一份 Markdown | — | | DOCX | docx | 先 **LibreOffice** 转 PDF 再走 PDF 流程 | 镜像内 `libreoffice` | | HTML | html | 先 **WeasyPrint** 转 PDF 再走 PDF 流程 | `weasyprint` | ### 输入方式与输出 - 单文件:`--input_file_or_path` 填文件路径,结果写到 `{output_path}/paddleocr-vl-result/` 下 `{原文件名}.md`。 - 多文件/多目录:英文逗号 `,` 分隔(中文逗号自动替换),目录递归处理 `docx/pdf/png/jpg/jpeg/html`,忽略隐藏文件与名为 `paddleocr-vl-result` 的目录,输出在 `{output_path}/paddleocr-vl-result/{输入目录名}/` 保持相对结构。 ### 参数(防 OOM) | 参数 | 说明 | 默认值 | |---|---|---| | `--input_file_or_path` | 待识别文件/目录,多个用英文逗号分隔 | `.../paddleocr` | | `--output_path` | 结果保存目录(实际在其下 `paddleocr-vl-result/`) | `.../paddleocr` | | `--max_image_height` | 图片最大高度(px),超过先按比例缩放,`0`=不限制(16G 显存建议 2000-3000) | `0` | | `--max_image_width` | 图片最大宽度(px),`0`=不限制 | `0` | 防 OOM 策略:预缩放(按上限缩放后再推理)→ 若仍 OOM 只清显存不重建模型、按比例(默认每次 90%)缩小重试,最多 10 次;该逻辑(`_predict_image_with_auto_resize()`)仅对图片类生效,PDF/DOCX/HTML 由 PaddleOCR-VL 内部按页处理。 ```bash python start.py --input_file_or_path /path/a.pdf,/path/images/ --output_path /mnt/{{creator}}/pipeline/example/paddleocr ``` > 可与下游「Markdown 转 QA」类模板串联,把 `paddleocr-vl-result` 作为后续清洗/检索/训练的输入。 --- *本篇为知识库导航/核对稿,具体参数与行为以各算子源码(`job-template/job/...`)为准。* --- ### 超参搜索任务模板(NNI / Ray Tune) - 链接: https://www.cubestudio.vip/docs/05-%E4%BB%BB%E5%8A%A1%E6%A8%A1%E6%9D%BF/08-%E8%B6%85%E5%8F%82%E6%90%9C%E7%B4%A2 - 分类: 05-任务模板 / 超参搜索 - 适用场景: 要对训练任务做超参数自动搜索(NNI 或 Ray Tune)、配置搜索空间并查看平行坐标图结果时读这篇 - 关键词: 超参搜索 / 超参数优化 / hyperparameter search / hpo / NNI / Neural Network Intelligence / nnictl / searchSpace / TPE / Random / Anneal / Ray / Ray Tune / ASHA / ASHAScheduler / grid_search / tune / 平行坐标图 / parallel coordinates / metric.json / AutoML - 最后更新: 2026-06-30 # 超参搜索任务模板 平台提供两种超参搜索算子,均在流水线节点内运行 `launcher.py`,产出结果 CSV 与平台可视化的平行坐标图(`/metric.json`): | 算子目录 | 框架 | 适用 | |---|---|---| | `hyperparameter-search-nni` | [NNI](https://github.com/microsoft/nni) | 通用超参实验,trial 脚本按 NNI 约定上报指标 | | `hyperparameter-search-ray` | [Ray Tune](https://docs.ray.io/en/latest/tune/index.html) + ASHA | 驱动外部训练命令做多轮搜索,从评估 JSON 读指标 | 面向使用者的功能说明另见 [03-平台使用/06-任务流与训练/超参搜索.md](../03-平台使用/06-任务流与训练/超参搜索.md);本篇侧重算子设计与参数核对。 --- ## hyperparameter-search-nni(基于 NNI) 镜像(以 `build.sh` 为准):`ccr.ccs.tencentyun.com/cube-studio/hyperparameter-search-nni:20250301`;注意 README 与模板注册 JSON 里默认值仍写旧镜像名 `ccr.ccs.tencentyun.com/cube-studio/hyperparam_search:nni-20230801`(`README.md:5,86`,已过时,二者并存,以 `build.sh` 实际构建的 `hyperparameter-search-nni:20250301` 为准)。启动命令 `python launcher.py`(核对 `hyperparameter-search-nni/launcher.py`、`build.sh`)。 ### 执行流程 1. **解析参数**:`launcher.py` 用 `argparse.parse_known_args()` 把平台传入的 `--key value` 收成字典并封成 `nni` 对象(`launcher.py:113-122`)。 2. **生成配置** `make_config(nni)`:拼出 NNI 的 `controll_template.yaml`(写到 `nni.workdir` 下),包含: - `searchSpace`:由 `--parameters`(JSON)转成 YAML 搜索空间(choice/uniform/loguniform 等)。 - `trialConcurrency=parallel_trial_count`、`trialCommand=command`、`trialCodeDirectory=workdir`、`maxExperimentDuration={max_exec_duration}s`、`maxTrialNumber=max_trial_count`。 - `trialGpuNumber`:取环境变量 `KFJ_TASK_RESOURCE_GPU`(含 `(` 时只取括号前数字)。 - `tuner.name=algorithm_name`、`tuner.classArgs.optimize_mode=objective_type`。 - `trainingService.platform=local`,`useActiveGpu`:GPU 为 `0`/空则 `false`,否则 `true`。 3. **启动 NNI**:`nnictl create --config --foreground -p {PORT}`(前台运行直至结束)。`PORT` 取环境变量 `PORT1`,默认 `80`(`launcher.py:13`)。 4. **收集结果** `get_nni_result(nni)`:从 NNI sqlite 库 `/root/nni-experiments/_latest/db/nni.sqlite` 读 `MetricData`(type=FINAL) 与 `TrialJobEvent`,把各 trial 的参数+最终指标汇总,写 `workdir/nni-result.csv`(每行一个 trial,末列 `result`),并 `draw_parallel` 生成平行坐标图配置写 `/metric.json`。 ### 启动参数 | 参数 | 含义 | Launcher 用途 | 示例默认 | |---|---|---|---| | `--workdir` | 代码/工作目录 | `trialCodeDirectory`,结果 CSV 也写此目录 | `/mnt/admin/pipeline/example/nni` | | `--command` | 每个 trial 的启动命令 | `trialCommand` | `python demo.py` | | `--parameters` | NNI 搜索空间(JSON) | `searchSpace` | `{"lr":{"_type":"choice","_value":[0.0001,0.001,0.01,0.1]},...}` | | `--parallel_trial_count` | 并行 trial 数 | `trialConcurrency` | `3` | | `--max_trial_count` | 最大 trial 数 | `maxTrialNumber` | `12` | | `--max_exec_duration` | 最大实验时长(秒) | `maxExperimentDuration` | `86400` | | `--objective_type` | 目标方向 maximize/minimize | `optimize_mode` | `maximize` | | `--algorithm_name` | 搜索算法 | `tuner.name` | `Random`(README 注册 `choice`:TPE/Random/Anneal/Evolution/SMAC/BatchTuner/GridSearch/Hyperband/NetworkMorphism/MetisTuner/BOHB/GPTuner/PPOTuner/PBTTuner,见 `README.md:204`) | | `--algorithm_setting` | 算法额外配置 | **当前 launcher 未使用,预留** | 空 | | `--objective_goal` / `--objective_metric_name` / `--objective_additional_metric_names` | 目标值/指标名 | **当前 launcher 未写入 NNI,预留** | — | > 已核实:`make_config` 仅用到 parameters / parallel_trial_count / command / workdir / max_exec_duration / max_trial_count / algorithm_name / objective_type;`algorithm_setting`、`objective_goal`、`objective_metric_name`、`objective_additional_metric_names` 确实未被写入 NNI 配置(`launcher.py:16-48`),属预留参数。 ### Trial 脚本约定与查看结果 - 每个 trial 由 NNI 在 `workdir` 下执行 `command`(如 `python demo.py`)。脚本需用 NNI API/环境变量接收当次超参,并**上报最终指标(FINAL)**,否则 launcher 无法从 sqlite 汇总结果。具体写法见 NNI 官方文档。 - **结果**:`workdir/nni-result.csv`(每行一个 trial)+ `/metric.json`(平台据此展示超参与结果的平行坐标图)。 - 可在任务模板环境变量里配 `TASK_RESOURCE_GPU=1`、`NO_RESOURCE_CHECK=true` 等固定资源/跳过校验。 --- ## hyperparameter-search-ray(基于 Ray Tune + ASHA) 镜像(以 `build.sh` 为准):`ccr.ccs.tencentyun.com/cube-studio/hyperparameter-search-ray:20260301`;注意 README/注册默认值仍写旧镜像名 `ccr.ccs.tencentyun.com/cube-studio/hyperparam_search:20230530`(`README.md:47`,已过时,以 `build.sh` 实际构建的 `hyperparameter-search-ray:20260301` 为准)。工作目录 `job-template/job/hyperparameter-search-ray`,启动命令 `python launcher.py`(核对 `hyperparameter-search-ray/launcher.py`、示例 `train-decision-tree.py`、`build.sh`)。 ### 执行流程(以代码为准) 1. **解析参数**:argparse 读 `--workdir`、`--command`、`--params`、`--outfile`、`--metric`、`--mode`、`--num_samples`、`--result_save_path`(`launcher.py:144-152`)。`--params` 用 `eval()` 解析为 Ray Tune 搜索空间字典。 2. **每个 trial** 调 `train_model(config)`(`launcher.py:38-74`): - 拼命令 `cd {workdir} && {command}`,然后**把本 trial 采样到的每个超参逐个追加为 `--{key} {value}`**(`launcher.py:51-53`),`os.system` 执行。 - 执行后若 `outfile` 不存在则报错退出;存在则把 `outfile` **复制**一份到 `outfile` 去掉 `.json` 再拼 `_.json` 的副本(区分各 trial 结果,`launcher.py:68`)。 - 读 `outfile` 的 JSON,若含 `metric`(单个指标名)则 `tune.report({metric: result[metric]})`。 3. **搜索**:`tune.run(train_model, config=params, metric=metric, mode=mode, num_samples=..., scheduler=ASHAScheduler(), ...)`,关闭 dashboard(`include_dashboard=False`,规避 pydantic 版本冲突)。 4. **产出**:取 `analysis.results_df` 中所有 `config/*` 列 + metric 列写 `result_save_path`(CSV);另写 `<结果文件名>_best.json`(最佳配置)与 `/metric.json`(`metric_type=echart-parallel`,`file_path` 指向 CSV)。 ### 启动参数 | 参数 | 必填 | 含义 | |---|---|---| | `--workdir` | 否 | 命令执行目录(相对路径会基于它解析 outfile/result_save_path) | | `--command` | 否 | 训练命令;launcher 会在其后追加各超参 `--{key} {value}` | | `--params` | 否 | Ray Tune 搜索空间,**字典字符串**(`tune.grid_search/tune.choice/tune.uniform/...`),如 `{"max_depth": tune.grid_search([3,4,5])}` | | `--outfile` | 是 | 训练脚本写出的评估结果 JSON 路径 | | `--metric` | 否 | 评估指标名(在 outfile JSON 中读该 key) | | `--mode` | 否 | `max` / `min` | | `--num_samples` | 否 | 采样 trial 次数(grid_search 时通常 `1`) | | `--result_save_path` | 否 | 结果 CSV 保存路径 | 命令行示例(取自 `launcher.py` 注释): ```bash python launcher.py \ --workdir '/mnt/admin/pipeline/example/ray' \ --command 'python train-decision-tree.py --save_model_dir decision_tree --train_dataset /mnt/admin/pipeline/example/ml/train.csv --label_columns y --feature_columns age,duration,campaign,pdays,previous,emp_var_rate,cons_price_idx,cons_conf_idx,euribor3m,nr_employed' \ --params '{"max_depth": tune.grid_search([3,4,5]),"min_samples_split": tune.grid_search([5,10,20])}' \ --outfile 'decision_tree/val_result.json' \ --metric "test_auc" --mode 'max' --num_samples '1' \ --result_save_path 'automl_result.csv' ``` 被搜索的训练脚本需要: - **接受被搜索的每个超参作为独立 CLI 参数**(如 `--max_depth`、`--min_samples_split`),launcher 逐个追加。 - 把评估指标写入 `--outfile` 指定的 JSON(键名与 `--metric` 一致)。`train-decision-tree.py` 即此约定的参考实现。 > 注意(README 与当前代码不一致,正文已按代码 `launcher.py` 描述):随算子附带的 `hyperparameter-search-ray/README.md` 声称——(1) launcher 在命令后追加 **`--model_params ''`** 整体传超参;(2) `--metric` 是**列表**且取 `metric[-1]` 为优化目标;(3) 会把命令/outfile 中的子串 `val_result` 替换为 `val_result`。但当前 `launcher.py` 实际是——(1) 把每个超参拆成独立 `--key value` 追加(`launcher.py:51-53`);(2) `--metric` 当作**单个指标名字符串**使用(`launcher.py:166,71-73`);(3) 训练脚本仍写固定 `outfile`,launcher 读取后再复制成 `_.json` 的副本(`launcher.py:68`,无 `val_result` 子串替换逻辑)。请确认 README 描述的是旧版接口还是预期行为;以仓库当前 `launcher.py` 为准。 ### 注意事项 - 多 trial 并发会向**同一个** `outfile` 写入,launcher 用 `time.sleep(random.randint(1,100)/10)` 错开并在读后复制备份;高并发下仍可能有写入竞争,建议训练脚本自身按超参生成唯一结果路径以彻底规避。 - 结果 CSV 在 `result_save_path`,平台据 `/metric.json`(echart-parallel)展示平行坐标图。 --- *本篇为知识库导航/核对稿,具体参数与行为以各算子源码(`job-template/job/...`)为准。* --- ### 开发并注册新任务模板 - 链接: https://www.cubestudio.vip/docs/05-%E4%BB%BB%E5%8A%A1%E6%A8%A1%E6%9D%BF/%E5%BC%80%E5%8F%91%E4%BB%BB%E5%8A%A1%E6%A8%A1%E6%9D%BF - 分类: 05-任务模板 / 模板开发 - 适用场景: 想自己开发一个 pipeline 任务模板(写代码、封装镜像、在平台上注册并配置入参)时 - 关键词: 开发任务模板 / 注册模板 / job模板 / job-template / 模板目录结构 / build.sh / Dockerfile / readme / 镜像构建 / 启动参数 / 环境变量 / metric.json / 可视化 / KFJ_CREATOR / NO_RESOURCE_CHECK / help_url - 最后更新: 2026-07-04 # 开发任务模板 如何开发并注册一个新的 pipeline 任务模板:编写代码、封装镜像、在平台上注册并配置入参。开发完成后的使用方式见 [模板使用手册](./模板使用/README.md);镜像构建相关细节见 06-二次开发段(镜像构建/各类构建镜像)。 ## 视频教程 [job 模板制作教程](https://www.bilibili.com/video/BV15B4y197nm) ## 1. job 模板规范 参考 demo 任务模板,代码仓库路径 `job-template/job/demo/`。 ### 1.1 模板目录结构 ``` - job-template # job模板合计 - $job_template_name # 自定义模板 - build.sh # job镜像构建过程 - Dockerfile # 构建所需的Dockerfile - readme.md # 使用方法,规定格式定义 - xxx # 项目代码 ``` ### 1.2 关于代码 不关注代码的实现,只要最终形成 docker 即可,镜像的输入参数统一为字符串。 1、代码中可以从环境变量中读取任务实例的信息。 ```bash creator = os.getenv('KFJ_CREATOR', 'admin') # 任务流的创建者 runner = os.getenv('KFJ_RUNNER', 'admin') # 任务流的运行者 pipeline_name = os.getenv('KFJ_PIPELINE_NAME','test') # 任务流的名称,或id task_name = os.getenv('KFJ_TASK_NAME','test') # 任务的名称或id cpu = os.getenv('KFJ_TASK_RESOURCE_CPU','2') # 申请的cpu资源或内存资源 gpu = os.getenv('KFJ_TASK_RESOURCE_GPU','0') # 申请的gpu资源 host_ip = os.getenv('K8S_HOST_IP','xx.xx.xx.xx') # 任务调度的主机ip run_id = os.getenv('KFJ_RUN_ID','xx') # 任务流运行实例id cache = redis.Redis.from_url(os.getenv('KFJ_CACHE_URL','')) # 缓存地址,可以在上下游传递数据 ``` > 以上环境变量名以 demo 模板为准,见 `job-template/job/demo/launcher.py:11-35`。 2、代码中可以读取输入参数中包含的输入地址和输出地址,做任何逻辑计算,读取输入地址文件,输出结果到输出地址。注意要想持久化,输入输出要在容器的 `/mnt/{{creator}}/` 目录下。 ```bash def do_something(args): input_file_path = args.input_file_path output_file_path = args.output_file_path # 示例:你的任务逻辑,从目录读取输入,进行计算,保存输出 input = pandas.read_csv(input_file_path) # 读取输入数据 result = input*3 # 根据输入数据和输入参数,做任何你想要的逻辑 result.to_csv(output_file_path, index=False) # 保存结果数据 ``` 3、我们也可以从缓存中读取输入数据,写数据到缓存中。 ```bash @pysnooper.snoop() def do_something_with_cache(): # 示例:你的任务逻辑,从目录读取输入,进行计算,保存输出 input = cache.hget(run_id, "output") if not input: raise ValueError("上游输出不存在") input = pickle.loads(input) result = input*3 # 根据输入数据和输入参数,做任何你想要的逻辑 cache.hset(run_id, "output", pickle.dumps(result)) # 保存结果数据 ``` 4、指标可视化,格式要求参考 03-平台使用段「任务流」文档的“结果可视化”环节。 构建任务模板时,在代码中按照规范格式输出可视化结果(包括文字、图片和 echart 源码),实现在 web 界面上的可视化展示。最终写入容器内的 `/metric.json` 文件(见 demo 模板 `job-template/job/demo/launcher.py:77`)。 `/metric.json` 文件格式为: ```bash [ { "metric_type":"image", "describe":"指标描述", "image":"图片地址" }, { "metric_type":"text", "describe":"指标描述", "text":"文本内容" }, { "metric_type":"html", "describe":"指标描述", "html":"html源码内容" }, { "metric_type":"iframe", "describe":"指标描述", "url":"链接的地址" }, { "metric_type":"table", "describe":"指标描述", "file_path":"csv文件地址" }, { "metric_type":"echart-xx", # 其中xx可以为line,bar,pie,scatter,radar,candlestick,heatmap,parallel,tree,sunburst 其中tree,sunburst 时数据为json,其他类型数据为csv "describe":"指标描述", "file_path":"csv或者json数据文件地址" }, { ...或者是echart的option源码 } ] ``` > echart 类型 line/bar/pie/scatter/radar/candlestick/heatmap/tree/sunburst/parallel 均已在后端支持,见 `myapp/utils/py/py_echart.py:528-547`。 5、要接收用户输入,如果输入为 json 的,接收后要进行反序列化,CubeStudio 提供过来的输入均为字符串,要自己手动转为相应格式。 ### 1.3 关于镜像 建议镜像的 tag 使用日期。 `ccr.ccs.tencentyun.com/cube-studio/$image_name:$image_tag` 可以使用自己的镜像仓库,自己构建后推送到仓库,前面的过程都可以不在 CubeStudio 上完成。 ## 2. 注册模板 ### 2.1 注册仓库和镜像 如果你的镜像 public,可以不用添加仓库。 如果你的镜像是 private 的,需要在 CubeStudio 页面上「训练 -> 仓库」先添加仓库的账号密码,才能在使用的时候拉取镜像。 然后在 CubeStudio 页面上「训练 -> 镜像」菜单里面,添加自己构建的镜像名。 ### 2.2 模板注册入口 在 CubeStudio 页面上「训练 -> 任务模板 -> 添加」按钮。 ### 2.3 模板配置 1、模板的名称和描述:会显示在 pipeline 编排界面。 2、模板版本:release 版本的模板才会出现在 pipeline 编排界面。 3、目录和启动命令:会覆盖 Dockerfile 中的启动目录和命令。比如 Dockerfile 中未定义启动命令,或多个模板使用同一个镜像时为了实现不同的功能配置不同的启动命令。 4、挂载目录:会为使用此模板的任务自动添加此挂载配置。比如: ```bash kubeflow-user-workspace(pvc):/mnt # pvc的挂载方式,会自动在pvc下挂载个人子目录 /data/k8s/kubeflow/pipeline/workspace/xxxx(hostpath):/mnt # 挂载主机目录的方式 ``` 5、启动参数编写实例: ```bash { "group1":{ # 属性分组,仅做web显示使用 "attr1":{ # 属性名 "type":"str", # str,text,json,int,float,bool,list "item_type": "", # 在type为text,item_type可为python,java,json,sql "label":"属性1", # 中文名 "require":1, # 是否必须 "choice":[], # type为enum/multiple时,可选值,可以分别设置key value,例如"choice":{"key1":"value1","key2":"value2",}, "range":"$min,$max", # 最小最大取值,在int,float时使用,包含$min,$max "default":"", # 默认值 "placeholder":"", # 输入提示内容 "describe":"这里是这个字段的描述和备注", "editable":1 # 是否可修改 }, "attr2":{ ... } }, "group2":{ } } ``` 6、环境变量:会为基于此模板的任务运行时均添加该环境变量。同时可以通过一些特殊的环境变量来控制任务配置。 模板中特殊的环境变量: ```bash NO_RESOURCE_CHECK=true # 使用该模板的task不会进行资源配置的自动校验 TASK_RESOURCE_CPU=4 # 使用该模板的task 忽略用户的资源配置,cpu固定配置资源为4核 TASK_RESOURCE_MEMORY=4G # 使用该模板的task 忽略用户的资源配置,mem固定配置资源为4G TASK_RESOURCE_GPU=0 # 使用该模板的task 忽略用户的资源配置,gpu固定配置资源为0卡 TASK_RESOURCE_RDMA=0 # 使用该模板的task 忽略用户的资源配置,rdma固定配置资源 ``` > 内置模板中普遍使用以上特殊环境变量,见 `myapp/init/init-job-template.json`(如第 72 行);`NO_RESOURCE_CHECK` 的判断逻辑见 `myapp/tools/watch_workflow.py:180`。其中 `TASK_RESOURCE_RDMA` 在内置模板里常见但源使用文档未列出,此处补充。 7、k8s 账号:表示此类任务运行时所附带的 k8s 账号,主要是此类任务要启动一个分布式的 pod 集群,用来进行分布式数据处理或训练。 8、扩展:扩展是 json 格式,index 用来控制在同一分组中排序的位置,help_url 用来表示此类模板的帮助文档。 ``` { "index": 1, "help_url": "https://github.com/data-infra/cube-studio/tree/main/job-template/job/pytorch" } ``` ## 3. 模板使用 注册模板以后,在 pipeline 编排界面,点击模板列表顶部的刷新小按钮,然后就可以在模板列表中搜索到自己创建的模板了。各内置模板的入参填法见 [模板使用手册](./模板使用/README.md)。 --- ### 基础命令模板(自定义镜像/逻辑节点/python 节点) - 链接: https://www.cubestudio.vip/docs/05-%E4%BB%BB%E5%8A%A1%E6%A8%A1%E6%9D%BF/%E6%A8%A1%E6%9D%BF%E4%BD%BF%E7%94%A8/00-%E5%9F%BA%E7%A1%80%E5%91%BD%E4%BB%A4 - 分类: 05-任务模板 / 模板使用 - 适用场景: 想用自己的镜像跑单任务、做条件分支判断、或直接贴一段 python 代码当节点时 - 关键词: 基础命令 / 自定义镜像 / custom image / 逻辑节点 / logical node / python节点 / python node / debug / command / workdir / code - 最后更新: 2026-06-30 # 基础命令 ## 自定义镜像 用户可以创建自定义镜像的基础算力,使用自己的镜像和代码运行任务,debug 单任务节点,确保模板任务可以正常运行并执行模板所具有的功能。 入参: - images:要调试的镜像 - workdir:启动目录 - command:启动命令 ## 逻辑节点 用户可以创建逻辑节点和下游节点,通过逻辑节点的打印输出来控制下游执行的任务。比如下图中,上游节点为模型 A 及模型 B,数据可同时过两个模型,然后对比两个模型的评估结果 auc,根据判断条件来输出相应的内容。 ![逻辑节点示意](https://foruda.gitee.com/images/1700484705175316752/47025039_1019082.png "屏幕截图") 入参: - code:逻辑判断的代码 ## python 节点 用户可以创建 python 节点,直接配置 python 代码来运行任务。有一些任务需要写的代码非常简短,几行可搞定,就不需要再封装一个镜像后拖拽使用了。 入参: - code:需要执行的 python 代码 --- ### 数据导入导出模板(datax/dataset/label-studio/model-download) - 链接: https://www.cubestudio.vip/docs/05-%E4%BB%BB%E5%8A%A1%E6%A8%A1%E6%9D%BF/%E6%A8%A1%E6%9D%BF%E4%BD%BF%E7%94%A8/01-%E6%95%B0%E6%8D%AE%E5%AF%BC%E5%85%A5%E5%AF%BC%E5%87%BA - 分类: 05-任务模板 / 模板使用 - 适用场景: 要从外部数据源/数据集/标注平台/模型库把数据或模型拉到分布式存储时 - 关键词: 数据导入 / 数据导出 / datax / dataset / 数据集下载 / label-studio / 标注平台导入 / model-download / 模型下载 / huggingface / hugging face - 最后更新: 2026-07-04 # 数据导入导出 ## datax 在 notebook 中编写 datax 需要的 json 文件(即定义数据从哪里导入到哪里),编写格式参数见 [DataX github](https://github.com/alibaba/DataX)。 然后在任务参数 `-f` 中配置该 json 文件的地址即可。 ## dataset 下载数据集到分布式存储,目前仅支持 CubeStudio 平台本身的数据集和 Hugging Face 数据集。 ## label-studio 从标注平台导入数据集。其中: - `--project_id`:标注任务的项目组 id,可以进入某个标注任务后,在浏览器的 url 中获取 - `--filter`:过滤条件,支持 `created_at`、`updated_at` 的大于小于 - `--save_path`:保存地址 > 说明:`--filter` 在代码中被拼接为标注库 `task` 表的 where 条件片段,支持用 `,`/`&`/`;` 分隔多个条件。见 `job-template/job/label-studio-import/launcher.py:30-62`(`_normalize_filter` 拆分条件后拼到 `select * from task ...`)。 ## model-download 下载模型文件到分布式存储,目前支持从 `模型管理列表` 和 `推理服务列表` 下载模型,以及从 Hugging Face 下载模型。 注意: 1. 如果在模型管理中注册的 `模型地址` 填写的为 json 格式,那么表示该模型是由多个子模型构成。每个 key 都表示一个子模型,这种情况下,模型拉取时可以直接拉取子模型。 2. 往往在生产中,我们需要拉取当前在线的推理服务的模型,作为下一次增量训练的模型,所以我们需要从在线的推理服务中拉取模型,这种情况下要求推理服务的模型地址是填写上的。 --- ### 数据处理模板(hadoop/volcanojob/ray/sparkjob) - 链接: https://www.cubestudio.vip/docs/05-%E4%BB%BB%E5%8A%A1%E6%A8%A1%E6%9D%BF/%E6%A8%A1%E6%9D%BF%E4%BD%BF%E7%94%A8/02-%E6%95%B0%E6%8D%AE%E5%A4%84%E7%90%86 - 分类: 05-任务模板 / 模板使用 - 适用场景: 要在 pipeline 里跑 hadoop/spark/ray/volcano 这类分布式数据处理作业时 - 关键词: 数据处理 / hadoop / volcano / volcanojob / ray / spark / sparkjob / 分布式数据处理 / 大数据 - 最后更新: 2026-06-30 # 数据处理 以下四类分布式数据处理模板的详细参数与设计说明,见本段(05-任务模板)对应家族模板文档,以及代码仓库 `job-template/job/` 下对应模板目录中的 `README.md`。 ## hadoop 模板 分布式 Hadoop 数据处理。详见代码仓库 `job-template/job/hadoop/README.md` 及本段 hadoop 家族模板文档。 ## volcanojob 模板 基于 Volcano 的批量作业调度。详见代码仓库 `job-template/job/volcano/README.md` 及本段 volcano 家族模板文档。 ## ray 模板 基于 Ray 的分布式计算。详见代码仓库 `job-template/job/ray/README.md` 及本段 ray 家族模板文档。 ## sparkjob 模板 分布式 Spark 数据处理。详见代码仓库 `job-template/job/spark/README.md` 及本段 spark 家族模板文档。 --- ### 数据预处理模板(去重/缺失/单一值/填充/统计量/异常值) - 链接: https://www.cubestudio.vip/docs/05-%E4%BB%BB%E5%8A%A1%E6%A8%A1%E6%9D%BF/%E6%A8%A1%E6%9D%BF%E4%BD%BF%E7%94%A8/03-%E6%95%B0%E6%8D%AE%E9%A2%84%E5%A4%84%E7%90%86 - 分类: 05-任务模板 / 模板使用 - 适用场景: 训练前要清洗数据:去重、删缺失/单一值列、填充缺失、算统计量、检测异常值时 - 关键词: 数据预处理 / drop-duplicate / 去重 / drop-missing / 缺失值 / drop-stablize / 单一值 / fill-missing / 填充 / calculate_metric / 统计量 / outlier-detection / 异常值检测 - 最后更新: 2026-06-30 # 数据预处理相关 ## drop-duplicate drop_duplicate 模板可以去除重复样本。(平台中注册的模板名为 `drop-duplicates`,复数) 入参: - input_dataset_path:需要去重的样本路径,如 `data/fin_data.csv` - save_dataset_path:去重之后结果保存的路径,如 `data/fin_data_r.csv` ## drop-missing drop_missing 模板可以删除缺失值过高的特征。 入参: - input_dataset_path:需要处理的样本路径,如 `data/fin_data.csv` - save_dataset_path:处理之后结果保存的路径,如 `data/fin_data_r.csv` - missing_ratio:门限值,比如设置 0.3,表示缺失率 > 30% 时删除该列 ## drop-stablize drop-stablize 模板可以删除值过于单一的特征。 入参: - input_dataset_path:需要处理的样本路径,如 `data/fin_data.csv` - save_dataset_path:处理之后结果保存的路径,如 `data/fin_data_r.csv` - stable_threshold:门限值,比如设置 0.95,表示当该特征 95% 的值都集中在同一个值时,删除该列 ## fill-missing fill-missing 模板可以填充缺失值。 入参: - input_dataset_path:需要处理的样本路径,如 `data/fin_data.csv` - save_dataset_path:处理之后结果保存的路径,如 `data/fin_data_r.csv` - fill_type:mean 表示用均值填充缺失值,median 表示中位数填充,modes 表示众数填充 ## calculate_metric calculate_metric 可以计算数据统计量,比如每个特征的非空值个数、分位数、均值、方差等。(平台中注册的模板名为 `calculate-metric`) 入参: - input_dataset_path:需要处理的样本路径,如 `data/fin_data.csv` - metric_path:统计值结果保存的路径,如 `data/fin_data_r.csv` ## outlier-detection outlier-detection 可以做异常值检测。 入参: - input_dataset_path:需要处理的样本路径,如 `data/fin_data.csv` - save_dataset_path:处理之后结果保存的路径,如 `data/fin_data_r.csv` - detection_type:异常值检测的方法,stddev 表示 3 倍标准差法,box_line 表示箱线图法,Tukey 表示 Tukey 方法,Z-score 表示 Z-score 法 - delete_or_not:是否删除检测出的异常值,yes 表示删除异常值,no 表示不删除 --- ### 特征处理模板(离散化/标准化/采样/降维/拆分/转换/编码/索引/排序/SQL/合并/特征重要性/特征组合/相关性) - 链接: https://www.cubestudio.vip/docs/05-%E4%BB%BB%E5%8A%A1%E6%A8%A1%E6%9D%BF/%E6%A8%A1%E6%9D%BF%E4%BD%BF%E7%94%A8/04-%E7%89%B9%E5%BE%81%E5%A4%84%E7%90%86 - 分类: 05-任务模板 / 模板使用 - 适用场景: 做特征工程:离散化/标准化/采样/降维/拆分/转换/编码/排序/SQL/表合并/算特征重要性、相关性时,查 params 怎么写 - 关键词: 特征处理 / 特征工程 / discretization / 离散化 / standardize / normalize / 标准化 / 归一化 / sample / 采样 / dimension-reduction / 降维 / pca / data-split / 数据拆分 / data-transform / 数据转换 / boxcox / one-hot / label_encoding / featurehasher / index-process / sort / run-sql / union-join / hadamard / feature-importance / 特征重要性 / feature-combine / 特征组合 / calculate-correlation / 相关性 / params - 最后更新: 2026-06-30 # 特征处理 本页大部分模板共用三个入参: - input_dataset_path:数据集来源,如 `/mnt/admin/pipeline/example/feature-process/data-test1.csv` - save_dataset_path:输出数据集保存路径,如 `/mnt/admin/pipeline/example/feature-process/result.csv` - params:特征工程参数配置,json 格式(具体字段见各小节示例) 通用约定:`col_name` 不写表示处理所有列;`keep` 为 1 时原数据加后缀 `_origin` 拼接在处理结果前面。 ## discretization 特征离散化,有等宽、等频、聚类几种可选。入参为上面的 input_dataset_path / save_dataset_path / params。 ### 等宽离散化 ``` [ { "process_type":"width_dist", "col_name":"age", "col_map":{"age":"age1"}, "bins":5, "keep":1 } ] ``` - process_type:width_dist 表示等宽离散化 - col_name:需要处理的列名,可多列,英文逗号分隔,不写表示处理所有列 - col_map:需要重命名的列名,比如 age 重命名为 age1 - bins:每个特征离散化到几个区间 - keep:是否保留原始数据,1 则原数据加后缀 `_origin` 拼接在前面 ### 等频离散化 按分位数来做离散化: ``` [ { "process_type":"freq_dist", "col_name":"age,duration", "col_map":{"age":"age1"}, "bins":5, "keep":1 } ] ``` - process_type:freq_dist 表示等频离散化 - 其余字段含义同等宽离散化 ### 聚类离散化 通过 kmeans 聚类来做离散化: ``` [ { "process_type":"kbinsdiscretizer", "col_name":"", "col_map":{}, "encode":"ordinal", "strategy":"kmeans", "n_bins":4, "keep":1 } ] ``` - process_type:kbinsdiscretizer 表示 k 箱离散化,默认是 kmeans 聚类离散化 - encode:表示做离散化(编码方式,如 ordinal) - strategy:表示通过 kmeans 做聚类离散化 - n_bins:每个特征离散化到几个区间 ## standardize-normalize 标准化及正则化,有最大绝对值归一化、最大最小归一化等等。入参为 input_dataset_path / save_dataset_path / params。各小节区别仅在 process_type。 ### maxabsscaler 最大绝对值归一化: ``` [ { "process_type":"maxabsscaler", "col_name":"", "col_map":{}, "keep":0 } ] ``` ### minmaxscaler 最大最小值归一化: ``` [ { "process_type":"minmaxscaler", "col_name":"", "col_map":{}, "keep":0 } ] ``` ### standardscaler 标准化: ``` [ { "process_type":"standardscaler", "col_name":"", "col_map":{}, "keep":0 } ] ``` ### normalizer 正则化: ``` [ { "process_type":"normalizer", "col_name":"", "col_map":{}, "keep":0 } ] ``` ### z_score z-score 标准化: ``` [ { "process_type":"z_score", "col_name":"", "col_map":{}, "keep":0 } ] ``` ### time_format 时间列格式化: ``` [ { "process_type":"time_format", "col_name":"time1,time2,time3", "col_map":{} } ] ``` - process_type:time_format 表示时间格式化 - col_name:需要处理的列名(时间列),可多列,英文逗号分隔 ## sample 采样,包括随机采样、分层采样、过采样、欠采样等等。入参为 input_dataset_path / save_dataset_path / params。 ### random_sample 随机采样: ``` [ { "process_type":"random_sample", "ratio":0.5, "keep":0 } ] ``` - ratio:采样比例,比如 0.5 表示随机采样 50% ### weight_sample 加权采样: ``` [ { "process_type":"weight_sample", "ratio":0.5, "weights_path":"/mnt/admin/pipeline/example/feature-process/weight.csv", "keep":0 } ] ``` - weights_path:样本权重文件 ### level_sample 分层采样: ``` [ { "process_type":"level_sample", "ratio":0.5, "level_path":"/mnt/admin/pipeline/example/feature-process/level.csv", "keep":0 } ] ``` - level_path:样本属于哪个分层的文件 ### over_under_sample 过采样及欠采样: ``` [ { "process_type":"over_under_sample", "col_y":"y", "type":"over_SMOTE", "keep":0 } ] ``` - col_y:目标列的名称 - type:过采样或欠采样类型,可选 over_random、over_SMOTE、over_ADASYN、over_BorderlineSMOTE、under_random、under_NearMiss、under_TomekLinks ## dimension-reduction 降维,包括 pca 降维和卡方降维。入参为 input_dataset_path / save_dataset_path / params。 ### pca pca 降维可以做主成分分析: ``` [ { "process_type":"pca", "col_name":"", "n_components":3, "col_map":{"age":"age1","duration":"duration2"}, "prefix":"pca_", "keep":0 } ] ``` - n_components:选出几个主成分 - prefix:pca 之后的列名前缀 ### chi_ 卡方降维: ``` [ { "process_type":"chi_", "col_name":"", "col_y":"y", "k":3 } ] ``` - col_y:目标列名称 - k:根据卡方值选出几列特征列 ## data-split 数据拆分,包括列内拆分、列间拆分、行间拆分、svd 奇异值分解。入参为 input_dataset_path / save_dataset_path / params。 ### split_column 列内拆分,拆分某列为 'a-b' 格式的列,拆为 'a' 和 'b' 两列: ``` [ { "process_type":"split_column", "split_map":{"a":",","b":"|"}, "prefix":"" } ] ``` - split_map:哪一列用哪个分隔符来拆分,可多列 - prefix:拆分后每列的前缀 ### split_data 列间或行间拆分: ``` [ { "process_type":"split_data", "col_split_map":{"r_a":"age,duration","r_b":"age,pdays"}, "row_split_map":{"c":"(0:100)","d":"(99:1002)"}, "split_outpath":"/mnt/{{creator}}/pipeline/example/feature-process/split_r/" } ] ``` - col_split_map:拆分后哪几列属于哪个文件,`"r_a":"age,duration"` 表示 age、duration 列属于文件 r_a - row_split_map:拆分后哪几行属于哪个文件,`"c":"(0:100)"` 表示第 1 到 100 行属于文件 c,`"c":"(0.8)"` 表示随机 80% 属于文件 c - split_outpath:拆分后的文件存到哪个文件夹下 ### svd 奇异值分解: ``` [ { "process_type":"svd", "col_name":"", "svd_outpath":"svd/" } ] ``` - svd_outpath:分解后的文件存到哪个文件夹下 ## data-transform 数据转换,包括 boxcox 转换、二值化、数据类型转换、根据函数转换等。入参为 input_dataset_path / save_dataset_path / params。 > 注:源文档此小节标题写作 `data-tranform`,按代码语义应为 data-transform(数据转换)。 ### boxcox boxcox 转换,只针对非负连续变量进行: ``` [ { "process_type":"boxcox", "col_name":"age,duration", "col_map":{"age":"age1","duration":"duration2"}, "keep":1 } ] ``` ### binarization 二值化,将特征转换为 0 或 1: ``` [ { "process_type":"binarization", "col_name":"age,duration", "col_map":{"age":"age1","duration":"duration2"}, "threshold":0.4, "keep":1 } ] ``` - threshold:转换门限,0.4 表示小于 0.4 为 0,大于 0.4 为 1 ### dct dct 变换: ``` [ { "process_type":"dct_transform", "col_name":"age,duration", "col_map":{"age":"age1","duration":"duration2"}, "keep":1 } ] ``` ### func_transfer 根据函数转换: ``` [ { "process_type":"func_transfer", "func_map":{"lambda x:x+1":"age,duration"} } ] ``` - func_map:哪些列做什么转换,比如 `{"lambda x:x+1":"age,duration"}` 表示 age、duration 列每个值加 1 ### ma 移动平均: ``` [ { "process_type":"ma", "col_map":{}, "time_col":"", "col_name":"age,duration", "window":3, "keep":0 } ] ``` - time_col:时间列;若有时间列,依据时间列从前往后排序后再做移动平均,若无则直接做 - window:移动平均的窗口大小 ### type_transfer 数据类型转换: ``` [ { "process_type":"type_transfer", "col_trans_map":{"sex":"to_str","family":"str_to_bool","education":"eval"} } ] ``` - col_trans_map:哪列做什么类型转换,可转换类型有 str_to_int、str_to_float、str_to_bool、to_str、eval(字符串变为列表、字典、集合) ### polynomialfeatures 多项式展开: ``` [ { "process_type":"polynomialfeatures", "col_name":"", "col_map":{}, "degree":2, "prefix":"expand_", "keep":0 } ] ``` - degree:展开的阶数 - prefix:展开后列名的前缀,默认 expand_ ## objective-process 非数值型变量的处理,包括 hash、根据统计量转换等。入参为 input_dataset_path / save_dataset_path / params。 ### featurehasher 对非数值型变量做 hash: ``` [ { "process_type":"featurehasher", "col_name":"", "col_map":{}, "prefix":"hash_", "n_features":3, "keep":0 } ] ``` - prefix:hash 后列名的前缀,默认 hash_ - n_features:hash 的阶数 ### label_encoding 非数值型变量依据统计量或指定 map 做数值转换: ``` [ { "process_type":"label_encoding", "col_name":"sex", "map":{"sex":{"f":1,"m":2}}, "type":"order" } ] ``` - map:当 type 为 order 时指定映射,`{"sex":{"f":1,"m":2}}` 表示 sex 列 f→1、m→2;其余 type 不需指定 map - type:转换类别,random 表示随机映射,order 表示按指定 map 映射,counting 表示把每个类别出现次数映射为数值,target 表示二分类中每个类别映射为该类别 y=1 的个数 ### one-hot 非数值型变量进行 one-hot 展开: ``` [ { "process_type":"one_hot", "col_name":"age", "col_map":{"age":"age1"}, "keep":0 } ] ``` ## index-process 索引处理,比如增加索引、索引转列、列索引重命名。入参为 input_dataset_path / save_dataset_path / params。 ### col_rename 列名重命名: ``` [ { "process_type":"col_rename", "col_map":{"age":"age1"}, "keep":1 } ] ``` ### index_to_col 将索引转换为列: ``` [ { "process_type":"index_to_col", "index_name":"order", "to_str":"false" } ] ``` - index_name:索引转换为列之后的列名 - to_str:转列后是否转为字符串型 ### add_index 增加行索引: ``` [ { "process_type":"add_index", "index_path":"/mnt/admin/pipeline/example/feature-process/level.csv", "save_index_path":"save_index_path.csv" } ] ``` - index_path:需要增加的行索引存放的位置 - save_index_path:保存索引数据结果的位置 ## sort 排序。入参为 input_dataset_path / save_dataset_path / params。 ``` [ { "process_type":"sort", "col_name":"a,c", "col_map":{}, "ascending":"False" } ] ``` - col_name:根据哪几列来排序,多列间英文逗号分隔 - ascending:True 升序,False 降序 ## run-sql 在数据集上执行 sql 语句。入参为 input_dataset_path / save_dataset_path / params。 ``` [ { "process_type":"runsql", "query":"select * from data where age>30" } ] ``` - query:要执行的 sql 语句 ## union-join-data 合并数据集,union 或 join。 入参: - data:数据集来源,可有多个表,表名用 `|` 分隔,如 `/mnt/.../a.csv|/mnt/.../b.csv|/mnt/.../c.csv` - merge_type:合并类型,row_union/column_union/left_join/right_join/inner_join/outer_join,分别表示行拼接、列拼接、按指定主键列做 left_join 等 - ignore_index:合并时是否忽略索引,如果是自增索引,忽略索引会从头开始,如 `True` - join_columns:如果是 join,需指定此参数,当作主键用于连接 - save_dataset_path:输出数据集保存路径 > 说明:源使用文档此处把取值写作 `left_jon`,已按代码改正为 `left_join`。合法取值见 `job-template/job/feature-process/launcher-union-join-data.py:19-36`:row_union/column_union/left_join/right_join/inner_join/outer_join,其中 join 类需配 `join_columns`。 ## hadamard-multiply hadamard 乘积。 入参: - data1:数据来源 1 - data2:数据来源 2 - save_dataset_path:hadamard 乘积结果保存路径 ## feature-importance 通过随机森林、逻辑回归、xgboost 等模型计算特征重要性,还可以计算特征的 iv 值、互信息值、方差等。 入参: - model_path:如果要用已有模型来评估特征重要性,则输入模型的路径 - method:logistic_regression | random_forest | xgb | iv | mutual_if | chi | variance,分别表示逻辑回归特征参数绝对值、随机森林特征重要性、xgboost 特征重要性、iv 值、互信息值、卡方值、方差(计算方差时先做了归一化) - input_dataset_path:输入数据集的路径 - col_name:需要计算重要性的列名,英文逗号分隔,不输入默认计算全部 - target:目标变量列名,可多列,英文逗号分隔 - save_dataset_path:输出所有特征重要性等信息的保存路径 ## feature-combine 特征组合,用于衍生特征。 入参: - params:特征衍生参数配置 - input_dataset_path:输入数据集文件路径 - save_dataset_path:输出数据集文件路径 params 示例: ```bash { "cross":"age,duration,campaign,emp_var_rate", "polynomial":"age,duration,campaign,emp_var_rate", "hashing":"age,duration,campaign,emp_var_rate", "aggregation":"age,duration,campaign,emp_var_rate", "statistics":"age,duration,campaign,emp_var_rate" } ``` params 的 key 表示用什么方法做特征衍生(5 种可选):cross 表示特征相乘,polynomial 表示多项式特征,hashing 表示两列做 hash,aggregation 表示根据 A 列对 B 列做聚合后得到的统计量作为组合特征,statistics 表示两列均值做组合特征。 params 的 value 表示方法作用于哪些列,英文逗号分隔。 ## calculate-correlation calculate-correlation 模板可以做特征向量间的相关性计算。 入参: - input_dataset_path:需要处理的样本路径,如 `data/fin_data.csv` - result_path:处理之后结果保存的路径,如 `data/fin_data_r.csv` - corr_type:corr 表示计算特征之间的相关系数矩阵 - feature_columns:需要计算相关性的特征列,英文逗号分隔 --- ### 机器学习算法模板(RF/LR/LightGBM/KNN/KMeans/GBDT/决策树/贝叶斯/XGB/AdaBoost/超参搜索/AR/ARIMA/回归) - 链接: https://www.cubestudio.vip/docs/05-%E4%BB%BB%E5%8A%A1%E6%A8%A1%E6%9D%BF/%E6%A8%A1%E6%9D%BF%E4%BD%BF%E7%94%A8/05-%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%E7%AE%97%E6%B3%95 - 分类: 05-任务模板 / 模板使用 - 适用场景: 在 pipeline 里跑 sklearn 系单机机器学习算法/超参搜索/时间序列,查训练集、特征列、model_params 怎么填 - 关键词: 机器学习 / 算法模板 / random-forest / 随机森林 / lr / 逻辑回归 / lightgbm / knn / kmean / kmeans / 聚类 / gbdt / decision-tree / 决策树 / bayesian / 朴素贝叶斯 / xgb / xgboost / adaboost / hyperparameter-search-ray / 超参搜索 / ar / arima / 时间序列 / rf-regression / 回归 / model_params - 最后更新: 2026-06-30 # 机器学习算法 > 以下 sklearn 系算法模板的代码入口在 `job-template/job/sklearn/`(每个算法一个 `launcher-xxx.py`)。多数算法共用一组入参:train_dataset、val_dataset、feature_columns、label_columns、save_model_dir、inference_dataset、model_params。save_model_dir 写到文件夹级别即可(不用写到 pkl 级别)。 ## random-forest 随机森林算法模板。 入参(通用六项 + model_params): - train_dataset:训练数据集路径,如 `data/fin_data_train.csv` - val_dataset:评估数据集地址,如 `data/fin_data_val.csv` - feature_columns:特征列,英文逗号分隔 - label_columns:标签列,英文逗号分隔 - save_model_dir:模型保存路径,如 `model/`,文件夹级别即可 - inference_dataset:测试数据集路径,如 `data/fin_data_test.csv` - model_params:模型输入参数,如 `{"n_estimators": 300}`,参考 [sklearn RandomForestClassifier](https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestClassifier.html#sklearn.ensemble.RandomForestClassifier) ## lr 逻辑回归算法模板。入参同上六项,外加: - model_params:如 `{"C": 2,"fit_intercept": True}`,参考 [sklearn LogisticRegression](https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html) ## lightgbm lightgbm 算法模板。入参同上六项,外加: - model_params:如 `{"max_depth": 5,"reg_lambda": 2}`,参考 [LightGBM 文档](https://lightgbm.cn/docs/6/#_2) “用于控制模型学习过程的参数”部分 ## knn knn 算法模板。入参同上六项,外加: - model_params:如 `{"n_neighbors": 200,"algorithm": "ball_tree"}`,参考 [sklearn KNeighborsClassifier](https://scikit-learn.org/stable/modules/generated/sklearn.neighbors.KNeighborsClassifier.html#sklearn.neighbors.KNeighborsClassifier) ## kmean kmean 算法模板(平台中注册的模板名为 `kmeans`)。入参同上六项,外加: - model_params:如 `{"n_clusters": 3,"max_iter": 200}`,参考 [sklearn KMeans](https://scikit-learn.org/stable/modules/generated/sklearn.cluster.KMeans.html#sklearn.cluster.KMeans) ## gbdt gbdt 算法模板。入参同上六项,外加: - model_params:如 `{"n_estimators": 150,"learning_rate": 0.1}`,参考 [sklearn GradientBoostingClassifier](https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.GradientBoostingClassifier.html#sklearn.ensemble.GradientBoostingClassifier) ## decision-tree 决策树算法模板。入参同上六项,外加: - model_params:如 `{"max_depth": 3,"min_samples_split": 5}`,参考 [sklearn DecisionTreeClassifier](https://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html#sklearn.tree.DecisionTreeClassifier) ## bayesian 朴素贝叶斯算法模板。 入参: - train_dataset:训练数据集路径,如 `data/fin_data_train.csv` - test_dataset:评估数据集路径,如 `data/fin_data_val.csv` - save_model_dir:模型保存路径,文件夹级别即可 - inference_dataset:测试数据集路径,如 `data/fin_data_test.csv` > 注:bayesian 模板的评估集参数名为 `test_dataset`(与其他算法的 `val_dataset` 不同),源文档如此,使用前可对照 `job-template/job/sklearn/launcher-bayesian.py`。 ## xgb xgb 单机训练模板。 入参: - train_dataset:训练数据集路径 - val_dataset:评估数据集路径 - feature_columns:特征列,英文逗号分隔 - label_columns:标签列,英文逗号分隔 - model_params:模型输入参数,如: ``` { "booster": "gbtree", "eta": 0.1, "gamma": 0, "max_depth": 6, "objective": "binary:logistic", "eval_metric": "auc" } ``` 参考 [XGBClassifier 文档](https://xgboost.readthedocs.io/en/latest/python/python_api.html#xgboost.XGBClassifier) - save_model_dir:模型保存路径,文件夹级别即可 - inference_dataset:测试数据集路径 ## adaboost adaboost 算法模板。入参同通用六项,外加: - model_params:如 `{"n_estimators": 100,"learning_rate": 0.05}`,参考 [sklearn AdaBoostClassifier](https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.AdaBoostClassifier.html#sklearn.ensemble.AdaBoostClassifier) ## hyperparameter-search-ray 超参搜索模板(基于 Ray Tune)。 入参: - command:运行算法模板的命令,比如 `python /mnt/admin/cube-studio/job-template/job/sklearn/launcher-kmeans.py --save_model_dir /mnt/admin/pipeline/kmeans/ --train_dataset /mnt/admin/pipeline/example/feature-process/data-test.csv --label_columns y --feature_columns age,duration,...` - params:需要进行超参搜索的超参数,如 `{"n_clusters": tune.grid_search([2,3,4]),"max_iter": tune.grid_search([50,100,200])}` - outfile:超参搜索评估结果,如 `mnt/admin/pipeline/kmeans/val_result.json` - metric:模型评估方式,如 silhouette_avg_train(训练集轮廓系数) - mode:评估参数越大越好还是越小越好,max 越大越好,min 越小越好 - num_samples:超参搜索用的样本数,默认 1 - result_save_path:输出结果地址,如 `/mnt/admin/pipeline/ray_hyperparams/hyperparams_r_kmeans.csv` > 注意:sklearn 系算法的 launcher 实为 `job-template/job/sklearn/launcher-<算法>.py`(如 kmeans 为 `launcher-kmeans.py`),仓库中并无 `job/kmeans/` 目录,上方命令路径已据此修正。此外该超参搜索模板还支持 `--workdir`(命令执行目录)入参(`hyperparameter-search-ray/launcher.py:145`),上方入参列表未列出,按实际部署的目录结构和模板入参填写即可。 ## ar 时间序列算法 AR。 入参: - train_dataset:训练数据集来源 - feature_col:特征列,只能有一个列名 - save_model_dir:模型相关输出文件保存的文件夹,到文件夹层面即可 - time_col:时间列的列名 - start:开始预测的位置 - end:结束预测的位置 - lag:AR 算法参数,窗口大小 ## arima 时间序列算法 ARIMA。 入参: - train_dataset:训练数据集来源 - feature_col:特征列,只能有一个列名 - save_model_dir:模型相关输出文件保存的文件夹 - time_col:时间列的列名 - start:开始预测的位置 - end:结束预测的位置 - order:ARIMA 算法参数,阶数大小 ## rf-regression 随机森林回归模型(平台中注册的模板名为 `random-forest-regression`)。入参同通用六项,外加: - model_params:如 `{"n_estimators": 300}`,参考 [sklearn RandomForestRegressor](https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestRegressor.html#sklearn.ensemble.RandomForestRegressor) --- ### 深度学习分布式训练模板(tfjob/pytorchjob/mxnet/paddlejob/mindspore) - 链接: https://www.cubestudio.vip/docs/05-%E4%BB%BB%E5%8A%A1%E6%A8%A1%E6%9D%BF/%E6%A8%A1%E6%9D%BF%E4%BD%BF%E7%94%A8/06-%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0 - 分类: 05-任务模板 / 模板使用 - 适用场景: 在 pipeline 里跑 TF/PyTorch/MXNet/Paddle/MindSpore 分布式训练,查 worker 镜像/启动目录/命令/副本数怎么填 - 关键词: 深度学习 / 分布式训练 / tfjob / tensorflow / pytorchjob / pytorch / mxnet / paddlejob / paddle / mindspore / num_worker / num_ps / image / working_dir / command - 最后更新: 2026-06-30 # 深度学习 > 这几类分布式训练模板共用入参思路:image(worker 运行镜像)、working_dir(启动目录)、command(启动命令)、num_worker(worker 数目),部分支持 num_ps(参数服务器数目)。镜像/命令仅为示例,实际以你的代码环境为准。 ## tfjob TensorFlow 分布式训练模板。 入参: - image:worker 镜像,直接运行你代码的环境镜像、基础镜像,如 `kubeflow/tf-mnist-with-summaries:latest` - working_dir:命令的启动目录,如 `/mnt/admin/pipeline/example/tf/` - command:启动命令,如 `python /var/tf_mnist/mnist_with_summaries.py` - num_worker:分布式训练 worker 的数目,如 `2` ## pytorchjob pytorch 分布式训练模板。 入参: - image:worker 镜像,如 `ccr.ccs.tencentyun.com/cube-studio/ubuntu-gpu:cuda11.8.0-cudnn8-python3.9` - working_dir:命令的启动目录,如 `/mnt/admin/pipeline/example/pytorch/` - command:启动命令,如 `bash start.sh` - num_worker:分布式训练 worker 的数目,如 `3` ## mxnet mxnet 分布式训练模板。 入参: - image:worker 镜像,如 `mxjob/mxnet:gpu` - working_dir:命令的启动目录,如 `/mnt/admin/pipeline/example/mxnet/` - command:启动命令,如 `bash start.sh` - num_worker:分布式训练 worker 的数目,如 `1` - num_ps:分布式训练 ps 的数目,如 `1` ## paddlejob paddle 分布式训练模板。 入参: - image:worker 镜像,如 `registry.baidubce.com/paddlepaddle/paddle:2.4.0rc0-gpu-cuda11.2-cudnn8.1-trt8.0` - working_dir:命令的启动目录,如 `/mnt/admin/pipeline/example/paddlejob/` - command:启动命令,如 `python -m paddle.distributed.launch run_check` - num_worker:分布式训练 worker 的数目,如 `2` - num_ps:分布式训练 ps 的数目,如 `0` ## mindspore mindspore 分布式训练模板。 入参: - image:worker 镜像,如 `lyd911/mindspore-cpu-example:0.2.0` - working_dir:启动目录,如 `/mnt/admin/pipeline/example/mindspore/` - command:启动命令,如 `python /tmp/lenet.py` - num_worker:占用机器个数,如 `3` --- ### 模型处理模板(model-evaluation 模型评估 / model-convert 模型转换) - 链接: https://www.cubestudio.vip/docs/05-%E4%BB%BB%E5%8A%A1%E6%A8%A1%E6%9D%BF/%E6%A8%A1%E6%9D%BF%E4%BD%BF%E7%94%A8/07-%E6%A8%A1%E5%9E%8B%E5%A4%84%E7%90%86 - 分类: 05-任务模板 / 模板使用 - 适用场景: 训练完要评估传统机器学习模型指标,或把 PyTorch/YOLO 模型转 ONNX / 边缘多格式时 - 关键词: 模型处理 / model-evaluation / 模型评估 / eval_type / model-convert / 模型转换 / onnx / tensorrt / rknn / openvino / ncnn / mnn / tflite / 量化 / quantize / pytorch转onnx - 最后更新: 2026-06-30 # 模型处理 ## model-evaluation 传统机器学习模型评估模板(代码入口 `job-template/job/model_evaluation/launcher.py`)。 入参: - true_dataset_path:真实数据集地址,如 `/mnt/admin/pipeline/example/ml/train.csv` - true_label_column:真实数据集 label 列,如 `y` - pred_dataset_path:预测数据集地址,如 `/mnt/admin/pipeline/example/ml/inference_result.csv` - pred_label_column:预测数据集 label 列,如 `y` - save_result_path:评估结果保存地址,如 `/mnt/admin/pipeline/example/ml/evaluation.json` - eval_type:评估类型/指标,如 `分类-accuracy`(多个指标用逗号分隔) - model_type:模型类型,如 `classify`(分类还是回归) ## 模型转换(model-convert) 将 PyTorch / YOLO 模型导出成 ONNX,并可进一步分发到边缘多格式(OpenVINO/NCNN/MNN/TFLite/RKNN/TensorRT engine/SDK lib)。 > ⚠️ 已按代码更新:源使用文档此处描述的是旧版接口(`model-path`/`onnx-path`/`framework`/`supported-pipelines`/`opset`)。当前模板 `job-template/job/model-convert/start.py:20-44` 已重构,入参如下,请以代码为准。 入参(当前版本): - model_type:模型种类,`yolo` 或 `torch`,默认 `torch` - model_path:待转换的 PyTorch 模型文件路径 - arch:`model_type=torch` 时的架构名,可留空让脚本猜测 - input_name:ONNX 输入名,多输入用逗号分隔,`none` 表示自动 - output_name:ONNX 输出名,多输出用逗号分隔,`none` 表示自动 - export_model_path:导出 ONNX 的完整路径(含文件名),其它格式产物会落到同目录,默认 `/mnt/pipeline/example/export-onnx/export.onnx` - do_quantize:是否对 ONNX 做 INT8 动态量化,生成 `*-int8.onnx`,默认 `false` - onnx2engine:是否生成 TensorRT FP32/FP16 engine 文件(等价于把 engine 加进 `--export_format`),默认 `false` - export_format:导出格式列表,逗号分隔,可选 `onnx,openvino,ncnn,mnn,tflite,rknn,engine,lib`,默认 `onnx`(ONNX 是其它 backend 的前置产物,会自动补上) - rknn_target_platform:RKNN 目标芯片,如 rk3566/rk3568/rk3588/rk3399pro/rv1103/rv1106 等,默认 `rk3588` - lib_target:lib 输出平台,`linux` 产 .so / `windows` 产 .dll / `both` 两者都产,默认 `linux` - lib_precision:lib 嵌入的 ONNX 精度,`fp32` 直接嵌入,`fp16` 先转 fp16 再嵌入,默认 `fp32` - lib_name:生成的库基础名称(不含前后缀),默认 `model_inference` --- ### 模型服务化模板(离线推理/服务部署/模型注册) - 链接: https://www.cubestudio.vip/docs/05-%E4%BB%BB%E5%8A%A1%E6%A8%A1%E6%9D%BF/%E6%A8%A1%E6%9D%BF%E4%BD%BF%E7%94%A8/08-%E6%A8%A1%E5%9E%8B%E6%9C%8D%E5%8A%A1%E5%8C%96 - 分类: 05-任务模板 / 模板使用 - 适用场景: 训练完要做离线批量推理、把模型部署成在线推理服务、或把模型注册进模型管理时 - 关键词: 模型服务化 / model-offline-predict / 离线推理 / 弹性分布式推理 / deploy-service / 服务部署 / 推理服务 / model-register / 模型注册 / model_version / service_type / replicas / resource_gpu - 最后更新: 2026-06-30 # 模型服务化 ## model-offline-predict 支持模型弹性分布式推理(离线批量推理)。 入参: - image:worker 镜像,直接运行你代码的环境镜像/基础镜像,如 `ccr.ccs.tencentyun.com/cube-studio/ubuntu-gpu:cuda11.8.0-cudnn8-python3.9` - working_dir:启动目录,如 `/mnt/admin/pipeline/example/offline-inference/` - command:环境安装和任务启动命令,如 `bash start.sh` - num_worker:占用机器个数,如 `3` ## deploy-service 服务部署模板,将训练模型注册到推理服务管理模块并自动部署推理服务(代码入口 `job-template/job/deploy-service/launcher.py`)。 入参: - project_name:项目组名称,如 `public` - label:推理服务描述/中文名,如 `demo推理服务` - model_name:模型名 - model_version:模型版本号,如 `v2022.10.01.1` - model_path:模型地址 - service_type:推理服务类型(默认 `serving`) - images:推理服务镜像 - working_dir:推理容器工作目录,个人工作目录 `/mnt/$username` - command:推理容器启动命令 - args:推理容器启动参数 - env:推理容器环境变量 - host:部署域名,留空自动生成 - ports:推理容器暴露端口,如 `80` - replicas:pod 副本数,如 `1` - resource_memory:每个 pod 占用内存,如 `2G` - resource_cpu:每个 pod 占用 cpu,如 `2` - resource_gpu:每个 pod 占用 gpu,如 `0` - volume_mount:容器挂载,支持 pvc/hostpath/configmap 三种形式,格式示例 `$pvc_name1(pvc):/$container_path1,$hostpath1(hostpath):/$container_path2`,注意 pvc 会自动挂载对应目录下的个人 username 子目录,如 `kubeflow-user-workspace(pvc):/mnt` - metrics:请求指标采集,配置端口+url,示例 `8080:/metrics` - health:健康检查接口,使用 http 接口或 shell 命令,示例 `8080:/health` 或 `shell:python health.py` > 代码中该模板还包含 `hpa`(弹性伸缩)和 `inference_config`(配置文件)两个入参,见 `job-template/job/deploy-service/launcher.py:152,155`。 注意:该模板可以配置 HOST 环境变量,以此在自动化部署的时候可以直接暴露服务的 ip,直接让外界进行访问。例如 `HOST=http://当前浏览器ip:当前浏览器端口`。 ## model-register 模型注册模板,将训练后的模型注册到模型管理中(代码入口 `job-template/job/model_register/launcher.py`)。 入参: - project_name:部署项目名,如 `public` - model_name:模型名(a-z0-9- 字符组成,最长 54 个字符),如 `mnist` - model_version:模型版本号,如 `{{ datetime.datetime.now().strftime('v%Y.%m.%d.1') }}` - model_path:模型地址,如 `https://cube-studio.oss-cn-hangzhou.aliyuncs.com/inference/tf-mnist.tar.gz` - model_metric:模型指标,如 `accuracy:0.8` - describe:模型描述,如 `mnist模型` - framework:模型框架(默认 `tf`) - inference_framework:推理框架(默认 `tfserving`) --- ### 多媒体类模板(媒体下载/视频抽帧/视频提音频) - 链接: https://www.cubestudio.vip/docs/05-%E4%BB%BB%E5%8A%A1%E6%A8%A1%E6%9D%BF/%E6%A8%A1%E6%9D%BF%E4%BD%BF%E7%94%A8/09-%E5%A4%9A%E5%AA%92%E4%BD%93%E7%B1%BB%E6%A8%A1%E6%9D%BF - 分类: 05-任务模板 / 模板使用 - 适用场景: 要分布式批量下载媒体文件、从视频抽帧出图片、或从视频里提取音频时 - 关键词: 多媒体 / media-download / 媒体文件下载 / 分布式下载 / video-image / video-img / 视频抽帧 / 提取图片 / video-audio / 视频提取音频 / num_worker / input_file - 最后更新: 2026-06-30 # 多媒体类模板 ## media-download 分布式媒体文件下载。 入参: - num_worker:分布式任务的 worker 数目,如 `3` - download_type:下载类型 - input_file:下载信息文件地址,如 `/mnt/admin/pipeline/example/media/video_url.txt`,url 类型每行格式:`$url $local_path` ## video-image 分布式提取视频图片(视频抽帧)。 > 注:该模板在平台中注册的名称为 `video-img`,见 `myapp/init/init-job-template.json`。 入参: - num_workers:worker 数量,如 `3` - input_file:配置文件地址,每行格式 `$local_video_path $des_img_dir $frame_rate`,如 `/mnt/admin/pipeline/example/media/video_image.txt` ## video-audio 分布式提取视频音频。 入参: - num_workers:worker 数量,如 `3` - input_file:配置文件地址,每行格式 `$local_video_path $des_audio_path`,如 `/mnt/admin/pipeline/example/media/video_audio.txt` --- ### 分布式加速模板(horovod) - 链接: https://www.cubestudio.vip/docs/05-%E4%BB%BB%E5%8A%A1%E6%A8%A1%E6%9D%BF/%E6%A8%A1%E6%9D%BF%E4%BD%BF%E7%94%A8/10-%E5%88%86%E5%B8%83%E5%BC%8F%E5%8A%A0%E9%80%9F - 分类: 05-任务模板 / 模板使用 - 适用场景: 要用 horovod 做多机多卡分布式训练加速时 - 关键词: 分布式加速 / horovod / 分布式训练 / work_images / working_dir / command / num_worker / ring-allreduce - 最后更新: 2026-06-30 # 分布式加速 ## horovod horovod 分布式训练模板。 入参: - work_images:worker 的运行镜像,如 `horovod/horovod:0.20.0-tf2.3.0-torch1.6.0-mxnet1.5.0-py3.7-cpu` - working_dir:命令的启动目录,如 `/mnt/admin/pipeline/example/horovod/` - command:训练启动命令,如 `python /examples/tensorflow2_mnist.py` - num_worker:分布式 worker 的数目,如 `2` --- ### 任务模板使用手册(总览) - 链接: https://www.cubestudio.vip/docs/05-%E4%BB%BB%E5%8A%A1%E6%A8%A1%E6%9D%BF/%E6%A8%A1%E6%9D%BF%E4%BD%BF%E7%94%A8/README - 分类: 05-任务模板 / 模板使用 - 适用场景: 在 pipeline 拖拽编排里使用各内置任务模板时,查每个模板的功能和入参怎么填 - 关键词: 模板使用 / 任务模板 / pipeline / 算子 / operator / job-template / 入参 / 参数 / 使用手册 / template usage - 最后更新: 2026-06-30 # 任务模板使用手册(总览) 本手册面向**使用者**,讲在 pipeline 编排界面里拖拽使用各内置任务模板时,每个模板**做什么**、**入参怎么填**。这是「使用视角」,与本段(05-任务模板)各家族模板文档(设计/参数视角)互补,建议结合阅读。 > 使用方法也可参考代码仓库 `job-template/job/` 下对应模板中的 `README.md`。 > 想自己开发并注册新模板,见 [开发任务模板](../开发任务模板.md)。 ## 子文件目录(TOC) | 文件 | 涵盖模板 | |---|---| | [00-基础命令](./00-基础命令.md) | 自定义镜像、逻辑节点、python 节点 | | [01-数据导入导出](./01-数据导入导出.md) | datax、dataset、label-studio、model-download | | [02-数据处理](./02-数据处理.md) | hadoop、volcanojob、ray、sparkjob | | [03-数据预处理](./03-数据预处理.md) | drop-duplicate、drop-missing、drop-stablize、fill-missing、calculate_metric、outlier-detection | | [04-特征处理](./04-特征处理.md) | discretization、standardize-normalize、sample、dimension-reduction、data-split、data-transform、objective-process、index-process、sort、run-sql、union-join-data、hadamard-multiply、feature-importance、feature-combine、calculate-correlation | | [05-机器学习算法](./05-机器学习算法.md) | random-forest、lr、lightgbm、knn、kmean、gbdt、decision-tree、bayesian、xgb、adaboost、hyperparameter-search-ray、ar、arima、rf-regression | | [06-深度学习](./06-深度学习.md) | tfjob、pytorchjob、mxnet、paddlejob、mindspore | | [07-模型处理](./07-模型处理.md) | model-evaluation、模型转换 | | [08-模型服务化](./08-模型服务化.md) | model-offline-predict、deploy-service、model-register | | [09-多媒体类模板](./09-多媒体类模板.md) | media-download、video-image、video-audio | | [10-分布式加速](./10-分布式加速.md) | horovod | ## 通用约定 - 模板入参传入容器时**统一为字符串**;若入参语义是 json,代码内部会自行反序列化。 - 需要持久化的输入/输出路径,应放在容器的 `/mnt/{{creator}}/` 目录下(个人工作目录)。 - 路径示例里的 `admin`、`{{creator}}` 等为占位,实际为当前用户名。 --- ## 二次开发(53 篇) ### 代码结构与模块地图 - 链接: https://www.cubestudio.vip/docs/06-%E4%BA%8C%E6%AC%A1%E5%BC%80%E5%8F%91/%E4%BB%A3%E7%A0%81%E7%BB%93%E6%9E%84%E4%B8%8E%E6%A8%A1%E5%9D%97%E5%9C%B0%E5%9B%BE - 分类: 二次开发 / 总览导航 - 适用场景: 第一次接触 CubeStudio 源码、想知道某个功能/某段代码在哪个目录、前端源码与编译产物分别在哪、各 view 对应哪个业务模块时读这篇 - 关键词: 代码结构 / 模块地图 / 目录结构 / code structure / repo layout / aihub / images / job-template / myapp / views / models / frontend / vision / visionPlus / 静态资源 / static / 二开导航 - 最后更新: 2026-07-04 # 代码结构与模块地图 本文是二次开发的总览/导览页,介绍仓库的四大代码块(`aihub`、`images`、`job-template`、平台本体 `myapp`),以及平台本体内部 `views`/`models`/前端源码与编译产物的分布。 > 更细的"哪个 model 对应哪张表、哪个 view 对应哪个 API"清单见 [07-参考速查/模块地图.md](../07-参考速查/模块地图.md) 与 [07-参考速查/核心数据模型速查.md](../07-参考速查/核心数据模型速查.md);本页只做整体定位,避免重复展开。 ## aihub 相关代码 AIhub 的所有相关内容都独立于 CubeStudio 平台,因为它们的代码是解耦的,没有与平台部分耦合在一起。 - `aihub/src`:Python 包的源码,包括 Docker 启动命令、环境镜像构建方法等。 - `aihub/src/cubestudio`:实际运行代码,以及涉及到 AIhub 前后端、模型服务的 Web 界面,数据集的 SDK、训练的 SDK、与 CubeStudio 后端对接的 request 等内容。 - `aihub/src/cubestudio/aihub/model.py`:定义模型的基础属性,以便表征模型的所有内容。 - `aihub/src/cubestudio/aihub/web`:实现将 model 中的所有内容转化为开发服务、训练微调、自动化标注等功能(其中 `gradio_server.py`、`server.py` 等为 Web 服务入口)。 - `aihub/dataset`:开源数据集(仓库内为 `init-dataset.csv` 等初始数据)。 > 上述路径已对照源码核实存在(`aihub/src/cubestudio/{aihub,dataset,request,train,utils}`、`aihub/src/cubestudio/aihub/{model.py,web}`)。 ## 镜像封装相关 在 `images` 文件夹中(仓库根目录下的 `images/`): - 所有的 GPU 镜像构建方法(如 `ubuntu-gpu`、多 CUDA 版本)。 - 商业版和开源版的 VSCode、jupyter、rstudio 等(对应 `theia`/`theia-new`、`jupyter-notebook`、`rstudio` 等子目录;VSCode 形态以 `theia` 提供)。 - 推理服务(如 ONNX、TF serving、Triton 等)的镜像构建(`serving` 子目录)。 - nni 的超参搜索基础镜像(`nni` 子目录)。 - NPU、matlab、window 等其它运行环境镜像。 ## Job template 相关代码 `job-template` 文件夹包含了已有的任务模板,模板实体位于 `job-template/job/` 下。 涵盖各种数据处理、数据集导入(`dataset`/`datax`)、特征工程、GPT/LLM 系列(`llama-factory`、`llm-benchmark`、`llm-distillation`、`llm-prune`、`llm-quantization`、`llm-safety-eval`、`opencompass`)、Hadoop 生态(`hadoop`)、Ray 超参数搜索(`hyperparameter-search-ray`)、NNI 超参搜索(`hyperparameter-search-nni`)、模型转换/下载/评估/离线推理/注册(`model-convert`、`model_download`、`model_evaluation`、`model_offline_predict`、`model_register`)、Spark、TF/PyTorch 分布式(`tf`、`pytorch`)、Volcano、视频音频分布式处理(`video-audio`、`voice-process`、`vision-process`)、目标检测(`yolov8`、`yolo26`、`paddleocr-vl`)等内容。 每个模板目录中通常包含: - 一个 `Dockerfile`(镜像定义)。 - 一个 `build.sh`(执行镜像构建并推送的脚本)。 - 一个 `launcher.py`(容器内的启动脚本,即任务入口)。 - 一个 `README.md`(模板说明)。 > 核实并修正:原文把"构建镜像的 build 文件"与"执行构建和推送命令的文件"列为两个独立文件,实际不存在单独的 build 文件——`job-template/job/` 下的模板(如 `tf`、`pytorch`、`model_download`)均只有一个 `build.sh`(同时负责构建与推送,共约 34 个模板带 `build.sh`,0 个带独立 `build`),外加 `Dockerfile`/`launcher.py`/`README.md`;部分模板还含 `pyarmor_runtime_*` 加密运行时目录。 ## CubeStudio 平台本身代码(myapp) ### 开发框架 平台控制端基于 FAB(Flask-AppBuilder)框架,详见 [FAB后端开发框架.md](FAB后端开发框架.md)。 ### 菜单控制 `myapp/views/home.py` 中的 `menu` 函数(通过 `@expose_api(url='/menu')` 暴露为 `/menu` 接口)。 > 核实:源码中函数名为 `menu`,通过 `@expose_api(url='/menu')` 暴露为 `/menu` 接口,`myapp/views/home.py:81-83`。 使用场景:部分主菜单/子菜单绑定到自有平台,或者添加新的平台视图。 ### 登录方式 / 消息推送 `myapp/project.py` 中包含登录的方式、推送消息的方式。 使用场景: 1. 登录方式支持账户密码、OpenID 认证、LDAP 认证、`AUTH_REMOTE_USER`(在 `MyCustomRemoteUserView.login` 中自行编排,可对接内部 OA 系统)。`myapp/project.py:60` 定义 `class MyCustomRemoteUserView(AuthRemoteUserView)`,`:64` 为 `login`。 2. 推送方式,自行对接企业微信、邮箱等报警方式,实现 `push_admin` 与 `push_message` 函数。 > 核实并修正:原文写"实现 push 和 push_admin 两个函数",源码中实际为 `push_admin`、`push_message`(另有 `push_resource_apply`、`push_resource_approve`),`myapp/project.py:28-47`。无名为 `push` 的函数。 ### 定时 / 异步任务的开发 - 启动配置:`myapp/config.py` 中 `CeleryConfig` 类(`myapp/config.py:540`)。 - 定时任务代码开发:`myapp/tasks/schedules.py`。使用场景:定时删除旧的 workflow、tfjob、pytorchjob、测试任务、服务、notebook 等;定时提交定时任务的配置;监控 GPU 资源;在多项目组间进行资源调配。 - 异步任务代码开发:`myapp/tasks/async_task.py`。使用场景:需要花费较长时间完成的功能,比如灰度升级服务、构建镜像等。 ### 监听 CRD 变化 代码开发:`myapp/tools/watch_xx.py`(实际为 `watch_pod.py`、`watch_service.py`、`watch_workflow.py`)。 使用场景:监听训练和推理 workflow 的状态变化,推送消息。 ### 数据库的更新迭代 `myapp/migrations/versions`(另有 `versions-mysql`、`versions-postgres` 两份历史结构;MySQL 用默认 `versions`,PostgreSQL/人大金仓启动时用 `versions-postgres` 覆盖,达梦则清空并改用 `db.create_all()` 建表,见 `install/docker/config.py:476-488`)。 注意事项(三步法,详见 [新增视图页面与数据库升级.md](新增视图页面与数据库升级.md)): 1. 先使用 `myapp db upgrade`,将数据库依据 versions 目录下的记录更新到最新。 2. 然后 `myapp db migrate`,将代码中的最新 model 结构对比生成升级文件到 versions 目录下。 3. 再调用 `myapp db upgrade` 把增量结构更新到数据库。 ### 数据库结构和视图 - `myapp/models`:数据库结构(ORM model)。 - `myapp/views`:API 请求接口和 Web 界面,对应的 model 均在代码中有引入。 注意事项(基础文件): - `__init__.py`:引入需要添加的视图。 - `view_log.py`:所有视图的日志访问记录(`LOG_ModelView_Api`,`route_base='/log_modelview/api'`)。 - `base.py`:FAB 基础框架功能(`BaseMyappView` 等)。 - `baseApi.py`:FAB 基础框架功能(`MyappModelRestApi`,前后端分离接口基类)。 - `route.py`:Flask 自带路由功能。 - `home.py`:菜单管理和弹窗提醒(`/menu`、`/feature/check`)。 > 核实并修正:原文以"log"指代日志视图文件,源码中文件名为 `view_log.py`(`myapp/views/view_log.py`)。另外 `myapp/views/` 还有 `baseFormApi.py`、`baseSQLA.py` 两个基础文件,原文未列。 业务视图(已对照 `myapp/views/` 核实下列文件均存在): | 文件 | 业务模块 | |---|---| | `view_team.py` | 项目组管理 | | `view_metadata.py` | 离线库表管理 | | `view_metadata_metric.py` | 指标服务 | | `view_dimension.py` | 维表管理 | | `view_dataset.py` | 数据集管理 | | `view_images.py` | 镜像管理、仓库管理 | | `view_docker.py` | 在线构建镜像的功能 | | `view_notebook.py` | 在线开发 | | `view_etl_pipeline.py` | 数据 ETL pipeline | | `view_job_template.py` | 任务模板的功能 | | `view_pipeline.py` | 训练 pipeline 管理 | | `view_task.py` | 训练任务管理 | | `view_runhistory.py` | 定时调度管理 | | `view_workflow.py` | 任务流实例管理 | | `view_nni.py` | 超参搜索 nni 的功能 | | `view_train_model.py` | 模型管理的功能 | | `view_serving.py` | 内部服务 | | `view_inferenceserving.py` | 推理服务 | | `view_total_resource.py` | 整体资源 | | `view_chat.py` | 私有知识库 | | `view_chat_dingtalk.py` | 钉钉群机器人 | | `view_chat_wechat.py` | 微信公众号智能问询 | | `view_chat_wework.py` | 企业微信机器人 | > 说明:`myapp/views/` 下的视图远不止上表,还包括 `view_aihub.py`、`view_blood.py`(血缘)、`view_sqllab.py`、`view_labelstudio.py`、`view_llm_ingress.py`、`view_k8s.py`、`view_pod.py`、`view_message.py`、`view_user_role.py`、`view_dashboard.py`、`view_etl_pipeline_etl.py` 等。完整对应关系见 [07-参考速查/模块地图.md](../07-参考速查/模块地图.md)。 ### 前端代码 源码位置: - CubeStudio 总体前端:`myapp/frontend` - CubeStudio 后端生成的 html 模板:`myapp/templates` - 训练 pipeline 前端:`myapp/vision` - 数据 ETL pipeline 前端:`myapp/visionPlus` 编译后地址: - CubeStudio 总体前端:`myapp/static/appbuilder/frontend` - 训练 pipeline 前端:`myapp/static/appbuilder/vison` - 数据 ETL pipeline 前端:`myapp/static/appbuilder/visonPlus` > 注意:编译产物目录确实是 `myapp/static/appbuilder/vison` 与 `myapp/static/appbuilder/visonPlus`(都少一个 `i`),与源码目录 `myapp/vision` / `myapp/visionPlus`(正确拼写)不一致,这是仓库现状(已核实),请勿"纠正"成 `vision*`。 其他部分前端静态资源:`myapp/static/appbuilder`。 前端静态文件所属容器: - 前端镜像 nginx 代理,代理 `myapp/static/` 下的静态文件。 - 其他少量 html 模板,`myapp/templates/` 下,在后端镜像。 ### 权限管理的基础逻辑 `myapp/security.py`(RBAC,自带 `Admin`/`Gamma` 角色,详见 [FAB后端开发框架.md](FAB后端开发框架.md) 的"用户和权限"章节)。 --- ### FAB 后端开发框架(Flask-AppBuilder) - 链接: https://www.cubestudio.vip/docs/06-%E4%BA%8C%E6%AC%A1%E5%BC%80%E5%8F%91/FAB%E5%90%8E%E7%AB%AF%E5%BC%80%E5%8F%91%E6%A1%86%E6%9E%B6 - 分类: 二次开发 / 后端框架 - 适用场景: 想了解平台后端整体框架(怎么加视图/接口、怎么做权限、怎么写定时/异步任务、怎么用缓存、怎么升级数据库、怎么部署)时读这篇——本段的纲领文档 - 关键词: FAB / Flask-AppBuilder / 后端框架 / SSO / OA登录 / RBAC / 权限 / 角色 / Admin / Gamma / add_view / add_api / MyappModelRestApi / celery / 定时任务 / 异步任务 / beat / worker / 缓存 / cache / redis / 行为日志 / event_logger / db migrate / db upgrade / 数据库升级 / docker / docker-compose / k8s - 最后更新: 2026-07-09 # FAB 后端开发框架(Flask-AppBuilder) > 本文是 CubeStudio 后端二次开发的纲领文档。它源自通用 FAB 框架介绍,部分示例为通用 FAB 概念演示;凡与本仓库实际代码有出入处,下文已就近用 `文件:行号` 标注或改正。 ## 简介 几分钟快速搭建前后端管理控制台,集成 OA 登录、RBAC 权限控制、定时调度、缓存、公司平台 SDK、前后端接口自动封装、用户行为记录、数据库升级管理、docker 镜像、docker-compose 调试、k8s 部署。 ## 框架由来 现在对每位开发者全栈能力的要求越来越强烈。团队里经常会产出一些工具优化工作效率,工具共享逐步形成管理端控制台,就开始需要有前后端能力介入。此时就要求开发者具有管理控制台的开发能力,而这些控制台大部分又是 CURD 的基本操作。本项目采用 FAB(Flask-AppBuilder)框架,部署及生成前后端代码,能够快速部署自己的前后端应用。 目前基于 FAB 的开源项目有很多:airflow、superset 都是典型案例。本项目在开源 FAB 基础上改造为**前后端分离**模式。 ## 环境准备 - 在本地安装 docker、docker-compose 环境。 - 你需要有一个 MySQL 数据库(开源/通用场景下创建名为 `myapp` 的 db;**本商业版 docker-compose 中默认库名为 `kubeflow`**)。 ```bash docker run -p 3306:3306 --restart always --name mysql \ -e MYSQL_ROOT_PASSWORD=admin \ -v $PWD/docker-add-file/mysqld.cnf:/etc/mysql/conf.d/mysqld.cnf \ -d mysql:8.0.32 # 进入数据库创建一个 db(通用示例) CREATE DATABASE IF NOT EXISTS myapp DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci; ``` > 核实并修正:本商业版仓库的数据库连接由环境变量决定,`install/docker/config.py:476` 读取 `MYSQL_SERVICE`(其次 `POSTGRESQL_SERVICE`/`KINGBASE_SERVICE`/`DM_SERVICE`)。`install/docker/docker-compose.yml` 中 MySQL 服务的 `MYSQL_DATABASE` 默认是 `kubeflow`,而非通用示例里的 `myapp`。同时支持 PostgreSQL / 人大金仓 / 达梦(按 URI 自动切换 `migrations/versions-*`)。 ## 启动 ```bash cd install/docker/ # docker-compose.yml 文件中可以修改 redis / mysql 的配置 docker-compose up # 即可启动 # 然后 http://127.0.0.1:80/ 就可以访问 ``` > 说明:本商业版 `install/docker/docker-compose.yml` 默认启用的服务为 `redis`、`mysql`、`frontend`(nginx 前端容器)、`myapp`(后端容器);`beat`、`worker`、`watch` 三个服务在文件中以注释形式提供,按需放开。后端容器默认 `command` 为 `sleep` 占位,需 exec 进容器执行 `/entrypoint.sh` 或 `python myapp/run.py`(见 `install/docker/docker-compose.yml`)。 ## 用户和权限 ### SSO 登录 多用户认证授权的相关逻辑在 `security.py` 中,开源版本默认为账号密码登录。若想添加 OA 认证,可以在 `MyCustomRemoteUserView` 中添加对应的函数(已添加 API 访问版的 OA 认证)。用户打开页面时会自动发起 OA 认证,并自动注册用户,创建和用户同名的角色。如果你需要修改 OA 认证,可以修改 `login` 函数(`myapp/project.py:64`)。用户登录后在右上角个人页面都会有一个秘钥,这个秘钥用来在 API 访问时进行认证。 平台向其他三方平台提供 API 接入能力时,只需要其他平台在 HTTP 请求 header 中提供这个字段,就能正常识别是哪个用户,后面的授权工作就和 Web 访问相同了。 ### 权限管理 登录后还需要进行授权,FAB 使用 RBAC 进行权限管理:用户可以绑定不同的角色,角色可以绑定不同的权限,这样用户就具有了指定的权限。 ### 用户层 系统自带了一个 `admin` 用户,每个用户登录时会自动注册,同时 admin 也可以手动创建用户。框架还添加了后门链接,管理员可借此模拟其他用户登录、查看用户登录后状态。 ### 角色层 系统自带 `Admin`、`Gamma` 角色(`myapp/security.py:250` 描述:Admin 拥有管理员权限,Gamma 为普通用户角色)。每个用户登录时会自动创建与用户名 username 同名的角色,并将用户绑定到该同名角色和 `Gamma` 角色上,所以普通用户进来会提示各种没有权限。具有 `Admin` 角色的用户拥有一切权限(为其他用户加角色、为角色加权限等)。系统自带只有 `admin` 用户具有 `Admin` 角色,默认账号密码为 `admin/admin`。 > 核实:新用户默认注册角色由 `myapp/config.py:94` 的 `AUTH_USER_REGISTRATION_ROLE = "Gamma"` 决定;`Admin`/`Gamma` 的绑定见 `myapp/security.py:871-872`。 你可以手动添加各种形式的角色:项目组、组织架构、一类用户等。 ### 权限层 权限层包含两部分:视图菜单 view/menu 和权限类型 Base Permissions。即在哪些对象上具有哪些权限(比如在 table1 上具有 add 权限,在 menu1 上具有 click 权限)。 在代码中一般 view/menu 对应 class,Base Permissions 对应 function。所以视图菜单和权限类型两者之间并不是可以随意绑定的。系统自带的视图权限可以在 Web 界面上查看,主要是某些菜单的点击权限、某些 model(table) 的增删改查权限、某些函数的执行权限。 如果想为自己的函数或 model 注册视图权限,只需要在函数上添加 `has_access` 修饰符: ```python from flask_appbuilder.security.decorators import has_access @has_access def list(self): pass ``` 这样用户就需要具有该函数的访问权限才能正常进入,否则会报权限异常。 建议基于 `myapp/views/baseApi.py` 中的 `MyappModelRestApi` 来编写接口,所有接口都默认做了权限注册。 > 核实并修正:原文写"建议基于 /view/base.py 中 MyappModelView 编写 api 接口",但当前仓库**不存在 `MyappModelView` 类**。`base.py` 提供的是 `BaseMyappView`(`myapp/views/base.py:272`),前后端分离的接口基类是 `MyappModelRestApi`(`myapp/views/baseApi.py:243`),各业务视图均继承自它(例如 `myapp/views/view_metadata_metric.py:191`)。 ## 添加页面视图和接口 系统自带了 model(数据库表记录)的增删改查接口和页面,所以用户需要做的就只有定义和注册 model 表结构。 > 本仓库为前后端分离模式:实际开发以"定义 model + 继承 `MyappModelRestApi` + `appbuilder.add_api(...)`"为主(见下方第 3 节),菜单入口在 `home.py` 的 `/menu` 中下发。下方第 1、2 节为通用 FAB 概念演示。 ### 1、仅添加菜单链接 在 `home.py` 的 `menu` 接口中添加(详见 [新增视图页面与数据库升级.md](新增视图页面与数据库升级.md))。 ### 2、同时添加 CURD 前端界面和后端接口(通用 FAB 概念) 需要先定义 model(表结构),再定义接口视图类,自动生成前后端代码,最后添加链接到菜单: ```python # 定义 model class Model2(Model): __tablename__ = 'model2' id = Column(Integer, primary_key=True) attr1 = Column(String(50), unique=True, nullable=False) def __repr__(self): return self.attr1 # 定义数据表视图 class Model2_ModelView(MyappModelView): datamodel = SQLAInterface(Model2) appbuilder.add_view( baseview=Model2_ModelView, name="submenu2", icon='fa-address-book-o', category='menu1', category_icon='fa-envelope' ) ``` > 核实并修正:上例为服务端渲染的传统 FAB 用法(`MyappModelView` + `appbuilder.add_view`)。当前 CubeStudio 商业版**未使用** `appbuilder.add_view(...)`,也没有 `MyappModelView` 类,应改用第 3 节的前后端分离写法。此处保留以说明 FAB 原始能力。 因为涉及前端显示,可配置参数较多,下面列举一些(均可不配置,使用默认)。这些参数在前后端分离的 `MyappModelRestApi` 中同样适用: ```python base_permissions # model 管理的操作类型 add_fieldsets # 创建页面分组展示 edit_fieldsets # 编辑页面分组展示 label_columns # 列别名 list_columns # list 页面显示的列 show_fieldsets # 单条记录详情分组 base_filters # list 页面默认筛选条件 base_order # list 页面排序方法 validators_columns # add/update 表单自动校验 # 关联字段自定义查询过滤器:add_query_rel_fields / edit_query_rel_fields / search_query_rel_fields # add_query_rel_fields = {'attr3': [['attr1', FilterStartsWith, 'a']]} # 自定义页面模板:show_template / edit_template / add_template def pre_add(self, obj): ... # 添加前 def post_add(self, obj): ... # 添加后 def pre_update(self, obj): ... # 更新前 def post_update(self, obj): ... # 更新后 def pre_delete(self, obj): ... # 删除前 def post_delete(self, obj): ... # 删除后 # 批量操作函数 @action("muldelete", "Delete", "Delete all Really?", "fa-rocket", single=False) def muldelete(self, items): ... ``` ### 3、添加 CURD 纯后端接口(本仓库主流写法) 先定义 model,再定义视图类,注册 API 接口: ```python # 定义数据表视图 class Model3_ModelView_Api(MyappModelRestApi): datamodel = SQLAInterface(Model2) route_base = '/model2/api' appbuilder.add_api(Model3_ModelView_Api) ``` > 核实:这正是仓库实际写法,例如 `Metadata_metric_ModelView_Api(... , MyappModelRestApi)`、`route_base = '/metadata_metric_modelview/api'`,并以 `appbuilder.add_api(...)` 注册(`myapp/views/view_metadata_metric.py:191`)。注意:`route_base` 要与 `home.py` 菜单中 API 类型 url 对应。 ### 4、添加自定义后端接口 自己定义一批接口,然后将类注册到系统中: ```python class Myapp(BaseMyappView): route_base = '/myapp' default_view = 'welcome' @expose('/welcome') def welcome(self): if not g.user or not g.user.get_id(): return redirect(appbuilder.get_url_for_login) msg = 'Hello ' + g.user.username + " !" return self.render_template('hello.html', msg=msg) # add_view_no_menu 添加视图,但不在 FAB 自带菜单显示 appbuilder.add_view_no_menu(Myapp) ``` > 核实:`add_view_no_menu` 在仓库中确有使用,如 `view_chat_dingtalk.py:192`、`view_chat_wework.py:164`、`view_chat_wechat.py:486`、`view_labelstudio.py:696` 等;菜单入口由 `/myapp/menu` 下发。(注:`view_blood.py` 用的是 `appbuilder.add_api(Blood)`,不属于此类。) ### 5、Flask 的传统方法 因为 FAB 基于 Flask,所以你也可以用 Flask 的任何方法,例如注册路由: ```python @app.route("/health") def health(): return "OK" ``` ## 外部组件调用 参考 [01-架构原理/基础组件介绍.md](../01-架构原理/基础组件介绍.md)。 ## 定时调度能力 管理控制台难免有很多离线定时任务或异步任务。框架集成了 celery,可以实现定时任务、异步任务的发起和执行。在 `config.py` 的 `CeleryConfig` 类中配置定时框架参数和要执行的任务参数。系统默认使用 redis 作为任务队列和结果存储数据库。 ### 任务编写 任务编写在 `tasks` 目录下,框架配置了示例任务 `tasks/schedules.py`,并添加了任务结果的微信推送: ```python # 配置 celery 任务 @celery_app.task(name="task.task_name1", bind=True) def task_name1(task): pass ``` > 核实:`myapp/tasks/schedules.py` 中实际任务即此形态,如 `@celery_app.task(name="task.delete_workflow", bind=True)` / `def delete_workflow(task)`(`schedules.py:133-134`)。 ### 配置任务调度参数 在 `config.py` 的 `CeleryConfig` 类中,`task_annotations` 用来配置单个任务执行时的限制条件: ```python # 任务的限制,key 是 celery_task 的 name,值是限制配置 task_annotations = { 'task.task_name1': { 'rate_limit': '1/s', # 任务的调度速率限制 'time_limit': 1200, # 运行时长限制,超时直接退出 'soft_time_limit': 1200, # 运行时长限制,会抛异常,可 catch 'ignore_result': True, }, } ``` `beat_schedule` 用来配置定时任务的调度周期: ```python # 定时任务的配置项,key 为 celery_task 的 name,值是调度配置 beat_schedule = { 'task_task1': { 'task': 'task.task_name1', # 控制任务 'schedule': 10.0, # 调度周期(秒) # 'schedule': crontab(minute='1', hour='*'), # 也可用 crontab } } ``` > 核实并修正(重要):原文使用旧式大写常量名 `CELERY_ANNOTATIONS` / `CELERYBEAT_SCHEDULE`。本仓库 `myapp/config.py` 的 `CeleryConfig` 采用 Celery 5 小写配置名:`task_annotations`(`config.py:602`)、`beat_schedule`(`config.py:691`),以及 `broker_url`、`result_backend`、`imports = ('myapp.tasks',)`。请按小写名编写。 ### 任务的调度 框架定时任务基于 celery,可直接用 celery 命令启动 beat 进程产生定时任务: ```bash celery --app=myapp.tasks.celery_app:celery_app beat --loglevel=info ``` 在 docker-compose 中包含(注释形态)`beat` 服务,用来产生定时任务并推送到 redis。 ### 任务的执行 定时任务发送到 redis 后,需要 worker 接收执行。同样用 celery 命令启动多个 worker 并发执行: ```bash celery --app=myapp.tasks.celery_app:celery_app worker --loglevel=info --pool=prefork -Ofair -c 2 -n worker@%h ``` 在 docker-compose 中包含(注释形态)`worker` 服务,创建 worker 容器接收并执行任务。 ## 缓存 框架包含缓存配置,`config.py` 中 `CACHE_CONFIG` 为缓存配置(`config.py:519`),系统默认使用 redis 作为缓存数据库(`CACHE_REDIS_URL` 使用 redis 的 1 号库)。代码中使用缓存: ```python from myapp import cache # 引入(myapp/__init__.py:230 装配) cache.set('msg', msg, timeout=60) # 设置 cache_value = cache.get('msg') # 读取 ``` ## 用户行为记录 框架已集成用户行为记录。如果想收集用户对指定函数的访问记录,只需在函数上添加修饰符,会将用户或 API 访问的行为记录到数据表 `logs` 中: ```python from myapp import event_logger # myapp/__init__.py:390 装配 @event_logger.log_this def list(self): pass ``` 这样就可以在用户行为记录中看到哪个用户、什么时间、访问了哪个路径、做了什么操作、传递了什么参数。 ## 数据库结构升级和回滚 基于 FAB 做 model 的新增或修改,对应数据表的变更。框架基于 Flask-Migrate 集成了数据库结构的升级和回滚。前提是:`myapp/__init__.py` 引入时能够引入该 model(`__init__.py` 最下面引入 views,每个 view 又引入对应 model,这样被引入的 model 才能被系统识别,用来判断升级或回滚策略)。 数据库管理文件在 `myapp/migrations` 下,升级记录在 `myapp/migrations/versions` 目录下。如果你新增或修改了 model(且可被系统发现),在容器的 `/home/myapp/` 目录下执行: ```bash myapp db migrate # 生成对应版本数据库表的升级文件到 versions 文件夹下 ``` 系统会对比当前连接数据库的表结构与代码中定义的表结构差异,生成升级文件到 versions 目录。**所以数据库一定不能手动修改**,否则升级记录文件就不再连贯。 有了升级记录文件,直接执行下面命令进行升级: ```bash myapp db upgrade # 数据库表同步更新到 mysql ``` > 完整的"upgrade → migrate → upgrade"三步法见 [新增视图页面与数据库升级.md](新增视图页面与数据库升级.md)。本仓库 `myapp/migrations` 下另有 `versions-mysql`、`versions-postgres` 两份历史结构。启动时的切换逻辑见 `install/docker/config.py:476-488`:配 `MYSQL_SERVICE` 时直接用默认 `versions`(不拷贝);配 `POSTGRESQL_SERVICE`/`KINGBASE_SERVICE` 时用 `versions-postgres` 覆盖 `versions`;配 `DM_SERVICE`(达梦)时清空 `versions`,改由 `db.create_all()` 建表、不走 Alembic 迁移。 ## docker 镜像封装 项目包含 docker 镜像封装,为方便代码调试快速迭代,镜像分两部分: 1. `install/docker/Dockerfile-base`:基础环境封装,耗时较久但环境部分改动小,封装一次可长期复用(`FROM ubuntu:22.04`,Python 3.9)。 2. `install/docker/Dockerfile`:在基础镜像之上加封代码,因为只是 copy 代码,封装较快,适合短周期迭代(`FROM ...kubeflow-dashboard:base-python3.9-...`)。 ## 本地调试 由于本框架涉及多个容器组件,本地调试使用 docker-compose 启动;也可用 docker-compose 做生产部署,但只能在单机上进行,无法避免单点故障。 单机部署调试的配置在 `install/docker/docker-compose.yml`,其中包含 `redis`/`myapp`/`frontend`/`mysql` 服务(以及注释形态的 `beat`/`worker`/`watch`)。需求简单时可注释掉不需要的部分。 为方便调试,一般会将代码目录、配置文件,甚至本地 python 库挂载到容器中: ```yaml - ../../myapp/:/home/myapp/myapp/ - ./entrypoint.sh:/entrypoint.sh - ./config.py:/home/myapp/myapp/config.py ``` 这样你就可以直接在 IDE 中编辑,容器中也能检测到自动加载执行。注意:dev 模式能自动检测文件变更热加载,prod 模式不能自检测,需要手动重启。 ## k8s 高可用部署 本地调试完成后上生产线。应用简单或仅内部使用时可用上面的 docker-compose 部署;更推荐部署上云,`install/kubernetes/` 目录中包含项目所需应用的全部 k8s 部署文件(需要一定的 k8s 基础)。云上部署详见 02-部署安装 段。通用 FAB 版本参考 。 --- ### 新增视图页面与数据库升级 - 链接: https://www.cubestudio.vip/docs/06-%E4%BA%8C%E6%AC%A1%E5%BC%80%E5%8F%91/%E6%96%B0%E5%A2%9E%E8%A7%86%E5%9B%BE%E9%A1%B5%E9%9D%A2%E4%B8%8E%E6%95%B0%E6%8D%AE%E5%BA%93%E5%8D%87%E7%BA%A7 - 分类: 二次开发 / 开发指南 - 适用场景: 想给平台加一张新表/一个新接口/一个新菜单,并把对应的数据库结构升级上去时,按这篇的 how-to 三步走 - 关键词: 新增视图 / 新增页面 / 新增接口 / 菜单注册 / home.py / menu / model / view / MyappModelRestApi / 数据库升级 / db upgrade / db migrate / alembic_version / migrations / versions / 三步法 / 表结构变更 - 最后更新: 2026-06-30 # 新增视图页面与数据库升级 本文聚焦 how-to:在 `home.py` 注册菜单 + 新增 `model`/`view` + 数据库升级三步法。原理性的框架说明见 [FAB后端开发框架.md](FAB后端开发框架.md),目录定位见 [代码结构与模块地图.md](代码结构与模块地图.md)。 ## 一、菜单控制 修改 `myapp/views/home.py` 中的 `menu` 函数(通过 `@expose_api(url='/menu')` 暴露为 `/menu` 接口),在对应位置增加一个接口、外联、iframe,或者 model/view 的 API。 > 注意:view 里注册的 `route_base` 要和 `menu` 函数中 API 类型的 url 相对应。 > 核实并修正:原文写"menus 函数",源码中函数名为 `menu`(单数),对外路由 `/menu`,见 `myapp/views/home.py:81-83`。 ## 二、增加一个 model/view 的 API 在 `myapp/models/` 目录下增加对应的 model 文件,可参考 `myapp/models/model_metadata_metric.py`。 在 `myapp/views/` 目录下增加对应的 view 文件,可参考 `myapp/views/view_metadata_metric.py`。 > 说明:上述两个参考文件已核实存在。view 一般继承 `MyappModelRestApi` 并以 `appbuilder.add_api(...)` 注册,例如 `view_metadata_metric.py:191` 的 `Metadata_metric_ModelView_Api`,其 `route_base = '/metadata_metric_modelview/api'`。要让数据库升级能识别到新 model,该 view 必须最终被 `myapp/__init__.py` 引入(详见 [FAB后端开发框架.md](FAB后端开发框架.md) 的"数据库结构升级和回滚")。 > 原文中这两处使用了指向源码的相对链接(`../../myapp/models/...`、`../../myapp/views/...`)。由于源码在 docs1 之外,这里改为文字路径,不留断链:直接到仓库 `myapp/models/model_metadata_metric.py`、`myapp/views/view_metadata_metric.py` 查看。 ## 三、数据库升级调整 增加完文件后,还需要让数据库中包含 model 中的数据库结构。 > 注意:不能手动修改数据库结构,若手动修改了,则所有的数据库变更结构都会失效(升级记录不再连贯)。 实现原理——三处记录数据库结构的地方: 1. 代码中定义的数据结构,主要在 `myapp/models/` 中的文件(**当前代码侧结构**)。 2. `myapp/migrations/versions` 中记录的数据结构变更历史(**历史所有结构**)。 3. 远程 MySQL 数据库中的当前结构,以及数据库中 `alembic_version` 表记录的当前应用数据版本号(**当前所处的数据库结构版本**)。 三步法命令: ```bash myapp db upgrade # 先将远程数据库升级到当前已记录的最新结构(把 migrations/versions 中的信息应用到 mysql) myapp db migrate # 检查数据库相对代码新增/修改了哪些结构(对比 mysql 与代码,把新变更写入 migrations/versions) myapp db upgrade # 增量把新的变更结构应用到数据库(把 migrations/versions 中内容应用到 mysql) ``` > 说明:本仓库 `myapp/migrations/` 下还有 `versions-mysql`、`versions-postgres` 两份历史结构。启动时按数据库类型处理 `versions`(见 `install/docker/config.py:476-488`):MySQL 直接用默认 `versions`;PostgreSQL/人大金仓用 `versions-postgres` 覆盖;达梦清空 `versions` 并改由 `db.create_all()` 建表、不走 Alembic。因此 PostgreSQL/达梦等场景下的迁移文件与 MySQL 不同。 --- ### 更换 Logo 与水印 - 链接: https://www.cubestudio.vip/docs/06-%E4%BA%8C%E6%AC%A1%E5%BC%80%E5%8F%91/%E6%9B%B4%E6%8D%A2Logo%E4%B8%8E%E6%B0%B4%E5%8D%B0 - 分类: 二次开发 / 前端定制 - 适用场景: 需要把平台界面替换成自有品牌(Logo、网页标题、水印)并重新构建前端镜像时阅读 - 关键词: logo / Logo / 水印 / watermark / 品牌 / 定制 / 换标 / 白标 / OEM / favicon / 网页标题 / title / 前端镜像 / frontend / kubeflow-dashboard-frontend / build.sh / dev/common - 最后更新: 2026-07-04 # 更换 Logo 与水印 前端品牌定制(Logo、favicon、网页标题、版权水印)通过仓库根目录下的 `dev/common/` 完成:替换素材 → 运行构建脚本生成前端镜像并推送 → 更新 K8s 前端 deployment 镜像。 ## 准备素材 `dev/common/` 目录下已有占位素材,替换为你自己的即可: - `logo.ico`:favicon 图标 - `logo.png`:主 Logo - `logo.svg`:矢量 Logo ## 构建步骤 1. **替换素材**:替换 `dev/common/` 下的 `logo.ico`、`logo.png`、`logo.svg`。 2. **登录镜像仓库**:本地 `docker login` 到你的镜像仓库。若没有,可在腾讯云申请个人免费版镜像仓库。 3. **改目标镜像名与标题**:编辑 `dev/common/build.sh`,替换其中的前端目标镜像名和网页标题名。 - 脚本默认把网页标题从 `cube-studio` 改成 `智能AI平台`,把 `Cube Studio` 字样替换成 `AI Studio`(即水印 / 版权文案),可按需修改。 - 脚本默认构建并推送的镜像名为 `ccr.ccs.tencentyun.com/cube-studio/kubeflow-dashboard-frontend-enterprise:common`(使用 `docker buildx build` 构建 `linux/amd64,linux/arm64` 多架构镜像,Dockerfile 为 `install/docker/dockerFrontend/Dockerfile`)。记得替换为你自己仓库的名称。 4. **执行构建**:在 **CubeStudio 项目根目录**下执行: ```bash sh dev/common/build.sh ``` 脚本会自动替换 Logo、水印、标题,构建目标前端镜像并推送到你的仓库。 > 脚本中区分了 mac 与 windows/linux 的 `sed` 写法(mac 用 `sed -i ""`,linux 用 `sed -i`)。当前默认启用的是 mac 版,linux 下需把对应行注释切换一下。 5. **更新 K8s deployment**:推送成功后,在 K8s 的 `infra` 命名空间下,把名为 `kubeflow-dashboard-frontend` 的 deployment 的镜像名改成你新构建的镜像,K8s 会自动重启前端 Pod。 > deployment 名称见 `install/kubernetes/cube/base/deploy-frontend.yaml`(`name: kubeflow-dashboard-frontend`,默认镜像 `ccr.ccs.tencentyun.com/cube-studio/kubeflow-dashboard-frontend`)。注意基础 deployment 镜像名与 build.sh 构建的镜像名(带 `-enterprise:common` 后缀)不同,更新 deployment 时填你实际构建推送的那个。 6. **刷新页面**:前端 Pod 重启后,强制刷新浏览器页面(Ctrl/Cmd + Shift + R)即可看到新 Logo 与标题。 ## 相关 - 前端 Pod 的网关接入与访问路径:见 [01-架构原理/流量代理与网关.md](../01-架构原理/流量代理与网关.md) --- ### 弹窗报警与提醒格式(前端协议) - 链接: https://www.cubestudio.vip/docs/06-%E4%BA%8C%E6%AC%A1%E5%BC%80%E5%8F%91/%E5%BC%B9%E7%AA%97%E6%8A%A5%E8%AD%A6%E4%B8%8E%E6%8F%90%E9%86%92%E6%A0%BC%E5%BC%8F - 分类: 二次开发 / 前端协议 - 适用场景: 后端 list 接口想让某个单元格点击弹出详情,或鼠标悬停显示提示时,需要按本协议输出 HTML 标签和返回 JSON - 关键词: 弹窗 / 报警 / 提醒 / alert / tips / enhancedDetails / addedValue / 详情弹窗 / tooltip / list单元数据 / 表格列渲染 / iframe / html / map / text / markdown / echart / table / image / audio / video / tabName / groupName / groupContent / bottomButton / TabsModal / VisualizationRenderer - 最后更新: 2026-06-30 # 弹窗报警与提醒格式(前端协议) 这是一套**前端约定协议**:后端在 list 查询返回的单元数据里,给某个 HTML 元素加上特定属性,前端就会把它渲染成「可点击弹出详情」或「鼠标悬停提示」的交互。 前端处理代码: - 表格 / 卡片:`myapp/frontend/src/pages/ADUGTemplate.tsx` - Notebook 文件列表:`myapp/frontend/src/pages/Jupyter/JupyterFileList.tsx` - 弹窗详情渲染:`myapp/frontend/src/components/TabsModal/TabsDetail.tsx` + `myapp/frontend/src/components/Visualization/VisualizationRenderer.tsx` ## 一、弹窗报警方式(enhancedDetails) 为 list 查询得到的单元数据,给元素设置属性 `type=enhancedDetails` 和 `addedValue='<详情接口地址>'`。点击该单元格时,前端会请求 `addedValue` 指向的接口并弹出详情弹窗。 ```html
{img_url}
``` > 上面 `/dataset_modelview/api/alert/info/...` 仅为示例地址,需后端自行实现该接口。仓库内现存的实际用法可参考 `myapp/views/view_k8s.py:508`: > ```python > Markup(f'
{pod["name"]}
') > ``` ### 弹窗详情接口返回 JSON 结构 ```jsonc { "message": "", "status": 0, "result": { "title": "", "content": [ // 一个弹窗可以有多个 tab;只有一个 tab 时不显示切换按钮 { "tabName": "第一个tab", "content": [ // 一个 tab 下可有多个子内容(group) { "groupName": "iframe", // 子内容的标题(支持 HTML) "groupContent": { "value": "xxxxx", // 子内容的值:iframe→url,html→html源码,map→字典, // text→字符串,markdown→markdown源码,echart→options,table→表格数据 "type": "iframe", // 子内容类型,见下方支持列表 "style": "width:200px" // 可选:子内容样式(高度、背景等) } } ], "bottomButton": [ // 该 tab 下的快捷跳转按钮(不是取消/确认按钮) { "text": "xxx", // 按钮文字 "url": "xxx" // 跳转地址 } ] } ], "bottomButton": [ // 弹窗底部的操作按钮(提交/取消/确认类) { "icon": "", // svg 图标,没有则不显示 "text": "xxx", // 按钮文本 "url": "xxx", // 提交地址 "arg": "", // 提交传递的参数 "method": "" // 提交方法:get / post / delete } ] } } ``` ### groupContent.type 支持的类型 源码 `VisualizationRenderer.tsx` 与 `tabsModalInterface.ts` 中声明的可渲染类型(比早期文档更多): `map`、`iframe`、`echart`、`text`、`html`、`markdown`、`image`、`table`、`array`、`api`、`audio`、`video`。 > 注意:底部操作按钮 `bottomButton[].method` 仅支持 `get` / `post` / `delete`,**不包含 `put`**。前端类型声明见 `myapp/frontend/src/api/interface/tabsModalInterface.ts:25-31`(`IActionButton.method` 为 `"get" | "post" | "delete"`)。 ## 二、提醒报警方式(tips) 为 list 查询得到的单元数据,设置属性 `type=tips` 和 `addedValue='<提示文案>'`。鼠标悬停在该单元格上时,前端会显示一个 tooltip 提示(`addedValue` 内容支持 HTML)。 ```html
{url}
``` 前端处理见 `JupyterFileList.tsx:56-61`(`typeValue === 'tips'` 时用 tooltip 渲染 `addedValue`)。 ## 相关 - 接口路径 / 方法速查:见 [07-参考速查/核心API速查.md](../07-参考速查/核心API速查.md) --- ### 登录认证与消息推送扩展 - 链接: https://www.cubestudio.vip/docs/06-%E4%BA%8C%E6%AC%A1%E5%BC%80%E5%8F%91/%E7%99%BB%E5%BD%95%E8%AE%A4%E8%AF%81%E4%B8%8E%E6%B6%88%E6%81%AF%E6%8E%A8%E9%80%81%E6%89%A9%E5%B1%95 - 分类: 二次开发 / 认证与推送 - 适用场景: 需要对接企业 SSO/LDAP/三方登录,或自定义钉钉/企业微信/飞书/邮件等消息推送渠道时阅读 - 关键词: 登录 / 认证 / login / auth / AUTH_TYPE / AUTH_REMOTE_USER / AUTH_DB / AUTH_LDAP / LDAP / OAuth2 / OIDC / SSO / CAS / 飞书 / feishu / 企业微信 / wecom / 钉钉 / dingtalk / 微信 / wechat / 单点登录 / 推送 / push / push_admin / push_message / 通知 / 告警通知 / 群机器人 / project.py / view_login.py / security.py - 最后更新: 2026-06-30 # 登录认证与消息推送扩展 登录认证与消息推送是两类最常见的二次开发任务,核心代码集中在三个文件: - `myapp/project.py`:用户自定义模块。包含推送函数(`push_admin` / `push_message` 等)和认证中转网关 `MyCustomRemoteUserView`。 - `myapp/views/view_login.py`:各种登录方式(DB / LDAP / OAuth2 / CAS / 飞书 / 企业微信 / 钉钉 / 微信)的具体实现。 - `myapp/security.py`:安全管理器 `MyappSecurityManager`,负责用户注册、角色权限以及视图注册。 > 说明:本仓库当前的认证体系与早期 Flask-AppBuilder「单一 AUTH_TYPE」模式不同,请以本页描述为准。 ## 一、登录认证 ### 1. 总体架构 平台**统一固定** `AUTH_TYPE = AUTH_REMOTE_USER`,由代码强制设置,`config.py` 中无需配置(见 `myapp/security.py:642`)。所有未登录请求先进入认证中转网关 `MyCustomRemoteUserView`(注册为 `/login/` 路由),再由它的 `login()` 决定跳转到哪一种具体登录方式。 具体的登录方式各自在 `myapp/views/view_login.py` 中注册独立路由: | 登录方式 | 路由前缀 | 视图类 | 说明 | |---|---|---|---| | 账号密码 / LDAP | `/login/db/` | `Myauthdbview` | 数据库账号密码,密码不匹配时尝试 LDAP bind 兜底 | | OAuth2 / OIDC | `/login/oauth2/` | `OAuth2LoginView` | 支持 GitHub / Google 预设,或自定义 IdP(Keycloak、Okta、Azure AD 等) | | CAS 单点登录 | `/login/cas/` | `CASLoginView` | | | 飞书 | `/login/feishu/` | `FeishuLoginView` | | | 企业微信 | `/login/wecom/` | `WeComLoginView` | | | 钉钉 | `/login/dingtalk/` | `DingTalkLoginView` | | | 微信开放平台 | `/login/wechat/` | `WeChatLoginView` | 需在 open.weixin.qq.com 创建"网站应用"并通过审核 | > 注意:`Myauthdbview` 类位于 `myapp/views/view_login.py`(route_base = `/login/db`),不在 `project.py` 中。`project.py` 中只有中转网关 `MyCustomRemoteUserView`。 默认账号密码为 `admin/admin`。 ### 2. 选择登录方式 / 对接 SSO 修改 `myapp/project.py` 中 `MyCustomRemoteUserView.login()` 的 `redirect`: - 默认:`return redirect('/frontend/login')`,跳到前端 DB 登录页(最终调用后端 `/login/db/`)。 - 切换到内置 SSO,改为对应路由即可,例如: ```python return redirect('/login/oauth2/') # OAuth2 / GitHub / Google return redirect('/login/cas/') # CAS return redirect('/login/feishu/') # 飞书 return redirect('/login/wecom/') # 企业微信 return redirect('/login/dingtalk/') # 钉钉 return redirect('/login/wechat/') # 微信 ``` - 对接自定义三方 SSO:在 `login()` 内重定向到三方授权页,回调带 `code` 回到 `/login/` 后,用 `code` 换取用户名,再调用 `myapp/views/view_login.py` 中的通用函数 `_sso_login_or_register(appbuilder, username=...)` 完成查找 / 自动注册 / 登录。`project.py` 顶部注释里给出了完整示例代码。 > 注意:`/frontend/login`、`/frontend/` 等前端路径与你所在环境的 URL 前缀(`/backend`、istio 网关放行规则)相关,部署时请确认前端登录页的实际访问地址。 ### 3. 各登录方式的配置项 SSO 相关配置在 `myapp/config.py` 中(默认全部注释,按需开启),路由跳转到对应 `/login/xxx/` 时才生效: - OAuth2 / OIDC:`OAUTH2_PROVIDER`(填 `github`/`google` 可自动补全端点 URL)、`OAUTH2_CLIENT_ID`、`OAUTH2_CLIENT_SECRET`、`OAUTH2_AUTHORIZE_URL`、`OAUTH2_TOKEN_URL`、`OAUTH2_USERINFO_URL`、`OAUTH2_SCOPES`、`OAUTH2_USERNAME_FIELD`、`OAUTH2_EMAIL_FIELD`、`OAUTH2_REDIRECT_URI`、`OAUTH2_LOGOUT_URL`。 - CAS:`CAS_SERVER_URL`、`CAS_SERVICE_URL`、`CAS_LOGOUT_URL`。 - 飞书:`FEISHU_APP_ID`、`FEISHU_APP_SECRET`、`FEISHU_REDIRECT_URI`。 - 企业微信:`WECOM_CORPID`、`WECOM_AGENTID`、`WECOM_CORPSECRET`、`WECOM_REDIRECT_URI`。 - 钉钉:`DINGTALK_APP_KEY`、`DINGTALK_APP_SECRET`、`DINGTALK_REDIRECT_URI`。 - 微信:`WECHAT_APP_ID`、`WECHAT_APP_SECRET`、`WECHAT_REDIRECT_URI`。 - LDAP(`/login/db/` 中密码不匹配时兜底):`AUTH_LDAP_SERVER`、`AUTH_LDAP_PORT`、`AUTH_LDAP_USE_TLS`、`AUTH_LDAP_BASE_DN`。 各 `REDIRECT_URI` 留空时会自动拼接为 `<本应用地址>/login/<方式>/callback`。 ### 4. Header / Token 认证(接口调用免登录) `myapp/security.py` 的 `load_user_from_header` 支持通过请求头认证: - **username 直传**:当全局开启 `AUTH_PLATFORM_ACCESS=True`,或通过 K8s 集群内部域名(host 含 `kubeflow-dashboard.infra`)访问时,header 值(长度 < 40)直接当作用户名免认证放行。 - **JWT Token**:否则按 JWT 解析,密钥为 `JWT_PASSWORD`(`config.py:241` 中默认 `myapp`;代码读取不到该配置时的兜底值为 `cube-studio`,见 `myapp/security.py:171,669`),算法 `HS256`,`sub` 字段为用户名。对只有 `payload.signature` 两段的短 token 会自动补回固定的 HS256 header。 认证 header 头名称由 `AUTH_HEADER_NAME` 控制,默认 `Authorization`。 ### 5. 自定义安全管理器 如需更深度定制(用户字段、角色映射等),可在 `config.py` 设置 `CUSTOM_SECURITY_MANAGER`,其类必须继承 `MyappSecurityManager`(见 `myapp/__init__.py:298-301`)。注册与权限逻辑在 `myapp/security.py` 中实现。 ## 二、消息推送 推送函数在 `myapp/project.py` 中,定时调度和异步任务发起通知时会调用它们。用户可自行实现 / 改写: | 函数 | 签名 | 用途 | 使用的渠道配置 | |---|---|---|---| | `push_admin` | `push_admin(message)` | 推送给管理员 | `PUSH_CONFIG[PUSH_ADMIN_CHANNEL]` | | `push_message` | `push_message(receivers, message, link=None)` | 推送给指定用户 | `PUSH_CONFIG[PUSH_CHANNEL]` | | `push_resource_apply` | `push_resource_apply(notebook_id, pipeline_id, task_id, service_id, **kwargs)` | 资源申请通知(默认空操作,按需实现) | — | | `push_resource_approve` | `push_resource_approve(notebook_id, pipeline_id, task_id, service_id, **kwargs)` | 资源审批通知(默认空操作,按需实现) | — | `push_admin` / `push_message` 默认都委托给 `myapp/utils/push.py` 的 `push_message(push_config, message, receivers=None)` 实现实际发送。 ### 推送渠道配置 在 `myapp/config.py` 中(约 909-942 行): ```python PUSH_ADMIN_CHANNEL = '' # 管理员消息使用的渠道名,对应 PUSH_CONFIG 的 key PUSH_CHANNEL = '' # 普通用户消息使用的渠道名 PUSH_CONFIG = { "channel1": { "type": 'wecom-bot', # 渠道类型 "webhook-key": "xxxxxxxx" # 群机器人 webhook key }, "channel2": { ... }, } ENABEL_ALERT_HOMEPAGE = True # 报警消息是否在首页显示(注意拼写为 ENABEL) ``` `type` 支持的渠道类型(见 `myapp/utils/push.py`): - `wecom-bot`:企业微信群机器人 - `dingtalk-bot`:钉钉群机器人 - `feishu-bot`:飞书群机器人 - `email`:邮件 - `webhook`:通用 webhook 要接入自有 IM / 工单系统,可直接重写 `project.py` 中的 `push_admin` / `push_message`,或在 `utils/push.py` 的 `push_message` 中新增渠道分支。 ## 相关 - 接口与认证头速查:见 [07-参考速查/核心API速查.md](../07-参考速查/核心API速查.md) - 前端访问路径与网关放行:见 [01-架构原理/流量代理与网关.md](../01-架构原理/流量代理与网关.md) --- ### 推理服务 JWT 认证(统一鉴权) - 链接: https://www.cubestudio.vip/docs/06-%E4%BA%8C%E6%AC%A1%E5%BC%80%E5%8F%91/%E6%8E%A8%E7%90%86%E6%9C%8D%E5%8A%A1JWT%E8%AE%A4%E8%AF%81 - 分类: 06-二次开发 / 服务与认证 - 适用场景: 给推理服务/模型服务加 token 鉴权,了解公私钥怎么生成、客户端怎么签 token 调用、istio 怎么校验时读这篇 - 关键词: JWT / jwt / 推理服务认证 / jwcrypto / jwk / RS256 / RSA / public_key / private_key / Authorization / Bearer / token / istio / RequestAuthentication / AuthorizationPolicy / sidecar / 服务网关 / 统一认证 / kid - 最后更新: 2026-06-30 # 推理服务 JWT 认证 推理服务(InferenceService)支持开启 JWT 统一认证:只有携带平台为该服务签发体系下生成的合法 token 的请求才能访问,其余请求被 istio 网关直接拒绝。 ## 原理概览 - 在创建/编辑推理服务时,给 `sidecar` 字段勾选 `jwt`(可同时勾 `istio`;`jwt` 依赖 `istio`,平台会自动补上,见下文)。 - 平台用 `jwcrypto` 为该服务生成一对 RSA 公私钥(`kid` = 服务英文名),存进服务的 **扩展字段(expand)**。 - 服务部署时,平台基于公钥下发 istio 的 `RequestAuthentication` + `AuthorizationPolicy`,校验请求头里的 token。 - 客户端用 **私钥** 自行签发 token,请求时带 `Authorization: Bearer ` 即可通过。 `sidecar` 字段定义(`myapp/views/view_inferenceserving.py:255-262`),描述为"容器的 agent 代理,istio 用于服务网格,jwt 用于统一认证(需要客户端在请求头中添加开发者生成的 token)",可选值 `istio` / `jwt`。 ## 一、平台侧:公私钥的生成与存储 勾选 `jwt` 后,保存服务时平台自动生成密钥(`myapp/views/view_inferenceserving.py:811-827`): ```python # sidecar 含 jwt 且 expand 里还没有 public_key 时,生成一对 RSA 公私钥 if item.sidecar and 'jwt' in item.sidecar: expand = json.loads(item.expand) if 'public_key' not in expand: from jwcrypto import jwk # kid 用服务英文名 item.name,所以每个服务的公私钥都不同 key = jwk.JWK.generate(kty='RSA', size=2048, alg='RS256', kid=item.name) expand['public_key'] = json.loads(key.export_public()) expand['private_key'] = json.loads(key.export_private()) item.expand = json.dumps(expand, indent=4, ensure_ascii=False) # 取消勾选 jwt 时,会从 expand 里删除 public_key / private_key ``` 要点: - 密钥算法固定为 `RSA / 2048 / RS256`;`kid` = 服务英文名(`item.name`),因此每个服务的公私钥都不一样。 - 公钥 `public_key`、私钥 `private_key` 都存在服务的 **扩展字段 expand**(数据库 `inferenceserving.expand`)。 - `jwt` 必须配合 `istio`:保存时若只勾了 `jwt` 没勾 `istio`,平台在 `pre_update` 自动补上 `istio`(`myapp/views/view_inferenceserving.py:877-879`)。 ### 在哪里拿到公私钥 打开对应推理服务的 **"详情"**,在 **扩展字段(expand)** 中即可看到 `public_key` 和 `private_key`(JSON 结构)。客户端签 token 用 `private_key`。 > 注意:原始文档示例里展示了一段明文私钥(`kid=decisiontree-20231001`),仅作格式示例,**切勿在生产中使用示例密钥**。实际密钥请从你自己服务的扩展字段中读取。 也可以离线手动生成同样结构的密钥(与平台逻辑一致): ```python from jwcrypto import jwk import json # kid 用你的服务英文名 key = jwk.JWK.generate(kty='RSA', size=2048, alg='RS256', kid='<服务英文名>') public_key = key.export_public() # 公钥(JSON 字符串) private_key = key.export_private() # 私钥(JSON 字符串) print(public_key) print(private_key) ``` 公钥 / 私钥的 JSON 结构示例(脱敏,仅看字段): ```json // public_key { "alg": "RS256", "e": "AQAB", "kid": "<服务英文名>", "kty": "RSA", "n": "" } ``` ```json // private_key(比公钥多 d/p/q/dp/dq/qi 等私有参数,全部脱敏) { "alg": "RS256", "d": "<已脱敏>", "dp": "<已脱敏>", "dq": "<已脱敏>", "e": "AQAB", "kid": "<服务英文名>", "kty": "RSA", "n": "<已脱敏>", "p": "<已脱敏>", "q": "<已脱敏>", "qi": "<已脱敏>" } ``` ## 二、平台侧:部署时下发 istio 校验规则 服务部署(deploy)时,若 `sidecar` 含 `jwt`,平台用公钥生成 jwks,并下发两个 istio CRD(`myapp/views/view_inferenceserving.py:1724-1783`): - `security.istio.io/v1beta1` `RequestAuthentication`: - `issuer` = 服务英文名(`service.name`)——**所以客户端 token 的 `iss` 必须等于服务英文名**。 - `jwks` = 服务公钥组成的 `{"keys":[public_key]}`。 - `forwardOriginalToken: true`(校验后把原始 token 透传给后端容器)。 - `security.istio.io/v1beta1` `AuthorizationPolicy`: - `action: DENY`,规则 `notRequestPrincipals: ["*"]`——即 **没有带合法认证主体(未通过 JWT 校验)的请求一律拒绝**。 删除服务时会一并清理这两个 CRD(`requestauthentications` / `authorizationpolicies`,见 `myapp/views/view_inferenceserving.py:865-866`)。 ## 三、客户端:签发 token 用服务的 **私钥** 签发 token。`iss` 必须等于服务英文名(与 istio `RequestAuthentication.issuer` 对应): ```python import datetime from jwcrypto import jwk, jwt private_key = '''<从服务扩展字段复制的 private_key JSON 字符串>''' claims = { "iss": "<服务英文名>", # 必须与服务名一致,否则 istio 校验不过 "sub": "pengluan", # 用户名(自定义) "iat": int(datetime.datetime.now().timestamp()), # 签发时间 "exp": int(datetime.datetime.now().timestamp() + 60*60*24*365), # 过期时间(示例:1 年) # "nbf": int(datetime.datetime.now().timestamp()), # 可选:生效时间 } # 用 RS256 算法签名 token = jwt.JWT(header={'alg': 'RS256'}, claims=claims) token.make_signed_token(jwk.JWK.from_json(private_key)) serialized_token = token.serialize() print(serialized_token) ``` ## 四、客户端:本地验证 token(可选) 用服务的公钥本地校验 token 是否合法: ```python from jwcrypto import jwk, jwt public_key_json = '''<从服务扩展字段复制的 public_key JSON 字符串>''' serialized_token = '<上一步生成的 token>' public_key = jwk.JWK.from_json(public_key_json) verified_token = jwt.JWT(key=public_key, jwt=serialized_token) print(verified_token.claims) ``` ## 五、客户端:携带 token 调用服务 请求头加上 `Authorization: Bearer ` 即可访问开启了 JWT 的推理服务: ```bash curl --header "Authorization: Bearer $token" https://<服务域名>/<推理路径> ``` 不带 token 或 token 非法的请求,会被 istio `AuthorizationPolicy` 直接拒绝(403)。 ## 相关源码 | 功能 | 位置 | |---|---| | `sidecar` 字段(istio/jwt 可选项) | `myapp/views/view_inferenceserving.py:255-262` | | 生成/删除公私钥到 expand | `myapp/views/view_inferenceserving.py:811-827` | | jwt 自动补 istio | `myapp/views/view_inferenceserving.py:877-879` | | 部署下发 RequestAuthentication / AuthorizationPolicy | `myapp/views/view_inferenceserving.py:1724-1783` | | 删除服务时清理 istio CRD | `myapp/views/view_inferenceserving.py:865-866` | | 服务模型 sidecar/expand 字段(`InferenceService` 类,行 202 起) | `myapp/models/model_serving.py:239`(sidecar)、`:246`(expand) | --- ### AIHub 算法应用开发 - 链接: https://www.cubestudio.vip/docs/06-%E4%BA%8C%E6%AC%A1%E5%BC%80%E5%8F%91/AIHub%E7%AE%97%E6%B3%95%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91 - 分类: 06-二次开发 / AIHub - 适用场景: 要新写一个 aihub 算法应用(含训练/推理/示例数据集/自动化标注/流推理)、调试构建镜像、并把应用注册到平台模型市场时读这篇 - 关键词: aihub / 算法应用 / AI应用开发 / Model类 / app.py / Dockerfile / init.sh / example.jpg / info.json / init-aihub.json / train_inputs / inference_inputs / load_model / inference / inference_resource / web_examples / set_dataset / labelstudio_predict / rtsp_inference / 流推理 / gradio / 一键微调 / 推理部署 / 基础镜像 / conda / cuda / modelscope - 最后更新: 2026-07-04 # AIHub 算法应用开发 AIHub 是 CubeStudio 的「AI 应用市场」。一个 aihub 应用用一份 `app.py`(继承 `Model` 类)描述模型的基础信息、训练、推理、示例数据、自动化标注、流推理等能力;平台据此自动对接 **可视化推理部署**、**一键微调转 pipeline**、**模型市场展示** 等功能。 面向使用者的市场使用见 [AIHub 模型市场](../03-平台使用/09-数据智能与市场/AIHub模型市场.md)。 > [aihub 应用开发视频教程](https://cube-studio.oss-cn-hangzhou.aliyuncs.com/video/aihub-dev.mp4) ## 开发流程总览 1. 本地新增 aihub 代码、修改、调试代码; 2. 调试时会在 `app.py` 同级目录自动生成 `info.json`; 3. 基于自己编写的 Dockerfile 构建 aihub 应用镜像,并用新镜像再完整测试一遍代码; 4. 把 `info.json` 追加到 `myapp/init/init-aihub.json`(注意需含 pic 图片、resource 资源、images 镜像等信息); 5. 重新打包后端镜像; 6. CubeStudio 升级该后端镜像后,AIHub 市场里就包含你的应用了。 > 已核实:注册清单路径为 `myapp/init/init-aihub.json`(本仓存在;英文版另有 `myapp/init-en/init-aihub.json`)。 ## 应用目录构成 在 `aihub/deep-learning/` 下新建应用目录(可直接复制参考应用 `app1`)。一个 aihub 应用必须包含的文件: - **`app.py`**:应用主体,定义 `Model` 类的信息和函数(训练/推理/服务入口)。 - **`Dockerfile`**:模型训练和推理环境所用镜像的构建文件。 - **`init.sh`**:初始化脚本,在基础镜像之上做场景化初始化(可选,可不含该文件)。 - **`readme` / `README.md`**:描述模型功能与用法。 - **`example.jpg`**:在模型市场卡片上展示的样式图(建议 330×180 比例),文件名需配置到 `app.py` 的 `pic` 属性。 - 其他配套内容自行添加。 > ⚠️ 命名约束:**目录名必须与 `app.py` 中 `Model` 的 `name` 属性一致**,且只能用英文小写、数字和 `-`。 > 已核实:示例应用 `aihub/deep-learning/app1/`(含 `app.py`/`Dockerfile`/`init.sh`/`example.jpg`/`info.json`)存在。 ## 镜像调试 基础镜像为 conda 环境。先用基础镜像启动容器: 可用的基础镜像 tag(均已在本仓 Dockerfile/构建脚本中核对存在): ```text # 纯 CPU / conda ccr.ccs.tencentyun.com/cube-studio/aihub:base-python3.8 # conda + python3.8 ccr.ccs.tencentyun.com/cube-studio/aihub:base-python3.9 # conda + python3.9 ccr.ccs.tencentyun.com/cube-studio/aihub:base-python3.10 # conda + python3.10 ccr.ccs.tencentyun.com/cube-studio/aihub:base-python3.11 # conda + python3.11 # CUDA 11.8 ccr.ccs.tencentyun.com/cube-studio/aihub:base-cuda11.8-python3.8 ccr.ccs.tencentyun.com/cube-studio/aihub:base-cuda11.8-python3.9 ccr.ccs.tencentyun.com/cube-studio/aihub:base-cuda11.8-python3.10 ccr.ccs.tencentyun.com/cube-studio/aihub:base-cuda11.8-python3.11 # CUDA 12.8.1 ccr.ccs.tencentyun.com/cube-studio/aihub:base-cuda12.8.1-python3.9 ccr.ccs.tencentyun.com/cube-studio/aihub:base-cuda12.8.1-python3.10 ccr.ccs.tencentyun.com/cube-studio/aihub:base-cuda12.8.1-python3.11 # modelscope 模型开发镜像 ccr.ccs.tencentyun.com/cube-studio/modelscope:base-cuda11.3-python3.7 ccr.ccs.tencentyun.com/cube-studio/modelscope:base-cuda11.8-python3.8 ccr.ccs.tencentyun.com/cube-studio/modelscope:base-cuda12.1-python3.10 ccr.ccs.tencentyun.com/cube-studio/modelscope:base-cuda12.1-python3.11 ``` > 更多基础镜像 tag 见 [镜像构建总览](镜像构建/镜像构建总览.md)。 启动基础环境进入容器: ```bash # 获取当前项目名作为应用名 aiapp=$(basename `pwd`) cube_dir=($(dirname $(dirname "$PWD"))) chmod +x $cube_dir/src/docker/entrypoint.sh docker run --name ${aiapp} --privileged -it \ -e NVIDIA_VISIBLE_DEVICES=all -e APPNAME=$aiapp \ -v $cube_dir/src:/src -v $PWD:/app -w /app -p 80:80 \ --entrypoint='/src/docker/entrypoint.sh' \ ccr.ccs.tencentyun.com/cube-studio/aihub:base-cuda11.8-python3.11 bash ``` 补全 `init.sh` 环境脚本后执行(注意:环境文件不要放在容器 `/app/` 目录下,否则会被加载进 git): ```bash # init.sh 会被复制到容器 / 根目录下再执行 cp init.sh /init.sh && bash /init.sh ``` 补齐 `app.py` 后运行调试: ```bash /src/docker/entrypoint.sh python app.py web ``` 出问题时看两个日志: - 日志1:上面命令直接打印的报错,是 cube-studio aihub 应用后台的报错; - 日志2:容器内 `/log.txt`,是 gradio 的报错。 Web 界面体验:浏览器打开 `http://xx.xx.xx/gradio/aihub/$aiapp/`(`$aiapp` 替换为你的应用名/目录名)。 > 已核实:`entrypoint.sh` 路径为 `aihub/src/docker/entrypoint.sh`(存在);gradio 挂载路径为 `/gradio/aihub/{应用名}`,见 `aihub/src/cubestudio/aihub/web/gradio_server.py:484`。 ## 构建 aihub 应用镜像 代码调试完成后,基于自己写的 Dockerfile 构建应用镜像,建议命名为 `xx.xx.xx.xx/cube-studio/aihub:${aiapp}`,并在 `app.py` 中把 `images` 属性设为该镜像名: ```bash aiapp=$(basename `pwd`) docker build --network=host -t ccr.ccs.tencentyun.com/cube-studio/aihub:${aiapp} . ``` 构建完成后,建议再用构建后的镜像完整体验测试一遍: ```bash aiapp=$(basename `pwd`) cube_dir=($(dirname $(dirname "$PWD"))) chmod +x $cube_dir/src/docker/entrypoint.sh sudo docker run --name ${aiapp} --privileged -d \ -e NVIDIA_VISIBLE_DEVICES=all -e APPNAME=$aiapp \ -v $cube_dir/src:/src -v $PWD:/app -w /app -p 80:80 \ --entrypoint='/src/docker/entrypoint.sh' \ ccr.ccs.tencentyun.com/cube-studio/aihub:${aiapp} python app.py web ``` 运行时会在应用目录下生成 `info.json`,下一步注册要用。 ## 注册到平台 1. 确保你的应用目录已更新到 `aihub/deep-learning/` 下; 2. 把容器内启动时生成的 `info.json` 追加到 `myapp/init/init-aihub.json`; 3. 重新打包后端镜像,并将生产环境后端镜像更新为重新打包的镜像。 ## 代码示例 AIHub 的入门示例应用是 `app1`,参考 `aihub/deep-learning/app1/app.py`。 ## Model 类属性与函数 `app.py` 中的应用类继承自 `Model`(`from cubestudio.aihub.model import Model, Validator, Field_type, Field`,基类见 `aihub/src/cubestudio/aihub/model.py`)。下列属性/函数均已与基类核对存在。 ### 基础信息 - 属性:`name`、`label`、`describe`、`field`、`scenes`、`status`、`version`、`pic`(另含 `images` 指定镜像名)。 - 含义:定义模型名、所属领域、用途、版本、示例图等。 - 用途:对接平台时用于推理部署可视化和 AIHub 列表中展示应用信息。 > 已核实:基类 `model.py:94-105` 定义 `name/field/scenes/status/version/label/describe/pic/images` 等属性;`field` 取值如「机器视觉/听觉/自然语言/多模态/大模型」。 ### 训练 - 属性:`train_inputs` + `train` 函数。 - 含义:训练输入的参数类型、参数名、描述、默认值、输入校验等(通过 `Field` 定义)。 - 用途:aihub 应用点击「开发/一键微调」时会转为 pipeline,其中模型微调节点的用户输入由 `train_inputs` 决定。 ### 推理 - 属性:`inference_inputs` + `load_model` 函数 + `inference` 函数 + `inference_resource` + `web_examples`。 - 含义:确定推理输入、模型加载函数、推理函数,以及部署所需资源和可用的推理输入示例。 - 用途: - 点击「部署 web」时会部署为 k8s 的 Deployment,生成前后端界面并同时提供 API; - `load_model` 关注模型保存地址:为空则加载预训练模型;不为空则从指定地址加载(一键微调生成的 pipeline 最后一个节点是「部署微调后模型」,要求应用能加载微调后模型); - 推理函数同时服务于离线推理和 Web 界面推理(调用同一函数),另有批推理能力主要用于离线推理。 > 已核实:基类有 `inference_inputs`、`inference_outputs`、`web_examples`、`inference_resource`(含 `resource_memory/resource_cpu/resource_gpu`)以及 `train`/`load_model`/`inference` 函数(`model.py:138-191,353-366`)。 ### 示例数据集 - 属性:`set_dataset` 函数。 - 含义:下载/生成训练示例数据集。 - 用途:aihub 应用转 pipeline 时,第一个任务即「下载示例数据集」,帮助使用者熟悉如何配置训练数据。 > 已核实:`model.py:346` 有 `def set_dataset(self, **kwargs)`。 ### 自动化标注 - 属性:`labelstudio_predict` 函数。 - 含义:标注函数。 - 用途:对接 LabelStudio 标注平台的模型服务接口,接收待标注内容,推理并生成标注格式回传给 LabelStudio。 > 详见 [LabelStudio 标注平台二次开发](LabelStudio标注开发.md) 的「自动化标注」一节。 ## 流推理 目前只有图片具备流推理能力,重写 `rtsp_inference` 函数即可。 > 已核实:基类 `model.py:370` 有 `def rtsp_inference(self, img: numpy.ndarray, **kwargs) -> numpy.ndarray`。 ## 相关文档 - 使用侧:[AIHub 模型市场](../03-平台使用/09-数据智能与市场/AIHub模型市场.md) - 自动化标注对接:[LabelStudio 标注平台二次开发](LabelStudio标注开发.md) - 镜像 tag 与构建:[镜像构建总览](镜像构建/镜像构建总览.md) --- ### LabelStudio 标注平台二次开发 - 链接: https://www.cubestudio.vip/docs/06-%E4%BA%8C%E6%AC%A1%E5%BC%80%E5%8F%91/LabelStudio%E6%A0%87%E6%B3%A8%E5%BC%80%E5%8F%91 - 分类: 06-二次开发 / 数据标注 - 适用场景: 要给 LabelStudio 接入自动化标注接口、编译/换 logo/打包 LabelStudio 镜像、打通 CubeStudio 用户与项目组、或理解标注平台与 aihub/大模型如何联动时读这篇 - 关键词: labelstudio / label-studio / 标注平台 / 数据标注 / 自动化标注 / auto-labeling / ML Backend / 机器学习后端 / predict / setup / health / 换logo / cookie共享 / 单点登录 / SSO / 项目组过滤 / my/project / istio / virtualservice / yolo26 / LabelStudio_ML_Backend / aihub标注 / nlp标注 / chatgpt标注 - 最后更新: 2026-07-04 # LabelStudio 标注平台二次开发 CubeStudio 的数据标注能力基于开源 [LabelStudio](https://labelstud.io/) 二次开发而来。LabelStudio 本身是一个独立的项目(Django 后端 + React 前端),CubeStudio 通过 **镜像定制 + istio 流量分流 + cookie 共享 + 自动化标注接口** 把它无缝集成进平台。 > 说明:LabelStudio 的源码(`label_studio/`、`web/`、`Dockerfile.cubestudio` 等)位于 **独立的 label-studio fork 仓库**,不在 `cube-studio-enterprise` 主仓内。本文涉及 `label_studio/...` 的文件路径均指那个源码仓库;与本仓相关的部分(istio 路由、NLP 自动化标注后端、项目组过滤接口、k8s 部署清单)已逐一核对并在文中标明 `文件:行号`。 面向使用者的操作流程见 [数据标注功能与操作流程](../03-平台使用/08-数据标注/标注平台/01-功能与操作流程.md)。 ## 代码结构 LabelStudio 源码仓库目录约定: - `label_studio/`:Django 框架的**后端**代码 - `web/`:React 框架的**前端**代码 - 其他目录可忽略 源码内容提示: - 配置文件:`label_studio/core/settings/label_studio.py` + `label_studio/core/settings/base.py` - 用户登录视图:`label_studio/users/views.py` ## 启动与本地调试 参考源码仓库的 `docker-compose.yaml`,它会启动三个服务:前端 nginx 打包镜像、后端 app、PostgreSQL 数据库。 后端 app 容器的启动命令是 `sleep`(即不自动起服务),所以流程是:先 `docker-compose up -d` 起容器,再手动进入 app 容器内操作。 容器内: - **前端构建**:第一次构建需要科学上网,执行 `cd /label-studio/web/ && sh build.sh`;之后的构建只需执行最后一步 `yarn run build:dev`。 - **启动后端**:`./deploy/docker-entrypoint.sh label-studio-uwsgi` 浏览器访问以下地址完成用户登录(会自动登录 admin 用户并跳转到标注任务项目管理界面): ``` http://xx.xx/user/login/?username=admin@tencent.com ``` 裸启动 Django 调试(不走 uwsgi)的命令参考: ```bash export LOG_LEVEL=INFO export DEBUG=1 export JSON_LOG=0 python3 label_studio/manage.py migrate python3 label_studio/manage.py collectstatic python3 label_studio/manage.py runserver 0.0.0.0:8080 ``` ## 构建与打包镜像 - **后端**:不需要构建。 - **前端**:见上文,`docker-compose` 启动后在容器内 `yarn run build:dev`。 - **打包镜像**:参考源码仓库的 `Dockerfile.cubestudio`: ```bash docker build --network=host \ -t ccr.ccs.tencentyun.com/cube-studio/label-studio:1.13.2-amd64 \ --build-arg TARGETARCH=amd64 \ -f Dockerfile.cubestudio . ``` > 注意:上面的镜像 tag `1.13.2-amd64` 是 LabelStudio 源码仓库构建脚本里的示例版本。本仓 k8s 部署清单中实际拉取的镜像 tag 为 `ccr.ccs.tencentyun.com/cube-studio/label-studio:20260701`(注释标 `heartexlabs/label-studio:1.10.1`),见 `install/kubernetes/labelstudio/labelstudio.yaml:40,89,151`。部署到平台时请以 `labelstudio.yaml` 中的 tag 为准。 ## 更换 logo 替换 `label_studio/dev/` 下的图片,然后执行: ```bash sh label_studio/dev/build.sh ``` > 平台级(CubeStudio 前端)的 logo / 水印替换是另一回事,见 [更换 Logo 与水印](更换Logo与水印.md)。 ## 用户与权限互通 LabelStudio 的**用户**和**项目分组**与 CubeStudio 打通,核心机制是「同 IP 端口 + istio 分流 + cookie 共享」。 ### 流量分流(istio) LabelStudio 和 CubeStudio 部署在**同一个 IP/端口**下,由 istio 的 VirtualService 按路径前缀分流: - `/labelstudio/` 前缀的流量被分流到 LabelStudio 的 pod; - 其余默认流量进入 CubeStudio 前端 pod。 由于二者属于同一 IP 的服务,**浏览器 cookie 天然共享**。 > 已核实:istio 路由配置见 `install/kubernetes/virtual.yaml:135`(`prefix: /labelstudio/`)→ `install/kubernetes/virtual.yaml:143`(`host: labelstudio.kubeflow.svc.cluster.local`)。原文档把前缀写作 `/lablestudio/`,系笔误,实际为 `/labelstudio/`。 ### 用户互通(cookie) CubeStudio 用户登录时会把用户名写入 cookie,因此 LabelStudio 侧能直接拿到当前用户名信息。 - LabelStudio 侧代码:`label_studio/users/views.py` 的 `user_login` 函数(label-studio 源码仓库)。 ### 项目分组过滤 打开标注任务组列表时,LabelStudio 后端会请求 CubeStudio 的 `/my/project` 接口,拿到当前用户所属的项目组,再据此过滤可见的标注任务组。 - LabelStudio 侧代码:`label_studio/projects/api.py` 的 `get_queryset` 函数(label-studio 源码仓库)。 - CubeStudio 侧接口:`/my/project`,见 `myapp/views/view_team.py:641`(`@expose_api ... url="/my/project"`,返回「我有权限的项目组」)。 > 补充(本仓实现):CubeStudio 后端另提供 `/proxy/labelstudio/projects` 接口(`myapp/views/view_labelstudio.py:648`),直接连 `LABEL_STUDIO_DAT` 指向的 PostgreSQL,按当前用户所属项目组 ID 过滤 `project` 表(`workspace` 字段存的是 CubeStudio 项目组 ID 字符串),供任务模板下拉等场景使用。`LABEL_STUDIO_DAT` 默认值见 `myapp/config.py:1119`(`postgresql+psycopg2://postgres:postgres@postgresql.kubeflow:5432/labelstudio`)。 ## 自动化标注 每种标注类型都需要单独编写自动化标注接口。平台自带示例的实现分两类: - **视觉、语音类**:由对应的 **aihub 应用**提供自动化标注(每个应用实现 `labelstudio_predict` 函数)。 - **NLP / chat 类**:由 CubeStudio 后端 `myapp/views/view_labelstudio.py` 实现,内部调用大模型(OpenAI 兼容)接口完成。 ### 视觉 / 语音类:对应的 aihub 应用 下列每个 aihub 应用的 `labelstudio_predict` 函数提供对应标注类型的自动化标注(路径均已核对存在): | 标注类型 | aihub 应用 | app.py 路径 | |---|---|---| | 目标识别 | DAMOYOLO-高性能通用检测模型-S | `aihub/modelscope/cv-tinynas-object-detection-damoyolo/app.py` | | 视觉-视频目标跟踪 | YOLO 多目标跟踪模型 | `aihub/deep-learning/yolo-object-track/app.py` | | 视觉-图像分类 | ViT 图像分类-中文-日常物品 | `aihub/modelscope/cv-vit-base-image-classification-dailylife-labels/app.py` | | 视觉-关键点检测 | 106 点人脸关键点-通用领域-2D | `aihub/modelscope/cv-mobilenet-face-2d-keypoints-alignment/app.py` | | 视觉-目标边界识别(实例分割) | CascadeMaskRCNN-SwinB 图像实例分割 | `aihub/modelscope/cv-swin-b-image-instance-segmentation-coco/app.py` | | 视觉-目标遮罩识别(语义分割) | Segformer-B0 实时语义分割 | `aihub/modelscope/cv-segformer-b0-image-semantic-segmentation-coco-stuff164k/app.py` | | 视觉-光学字符识别(OCR) | ocr 识别 | `aihub/deep-learning/paddleocr/app.py` | | 视觉-图片描述 | mPLUG 图像描述模型-中文-base | `aihub/modelscope/mplug-image-captioning-coco-base-zh/app.py` | | audio-语音识别 | Paraformer 语音识别-中文-通用-16k-离线-large-pytorch | `aihub/modelscope/speech-paraformer-large-asr-nat-zh-cn-16k-common-vocab8404-pytorch/app.py` | | audio-说话人分隔 | CAM++ 说话人日志-对话场景角色区分-通用 | `aihub/modelscope/speech-campplus-speaker-diarization-common/app.py` | | audio-多说话人语音识别 | CAM++ 说话人日志-对话场景角色区分-通用 | `aihub/modelscope/speech-campplus-speaker-diarization-common/app.py` | > 已核实:上述全部 `app.py` 路径在本仓存在;以 `cv-tinynas-object-detection-damoyolo/app.py:144` 为例,确有 `def labelstudio_predict(self, tasks, project, label_config, force_reload=False, try_fetch=True, params={}, model_version=None, **kwargs)`。aihub 应用如何实现 `labelstudio_predict` 见 [AIHub 算法应用开发](AIHub算法应用开发.md)。 ### NLP / chat 类:后端调用大模型 NLP 和 chat 相关的自动化标注在 `myapp/views/view_labelstudio.py` 中实现。 后端类 `Labelstudio_View_Base`(`route_base = '/proxy/labelstudio'`)对外暴露统一的 `///{health,setup,predict}` 接口,`predict` 按 `field=='nlp'` 分发到不同子类型处理(`view_labelstudio.py:72-93`): | model_type | 处理函数 | |---|---| | classification | `nlp_classification` | | summary | `nlp_summary` | | translaton | `nlp_translaton`(代码中即此拼写) | | ner | `nlp_ner` | | faq | `nlp_faq` | | rank | `nlp_rank` | | intent | `nlp_intent` | | chat | `nlp_chat` | 这些函数都通过 `self.chatgpt(prompt)` 调用大模型(`view_labelstudio.py:603`),相关配置(`myapp/config.py`): - `CHATGPT_CHAT_URL`:大模型 OpenAI 兼容接口地址,默认 `https://api.openai.com/v1`(代码默认值;`config.py:1380` 示例配的是 `['https://lonlie.plus7.plus/v1']`,可为列表随机选)。请求时会自动补 `/chat/completions`。 - `CHATGPT_TOKEN`:鉴权 token,写入 `Authorization: Bearer` 头(同时写 `api-key` 头兼容微软接口),见 `config.py:1379`。 - `CHATGPT_ARGS`:模型参数字典,`model` 默认 `gpt-5-mini`,另含 `temperature`、`top_p`、`stop`、`max_tokens`、`presence_penalty`、`frequency_penalty` 等(`view_labelstudio.py:608-622`)。 ## 自定义自动化标注接口 要为新的标注类型编写自动化标注后端,做法是:把 `job-template/job/yolo26/labelstudio.py` 复制到你的接口代码旁,引入其中的 `LabelStudio_ML_Backend` 类,并在你的 API 中对外提供三个接口: 1. **`/health`** 和 **`/setup`**:仅用于检查接口是否启动。参考 `job-template/job/yolo26/server.py` 中的 `labelstudio_setup` / `labelstudio_health` 函数。 2. **`/predict`**:提供真正的自动化标注。 > 注意(路由前缀):原文档把接口写作 `/health`、`/setup`、`/predict`。在 `job-template/job/yolo26/server.py` 中,三个接口的**实际注册路径带 `/labelstudio/` 前缀**:`@app.get("/labelstudio/health")`(`server.py:427`)、`@app.post("/labelstudio/setup")`(`server.py:421`)、`@app.post("/labelstudio/predict")`(`server.py:350`)。而 CubeStudio 内置 NLP 后端则用 `/proxy/labelstudio///{health,setup,predict}`(`view_labelstudio.py:47,51,72`)。接入时请以你实际部署的服务实现为准。 `LabelStudio_ML_Backend` 类(`job-template/job/yolo26/labelstudio.py`)的职责: - `labelstudio_health(**kwargs)`:返回 `{}`。 - `labelstudio_setup(**kwargs)`:保存标注平台发来的元数据 `access_token`、`hostname`、`project`,用于后续下载素材时鉴权。 - `labelstudio_download_image(image_path, save_dir='result', ...)` / `labelstudio_download_audio(...)`:把 LabelStudio 里的图片/音频下载到本地再推理(命中 `hostname` 时走 `/static/` 直链下载)。 ### 推理接口(/predict)输入 `/predict` 接收的参数包含:`tasks`、`project`、`label_config`、`force_reload`、`try_fetch`、`params`、`model_version`。 - `tasks`:当前要标注的数据 source,JSON 格式(如 `task['data']['image']` 为图片路径)。 ![task 数据格式示意](https://i-blog.csdnimg.cn/img_convert/e24351e2a29e686835bba3699648e453.png) - `project`:目前无用。 - `label_config`:你的标注项目「标签接口」中 Code 的值,字符串格式(XML),后端会从中解析出可用标签集合(`server.py:365-375` 用 `ET.fromstring` 解析 `