多机/多集群/多资源组部署

单机部署后要扩容成多机集群、对接多个 k8s 集群、或把算力按项目组/资源组划分时读这篇

02-部署安装 / 部署方式
多机部署集群扩容多集群multi cluster多资源组resource grouporg标签机器label节点标签node labelCLUSTERSkubeconfigkubernetes-config configmapkubeflow-watch算力均衡adjust_node_resource

多机/多集群/多资源组部署

部署视频(公有云/单机/多机/多集群/分布式存储/私有仓库/GPU/功能初验)

配置文件所在地

本地调试时(启动方式:在 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=V100gpu-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:25kubectl label node 命令里可以看到完整集合(含 logging=true)。


单集群多机

1、分布式存储

需要分布式存储的情况下,要先部署分布式存储:先在每台机器上部署分布式存储,可参考 install/kubernetes/nfs/NFS离线部署.md 部署 nfs(主节点部署并配置服务端,其他节点部署配置客户端)。

机器学习平台依赖强 IO 性能的分布式存储。原理参考 算力统筹与分布式存储

!!!重要:分布式文件系统需要挂载到每台机器的 /data/k8s/ 下面(也可以挂载到其他目录,再以软链形式链接到 /data/k8s/)。如果使用 juicefs,则不需要这一步。

需要每台机器都有目录 /data/k8s 作为分布式存储目录(juicefs 不需要):

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,之后再扩容。参考 单机部署

3、集群扩容

基础准备:主机 /data/k8s 目录下需为分布式存储。

1)初始化机器

先部署 docker、拉取代码文件。

在新机器上拉取 rancher 镜像:

cd install/kubernetes/rancher
sh pull_rancher_images.sh

在新机器上拉取 CubeStudio 镜像:

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)为机器添加标签

service=true
train=true
notebook=true
org=public
cpu=true          # 按需
gpu=true          # 按需
gpu-type=A100     # 按需

多机标签

可以在 rancher 中加,也可以通过 kubectl 命令加。


多集群

实现原理: 在每个集群上都完成平台部署,但仅保留其中一个 web 端。web 端所在集群称为「主集群」,其他为「远程集群」。

先在新集群上部署 k8s 和 CubeStudio。

1、远程 k8s 集群卸载非必要组件

# 删除 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校验

2、修改远程 k8s 集群分布式存储配置

如果想让主集群和远程集群使用相同的分布式存储,需要将同一个分布式存储挂载到主集群和从集群主机的 /data/k8s 目录下。

挂载相同分布式存储后,为新集群的 prometheus 创建新的存储目录:

# 创建新 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:

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 命名空间用到,pipelineautoml 命名空间也会挂载它(见 cube/base/deploy-backend.yamldeploy-watch.yamldeploy-worker.yaml)。新增集群更新 kubeconfig 后,建议在这三个命名空间都重建一遍:

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.pyCLUSTERS 中添加集群信息(结构见 config.py:1403,字段为 NAME/KUBECONFIG/HOST/可选 SERVICE_DOMAIN):

# 所有训练集群的信息
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 生效:

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 集群调度,即在项目组的扩展参数中添加:

{
  "cluster": "dev1"
}

多集群

3.3 添加新集群的 watch 组件

复制 infra/kubeflow-watch 的 deployment(对应 cube/base/deploy-watch.yaml,deployment 名为 kubeflow-watch),修改名称,并把环境变量 ENVIRONMENT 改为新 k8s 集群的名称。

说明:ENVIRONMENTdeploy-watch.yaml 中默认来自 configmap deploy-configENVIRONMENT 键(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=xxxx 为资源组名称)。添加后,在项目组中把资源组配置为上面的 xx,保存项目组配置后,该项目组下的成员就会自动使用这一波资源组算力。

多资源组


单集群多项目组算力均衡

多项目组之间的算力均衡通过 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);具体周期以你启用时的配置为准。

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