如何设置虚拟集群

Hived Scheduler介绍

OpenPAI 支持两种调度器:Kubernetes default scheduler 和 hivedscheduler。Hivedscheduler是一个用于深度学习的 Kubernetes Scheduler。它支持虚拟集群划分,拓扑感知的资源保证、以及性能优化的 Gang Scheduling,这些都是 k8s default scheduler 不支持的。如果您没有在安装时显式声明 enable_hived_scheduler: false,那么 Hivedscheduler 就是开启的。请注意,目前只有Hivedscheduler支持虚拟集群设置,k8s default scheduler 不支持。

设置虚拟集群 (Virtual Cluster)

GPU虚拟集群的配置

在开始之前,请阅读 此文档,以了解如何写 hived scheduler 配置。

services-configuration.yaml 中,有一个 hived scheduler 部分,如下:

# services-configuration.yaml
...
hivedscheduler:
  config: |
    physicalCluster:
      skuTypes:
        DT:
          gpu: 1
          cpu: 5
          memory: 56334Mi
      cellTypes:
        DT-NODE:
          childCellType: DT
          childCellNumber: 4
          isNodeLevel: true
        DT-NODE-POOL:
          childCellType: DT-NODE
          childCellNumber: 3
      physicalCells:
      - cellType: DT-NODE-POOL
        cellChildren:
        - cellAddress: worker1
        - cellAddress: worker2
        - cellAddress: worker3
    virtualClusters:
      default:
        virtualCells:
        - cellType: DT-NODE-POOL.DT-NODE
          cellNumber: 3
...

如果您按照 安装指南 操作,您会在 services-configuration.yaml 里找到类似的设置hived scheduler 文档包含这些字段的详细说明。您可以更新配置并建立虚拟集群。例如,在上面的设置中,我们有 3 个节点:worker1worker2worker3。它们都在 default 虚拟集群中。如果我们要创建两个 VC(Virtual Cluster,即虚拟集群),一个叫 default,包含两个节点,另一个叫 new ,包含一个节点,我们可以先修改 services-configuration.yaml

# services-configuration.yaml
...
hivedscheduler:
  config: |
    physicalCluster:
      skuTypes:
        DT:
          gpu: 1
          cpu: 5
          memory: 56334Mi
      cellTypes:
        DT-NODE:
          childCellType: DT
          childCellNumber: 4
          isNodeLevel: true
        DT-NODE-POOL:
          childCellType: DT-NODE
          childCellNumber: 3
      physicalCells:
      - cellType: DT-NODE-POOL
        cellChildren:
        - cellAddress: worker1
        - cellAddress: worker2
        - cellAddress: worker3
    virtualClusters:
      default:
        virtualCells:
        - cellType: DT-NODE-POOL.DT-NODE
          cellNumber: 2
      new:
        virtualCells:
        - cellType: DT-NODE-POOL.DT-NODE
          cellNumber: 1
...

CPU虚拟集群的配置

如果您想添加CPU机器,在修改配置这一步,我们建议您设置一个纯 CPU 的虚拟集群,不要在一个虚拟集群中混合 CPU 节点和 GPU 节点。设置CPU结点时,请省略 skuTypes 中的 gpu 字段,或使用 gpu: 0。示例如下:

hivedscheduler:
  config: |
    physicalCluster:
      skuTypes:
        DT:
          gpu: 1
          cpu: 5
          memory: 56334Mi
        CPU:
          cpu: 1
          memory: 10240Mi
      cellTypes:
        DT-NODE:
          childCellType: DT
          childCellNumber: 4
          isNodeLevel: true
        DT-NODE-POOL:
          childCellType: DT-NODE
          childCellNumber: 3
        CPU-NODE:
          childCellType: CPU
          childCellNumber: 8
          isNodeLevel: true
        CPU-NODE-POOL:
          childCellType: CPU-NODE
          childCellNumber: 1
      physicalCells:
      - cellType: DT-NODE-POOL
        cellChildren:
        - cellAddress: worker1
        - cellAddress: worker2
        - cellAddress: worker3
      - cellType: CPU-NODE-POOL
        cellChildren:
        - cellAddress: cpu-worker1
    virtualClusters:
      default:
        virtualCells:
        - cellType: DT-NODE-POOL.DT-NODE
          cellNumber: 3
      cpu:
        virtualCells:
        - cellType: CPU-NODE-POOL.CPU-NODE
          cellNumber: 1

上面示例的解释:假设我们在 Kubernetes 中有一个名为 cpu-worker1 的节点。它有 80GB 的内存和 8 个可分配的 CPU(请使用 kubectl describe node cpu-worker1 来确认可分配的资源)。然后,在skuTypes中,我们可以设置一个 CPU sku,它有 1 个 CPU 和 10240 MiB(80GiB / 8)的内存。如果需要,可以保留一些内存或 CPU。在 cellTypes 相应的设置了 CPU-NODECPU-NODE-POOL。最后,该设置将产生一个 default VC 和一个 cpu VC。cpu VC 包含一个 CPU 节点。

应用配置到集群

修改配置后,使用以下命令来应用配置:

./paictl.py service stop -n rest-server hivedscheduler
./paictl.py config push -p <config-folder> -m service
./paictl.py service start -n hivedscheduler rest-server

现在,您可以使用 OpenPAI 中的任何管理员账户测试这些新的 VC。下一节 将介绍如何向非管理员账户授予 VC 访问权限。

将集群授权给用户

管理员用户有权访问所有 VC。因此,如果您设置了一个新的 VC,可以用管理员账户来测试这个新VC。对于非管理员用户,管理员应该手动向其授予 VC 访问权限。具体方法取决于集群的 认证模式

在基础认证模式中

在基础认证模式中,管理员可以在 User Management 页面上授予用户访问 VC 的权限。首先,点击页面的 Edit。然后,为每个用户配置 VC 访问权限,如下所示。

请注意您无法撤销用户对default VC的访问权限。

在AAD认证模式中

在 AAD 模式下,用户通过 AAD 服务分组。应该为每个组分配 VC 访问权限。

首先,在 services-configuration.yaml 中找到以下部分:

# services-configuration.yaml
...
group-manager:
  ...
  grouplist:
    - groupname: group1
      externalName: sg1
      extension:
        acls:
          admin: false
          virtualClusters: ["vc1"]
          storageConfigs: ["azure-file-storage"]
    - groupname: group2
      externalName: sg2
      extension:
        acls:
          admin: false
          virtualClusters: ["vc1", "vc2"]
          storageConfigs: ["nfs-storage"]
...

virtualClusters 字段用于管理不同组的 VC 访问。使用以下命令应用配置更改:

./paictl.py service stop -n rest-server
./paictl.py config push -p <config-folder> -m service
./paictl.py service start -n rest-server

Worker结点含有不同硬件配置

我们建议一台 VC 应该拥有相同的硬件,表现在 hived scheduler 设置中,一个 VC 应该只包含一个 skuType。如果您有不同类型的 worker 结点(例如,不同结点上的 GPU 类型不同),请在不同的 VC 中进行配置。以下是 2 种结点的示例:

hivedscheduler:
  config: |
    physicalCluster:
      skuTypes:
        K80:
          gpu: 1
          cpu: 5
          memory: 56334Mi
        V100:
          gpu: 1
          cpu: 8
          memory: 80000Mi
      cellTypes:
        K80-NODE:
          childCellType: K80
          childCellNumber: 4
          isNodeLevel: true
        K80-NODE-POOL:
          childCellType: K80-NODE
          childCellNumber: 2
        V100-NODE:
          childCellType: V100
          childCellNumber: 4
          isNodeLevel: true
        V100-NODE-POOL:
          childCellType: V100-NODE
          childCellNumber: 3
      physicalCells:
      - cellType: K80-NODE-POOL
        cellChildren:
        - cellAddress: k80-worker1
        - cellAddress: k80-worker2
      - cellType: V100-NODE-POOL
        cellChildren:
        - cellAddress: v100-worker1
        - cellAddress: v100-worker2
        - cellAddress: v100-worker3
    virtualClusters:
      default:
        virtualCells:
        - cellType: K80-NODE-POOL.K80-NODE
          cellNumber: 2
      V100:
        virtualCells:
        - cellType: V100-NODE-POOL.V100-NODE
          cellNumber: 3

在上面的示例中,我们设置了 2 个 VC:defaultv100default VC 有两个 K80 结点,V100 VC 有 3 个 V100 结点。每个 K80 结点有 4 个 K80 GPU,每个 V100 结点有 4 个 V100 GPU。

在同一个结点上同时设置CPU和GPU sku

如果你想要在同一个结点上同时设置CPU和GPU sku,您可以参考下面的配置,在不同的cellTypes里使用相同的cellAddress

hivedscheduler:
  config: |
    physicalCluster:
      skuTypes:
        GPU:
          gpu: 1
          cpu: 4
          memory: 40960Mi
        CPU:
          gpu: 0
          cpu: 1
          memory: 10240Mi
      cellTypes:
        GPU-NODE:
          childCellType: GPU
          childCellNumber: 4
          isNodeLevel: true
        GPU-NODE-POOL:
          childCellType: GPU-NODE
          childCellNumber: 2
        CPU-NODE:
          childCellType: CPU
          childCellNumber: 12
          isNodeLevel: true
        CPU-NODE-POOL:
          childCellType: CPU-NODE
          childCellNumber: 2
      physicalCells:
      - cellType: GPU-NODE-POOL
        cellChildren:
        - cellAddress: node1
        - cellAddress: node2
      - cellType: CPU-NODE-POOL
        cellChildren:
        - cellAddress: node1
        - cellAddress: node2
    virtualClusters:
      default:
        virtualCells:
        - cellType: GPU-NODE-POOL.GPU-NODE
          cellNumber: 2
      cpu:
        virtualCells:
        - cellType: CPU-NODE-POOL.CPU-NODE
          cellNumber: 2

目前,在同一个结点上,我们只支持CPU和NVIDIA GPU的混合,或者CPU和AMD GPU的混合。暂不支持在同一个结点上同时存在NVIDIA和AMD GPU的情形。

使用Pinned Cell在虚拟集群中保留特定结点

在某些情况下,您可能希望保留虚拟集群中的特定节点,将作业明确提交到该结点以进行调试或快速测试。OpenPAI 提供了一种“固定”结点到虚拟集群的方法。

例如,假设您有三个 worker 结点: worker1worker2worker3,以及 2 个虚拟集群:defaultnewdefault VC 有 2 个 worker,new VC 只有 1 个 worker。以下是配置示例:

# services-configuration.yaml
...
hivedscheduler:
  config: |
    physicalCluster:
      skuTypes:
        DT:
          gpu: 1
          cpu: 5
          memory: 56334Mi
      cellTypes:
        DT-NODE:
          childCellType: DT
          childCellNumber: 4
          isNodeLevel: true
        DT-NODE-POOL:
          childCellType: DT-NODE
          childCellNumber: 3
      physicalCells:
      - cellType: DT-NODE-POOL
        cellChildren:
        - cellAddress: worker1
        - cellAddress: worker2
        - cellAddress: worker3
    virtualClusters:
      default:
        virtualCells:
        - cellType: DT-NODE-POOL.DT-NODE
          cellNumber: 2
      new:
        virtualCells:
        - cellType: DT-NODE-POOL.DT-NODE
          cellNumber: 1
...

现在,如果要将节点 worker2 “固定”到默认的 VC。可以将配置更改为:

# services-configuration.yaml
...
hivedscheduler:
  config: |
    physicalCluster:
      skuTypes:
        DT:
          gpu: 1
          cpu: 5
          memory: 56334Mi
      cellTypes:
        DT-NODE:
          childCellType: DT
          childCellNumber: 4
          isNodeLevel: true
        DT-NODE-POOL:
          childCellType: DT-NODE
          childCellNumber: 3
      physicalCells:
      - cellType: DT-NODE-POOL
        cellChildren:
        - cellAddress: worker1
        - cellAddress: worker2
          pinnedCellId: node-worker2
        - cellAddress: worker3
    virtualClusters:
      default:
        virtualCells:
        - cellType: DT-NODE-POOL.DT-NODE
          cellNumber: 1
        pinnedCells:
        - pinnedCellId: node-worker2
      new:
        virtualCells:
        - cellType: DT-NODE-POOL.DT-NODE
          cellNumber: 1
...

如您在配置中看到的,一个虚拟集群可以同时包含 virtual cells 和 pinned cells。现在 default VC 有一个 virtual cell 和一个 pinned cell。要将一个 pinned cell 包含到虚拟集群中,您应该为其指定一个 pinnedCellId。 例如上述配置将在 default VC 中保留 worker2

在任务提交时,您可以通过在 extras.hivedScheduler.taskRoles.<task-role-name>.pinnedCellId 中指定相应的 pinned cell id,将任务显式提交到 worker2,示例如下:

protocolVersion: 2
name: job-with-pinned-cell
type: job
jobRetryCount: 0
prerequisites:
  - type: dockerimage
    uri: 'openpai/standard:python_3.6-pytorch_1.2.0-gpu'
    name: docker_image_0
taskRoles:
  myworker:
    instances: 1
    completion:
      minFailedInstances: 1
    taskRetryCount: 0
    dockerImage: docker_image_0
    resourcePerInstance:
      gpu: 1
      cpu: 4
      memoryMB: 8192
    commands:
      - sleep 100s
defaults:
  virtualCluster: default
extras:
  com.microsoft.pai.runtimeplugin:
    - plugin: ssh
      parameters:
        jobssh: true
  hivedScheduler:
    taskRoles:
      myworker:
        pinnedCellId: node-worker2