全部產品
Search
文件中心

Container Service for Kubernetes:在ACK叢集上通過容器化部署並運行Slurm

更新時間:Dec 26, 2025

Container Service for Kubernetes (ACK)通過提供Slurm on Kubernetes解決方案及ack-slurm-operator應用組件,使得您能夠在阿里雲的ACK叢集上便捷、高效地部署和管理Slurm(Simple Linux Utility for Resource Management)調度系統,以適應Alibaba Cloud HPC和大規模AI/ML等情境。

Slurm介紹

Slurm是一個強大的開源叢集資源管理和作業調度平台,專門設計用於最佳化超級電腦和大型計算叢集的效能與效率。其核心組件協同工作,確保系統的高效運作和靈活的管理。Slurm的工作原理如下所示。

image
  • slurmctld(Slurm Control Daemon):作為Slurm的中央大腦,slurmctld負責監控系統資源、調度作業並管理整個叢集的狀態。為了增強系統的可靠性,可配置一個備用slurmctld實現高可用性,確保即使主控制器故障也不會中斷服務。

  • slurmd(Slurm Node Daemon):在每個計算節點上部署,slurmd守護進程負責接收來自slurmctld的指令,執行作業任務,包括作業的啟動、執行、狀態報表以及準備接受新的作業。它作為與計算資源直接互動的介面,是實現作業調度的基礎。

  • slurmdbd(Slurm Database Daemon):雖然是可選組件,但它能夠通過維護一個集中式資料庫來儲存作業歷史、記賬資訊等,這對於大規模叢集的長期管理和審計至關重要。支援跨多個Slurm管理叢集的資料整合,提升了資料管理的效率和便利性。

  • SlurmCLI:提供了一系列命令列工具,以便於作業管理與系統監控:

    • scontrol:用於叢集管理和配置的詳細控制。

    • squeue:查詢作業隊列狀態。

    • srun:用於提交和管理作業。

    • sbatch:用於提交批次工作的命令,可以協助您調度和管理計算資源。

    • sinfo:查看叢集的總體狀態,包括節點的可用性。

Slurm on ACK介紹

Slurm Operator通過SlurmCluster的自訂資源,解決了Slurm叢集管理需要的設定檔以及控制面管理問題,簡化了部署和營運Slurm叢集的複雜度。Slurm on ACK的架構如下圖所示。叢集管理員通過操作SlurmCluster即可輕鬆部署及管理Slurm叢集,SlurmOperator會根據SlurmCluster在叢集中建立出相應的Slurm管控組件。Slurm的設定檔可以通過共用儲存的方式掛載到管控組件中,也可以通過ConfigMap掛載。

image

前提條件

已建立包含一個GPU節點的叢集,且叢集版本需為1.22及以上。具體操作,請參見為叢集添加GPU節點升級叢集

步驟一:安裝ack-slurm-operator組件

  1. 登入Container Service管理主控台,在左側導覽列選擇市場 > 應用市場

  2. 應用市場頁面搜尋並單擊ack-slurm-operator卡片,然後在ack-slurm-operator的詳情頁面,單擊一鍵部署,並根據頁面提示完成組件配置。

    配置組件時,您只需要為組件選擇目的地組群,其他參數配置保持預設即可。

  3. 組件配置完成後,單擊確定

步驟二:建立SlurmCluster

手動建立

  1. 為ACK叢集建立用於Munge認證的Slurm Secret。

    1. 執行以下命令,使用OpenSSL工具產生一個密鑰。該密鑰用於Munge認證。

      openssl rand -base64 512 | tr -d '\r\n'
    2. 執行以下命令,建立一個Secret。該Secret用於儲存上一步產生的Munge密鑰。

      kubectl create secret generic <$MungeKeyName> --from-literal=munge.key=<$MungeKey>
      • <$MungeKeyName>需要替換為您自訂的密鑰名稱,例如mungekey

      • <$MungeKey>需要替換為上一步產生的密鑰字串。

    執行以上步驟後,SlurmCluster可以通過配置或關聯此Secret來擷取並使用該密鑰進行Munge認證。

  2. 執行以下命令,建立SlurmCluster需要使用的ConfigMap。

    本樣本通過在CR(Custom Resource)中指定slurmConfPath的方式將如下ConfigMap設定檔掛載到Pod中,這樣可以確保即使Pod因任何原因被重新建立,配置也能自動回復到預期狀態。

    代碼中的data參數為設定檔樣本。如果您需要組建組態檔案,推薦使用Easy ConfiguratorFull Configurator工具產生。

    展開查看命令詳情

    kubectl create -f - << EOF
    apiVersion: v1
    data:
      slurm.conf: |
        ProctrackType=proctrack/linuxproc
        ReturnToService=1
        SlurmctldPidFile=/var/run/slurmctld.pid
        SlurmctldPort=6817
        SlurmdPidFile=/var/run/slurmd.pid
        SlurmdPort=6818
        SlurmdSpoolDir=/var/spool/slurmd
        SlurmUser=root # test2
        StateSaveLocation=/var/spool/slurmctld
        TaskPlugin=task/none
        InactiveLimit=0
        KillWait=30
        MinJobAge=300
        SlurmctldTimeout=120
        SlurmdTimeout=300
        Waittime=0
        SchedulerType=sched/builtin
        SelectType=select/cons_tres
        JobCompType=jobcomp/none
        JobAcctGatherFrequency=30
        SlurmctldDebug=info
        SlurmctldLogFile=/var/log/slurmctld.log
        SlurmdDebug=info
        SlurmdLogFile=/var/log/slurmd.log
        TreeWidth=65533
        MaxNodeCount=10000
        PartitionName=debug Nodes=ALL Default=YES MaxTime=INFINITE State=UP
    
        ClusterName=slurm-job-demo
        # SlurmctldHost 應當設定為 slurmCluster 的 Name 加上 -0 尾碼,高可用部署時
        # 可以採用以下配置,數量取決於slurmctld的副本數量:
        # SlurmctldHost=slurm-job-demo-0
        # SlurmctldHost=slurm-job-demo-1
        SlurmctldHost=slurm-job-demo-0
    kind: ConfigMap
    metadata:
      name: slurm-test
      namespace: default
    EOF

    預期輸出:

    configmap/slurm-test created

    預期輸出表明,ConfigMap已建立成功。

  3. 提交SlurmCluster CR。

    1. 複製並粘貼如下內容,用於建立slurmcluster.yaml,程式碼範例如下。

      說明

      樣本中使用的鏡像是使用Ubuntu製作的、包含了CUDA 11.4以及Slurm 23.06版本的鏡像,其中包含了自研的支援Cloud Node(叢集中狀態為Cloud的節點)動態擴縮容功能的組件。如果您需要自訂鏡像,您可以自行進行鏡像製作以及上傳。

      展開查看YAML樣本

      # 這是一個Kubernetes設定檔,用於部署一個Slurm叢集在阿里雲ACK上,通過Kai的自訂資源定義(CRD)實現。
      apiVersion: kai.alibabacloud.com/v1
      kind: SlurmCluster
      metadata:
        name: slurm-job-demo # 叢集的名稱。
        namespace: default # 部署的命名空間。
      spec:
        mungeConfPath: /var/munge # Munge服務的設定檔路徑。
        slurmConfPath: /var/slurm #  # Slurm服務的設定檔路徑。
        slurmctld: # 主節點(控制節點)規格設定。控制器將會為主節點建立一個StatefulSet進行控制。
          template:
            metadata: {}
            spec:
              containers:
              - image: registry-cn-hangzhou.ack.aliyuncs.com/acs/slurm-cuda:23.06-aliyun-cuda-11.4
                imagePullPolicy: Always
                name: slurmctld
                ports:
                - containerPort: 8080
                  protocol: TCP
                resources:
                  requests:
                    cpu: "1"
                    memory: 1Gi
                volumeMounts:
                - mountPath: /var/slurm # Slurm設定檔掛載點。
                  name: config-slurm-test
                - mountPath: /var/munge # Munge密鑰檔案掛載點。
                  name: secret-slurm-test 
              volumes:
              - configMap:
                  name: slurm-test
                name: config-slurm-test
              - name: secret-slurm-test
                secret:
                  secretName: slurm-test
        workerGroupSpecs: # 工作節點規格設定,這裡定義了兩個組:cpu和cpu1
        - groupName: cpu
          replicas: 2
          template:
            metadata: {}
            spec:
              containers:
              - env:
                - name: NVIDIA_REQUIRE_CUDA
                image: registry-cn-hangzhou.ack.aliyuncs.com/acs/slurm-cuda:23.06-aliyun-cuda-11.4
                imagePullPolicy: Always
                name: slurmd
                resources:
                  requests:
                    cpu: "1"
                    memory: 1Gi
                volumeMounts:
                - mountPath: /var/slurm
                  name: config-slurm-test
                - mountPath: /var/munge
                  name: secret-slurm-test
              volumes:
              - configMap:
                  name: slurm-test
                name: config-slurm-test
              - name: secret-slurm-test
                secret:
                  secretName: slurm-test
        - groupName: cpu1 # 第二個工作節點群組定義,與第一個相似,但可以根據需要調整資源或配置。
          replicas: 2
          template:
            metadata: {}
            spec:
              containers:
              - env:
                - name: NVIDIA_REQUIRE_CUDA
                image: registry-cn-hangzhou.ack.aliyuncs.com/acs/slurm-cuda:23.06-aliyun-cuda-11.4
                imagePullPolicy: Always
                name: slurmd
                resources:
                  requests:
                    cpu: "1"
                    memory: 1Gi
                securityContext: # 此處添加了安全上下文配置,允許容器以特權模式運行。
                  privileged: true
                volumeMounts:
                - mountPath: /var/slurm
                  name: config-slurm-test
                - mountPath: /var/munge
                  name: secret-slurm-test
              volumes:
              - configMap:
                  name: slurm-test
                name: config-slurm-test
              - name: secret-slurm-test
                secret:
                  secretName: slurm-test

      使用以上SlurmCluster CR將會建立出帶有1個Head Node和4個Worker的SlurmCluster(SlurmCluster作為Pod運行在ACK叢集中)。需要注意的是,SlurmCluster CR中指定的mungeConfPath以及slurmConfPath需要與HeadGroupTemplate以及各WorkerGroupTemplate中相關檔案的掛載路徑相同。

    2. 執行以下命令,部署slurmcluster.yaml到叢集

      kubectl apply -f slurmcluster.yaml

      預期輸出:

      slurmcluster.kai.alibabacloud.com/slurm-job-demo created
    3. 執行以下命令,查看已建立出的SlurmCluster是否正常運行。

      kubectl get slurmcluster

      預期輸出:

      NAME             AVAILABLE WORKERS   STATUS   AGE
      slurm-job-demo   5                   ready    14m

      輸出結果表明SlurmCluster已成功部署,並且有5個節點均處於就緒狀態。

    4. 執行以下命令,查看名為slurm-job-demo的SlurmCluster中的Pods是否處於Running狀態。

      kubectl get pod

      預期輸出:

      NAME                                          READY   STATUS      RESTARTS     AGE
      slurm-job-demo-head-x9sgs                     1/1     Running     0            14m
      slurm-job-demo-worker-cpu-0                   1/1     Running     0            14m
      slurm-job-demo-worker-cpu-1                   1/1     Running     0            14m
      slurm-job-demo-worker-cpu1-0                  1/1     Running     0            14m
      slurm-job-demo-worker-cpu1-1                  1/1     Running     0            14m

      輸出結果表明SlurmCluster中的1個Head Node和4個Worker均正常運行。

使用Helm建立

如需快速安裝、管理SlurmCluster,以及靈活調整叢集配置,您可以使用Helm軟體包管理器來部署阿里雲提供的SlurmCluster Chart。從charts-incubator(阿里雲的Chart倉庫)中下載由阿里雲封裝好的SlurmCluster的Helm,設定好相應的參數後,Helm會協助您建立出RBAC、ConfigMap、Secret以及SlurmCluster等資源。

Helm Chart中包含以下資源:

資源類型

資源名稱

功能及用途

ConfigMap

{{ .Values.slurmConfigs.configMapName }}

當.Values.slurmConfigs.createConfigsByConfigMap為True時建立該ConfigMap,用於儲存使用者定義的Slurm設定檔。該設定檔會被掛載到.Values.slurmConfigs.slurmConfigPathInPod的路徑中(該路徑會被渲染到SlurmCluster的.Spec.SlurmConfPath中,最終被渲染到Pod的啟動命令中),在Pod啟動時被複製到/etc/slurm/路徑下並設定存取權限。

ServiceAccount

{{ .Release.Namespace }}/{{ .Values.clusterName }}

允許SlurmCtld所在的Pod修改SlurmCluster,用於SlurmCluster使用CloudNode功能自動擴縮容的情境中。

Role

{{ .Release.Namespace }}/{{ .Values.clusterName }}

允許SlurmCtld所在的Pod修改SlurmCluster,用於SlurmCluster使用CloudNode功能自動擴縮容的情境中。

RoleBinding

{{ .Release.Namespace }}/{{ .Values.clusterName }}

允許SlurmCtld所在的Pod修改SlurmCluster,用於SlurmCluster使用CloudNode功能自動擴縮容的情境中。

Role

{{ .Values.slurmOperatorNamespace }}/{{ .Values.clusterName }}

允許SlurmCtld所在的Pod修改SlurmOperator命名空間下的Secrets,用於SlurmCluster與Kubernetes混部情境下SlurmCluster更新Token使用。

RoleBinding

{{ .Values.slurmOperatorNamespace }}/{{ .Values.clusterName }}

允許SlurmCtld所在的Pod修改SlurmOperator命名空間下的Secrets,用於SlurmCluster與Kubernetes混部情境下SlurmCluster更新Token使用。

Secret

{{ .Values.mungeConfigs.secretName }}

用於Slurm組件之間的認證,當.Values.mungeConfigs.createConfigsBySecret為True時會自動建立,內容即為"munge.key"={{ .Values.mungeConfigs.content }}。.Values.mungeConfigs.createConfigsBySecret為True時.Values.mungeConfigs.createConfigsBySecret會被渲染為.Spec.MungeConfPath,最終被渲染為Pod的掛載路徑。Pod的啟動命令中會根據該路徑初始化/etc/munge/munge.key。

SlurmCluster

渲染出的SlurmCluster

相關的參數以及說明可參考下表:

參數

參考值

用途

clusterName

""

叢集名稱,被用於Secret、Role等資源產生,需要與後續Slurm設定檔中的ClusterName對應。

headNodeConfig

必須存在。申明Slurmctld的Pod的相關配置。

workerNodesConfig

申明Slurmd的Pod的相關配置。

workerNodesConfig.deleteSelfBeforeSuspend

true

該值為true時,為workerPod自動添加preStopHook,用於節點下線前自動排水並將節點標記為下線狀態。

slurmdbdConfigs

申明Slurmdbd的Pod的相關配置,不存在該值時,將不會建立Slurmdbd的對應Pod。

slurmrestdConfigs

申明Slurmrestd的Pod的相關配置,不存在該值時,將不會建立Slurmrestd的對應Pod。

headNodeConfig.hostNetwork

slurmdbdConfigs.hostNetwork

slurmrestdConfigs.hostNetwork

workerNodesConfig.workerGroups[].hostNetwork

false

渲染為Slurmctld的Pod的hostNetwork。

headNodeConfig.setHostnameAsFQDN

slurmdbdConfigs.setHostnameAsFQDN

slurmrestdConfigs.setHostnameAsFQDN

workerNodesConfig.workerGroups[].setHostnameAsFQDN

false

渲染為Slurmctld的Pod的setHostnameAsFQDN。

headNodeConfig.nodeSelector

slurmdbdConfigs.nodeSelector

slurmrestdConfigs.nodeSelector

workerNodesConfig.workerGroups[].nodeSelector

nodeSelector:
  example: example

渲染為Slurmctld的Pod的NodeSelector。

headNodeConfig.tolerations

slurmdbdConfigs.tolerations

slurmrestdConfigs.tolerations

workerNodesConfig.workerGroups[].tolerations

tolerations:
- key:
  value:
  operator:

渲染為Slurmctld的Pod的Toleration。

headNodeConfig.affinity

slurmdbdConfigs.affinity

slurmrestdConfigs.affinity

workerNodesConfig.workerGroups[].affinity

affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: topology.kubernetes.io/zone
          operator: In
          values:
          - zone-a
    preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 1
      preference:
        matchExpressions:
        - key: another-node-label-key
          operator: In
          values:
          - another-node-label-value

渲染為Slurmctld的Pod的Affinity。

headNodeConfig.resources

slurmdbdConfigs.resources

slurmrestdConfigs.resources

workerNodesConfig.workerGroups[].resources

resources:
  requests:
    cpu: 1
  limits:
    cpu: 1

渲染為Slurmctld的主容器的資源。WorkerPod的主容器的資源限制會被渲染成為slurm節點的資源上限。

headNodeConfig.image

slurmdbdConfigs.image

slurmrestdConfigs.image

workerNodesConfig.workerGroups[].image

"registry-cn-hangzhou.ack.aliyuncs.com/acs/slurm:23.06-1.6-aliyun-49259f59"

渲染為Slurmctld的鏡像。如需使用自訂鏡像請參考ai-models-on-ack/framework/slurm/building-slurm-image at main · AliyunContainerService/ai-models-on-ack (github.com)

headNodeConfig.imagePullSecrets

slurmdbdConfigs.imagePullSecrets

slurmrestdConfigs.imagePullSecrets

workerNodesConfig.workerGroups[].imagePullSecrets

imagePullSecrets:
- name: example

渲染為Slurmctld的鏡像拉取密鑰。

headNodeConfig.podSecurityContext

slurmdbdConfigs.podSecurityContext

slurmrestdConfigs.podSecurityContext

workerNodesConfig.workerGroups[].podSecurityContext

podSecurityContext:
  runAsUser: 1000
  runAsGroup: 3000
  fsGroup: 2000
  supplementalGroups: [4000]

渲染為Slurmctld的SecurityContext。

headNodeConfig.securityContext

slurmdbdConfigs.securityContext

slurmrestdConfigs.securityContext

workerNodesConfig.workerGroups[].securityContext

securityContext:
  allowPrivilegeEscalation: false

渲染為Slurmctld的主容器的SecurityContext。

headNodeConfig.volumeMounts

slurmdbdConfigs.volumeMounts

slurmrestdConfigs.volumeMounts

workerNodesConfig.workerGroups[].volumeMounts

渲染為Slurmctld的主容器的卷掛載。

headNodeConfig.volumes

slurmdbdConfigs.volumes

slurmrestdConfigs.volumes

workerNodesConfig.workerGroups[].volumes

渲染為Slurmctld的Pod的卷。

slurmConfigs.slurmConfigPathInPod

""

slurm相關配置在Pod中的掛載位置。當Slurm的相關設定檔是通過Volume掛載進入Pod時。需要通過該項聲明slurm.conf的位置。Pod的啟動命令中會將該路徑下的檔案複製到/etc/slurm/下並設定對應許可權。

slurmConfigs.createConfigsByConfigMap

true

是否自動建立儲存Slurm設定檔的Configmap。

slurmConfigs.configMapName

""

儲存Slurm設定檔的Configmap的資源名稱。

slurmConfigs.filesInConfigMap

""

自動建立儲存Slurm設定檔的Configmap時設定檔的內容。

mungeConfigs.mungeConfigPathInPod

munge相關配置在Pod中的掛載位置。當munge的相關設定檔是通過Volume掛載進入Pod時。需要通過該項聲明munge.key的位置。Pod的啟動命令中會將該路徑下的檔案複製到/etc/munge/下並設定對應許可權。

mungeConfigs.createConfigsBySecret

是否自動建立儲存munge設定檔的Secret。

mungeConfigs.secretName

自動建立儲存munge設定檔的Secret時的資源名稱。

mungeConfigs.content

自動建立儲存munge設定檔的Secret時設定檔的內容。

其中slurmConfigs.filesInConfigMap的內容可以參考Slurm System Configuration Tool (schedmd.com)

重要

Pod啟動後修改slurmConfigs.filesInConfigMap的情況下,需要重建Pod應用新的設定檔,故請提前確認設定檔中的內容。

通過Helm Chart安裝的具體操作如下所示:

  1. 執行以下命令,將阿里雲Helm倉庫添加到您的本地Helm用戶端。

    helm repo add aliyun https://aliacs-app-catalog.oss-cn-hangzhou.aliyuncs.com/charts-incubator/

    該操作將允許您訪問阿里雲提供的各種Charts,包括Slurm Cluster。

  2. 執行以下命令,拉取並解壓Helm Chart。

    helm pull aliyun/ack-slurm-cluster --untar=true

    該操作將會在目前的目錄下建立一個名為ack-slurm-cluster的目錄,其中包含了Chart的所有檔案和模板。

  3. 執行以下命令,在名為values.yaml的檔案中修改Chart參數。

    values.yaml檔案包含了Chart的預設配置。您可以根據您的實際需求通過編輯這個檔案來修改參數。例如Slurm的配置、資源請求與限制、儲存等。

    cd ack-slurm-cluster
    vi values.yaml
  4. 使用Helm安裝Chart。

    cd ..
    helm install my-slurm-cluster ack-slurm-cluster # my-slurm-cluster可以根據實際情況變更。

    該操作將會部署Slurm Cluster。

  5. 驗證部署

    部署完成後,可以通過Kubernetes的命令列工具kubectl來檢查部署狀態,確保Slurm Cluster已經成功啟動並且運行正常。

    kubectl get pods -l app.kubernetes.io/name=slurm-cluster

步驟三:登入SlurmCluster

Kubernetes叢集管理員

由於叢集管理員擁有Kubernetes叢集的操作許可權,SlurmCluster對於Kubernetes叢集管理員來說是一個運行在叢集中的Pod,因此Kubernetes叢集管理員可以使用kubectl命令列工具登入到叢集中任意SlurmCluster的任意Pod上,且將自動擁有SlurmCluster的Root使用者的許可權。

執行以下命令,可以登入到SlurmCluster的任意Pod上。

# 將slurm-job-demo-head-x9sgs替換成您叢集中具體的Pod名。
kubectl exec -it slurm-job-demo-xxxxx -- bash

SlurmCluster普通使用者

SlurmCluster的管理員或SlurmCluster的普通使用者可能沒有kubectl exec命令的許可權,在使用叢集時需要通過SSH登入的方式登入到已建立的SlurmCluster中。

  • 通過Service的ExternalIP登入Head Pod是更持久和可擴充的方案,適合需要長期穩定訪問的情境。通過負載平衡器和External IP,可以從內網的任何位置訪問到SlurmCluster。

  • 通過Port-forward轉寄請求是臨時性的解決方案,適用於短期營運或調試需求,因為它依賴於持續啟動並執行kubectl port-forward命令。

通過Service的External IP登入Head Pod

  1. 建立一個LoadBalancer類型的Service,用於流量轉寄(使叢集內部服務可由外部存取)。具體操作,請參見通過使用已有負載平衡的服務暴露應用通過使用自動建立負載平衡的服務公開應用

    • Service需使用私網CLB。

    • 需要為該Service設定標籤kai.alibabacloud.com/slurm-cluster: ack-slurm-cluster-1kai.alibabacloud.com/slurm-node-type: head,以便它能夠路由到正確的Pod。

  2. 執行以下命令,擷取LoadBalancer類型Service的External IP。

    kubectl get svc
  3. 執行以下命令,通過SSH登入到服務對應的Head Pod。

    # $YOURUSER請替換為實際Pod中的使用者名稱,$EXTERNAL_IP請替換為從Service擷取的外部IP地址。
    ssh $YOURUSER@$EXTERNAL_IP

通過Port-forward轉寄請求

警告

Port-forward方式需要在本地儲存Kubernetes叢集的KubeConfig,存在一定的安全風險,不建議在生產環境中使用此方法。

  1. 執行以下命令,在本地機器上開啟一個連接埠轉寄,將本地的$LOCALPORT映射到叢集內slurmctld Pod的22連接埠(SSH服務預設連接埠)。

    # 將$NAMESPACE、$CLUSTERNAME和$LOCALPORT替換為實際值。
    kubectl port-forward -n $NAMESPACE svc/$CLUSTERNAME $LOCALPORT:22
  2. port-forward命令沒有結束的情況下,執行以下命令,當前機器上的所有使用者均可以登入到叢集中提交任務。

    # $YOURUSER是Pod中您想要登入的使用者名稱。
    ssh -p $LOCALPORT $YOURUSER@localhost

步驟四:使用SlurmCluster

以下介紹如何在SlurmCluster中實現節點間的使用者同步、節點間的日誌共用以及叢集自動擴縮容配置。

節點間的使用者同步

由於Slurm本身不提供集中化的使用者認證服務,當使用sbatch提交作業至SlurmCluster時,如果目標節點上沒有與提交作業使用者對應的賬戶,作業可能無法執行。為解決該問題,您可以通過為SlurmCluster配置LDAP(Lightweight Directory Access Protocol)進行使用者管理,利用LDAP作為一個集中認證的後端,讓Slurm能夠依託此服務驗證使用者身份。具體操作如下所示:

  1. 拷貝以下YAML內容至ldap.yaml檔案中,建立一個基礎的LDAP服務執行個體,用於儲存和系統管理使用者資訊。

    ldap.yaml檔案定義了一個LDAP後端Pod和對應的Service。Pod包含LDAP服務的容器,而Service則暴露了LDAP服務,使其在網路中可訪問。

    展開查看LDAP後端Pod和對應的Service

    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      namespace: default
      name: ldap
      labels:
        app: ldap
    spec:
      selector:
        matchLabels:
          app: ldap
      revisionHistoryLimit: 10
      template:
        metadata:
          labels:
            app: ldap
        spec:
          securityContext:
            seLinuxOptions: {}
          imagePullSecrets: []
          restartPolicy: Always
          initContainers: []
          containers:
            - image: 'osixia/openldap:1.4.0'
              imagePullPolicy: IfNotPresent
              name: ldap
              volumeMounts:
                - name: openldap-data
                  mountPath: /var/lib/ldap
                  subPath: data
                - name: openldap-data
                  mountPath: /etc/ldap/slapd.d
                  subPath: config
                - name: openldap-data
                  mountPath: /container/service/slapd/assets/certs
                  subPath: certs
                - name: secret-volume
                  mountPath: /container/environment/01-custom
                - name: container-run
                  mountPath: /container/run
              args:
                - '--copy-service'
              resources:
                limits:
                requests:
              env: []
              readinessProbe:
                tcpSocket:
                  port: openldap
                initialDelaySeconds: 20
                timeoutSeconds: 1
                periodSeconds: 10
                successThreshold: 1
                failureThreshold: 10
              livenessProbe:
                tcpSocket:
                  port: openldap
                initialDelaySeconds: 20
                timeoutSeconds: 1
                periodSeconds: 10
                successThreshold: 1
                failureThreshold: 10
              lifecycle: {}
              ports:
                - name: openldap
                  containerPort: 389
                  protocol: TCP
                - name: ssl-ldap-port
                  containerPort: 636
                  protocol: TCP
          volumes:
            - name: openldap-data
              emptyDir: {}
            - name: secret-volume
              secret:
                secretName: ldap-secret
                defaultMode: 420
                items: []
            - name: container-run
              emptyDir: {}
          dnsPolicy: ClusterFirst
          dnsConfig: {}
          terminationGracePeriodSeconds: 30
      progressDeadlineSeconds: 600
      strategy:
        type: RollingUpdate
        rollingUpdate:
          maxUnavailable: 25%
          maxSurge: 25%
      replicas: 1
    ---
    apiVersion: v1
    kind: Service
    metadata:
      annotations: {}
      labels:
        app: ldap
      name: ldap-service
      namespace: default
    spec:
      ports:
        - name: openldap
          port: 389
          protocol: TCP
          targetPort: openldap
        - name: ssl-ldap-port
          port: 636
          protocol: TCP
          targetPort: ssl-ldap-port
      selector:
        app: ldap
      sessionAffinity: None
      type: ClusterIP
    ---
    metadata:
      name: ldap-secret
      namespace: default
      annotations: {}
    data:
      env.startup.yaml: >-
        IyBUaGlzIGlzIHRoZSBkZWZhdWx0IGltYWdlIHN0YXJ0dXAgY29uZmlndXJhdGlvbiBmaWxlCiMgdGhpcyBmaWxlIGRlZmluZSBlbnZpcm9ubWVudCB2YXJpYWJsZXMgdXNlZCBkdXJpbmcgdGhlIGNvbnRhaW5lciAqKmZpcnN0IHN0YXJ0KiogaW4gKipzdGFydHVwIGZpbGVzKiouCgojIFRoaXMgZmlsZSBpcyBkZWxldGVkIHJpZ2h0IGFmdGVyIHN0YXJ0dXAgZmlsZXMgYXJlIHByb2Nlc3NlZCBmb3IgdGhlIGZpcnN0IHRpbWUsCiMgYWZ0ZXIgdGhhdCBhbGwgdGhlc2UgdmFsdWVzIHdpbGwgbm90IGJlIGF2YWlsYWJsZSBpbiB0aGUgY29udGFpbmVyIGVudmlyb25tZW50LgojIFRoaXMgaGVscHMgdG8ga2VlcCB5b3VyIGNvbnRhaW5lciBjb25maWd1cmF0aW9uIHNlY3JldC4KIyBtb3JlIGluZm9ybWF0aW9uIDogaHR0cHM6Ly9naXRodWIuY29tL29zaXhpYS9kb2NrZXItbGlnaHQtYmFzZWltYWdlCgojIFJlcXVpcmVkIGFuZCB1c2VkIGZvciBuZXcgbGRhcCBzZXJ2ZXIgb25seQpMREFQX09SR0FOSVNBVElPTjogRXhhbXBsZSBJbmMuCkxEQVBfRE9NQUlOOiBleGFtcGxlLm9yZwpMREFQX0JBU0VfRE46ICNpZiBlbXB0eSBhdXRvbWF0aWNhbGx5IHNldCBmcm9tIExEQVBfRE9NQUlOCgpMREFQX0FETUlOX1BBU1NXT1JEOiBhZG1pbgpMREFQX0NPTkZJR19QQVNTV09SRDogY29uZmlnCgpMREFQX1JFQURPTkxZX1VTRVI6IGZhbHNlCkxEQVBfUkVBRE9OTFlfVVNFUl9VU0VSTkFNRTogcmVhZG9ubHkKTERBUF9SRUFET05MWV9VU0VSX1BBU1NXT1JEOiByZWFkb25seQoKIyBCYWNrZW5kCkxEQVBfQkFDS0VORDogaGRiCgojIFRscwpMREFQX1RMUzogdHJ1ZQpMREFQX1RMU19DUlRfRklMRU5BTUU6IGxkYXAuY3J0CkxEQVBfVExTX0tFWV9GSUxFTkFNRTogbGRhcC5rZXkKTERBUF9UTFNfQ0FfQ1JUX0ZJTEVOQU1FOiBjYS5jcnQKCkxEQVBfVExTX0VORk9SQ0U6IGZhbHNlCkxEQVBfVExTX0NJUEhFUl9TVUlURTogU0VDVVJFMjU2Oi1WRVJTLVNTTDMuMApMREFQX1RMU19QUk9UT0NPTF9NSU46IDMuMQpMREFQX1RMU19WRVJJRllfQ0xJRU5UOiBkZW1hbmQKCiMgUmVwbGljYXRpb24KTERBUF9SRVBMSUNBVElPTjogZmFsc2UKIyB2YXJpYWJsZXMgJExEQVBfQkFTRV9ETiwgJExEQVBfQURNSU5fUEFTU1dPUkQsICRMREFQX0NPTkZJR19QQVNTV09SRAojIGFyZSBhdXRvbWF0aWNhbHkgcmVwbGFjZWQgYXQgcnVuIHRpbWUKCiMgaWYgeW91IHdhbnQgdG8gYWRkIHJlcGxpY2F0aW9uIHRvIGFuIGV4aXN0aW5nIGxkYXAKIyBhZGFwdCBMREFQX1JFUExJQ0FUSU9OX0NPTkZJR19TWU5DUFJPViBhbmQgTERBUF9SRVBMSUNBVElPTl9EQl9TWU5DUFJPViB0byB5b3VyIGNvbmZpZ3VyYXRpb24KIyBhdm9pZCB1c2luZyAkTERBUF9CQVNFX0ROLCAkTERBUF9BRE1JTl9QQVNTV09SRCBhbmQgJExEQVBfQ09ORklHX1BBU1NXT1JEIHZhcmlhYmxlcwpMREFQX1JFUExJQ0FUSU9OX0NPTkZJR19TWU5DUFJPVjogYmluZGRuPSJjbj1hZG1pbixjbj1jb25maWciIGJpbmRtZXRob2Q9c2ltcGxlIGNyZWRlbnRpYWxzPSRMREFQX0NPTkZJR19QQVNTV09SRCBzZWFyY2hiYXNlPSJjbj1jb25maWciIHR5cGU9cmVmcmVzaEFuZFBlcnNpc3QgcmV0cnk9IjYwICsiIHRpbWVvdXQ9MSBzdGFydHRscz1jcml0aWNhbApMREFQX1JFUExJQ0FUSU9OX0RCX1NZTkNQUk9WOiBiaW5kZG49ImNuPWFkbWluLCRMREFQX0JBU0VfRE4iIGJpbmRtZXRob2Q9c2ltcGxlIGNyZWRlbnRpYWxzPSRMREFQX0FETUlOX1BBU1NXT1JEIHNlYXJjaGJhc2U9IiRMREFQX0JBU0VfRE4iIHR5cGU9cmVmcmVzaEFuZFBlcnNpc3QgaW50ZXJ2YWw9MDA6MDA6MDA6MTAgcmV0cnk9IjYwICsiIHRpbWVvdXQ9MSBzdGFydHRscz1jcml0aWNhbApMREFQX1JFUExJQ0FUSU9OX0hPU1RTOgogIC0gbGRhcDovL2xkYXAuZXhhbXBsZS5vcmcgIyBUaGUgb3JkZXIgbXVzdCBiZSB0aGUgc2FtZSBvbiBhbGwgbGRhcCBzZXJ2ZXJzCiAgLSBsZGFwOi8vbGRhcDIuZXhhbXBsZS5vcmcKCgojIFJlbW92ZSBjb25maWcgYWZ0ZXIgc2V0dXAKTERBUF9SRU1PVkVfQ09ORklHX0FGVEVSX1NFVFVQOiB0cnVlCgojIGNmc3NsIGVudmlyb25tZW50IHZhcmlhYmxlcyBwcmVmaXgKTERBUF9DRlNTTF9QUkVGSVg6IGxkYXAgIyBjZnNzbC1oZWxwZXIgZmlyc3Qgc2VhcmNoIGNvbmZpZyBmcm9tIExEQVBfQ0ZTU0xfKiB2YXJpYWJsZXMsIGJlZm9yZSBDRlNTTF8qIHZhcmlhYmxlcy4K
      env.yaml: >-
        IyBUaGlzIGlzIHRoZSBkZWZhdWx0IGltYWdlIGNvbmZpZ3VyYXRpb24gZmlsZQojIFRoZXNlIHZhbHVlcyB3aWxsIHBlcnNpc3RzIGluIGNvbnRhaW5lciBlbnZpcm9ubWVudC4KCiPCoEFsbCBlbnZpcm9ubWVudCB2YXJpYWJsZXMgdXNlZCBhZnRlciB0aGUgY29udGFpbmVyIGZpcnN0IHN0YXJ0CiMgbXVzdCBiZSBkZWZpbmVkIGhlcmUuCiMgbW9yZSBpbmZvcm1hdGlvbiA6IGh0dHBzOi8vZ2l0aHViLmNvbS9vc2l4aWEvZG9ja2VyLWxpZ2h0LWJhc2VpbWFnZQoKIyBHZW5lcmFsIGNvbnRhaW5lciBjb25maWd1cmF0aW9uCiMgc2VlIHRhYmxlIDUuMSBpbiBodHRwOi8vd3d3Lm9wZW5sZGFwLm9yZy9kb2MvYWRtaW4yNC9zbGFwZGNvbmYyLmh0bWwgZm9yIHRoZSBhdmFpbGFibGUgbG9nIGxldmVscy4KTERBUF9MT0dfTEVWRUw6IDI1Ngo=
    type: Opaque
    kind: Secret
    apiVersion: v1
    
  2. 執行以下命令,部署LDAP後端服務。

    kubectl apply -f ldap.yaml

    預期輸出:

    deployment.apps/ldap created
    service/ldap-service created
    secret/ldap-secret created
  3. (可選)拷貝以下YAML內容至phpldapadmin.yaml檔案中,部署一個前端Pod和Service,用於配置前端介面以提升管理效率。

    展開查看LDAP前端Pod和對應的Service

    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      namespace: default
      name: phpldapadmin
      labels:
        io.kompose.service: phpldapadmin
    spec:
      selector:
        matchLabels:
          io.kompose.service: phpldapadmin
      revisionHistoryLimit: 10
      template:
        metadata:
          labels:
            io.kompose.service: phpldapadmin
        spec:
          securityContext:
            seLinuxOptions: {}
          imagePullSecrets: []
          restartPolicy: Always
          initContainers: []
          containers:
            - image: 'osixia/phpldapadmin:0.9.0'
              imagePullPolicy: Always
              name: phpldapadmin
              volumeMounts: []
              resources:
                limits:
                requests:
              env:
                - name: PHPLDAPADMIN_HTTPS
                  value: 'false'
                - name: PHPLDAPADMIN_LDAP_HOSTS
                  value: ldap-service
              lifecycle: {}
              ports:
                - containerPort: 80
                  protocol: TCP
          volumes: []
          dnsPolicy: ClusterFirst
          dnsConfig: {}
          terminationGracePeriodSeconds: 30
      progressDeadlineSeconds: 600
      strategy:
        type: RollingUpdate
        rollingUpdate:
          maxUnavailable: 25%
          maxSurge: 25%
      replicas: 1
    ---
    apiVersion: v1
    kind: Service
    metadata:
      namespace: default
      name: phpldapadmin
      annotations:
        k8s.kuboard.cn/workload: phpldapadmin
      labels:
        io.kompose.service: phpldapadmin
    spec:
      selector:
        io.kompose.service: phpldapadmin
      type: ClusterIP
      ports:
        - port: 8080
          targetPort: 80
          protocol: TCP
          name: '8080'
          nodePort: 0
      sessionAffinity: None

    執行以下命令,部署LDAP前端服務。

    kubectl apply -f phpldapadmin.yaml
  4. 按照步驟三的操作登入到SlurmCluster的具體Pod中,執行以下命令,安裝LDAP用戶端軟體包。

    apt update
    apt install libnss-ldapd
  5. 安裝完libnss-ldapd軟體包後,在Pod中配置SlurmCluster的網路認證服務。

    1. 執行以下命令,安裝vim軟體包,用於後續編輯指令碼和檔案。

      apt update
      apt install vim
    2. 在/etc/ldap/ldap.conf檔案中編輯如下參數,配置LDAP用戶端。

      ...
      BASE	dc=example,dc=org # 替換為您的LDAP基礎DN。
      URI	ldap://ldap-service # 替換為您的LDAP伺服器位址。
      ...
    3. 在/etc/nslcd.conf檔案中編輯如下參數,定義串連到LDAP伺服器。

      ...
      uri ldap://ldap-service # 替換為實際的LDAP伺服器位址。
      base dc=example,dc=org # 應根據你的LDAP目錄結構進行設定。
      ...
      tls_cacertfile /etc/ssl/certs/ca-certificates.crt # 指定CA認證檔案的路徑,用於驗證LDAP伺服器的認證。
      ...

日誌共用與訪問

預設情況下,使用sbatch產生的作業日誌直接被儲存在執行任務的節點上,給查看日誌帶來了不便。為了方便查看日誌,您可以通過建立NAS檔案系統,將所有的作業日誌統一儲存在一個可訪問的位置。這樣即使計算任務在不同的節點上執行,它們產生的日誌都能被統一收集和儲存,從而提升了日誌管理的便利性。具體操作如下所示。

  1. 建立一個NAS檔案系統,這個檔案系統將用於儲存和共用各節點的日誌。具體操作,請參見建立檔案系統

  2. 登入Container Service管理主控台建立NAS的相關PV(Persistent Volume)和PVC(Persistent Volume Claim)。具體操作,請參見使用NAS靜態儲存卷

  3. 修改SlurmCluster CR。

    headGroupSpec和每個workerGroupSpec添加volumeMountsvolumes參數配置引用已建立的PVC,將其掛載到/home目錄下。樣本如下:

    headGroupSpec:
    ...
    # 新增對於/home的掛載。
      volumeMounts:
      - mountPath: /home
        name: test  # 這裡為引用PVC的volume名稱。
      volumes:
    # 添加PVC的定義。
      - name: test  # 這裡需要與volumeMounts中的name匹配。
        persistentVolumeClaim:
          claimName: test  # 這裡替換實際PVC的名稱。
    ...
    workerGroupSpecs:
      # ... 對於每個workerGroupSpec重複上述volume和volumeMounts的添加過程。
  4. 執行以下命令,部署SlurmCluster CR資源。

    重要

    如果SlurmCluster CR資源部署失敗,請執行kubectl delete slurmcluster slurm-job-demo命令刪除CR資源,然後重新部署即可成功。

    kubectl  apply -f slurmcluster.yaml

    部署後即可在不同的工作節點中擁有相同的檔案系統。

叢集自動擴縮容

在預設提供的Slurm鏡像的根路徑下包含slurm-resume.shslurm-suspend.sh以及slurmctld-copilot等可執行檔和指令碼,它們負責與slurmctld互動以進行叢集的擴縮容。

基於CloudNode的Slurm叢集自動擴縮容原理

  • Local Nodes:指直接連接到叢集管理器、物理存在的計算節點。

  • Cloud Nodes:邏輯上存在的節點,代表可通過雲端服務供應商按需建立和銷毀的虛擬機器執行個體。

image

Slurm on ACK自動擴縮容原理

image

操作步驟

  1. 配置自動擴縮容許可權(Helm安裝時會自動建立Slurmctld的擴縮容許可權,該步驟可以跳過)。

    自動擴縮容需要從Head Pod中能夠訪問並更新SlurmCluster CR,因此建議您在使用該能力時通過RBAC給Head Pod配置相關許可權。配置相關許可權包括以下兩步:

    首先需要建立Slurmctld需要的ServiceAccount、Role以及RoleBinding。假設您的SlurmCluster的Name為slurm-job-demo,Namespace為default。首先在檔案中儲存以下內容,假設檔案名稱為rbac.yaml

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: slurm-job-demo
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      name: slurm-job-demo
    rules:
    - apiGroups: ["kai.alibabacloud.com"]
      resources: ["slurmclusters"]
      verbs: ["get", "watch", "list", "update", "patch"]
      resourceNames: ["slurm-job-demo"]
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: slurm-job-demo
    subjects:
    - kind: ServiceAccount
      name: slurm-job-demo
    roleRef:
      kind: Role
      name: slurm-job-demo
      apiGroup: rbac.authorization.k8s.io

    儲存到檔案中之後通過kubectl apply -f rbac.yaml的方式提交該資源清單。

    第二步為給Slurmctld的Pod賦予該許可權。首先通過kubectl edit slurmcluster slurm-job-demo修改slurmcluster,將.Spec.Slurmctld.Template.Spec.ServiceAccountName中設定為剛剛建立的ServiceAccount。

    apiVersion: kai.alibabacloud.com/v1
    kind: SlurmCluster
    ...
    spec:
      slurmctld:
        template:
          spec:
            serviceAccountName: slurm-job-demo
    ...

    之後重建管理slurmctld的statefulset應用剛才的修改。您可以通過kubectl get sts slurm-job-demo的方式查看到當前管理slurmctld pod的statefulset,並通過kubectl delete sts slurm-job-demo刪除該statefulset,slurmoperator會重建該statefulset並應用新的配置。

  2. 配置自動擴縮容檔案/etc/slurm/slurm.conf。

    通過共用隱藏檔管理設定檔

    # 以下設定為使用CLOUDNODE時的必填項。 
    # SuspendProgram與ResumeProgram為自研功能
    SuspendTimeout=600
    ResumeTimeout=600
    # 當節點上沒有任務時,將節點自動掛起的時間間隔 
    SuspendTime=600
    # 設定每分鐘能夠擴容或縮容的節點數量 
    ResumeRate=1
    SuspendRate=1
    # NodeName的格式必須為${cluster_name}-worker-${group_name}-。需要在這一行中聲明節點的資源量,否則Slurmctld會
    # 將Node視為僅有 1c 資源。這裡聲明的資源請盡量與workerGroup中聲明的資源量相同,否則可能發生資源的浪費。
    NodeName=slurm-job-demo-worker-cpu-[0-10] Feature=cloud State=CLOUD
    # 以下為固定配置,保持不變即可 
    CommunicationParameters=NoAddrCache
    ReconfigFlags=KeepPowerSaveSettings
    SuspendProgram="/slurm-suspend.sh"
    ResumeProgram="/slurm-resume.sh"

    通過Configmap手動管理設定檔

    假設slurm.conf儲存在slurm-config的ConfigMap中,可以通過kubectl edit slurm-config,在其中添加如下配置:

    slurm.conf:
    ...
      # 以下設定為使用CLOUDNODE時的必填項。 
      # SuspendProgram與ResumeProgram為自研功能
      SuspendTimeout=600
      ResumeTimeout=600
      # 當節點上沒有任務時,將節點自動掛起的時間間隔 
      SuspendTime=600
      # 設定每分鐘能夠擴容或縮容的節點數量 
      ResumeRate=1
      SuspendRate=1
      # NodeName的格式必須為${cluster_name}-worker-${group_name}-。需要在這一行中聲明節點的資源量,否則Slurmctld會
      # 將Node視為僅有 1c 資源。這裡聲明的資源請盡量與workerGroup中聲明的資源量相同,否則可能發生資源的浪費。
      NodeName=slurm-job-demo-worker-cpu-[0-10] Feature=cloud State=CLOUD
      # 以下為固定配置,保持不變即可 
      CommunicationParameters=NoAddrCache
      ReconfigFlags=KeepPowerSaveSettings
      SuspendProgram="/slurm-suspend.sh"
      ResumeProgram="/slurm-resume.sh"

    通過Helm管理設定檔

    1. 修改values.yaml,在其中添加如下的配置項:

      slurm.conf:
      ...
        # 以下設定為使用CLOUDNODE時的必填項。 
        # SuspendProgram與ResumeProgram為自研功能
        SuspendTimeout=600
        ResumeTimeout=600
        # 當節點上沒有任務時,將節點自動掛起的時間間隔 
        SuspendTime=600
        # 設定每分鐘能夠擴容或縮容的節點數量 
        ResumeRate=1
        SuspendRate=1
        # NodeName的格式必須為${cluster_name}-worker-${group_name}-。需要在這一行中聲明節點的資源量,否則Slurmctld會
        # 將Node視為僅有 1c 資源。這裡聲明的資源請盡量與workerGroup中聲明的資源量相同,否則可能發生資源的浪費。
        NodeName=slurm-job-demo-worker-cpu-[0-10] Feature=cloud State=CLOUD
        # 以下為固定配置,保持不變即可 
        CommunicationParameters=NoAddrCache
        ReconfigFlags=KeepPowerSaveSettings
        SuspendProgram="/slurm-suspend.sh"
        ResumeProgram="/slurm-resume.sh"
    2. 通過helm upgrade命令更新當前的slurm配置。

  3. 應用新的配置

    假設您提交的slurmcluster的Name為slurm-job-demo,您可以通過kubectl delete sts slurm-job-demo應用新的slurmctld的Pod的配置。

  4. 將slurmcluster.yaml檔案中的工作複本數調整為0,方便後續查看節點的擴縮容。

    手動管理

    假設提交的slurmcluster的Name為slurm-job-demo。通過kubectl edit slurmcluster slurm-job-demo將slurmcluster中的workerGroup的workerCount調整為0。即可將工作節點副本數調整為0。

    通過Helm管理

    values.yaml.Values.workerGroup[].workerCount調整為0,之後通過helm upgrade slurm-job-demo .的方式更新當前helm chart即可將工作複本數調整為0。

  5. 提交一個sbatch任務。

    1. 執行以下命令,建立一個Shell指令碼。

      cat << EOF > cloudnodedemo.sh

      在命令提示字元後輸入以下內容:

      #!/bin/bash
      srun hostname
      EOF
    2. 執行以下命令,查看執行的指令碼內容是否正確。

      cat cloudnodedemo.sh

      預期輸出:

        #!/bin/bash
        srun hostname

      指令碼輸出內容無誤。

    3. 執行以下命令,將指令碼提交給SlurmCluster進行處理。

      sbatch cloudnodedemo.sh

      預期輸出:

      Submitted batch job 1

      預期輸出表明任務已成功提交並分配了一個作業ID。

  6. 查看叢集擴縮容情況。

    1. 執行以下命令,查看SlurmCluster的伸縮日誌。

      cat /var/log/slurm-resume.log

      預期輸出:

       namespace: default cluster: slurm-demo
        resume called, args [slurm-demo-worker-cpu-0]
        slurm cluster metadata: default slurm-demo
        get SlurmCluster CR slurm-demo succeed
        hostlists: [slurm-demo-worker-cpu-0]
        resume node slurm-demo-worker-cpu-0
        resume worker -cpu-0
        resume node -cpu-0 end

      日誌輸出結果表明SlurmCluster根據工作負載需求自動擴容了一個計算節點來應對提交的作業需求。

    2. 執行以下命令,查看叢集中Pod的情況。

      kubectl get pod

      預期輸出:

      NAME                                          READY   STATUS    RESTARTS        AGE
      slurm-demo-head-9hn67                         1/1     Running   0               21m
      slurm-demo-worker-cpu-0                       1/1     Running   0               43s

      輸出結果表明slurm-demo-worker-cpu-0為新加入的叢集的Pod,即提交任務已觸發叢集的擴容。

    3. 執行以下命令,查看叢集節點資訊。

      sinfo

      預期輸出:

      PARTITION AVAIL  TIMELIMIT  NODES  STATE NODELIST
      debug*       up   infinite      10  idle~ slurm-job-demo-worker-cpu-[2-10]
      debug*       up   infinite      1   idle slurm-job-demo-worker-cpu-[0-1]

      輸出結果表示slurm-demo-worker-cpu-0是剛剛拉起的節點,而Cloud Code中還有1-10總共10個節點可以擴容。

    4. 執行以下命令,查看剛剛執行的任務資訊。

      scontrol show job 1

      預期輸出:

      JobId=1 JobName=cloudnodedemo.sh
         UserId=root(0) GroupId=root(0) MCS_label=N/A
         Priority=4294901757 Nice=0 Account=(null) QOS=(null)
         JobState=COMPLETED Reason=None Dependency=(null)
         Requeue=1 Restarts=0 BatchFlag=1 Reboot=0 ExitCode=0:0
         RunTime=00:00:00 TimeLimit=UNLIMITED TimeMin=N/A
         SubmitTime=2024-05-28T11:37:36 EligibleTime=2024-05-28T11:37:36
         AccrueTime=2024-05-28T11:37:36
         StartTime=2024-05-28T11:37:36 EndTime=2024-05-28T11:37:36 Deadline=N/A
         SuspendTime=None SecsPreSuspend=0 LastSchedEval=2024-05-28T11:37:36 Scheduler=Main
         Partition=debug AllocNode:Sid=slurm-job-demo:93
         ReqNodeList=(null) ExcNodeList=(null)
         NodeList=slurm-job-demo-worker-cpu-0
         BatchHost=slurm-job-demo-worker-cpu-0
         NumNodes=1 NumCPUs=1 NumTasks=1 CPUs/Task=1 ReqB:S:C:T=0:0:*:*
         ReqTRES=cpu=1,mem=1M,node=1,billing=1
         AllocTRES=cpu=1,mem=1M,node=1,billing=1
         Socks/Node=* NtasksPerN:B:S:C=0:0:*:* CoreSpec=*
         MinCPUsNode=1 MinMemoryNode=0 MinTmpDiskNode=0
         Features=(null) DelayBoot=00:00:00
         OverSubscribe=OK Contiguous=0 Licenses=(null) Network=(null)
         Command=//cloudnodedemo.sh
         WorkDir=/
         StdErr=//slurm-1.out
         StdIn=/dev/null
         StdOut=//slurm-1.out
         Power=

      輸出結果中的NodeList=slurm-demo-worker-cpu-0代表任務執行在剛剛擴容出的節點上。

    5. 等待一段時間後,執行以下命令,查看節點縮容資訊。

      sinfo

      預期輸出:

      PARTITION AVAIL  TIMELIMIT  NODES  STATE NODELIST
      debug*       up   infinite     11  idle~ slurm-demo-worker-cpu-[0-10]

      可以看到可擴容節點又回到0-10,總共11個節點,即完成了自動縮容。