すべてのプロダクト
Search
ドキュメントセンター

Container Service for Kubernetes:ACK Lingjunクラスターでネットワークトポロジ認識スケジューリングを使用する

最終更新日:Jan 24, 2025

機械学習やビッグデータ分析などのシナリオでは、ポッドは頻繁な通信を必要とすることがよくあります。 デフォルトでは、Kubernetesスケジューラは、Container Service for Kubernetes (ACK) クラスター内のノードにポッドを均等に分散します。 その結果、ポッドは高い待ち時間で通信することができ、ジョブを完了するのに必要な時間が増加する。 ACK Lingjunクラスターでは、ネットワークトポロジ対応スケジューリングにより、ポッドを同じレイヤ1またはレイヤ2転送ドメインに割り当てることができます。 このアプローチは、ネットワークの待ち時間を短縮し、ジョブの完了を高速化します。

ソリューションの概要

ネットワークトポロジ認識スケジューリングは、グリーディアルゴリズムを使用して、最小限のトポロジスパンでタスクをLingjunノードに割り当てます。

ACK Lingjunクラスターに2層のネットワークトポロジがあるとします。ポッドとアクセススイッチ (ASW) です。 ASWはLingjunクラスターの直接インターフェイスとして機能しますが、Podはより広いネットワークトポロジを表します。 Lingjunノード間の送信は、ネットワーク転送の少なくとも1つのホップを必要とし、ASWノード間の送信は、少なくとも2つのホップを必要とする。

  • 2つのLingjunノードを必要とするタスクの場合、ネットワークトポロジ認識スケジューリングは、タスクをノードペアA-BまたはノードペアE-Fに割り当てます。

  • 4つのLingjunノードを必要とするタスクの場合、ネットワークトポロジ認識スケジューリングは、タスクをノードペアA-DまたはノードペアE-Hに割り当てます。

ACK Lingjunクラスター内のノードが同じASWまたはPodの一部であるかどうかを判断するには、ノードにalibabacloud.com/asw-idおよびalibabacloud.com/point-of-deliveryのラベルがあるかどうかを確認します。 これらのラベルは、ネットワークの場所に関する詳細を提供します。

トポロジ構造の宣言

ACK Lingjunクラスターでネットワークトポロジ認識スケジューリングを実装するには、クラスターレベルのトポロジスケジューリング要件を定義し、タスクでスケジューリング情報を識別します。

  1. cluster-network-topology.yamlという名前のファイルを作成して、2レベルのトポロジ構造を宣言します。

    展開して完全なYAMLテンプレートを表示

    apiVersion: scheduling.koordinator.sh/v1alpha1
    kind: ClusterNetworkTopology
    metadata:
      # Keep unchanged.
      name: default
    spec:
      networkTopologySpec:
      # parentTopologyLayer is used to declare the upper topology structure.
      - parentTopologyLayer: ASWTopologyLayer
      # When you define topology for Lingjun nodes, the lowest level must be NodeTopologyLayer.
        topologyLayer: NodeTopologyLayer
      # The following section defines cross-layer network topology. Normally, no modification is needed.
      - labelKey:
        - alibabacloud.com/point-of-delivery
        topologyLayer: PoDTopologyLayer
      - labelKey:
        - alibabacloud.com/asw-id
        parentTopologyLayer: PoDTopologyLayer
        topologyLayer: ASWTopologyLayer
  2. sample-network-topology.yamlという名前のファイルを作成して、タスクのネットワークトポロジ対応のスケジューリング要件を宣言します。

    展開して完全なYAMLテンプレートを表示

    apiVersion: scheduling.koordinator.sh/v1alpha1
    kind: JobNetworkTopology
    metadata:
      labels:
        network-topology-permit-wait-time: "999999"
      # The task name.
      name: sample-network-topology
      # The namespace to which the task belongs.
      namespace: sample-network-topology
    spec:
      topologyStrategy:
      # This configuration allows scheduling across ASWs.
      - layer: ASWTopologyLayer
        # This configuration supports two strategies: PreferGather and MustGather. PreferGather allows pod scheduling across different layers,
        # while MustGather restricts pod scheduling to within the same layer.
        strategy: PreferGather
      - layer: NodeTopologyLayer
        strategy: PreferGather
      # Do not allow scheduling across pods.
      - layer: PoDTopologyLayer
        strategy: MustGather
      # The number of pods for this task.
      workerNum: 2
  3. pi.yamlという名前のファイルを作成して、ネットワークトポロジ対応のスケジューリング情報を宣言します。

    タスクを送信するときは、関連するJobNetworkTopology情報を含める必要があります。

    展開して完全なYAMLテンプレートを表示

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: pi
    spec:
      # The number of pods for the task. This number must be consistent with the number in JobNetworkTopology.
      parallelism: 2
      template:
        metadata:
          labels:
            # The number of pods for the task. This number must be consistent with the number in JobNetworkTopology.
            pod-group.scheduling.sigs.k8s.io/min-available: "2"
            pod-group.scheduling.sigs.k8s.io/name: sample-gang
            # Reference the task topology information just submitted.
            network-topology-job-name: sample-network-topology
            network-topology-job-namespace: sample-network-topology
        spec:
          schedulerName: default-scheduler
          containers:
          - name: pi
            image: perl:5.34.0
            command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
            resources:
              limits:
                # This example uses a single GPU. Adjust this number as needed for actual use cases.
                nvidia.com/gpu: 1
          restartPolicy: Never
      backoffLimit: 4
  4. 次のコマンドを実行して、YAMLファイルをクラスターにデプロイします。

    kubectl apply -f cluster-network-topology.yaml
    kubectl apply -f sample-network-topology.yaml
    kubectl apply -f pi.yaml

スケジューリング結果のデモ

  1. kubectlを使用してクラスターに接続し、ネットワークトポロジ情報を取得します。

    ACK Lingjunクラスターでは、lingjun-networktopology-collectorコンポーネントがこの情報を収集し、Lingjunノードにラベルを付けます。

    他のノードまたは異なるタイプのクラスターの場合、手動でラベルを追加し、ラベルキーが上記のYAMLテンプレートのClusterNetworkTopologyで指定されたlabelKeyに対応することを確認する必要があります。

    # Network topology is like:
    #              test-pod-1                     test-pod-2
    #        /          |           \                   |
    #    test-1      test-2      test-3               test-4
    #     /   \         |           |                   |
    #   0.12  0.14     0.15        0.16                0.17
    
    ➜  network kubectl get no -l alibabacloud.com/asw-id,alibabacloud.com/point-of-delivery -ojson | jq '.items[] | {"Name":.metadata.name, "ASW":.metadata.labels."alibabacloud.com/asw-id", "POD":.metadata.labels."alibabacloud.com/point-of-delivery"}'
    {
      "Name": "cn-hongkong.10.1.0.12",
      "ASW": "test-1",
      "POD": "test-pod-1"
    }
    {
      "Name": "cn-hongkong.10.1.0.14",
      "ASW": "test-1",
      "POD": "test-pod-1"
    }
    {
      "Name": "cn-hongkong.10.1.0.15",
      "ASW": "test-2",
      "POD": "test-pod-1"
    }
    {
      "Name": "cn-hongkong.10.1.0.16",
      "ASW": "test-3",
      "POD": "test-pod-1"
    }
    {
      "Name": "cn-hongkong.10.1.0.17",
      "ASW": "test-4",
      "POD": "test-pod-2"
    }
  2. 次のコマンドを実行して、設定済みのJobタスクを送信し、test-1内の2つのLingjunノードでの実行を確認します。

    ➜ kubectl get pod -owide
    NAME       READY   STATUS              RESTARTS   AGE   IP               NODE                    NOMINATED NODE   READINESS GATES
    pi-8p89l   1/1     Running             0          4s    172.30.240.197   cn-hongkong.10.1.0.14   <none>           <none>
    pi-p8swv   0/1     ContainerCreating   0          4s    <none>           cn-hongkong.10.1.0.12   <none>           <none>
    1. タスク内のポッド数を4に設定した場合、JobNetworkTopologyのYAML設定ファイルの並列処理パラメーターとpod-group.scheduling.sigs.k8s.io/min-availableパラメーター、およびJobNetworkTopologyのYAML設定ファイルのworkerNumパラメーターを更新する必要があります。

      これらの変更を行うと、test-pod-2を実行しているLingjunノードのみがスケジュールされていないことがわかります。

    ➜ kubectl get pod -owide
    NAME       READY   STATUS              RESTARTS   AGE   IP               NODE                    NOMINATED NODE   READINESS GATES
    pi-2kwq9   1/1     Running             0          4s    172.30.241.123   cn-hongkong.10.1.0.12   <none>           <none>
    pi-87hm5   0/1     ContainerCreating   0          4s    <none>           cn-hongkong.10.1.0.16   <none>           <none>
    pi-bsvx8   1/1     Running             0          4s    172.30.240.198   cn-hongkong.10.1.0.14   <none>           <none>
    pi-dvwhl   0/1     ContainerCreating   0          4s    <none>           cn-hongkong.10.1.0.15   <none>           <none>
    1. タスクのポッド数を5に設定した場合、JobNetworkTopologyのYAML設定ファイルの並列処理パラメーターとpod-group.scheduling.sigs.k8s.io/min-availableパラメーター、およびJobNetworkTopologyのYAML設定ファイルのworkerNumパラメーターを更新する必要があります。

      これらの変更を行うと、タスクのスケジューリングが失敗します。 スケジューリング失敗メッセージを含む最初のスケジュールドポッドは、MustGatherによるすべてのトポロジパスに失敗します。理由: [path:RootNode->test-pod-1, freeSlotNum:4], [path:RootNode->DefaultTopologyName, freeSlotNum:0], [path:RootNode->test-pod-2, freeSlotNum:1] このメッセージは、クロスポッドスケジューリングが許可されていないため、スケジューリングが失敗したことを示します。

      ➜ kubectl get pod
      NAME       READY   STATUS    RESTARTS   AGE
      pi-75qf5   0/1     Pending   0          2s
      pi-8k4nd   0/1     Pending   0          2s
      pi-b2pmc   0/1     Pending   0          2s
      pi-n7c2b   0/1     Pending   0          2s
      pi-wf4zn   0/1     Pending   0          2s
      
      
      ➜ kubectl get pod -ojson | jq '.items[].status'
      {
        "conditions": [
          {
            "lastProbeTime": null,
            "lastTransitionTime": "2024-05-29T07:46:27Z",
            "message": "0/6 nodes are available: 1 Insufficient nvidia.com/gpu, 1 [NetworkTopology begin] cluster total nodes:6, 5 node provide 5 freeSlot, 1 node unavailable cause Insufficient nvidia.com/gpu, job desireNum:5, all fail topology paths by MustGather reason: [path:RootNode->test-pod-1, freeSlotNum:4], [path:RootNode->DefaultTopologyName, freeSlotNum:0], [path:RootNode->test-pod-2, freeSlotNum:1] [NetworkTopology end], 4 NetworkTopology bestPlan empty. network topology job sample-network-topology/sample-network-topology gets rejected due to pod is unschedulable, preemption: 0/6 nodes are available: 1 No victims found on node cn-hongkong.10.1.0.10 for preemptor pod pi-75qf5, 5 Preemption is not helpful for scheduling..",
            "reason": "Unschedulable",
            "status": "False",
            "type": "PodScheduled"
          }
        ],
        "phase": "Pending",
        "qosClass": "BestEffort"
      }
      {
        "phase": "Pending",
        "qosClass": "BestEffort"
      }
      {
        "phase": "Pending",
        "qosClass": "BestEffort"
      }
      {
        "phase": "Pending",
        "qosClass": "BestEffort"
      }
      {
        "phase": "Pending",
        "qosClass": "BestEffort"
      }