Tất cả tài liệu

Managed GPU Cluster (Kubernetes)

    Slurm on FPTCloud Managed GPU cluster
    Slurm on FPTCloud Managed GPU cluster
    Updated on 30 Jun 2025

    FPT Managed GPU Cluster dựa trên nền tảng mã nguồn mở K8s giúp tự động hoá triển khai, nhân rộng và quản lý các ứng dụng container. FPT Managed GPU Cluster tích hợp đầy đủ các thành phần: Container Orchestration, Storage, Networking, Security, PaaS cung cấp cho khách hàng môi trường tốt nhất để phát triển và triển khai ứng dụng trên Cloud.

    FPT Managed GPU Cluster là một mô hình cung cấp dịch vụ Managed GPU Cluster của FKE. Với MANAGED GPU CLUSTER, FPT Cloud quản trị toàn bộ thành phần control-planes, người sử dụng sẽ triển khai và quản trị các Worker Nodes. MANAGED GPU CLUSTER giúp người sử dụng tập trung vào việc triển khai ứng dụng mà không cần tốn nguồn lực vào việc quản trị K8s Cluster.

    FPT Managed GPU Cluster là mô hình dịch vụ dựa trên nền tảng mã nguồn mở Kubernetes, giúp tự động hoá triển khai, nhân rộng và quản lý các ứng dụng đã được container hoá. Sản phẩm FPT Managed GPU Cluster ngoài tích hợp đầy đủ các thành phần: Container Orchestration, Storage, Networking, Security, PaaS thì còn cung cấp tài nguyên GPU, giúp hỗ trợ các thao tác tính toán phức tạp.

    💡 Những điều cần lưu ý trước khi sử dụng Managed GPU Cluster?

    · Vị trí đặt Managed GPU Cluster: Vị trí địa lý (Region) có thể sẽ ảnh hưởng đến tốc độ truy cập đến máy chủ trong quá trình sử dụng. Bạn nên chọn Region gần nhất với đối tượng phát sinh traffic để tối ưu được tốc độ.

    · Số lượng các Nodes và cấu hình của từng Nodes cần sử dụng : Các tài khoản FPT Cloud đều được cấp một hạn mức nhất định cho các tài nguyên Ram, CPU, Storage, IP… Vì vậy, khách hàng nên xác định số lượng tài nguyên cần sử dụng và giới hạn tối đa cần đáp ứng để FPT Cloud hỗ trợ bạn tốt nhất.

    1. Giới thiệu Slurm và Slurm on Kubernetes

    1.1 Giới thiệu Slurm

    Slurm là một nền tảng mã nguồn mở mạnh mẽ dùng để quản lý tài nguyên cụm và lập lịch công việc (job). Nó được thiết kế nhằm tối ưu hiệu năng và hiệu quả cho các siêu máy tính và cụm tính toán lớn. Các thành phần chính của nó hoạt động cùng nhau để đảm bảo hệ thống đạt hiệu suất cao và tính linh hoạt. Hình sau đây minh họa cách thức hoạt động của Slurm.

    slurmctld: là trình nền điều khiển của Slurm. Được xem như “bộ não” của Slurm, slurmctld giám sát tài nguyên hệ thống, lập lịch job và quản lý trạng thái cụm. Để tăng tính tin cậy, bạn có thể cấu hình một slurmctld thứ cấp nhằm tránh gián đoạn dịch vụ nếu slurmctld chính gặp sự cố, đảm bảo hệ thống luôn sẵn sàng cao.

    slurmd: là trình nền nút của Slurm. slurmd được triển khai trên mỗi nút tính toán. Nó nhận lệnh từ slurmctld và quản lý job, bao gồm khởi chạy và thực thi job, báo cáo trạng thái job và chuẩn bị cho các lệnh job mới. slurmd đóng vai trò giao diện để giao tiếp trực tiếp với tài nguyên tính toán và là cơ sở để lập lịch job.

    slurmdbd: là trình nền cơ sở dữ liệu của Slurm. slurmdbd là thành phần tùy chọn nhưng rất quan trọng cho quản lý lâu dài và kiểm toán trong các cụm lớn, vì nó duy trì một cơ sở dữ liệu tập trung để lưu lịch sử job và thông tin kế toán. slurmdbd có thể tổng hợp dữ liệu từ nhiều cụm do Slurm quản lý, giúp đơn giản hóa và nâng cao hiệu quả quản lý dữ liệu.

    🎉SlurmCLI: cung cấp các lệnh sau để hỗ trợ quản lý job và giám sát hệ thống:

    · scontrol: quản lý cụm và điều khiển cấu hình cụm.

    · squeue: truy vấn trạng thái job trong hàng đợi.

    · srun: gửi và quản lý job.

    · sbatch: gửi job theo lô, giúp bạn lập lịch và quản lý tài nguyên tính toán.

    · sinfo: truy vấn trạng thái chung của cụm, bao gồm tình trạng sẵn sàng của các nút.

    1.2 Why Slurm K8s?

    👍Cả Slurm và Kubernetes đều có thể đóng vai trò là hệ thống quản lý tải công việc cho huấn luyện mô hình phân tán và tính toán hiệu năng cao (HPC) nói chung.

    👍Mỗi hệ thống đều có điểm mạnh và điểm yếu riêng, và việc đánh đổi giữa chúng là đáng kể. Slurm cung cấp khả năng lập lịch tiên tiến, hiệu quả, kiểm soát phần cứng chi tiết và khả năng kế toán, nhưng lại thiếu tính phổ quát. Ngược lại, Kubernetes có thể được sử dụng cho nhiều mục đích khác ngoài huấn luyện (ví dụ: inferencing) và cung cấp khả năng tự động mở rộng và tự phục hồi tốt.

    👍Thật đáng tiếc là hiện chưa có cách nào để kết hợp lợi ích của cả hai giải pháp này. Và vì nhiều công ty công nghệ lớn sử dụng Kubernetes như một lớp hạ tầng mặc định mà không hỗ trợ hệ thống huấn luyện mô hình chuyên dụng, nên một số kỹ sư ML thậm chí không có sự lựa chọn.

    👍Việc sử dụng Slurm trên k8s cho phép chúng tôi tái sử dụng khả năng tự động mở rộng và tự phục hồi của Kubernetes trong Slurm, đồng thời triển khai một số tính năng độc đáo, mà vẫn giữ nguyên cách tương tác quen thuộc với hệ thống.

    1.3 Giới thiệu Slurm on FPT Cloud Managed GPU/K8s cluster

    Slurm Operator sử dụng tài nguyên tùy chỉnh SlurmCluster (CR) để định nghĩa các tập tin cấu hình cần thiết cho việc quản lý các cụm Slurm và giải quyết các vấn đề liên quan đến quản lý tầng điều khiển. Điều này giúp đơn giản hóa việc triển khai và bảo trì các cụm được quản lý bởi Slurm. Hình dưới đây mô tả kiến trúc của Slurm trên FPTCloud Managed GPU/k8s cluster. Quản trị viên cụm có thể triển khai và quản lý một cụm Slurm thông qua SlurmCluster. Slurm Operator sẽ tạo các thành phần điều khiển của Slurm trong cụm dựa trên SlurmCluster. Một tập tin cấu hình Slurm có thể được gắn vào thành phần điều khiển thông qua một volume chia sẻ hoặc một ConfigMap.

    ✋Trong mô hình triển khai Slurm on K8s, các thành phần của một cụm slurm như login node, worker node, ... được biểu diễn thành các pods trên K8s, đồng thời trong mô hình này, khái niệm shared-root volume được thực hiện, hiểu đơn giản thì chúng ta sẽ triển khai một shared filesystem, file system tương đương với file system của một OS, mọi job sau khi được chuyển đến worker node sẽ đều được triển khai trên môi trường shared root volume này. Điều này đảm bảo rằng mọi worker node sẽ luôn có cấu hình, các packages & trạng thái giống nhau mà không cần quản lý thủ công. Nói cách khác, khi bạn cài đặt packages trên một node, các packages đó sẽ tự động xuất hiện trên các node còn lại.

    👉Tất cả những gì bạn cần làm là định nghĩa về cụm slurm mong muốn của bạn tại Slurm cluster custom resource, Slurm operator sẽ thực hiện việc triển khai & quản lý cụm Slurm thay cho bạn về trạng thái bạn đã định nghĩa ở Slurm cluster CR.

    2. Hướng dẫn cài đặt

    2.1 Hướng dẫn triển khai cụm slurm trên k8s

    ⚠️Yêu cầu bắt buộc:

    - Cụm k8s có thể sử dụng tính năng dynamic provisioning volume & còn dư quota storage.

    - Ít nhất một storage class có thể cấp volume dạng Read Write Many.

    Bước 1: Cài đặt Slurm Operator, GPU Operator, Network Operator tại phần cài đặt GPU software & chờ cho đến khi trạng thái các phần này ở ready

    Bước 2: Tại cụm k8s, tạo sẵn các Persistent volume để chứa shared root space và dữ liệu của controller node.

    Chúng ta hãy chú ý về các volume trong mô hình triển khai Slurm on k8s:

    Trong đó:

    · jail-pvc: mount vào worker node và login node, đóng vai trò như một shared sandbox, là môi trường các job được thực thi, cũng là môi trường user thao tác, dung lượng volume này ít nhất là 40Gi để chứa file system của một OS.

    · controller-spool-pvc: Lưu thông tin cấu hình về cụm, đặt tại controller node.

    jail-pvc.yaml

    apiVersion: v1 
    kind: PersistentVolumeClaim 
     metadata: 
     name: jail-pvc 
    namespace: fpt-hpc 
    spec: 
     storageClassName: default 
     accessModes: 
      - ReadWriteMany 
    resources: 
     requests: 
      storage: 100Gi

    controller-spool-pvc.yaml

    apiVersion: v1 
    kind: PersistentVolumeClaim 
    metadata: 
     name: controller-spool-pvc 
     namespace: fpt-hpc 
    spec: 
     storageClassName: default 
     accessModes: 
    - ReadWriteMany 
    resources: 
     requests: 
     storage: 10Gi

    ⚠️Lưu ý:

    ➤ Các volume này đều là các volume bắt buộc phải có, chúng đều cần cung cấp cơ chế Read write many và tên của các PVC này phải giữ nguyên như trên.

    ➤ Nhằm thuận tiện để triển khai, chúng tôi đã sử dụng cơ chế dynamic provisioning volume trên sản phẩn FPTcloud managed k8s.

    ➤ Với môi trường production, chúng tôi khuyến nghị việc mount root volume từ một phân vùng tĩnh thuộc file server, để thuận tiện cho việc migrate & bảo trì cụm Slurm. Bước 3: download Slurm cluster CR helm chart + define cấu hình mong muốn

    helm repo add xplat-fke https://registry.fke.fptcloud.com/chartrepo/xplat-fke 
    helm repo update helm repo list 
    helm search repo slurm 
    helm pull xplat-fke/helm-slurm-cluster --version 1.14.10 --untar=true

    ⚠️Lưu ý: chỉnh version của slurm-cluster đúng với version của Slurm operator

    Để tìm hiểu sâu hơn về các tham số của một cụm slurm, chúng tôi khuyến khích bạn đọc phần 3: mô tả các tham số cụm Slurm.

    cd helm-slurm-cluster/
    
    vi values.yaml

    Tại file values.yaml của folder vừa tải, bạn cần chỉnh một số trường quan trọng như:

    Tên trường Mô tả
    slurmNodes.worker.size số lượng worker nodes
    slurmNodes.worker.size.spool.volumeClaimTemplateSpec.storageClassName storage class của persistent volume dùng để lưu trạng thái worker nodes
    slurmNode.login.sshRootPublicKeys danh sách các public key của user root trong cụm Slurm
    SlurmNode.accounting.mariadbOperator.storage.volumeClaimTemplate.storageClassNam storage class của persistent volume dùng để lưu dữ liệu tại slurmdbd node

    Sau khi chỉnh cấu hình cụm theo nhu cầu, chạy lệnh sau

    helm install fpt-hpc ./ -n fpt-hpc

    Bước 4: Chờ cho đến khi toàn bộ pod Slurm ở trạng thái running Quá trình này mất khoảng 20 phút ở lần đầu tiên cài slurm cluster trên cụm k8s, bao gồm 2 phase, phase 1 chạy job setup và phase 2 cài đặt các pod slurm components

    Sau khi toàn bộ các component ready, tìm IP public của login node bằng lệnh

    kubectl get svc -n fpt-hpc | grep login

    Thực hiện ssh vào head node cụm Slurm

    ssh root@<> 
    
    Nếu dùng nodeshell thì 
    chroot /mnt/jail
    sudo -i 
    
    Chạy kiểm tra: 
    srun --nodes=2 --gres=gpu:1 nvidia-smi –L 
    salloc --nodes=1 --ntasks=1 --mem=4G --time=00:20:00 --gres=gpu:1

    2.2 Chạy job mẫu trên cụm Slurm

    Sau khi login thành công vào cụm Slurm, bạn có thể kiểm tra hoạt động của cụm slurm bằng việc train model mingpt theo hướng dẫn sau:

    Bước 1: clone pytorch/example repository

    mkdir /shared 
    cd /shared 
    git clone https://github.com/pytorch/examples

    Bước 2: chuyển hướng đến folder minGPT-ddp & cài đặt các gói cần thiết

    cd examples/distributed/minGPT-ddp 
    pip3 install -r requirements.txt 
    pip3 install numpy

    ✨Nhờ cơ chế shared root, chúng ta chỉ cần chạy lệnh trên một lần, các package này sẽ tự sync trên toàn bộ các node worker khác.

    ⚠️Lưu ý: trong môi trường production, chúng tôi khuyến nghị việc dùng conda evironment/ container để tạo môi trường train thay vì cài trực tiếp các package ở môi trường global như trên.

    Bước 3: edit file slurm script

    vi mingpt/slurm/sbatch_run.s

    chú ý: chỉnh path của file main.py trong file sbatch_run.sh về path của file main.py trong folder mingpt

    Bước 4: chạy mẫu slurm job

    sbatch mingpt/slurm/sbatch_run.sh

    Bước 5: Kiểm tra

    squeue 
    scontrol show job <> 
    cat <>

    3.Mô tả các tham số trong Custom resource của Slurm cluster

    💡Tại phần 2 của hướng dẫn chạy Slurm trên K8s, chúng tôi đã hướng dẫn bạn chỉnh các tham số quan trọng nhất. Tại phần này, chúng ta sẽ đi vào tìm hiểu thêm về các tham số/thuộc tính được định nghĩa cho một Slurm cluster, bạn cũng có thể đọc phần comment tại file values.yaml của slurm cluster custom resource đã tải ở phần 2 để biết thêm thông tin về các trường.

    Thuộc tính giá trị mẫu Mô tả
    clusterName "fpt-hpc" tên cụm (lưu ý không đổi)
    k8sNodeFilters N/A Chia cụm k8s ra làm hai danh sách: các node GPU (deploy slurm worker) và các node no-gpu để deploy các thành phần khác, trong trường hợp cụm chỉ có node GPU, hai danh sách node này có thể giống nhau.
    volumeSources volumeSources:
     - name: controller-spool
       persistentVolumeClaim:
        claimName: "controller-spool-pvc"
        readOnly: false
     - name: jail
       persistentVolumeClaim:
        claimName: "jail-pvc"
        readOnly: false
    định nghĩa các Persistent volume claim sẽ đường dùng bởi các container đại diện các component (worker, login, controller nodes,...) thuộc cụm Slurm
    periodicChecks N/A job chạy định kỳ để kiểm tra tình trạng của một node. Nếu node đó chứa GPU gặp vấn đề, drain node đó.
    slurmNodes N/A Định nghĩa về số lượng, cấu hình của các node thành phần trong một cụm slurm (login node, worker node, ...)
    slurmNodes.accounting enabled: true
    mariadbOperator:
     enabled: true
     resources:
      cpu: "1000m"
      memory: "1Gi"
      ephemeralStorage: "5Gi"
     replicas: 1
     replication: {}
     storage:
      ephemeral: false
      volumeClaimTemplate:
       accessModes:
       - ReadWriteOnce
       resources:
        requests:
         storage: 10Gi
        storageClassName: xplat-nfs
    cấu hình accounting node, tại đây chúng tôi sử dụng mariadb operator để tạo database, bạn cũng có thể sử dụng database ngoài (đọc thêm tại phần values.yaml)
    slurmNodes.controller size: 1
       k8sNodeFilterName: "no-gpu"
       slurmctld:
         port: 6817
         resources:
           cpu: "1000m"
           memory: "3Gi"
           ephemeralStorage: "20Gi"
       munge:
         resources:
           cpu: "1000m"
           memory: "1Gi"
           ephemeralStorage: "5Gi"
       volumes:
         spool:
           volumeSourceName: "controller-spool"
         jail:
           volumeSourceName: "jail"
    Cấu hình controller node, với 1 controller node + mount 2 volume spool & jail shared root space) vào node nà
    slurmNodes.worker size: 8
        k8sNodeFilterName: "gpu"
        cgroupVersion: v2
        slurmd:
          port: 6818
          resources:
            cpu: "110000m"
            memory: "1220Gi"
            ephemeralStorage: "55Gi"
            gpu: 8
            rdma: 1
        munge:
          resources:
            cpu: "2000m"
            memory: "4Gi"
            ephemeralStorage: "5Gi"
        volumes:
          spool:
            volumeClaimTemplateSpec:
              storageClassName: "xplat-nfs"
              accessModes: ["ReadWriteOnce"]
              resources:
                requests:
                  storage: "120Gi"
          jail:
            volumeSourceName: "jail"
    Cấu hình worker nodes, với 8 worker nodes, mỗi node 8 GPUs + mount volume jail(shared root space) vào node này.
    slurmNodes.login login:
        size: 2
        k8sNodeFilterName: "no-gpu"
        sshd:
          port: 22
          resources:
            cpu: "3000m"
            memory: "9Gi"
            ephemeralStorage: "30Gi"
        sshRootPublicKeys:
          - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHke7B5+kGXx/Dwr76NI5KxfAAEkqcxbh6/8SV7tnpUP [email protected]"
        sshdServiceLoadBalancerIP: ""
        sshdServiceNodePort: 30022
        munge:
          resources:
            cpu: "500m"
            memory: "500Mi"
            ephemeralStorage: "5Gi"
        volumes:
          jail:
            volumeSourceName: "jail"
    Cấu hình worker nodes, với 2 login nodes, expose sshd service bằng load-balancer service type trong k8s, sử dụng publickey định nghĩa tại sshRootPublicKeys cho root user và mount các volume tương tự controller node & worker node.
    slurmNodes.exporter exporter:
        enabled: true
        size: 1
        k8sNodeFilterName: "no-gpu"
        exporter:
          resources:
            cpu: "250m"
            memory: "256Mi"
            ephemeralStorage: "500Mi"
        munge:
          resources:
            cpu: "1000m"
            memory: "1Gi"
            ephemeralStorage: "5Gi"
        volumes:
          jail:
            volumeSourceName: "jail"
    Cài đặt node exporter phục vụ monitoring.

    4.Các usecase thường gặp.

    4.1 Thêm user/ login

    👍Thêm user

    Để thêm ssh key cho root, bạn đơn giản chỉ cần edit slurm cluster CR:

    kubectl edit SlurmCluster  fpt-hpc -n fpt-hpc

    Tại phần cấu hình login node, chuyển hướng đến thuộc tính sshRootPublicKeys, thêm public key mong muốn của bạn.

    Để thêm một regular user, bạn làm tương tự việc thêm user cho một linux host

    sudo adduser <>

    Chỉnh sửa việc login

    Mặc định, chúng tôi expose login node qua một Load Balancer public, điều này có thể không phù hợp với một số yêu cầu. Do vậy, bạn có thể chuyển type của LB này về private, dùng cơ chế port-forward để access vào cụm slurm, hoặc tự customize theo ý bạn tại portal + node LB của chúng tôi.

    4.2 Scale up + down worker nodes

    Để chỉnh sửa số lượng worker nodes nói riêng và số lượng các nodes thuộc loại khác nói chung, chúng ta đơn giản chỉ cần edit lại slurm cluster CR:

    kubectl edit SlurmCluster  fpt-hpc -n fpt-hpc

    Tại phần cấu hình worker nodes, chuyển hướng tới mục “size" và edit số lượng worker node theo mong muốn

    ⚠️Lưu ý:

    -Khi scale up số lượng worker nodes, node mới sẽ được tự động thêm vào danh sách worker nodes tại slurm controller node và sẵn sàng để chạy job.

    -Khi scale down nodes, bạn cần xóa node thủ công tại slurm controller bằng lệnh:

    scontrol delete nodeName=<>

    -Danh sách nodes trong một cluster luôn là worker-[0, (size - 1)]

    4.3 Migrate Slurm cluster sang k8s cluster khác

    ✅Nhờ sự linh hoạt của k8s và network file storage, chúng ta có thể dễ dàng chuyển slurm cluster từ một cụm k8s này sang cụm k8s khác, việc phải làm là mounting & tạo lại jail-pvc trên cụm slurm k8s mới và thực hiện lại các bước tạo slurm k8s.

    4.4 Mounting external volumes vào cụm slurm

    ✅Để mount một volume vào slurm cluster, bạn cần tạo volume đó trước, sau đó triển khai volume đó dưới dạng PV & PVC tại K8s. Ví dụ sau sử dụng dynamic provisioning để tạo PV/PVC này (trong môi trường production chúng tôi khuyến nghị sử dụng static provisioning volume để đảm bảo an toàn dữ liệu)

    Bước 1: tạo PVC

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: jail-submount-mlperf-sd-pvc
    spec:
      storageClassName: default
      accessModes:
        - ReadWriteMany
      resources:
         requests:
            storage: 100Gi

    Bước 2: khai báo volume này tại slurm cluster

    ⭐Edit trường volumeSource tại slurm cluster CR

    kubectl edit SlurmCluster  fpt-hpc -n fpt-hpc
    volumeSources:
      - name: controller-spool
        persistentVolumeClaim:
          claimName: "controller-spool-pvc"
          readOnly: false
      - name: jail
        persistentVolumeClaim:
          claimName: "jail-pvc"
          readOnly: false
      - name: mlperf-sd
        persistentVolumeClaim:
          claimName: "jail-submount-mlperf-sd-pvc"
          readOnly: false

    Bước 3: mount các volume trên vào các node login và worker trong cụm slurm

    ⭐Tại login node:

    volumes:
          jail:
            volumeSourceName: "jail"
          jailSubMounts:
            - name: "mlcommons-sd-bench-data"
              mountPath: "/mnt/data-hps"
              volumeSourceName: "mlperf-sd"

    ⭐Tại worker node:

    volumes:
          spool:
            volumeClaimTemplateSpec:
              storageClassName: "xplat-nfs"
              accessModes: ["ReadWriteOnce"]
              resources:
                requests:
                  storage: "120Gi"
          jail:
            volumeSourceName: "jail"
          jailSubMounts:
            - name: "mlcommons-sd-bench-data"
              mountPath: "/mnt/data-hps"
              volumeSourceName: "mlperf-sd"

    ⚠️Lưu ý: mount path cần giống nhau trên các worker node và login node