הכנת תשתית GKE לעומסי עבודה של DRA

במאמר הזה נסביר איך להגדיר את התשתית של Google Kubernetes Engine ‏ (GKE) כדי לתמוך בהקצאת משאבים דינמית (DRA). שלבי ההגדרה כוללים יצירה של מאגרי צמתים שמשתמשים ב-GPU או ב-TPU, והתקנה של מנהלי התקנים של DRA באשכול. המסמך הזה מיועד לאדמינים של פלטפורמות שרוצים לצמצם את המורכבות והתקורה של הגדרת תשתיות עם מכשירי חומרה ייעודיים.

מגבלות

  • אין תמיכה בהקצאת צמתים אוטומטית.
  • אשכולות Autopilot לא תומכים ב-DRA.
  • התקנה אוטומטית של דרייבר ל-GPU לא נתמכת ב-DRA.
  • אי אפשר להשתמש בתכונות הבאות של שיתוף GPU:
    • שיתוף זמן ב-GPU
    • יחידות GPU עם כמה מופעים במקביל
    • שירות מרובה תהליכים (MPS)
  • ב-TPU, צריך להפעיל את הגרסאות v1beta1 ו-v1beta2 של סוגי DRA API. המגבלה הזו לא חלה על מעבדים גרפיים, שיכולים להשתמש בגרסאות של v1 API.

דרישות

כדי להשתמש ב-DRA, אשכול GKE צריך להיות מגרסה 1.34 ואילך.

כדאי גם להכיר את הדרישות והמגבלות הבאות, בהתאם לסוג החומרה שבה רוצים להשתמש:

לפני שמתחילים

לפני שמתחילים, חשוב לוודא שביצעתם את הפעולות הבאות:

  • מפעילים את ממשק ה-API של Google Kubernetes Engine.
  • הפעלת Google Kubernetes Engine API
  • אם רוצים להשתמש ב-CLI של Google Cloud למשימה הזו, צריך להתקין ואז להפעיל את ה-CLI של gcloud. אם התקנתם בעבר את ה-CLI של gcloud, מריצים את הפקודה gcloud components update כדי לקבל את הגרסה העדכנית. יכול להיות שגרסאות קודמות של ה-CLI של gcloud לא יתמכו בהרצת הפקודות שמופיעות במסמך הזה.
  • יש לכם אשכול GKE Standard שפועל בגרסה 1.34 ואילך. אפשר גם ליצור אשכול אזורי.

  • אם אתם לא משתמשים ב-Cloud Shell, צריך להתקין את Helm CLI:

    curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
    chmod 700 get_helm.sh
    ./get_helm.sh
    
  • כדי להשתמש ב-DRA ב-TPU, צריך להפעיל את הגרסאות v1beta1 ו-v1beta2 של סוגי ה-API של DRA:

    gcloud container clusters update CLUSTER_NAME \
        --location=CONTROL_PLANE_LOCATION \
        --enable-kubernetes-unstable-apis="resource.k8s.io/v1beta1/deviceclasses,resource.k8s.io/v1beta1/resourceclaims,resource.k8s.io/v1beta1/resourceclaimtemplates,resource.k8s.io/v1beta1/resourceslices,resource.k8s.io/v1beta2/deviceclasses,resource.k8s.io/v1beta2/resourceclaims,resource.k8s.io/v1beta2/resourceclaimtemplates,resource.k8s.io/v1beta2/resourceslices"
    

יצירת מאגר צמתים ב-GKE עם יחידות GPU או TPU

ב-GKE, אפשר להשתמש ב-DRA גם עם GPU וגם עם TPU. הגדרות התצורה של מאגר הצמתים – כמו סוג המכונה, סוג המאיץ, מספר הצמתים, מערכת ההפעלה של הצמתים והמיקומים של הצמתים – תלויות בדרישות שלכם. כדי ליצור מאגר צמתים שתומך ב-DRA, בוחרים באחת מהאפשרויות הבאות:

GPU

כדי להשתמש ב-DRA עבור יחידות GPU, צריך לבצע את הפעולות הבאות כשיוצרים את מאגר הצמתים:

  • כדי להשבית את ההתקנה האוטומטית של מנהל התקן ל-GPU, צריך לציין את האפשרות gpu-driver-version=disabled בדגל --accelerator כשמגדירים GPU למאגר צמתים.
  • משביתים את הפלאגין של מכשיר ה-GPU על ידי הוספת התווית gke-no-default-nvidia-gpu-device-plugin=true של הצומת.
  • מאפשרים ל-DaemonSet של מנהל ההקצאה הדינמית של משאבים (DRA) לפעול בצמתים על ידי הוספת התווית nvidia.com/gpu.present=true node.

כדי ליצור מאגר צמתים של GPU ל-DRA, מבצעים את השלבים הבאים:

  1. יוצרים מאגר צמתים עם החומרה הנדרשת. בדוגמה הבאה נוצר מאגר צמתים עם מופע g2-standard-24 במערכת הפעלה שמותאמת לקונטיינרים עם שני GPU L4.

    gcloud container node-pools create NODEPOOL_NAME \
        --cluster=CLUSTER_NAME \
        --location=CONTROL_PLANE_LOCATION \
        --machine-type "g2-standard-24" \
        --accelerator "type=nvidia-l4,count=2,gpu-driver-version=disabled" \
        --num-nodes "1" \
        --node-labels=gke-no-default-nvidia-gpu-device-plugin=true,nvidia.com/gpu.present=true
    

    מחליפים את מה שכתוב בשדות הבאים:

    • NODEPOOL_NAME: השם של מאגר הצמתים.
    • CLUSTER_NAME: השם של האשכול.
    • CONTROL_PLANE_LOCATION: האזור או האזור של מישור הבקרה של האשכול, למשל us-central1 או us-central1-a.
  2. מתקינים את הדרייברים באופן ידני בצמתים של מערכת הפעלה שמותאמת לקונטיינרים או של Ubuntu. הוראות מפורטות זמינות במאמר בנושא התקנה ידנית של מנהלי התקנים (דרייברים) של NVIDIA GPU.

TPU

כדי להשתמש ב-DRA עבור TPU, צריך להשבית את הפלאגין של מכשיר ה-TPU על ידי הוספת התווית gke-no-default-tpu-device-plugin=true של הצומת. בדוגמה הבאה נוצר מאגר צמתים של TPU Trillium עם תמיכה ב-DRA:

gcloud container node-pools create NODEPOOL_NAME \
    --cluster CLUSTER_NAME --num-nodes 1 \
    --location=CONTROL_PLANE_LOCATION \
    --node-labels "gke-no-default-tpu-device-plugin=true,gke-no-default-tpu-dra-plugin=true" \
    --machine-type=ct6e-standard-8t

מחליפים את מה שכתוב בשדות הבאים:

  • NODEPOOL_NAME: השם של מאגר הצמתים.
  • CLUSTER_NAME: השם של האשכול.
  • CONTROL_PLANE_LOCATION: האזור או האזור של מישור הבקרה של האשכול, למשל us-central1 או us-central1-a.

התקנת מנהלי התקנים של DRA

GPU

  1. מושכים ומעדכנים את תרשים Helm שמכיל את הדרייבר NVIDIA DRA:

    helm repo add nvidia https://helm.ngc.nvidia.com/nvidia \
        && helm repo update
    
  2. מתקינים את הדרייבר של NVIDIA DRA בגרסה 25.3.2:

    helm install nvidia-dra-driver-gpu nvidia/nvidia-dra-driver-gpu \
        --version="25.3.2" --create-namespace --namespace=nvidia-dra-driver-gpu \
        --set nvidiaDriverRoot="/home/kubernetes/bin/nvidia/" \
        --set gpuResourcesEnabledOverride=true \
        --set resources.computeDomains.enabled=false \
        --set kubeletPlugin.priorityClassName="" \
        --set 'kubeletPlugin.tolerations[0].key=nvidia.com/gpu' \
        --set 'kubeletPlugin.tolerations[0].operator=Exists' \
        --set 'kubeletPlugin.tolerations[0].effect=NoSchedule'
    

    בצמתים של Ubuntu, משתמשים בנתיב של ספריית nvidiaDriverRoot="/opt/nvidia".

TPU

  1. משכפלים את מאגר ai-on-gke כדי לגשת לתרשימי Helm שמכילים את מנהלי ההתקנים של DRA עבור יחידות GPU ו-TPU:

    git clone https://github.com/ai-on-gke/common-infra.git
    
  2. עוברים לספרייה שמכילה את התרשימים:

    cd common-infra/common/charts
    
  3. מתקינים את מנהל ההתקן TPU DRA:

    ./tpu-dra-driver/install-tpu-dra-driver.sh
    

בדיקה שהתשתית מוכנה ל-DRA

  1. כדי לוודא שרכיבי ה-Pod של מנהל ה-DRA פועלים, בוחרים באחת מהאפשרויות הבאות:

    GPU

    kubectl get pods -n nvidia-dra-driver-gpu
    

    הפלט אמור להיראות כך:

    NAME                                         READY   STATUS    RESTARTS   AGE
    nvidia-dra-driver-gpu-kubelet-plugin-52cdm   1/1     Running   0          46s
    

    TPU

    kubectl get pods -n tpu-dra-driver
    
    

    הפלט אמור להיראות כך:

    NAME                                         READY   STATUS    RESTARTS   AGE
    tpu-dra-driver-kubeletplugin-h6m57           1/1     Running   0          30s
    
  2. מוודאים שברשימה ResourceSlice מופיעים מכשירי החומרה שהוספתם:

    kubectl get resourceslices -o yaml
    

    אם השתמשתם בדוגמה שבקטע הקודם, הפלט ייראה בערך כך, בהתאם להגדרות של מעבדי ה-GPU או ה-TPU:

    GPU

    apiVersion: v1
    items:
    - apiVersion: resource.k8s.io/v1
      kind: ResourceSlice
      metadata:
      # Multiple lines are omitted here.
      spec:
        devices:
        - attributes:
            architecture:
              string: Ada Lovelace
            brand:
              string: Nvidia
            cudaComputeCapability:
              version: 8.9.0
            cudaDriverVersion:
              version: 13.0.0
            driverVersion:
              version: 580.65.6
            index:
              int: 0
            minor:
              int: 0
            pcieBusID:
              string: "0000:00:03.0"
            productName:
              string: NVIDIA L4
            resource.kubernetes.io/pcieRoot:
              string: pci0000:00
            type:
              string: gpu
            uuid:
              string: GPU-ccc19e5e-e3cd-f911-65c8-89bcef084e3f
          capacity:
            memory:
              value: 23034Mi
          name: gpu-0
        - attributes:
            architecture:
              string: Ada Lovelace
            brand:
              string: Nvidia
            cudaComputeCapability:
              version: 8.9.0
            cudaDriverVersion:
              version: 13.0.0
            driverVersion:
              version: 580.65.6
            index:
              int: 1
            minor:
              int: 1
            pcieBusID:
              string: "0000:00:04.0"
            productName:
              string: NVIDIA L4
            resource.kubernetes.io/pcieRoot:
              string: pci0000:00
            type:
              string: gpu
            uuid:
              string: GPU-f783198d-42f9-7cef-9ea1-bb10578df978
          capacity:
            memory:
              value: 23034Mi
          name: gpu-1
        driver: gpu.nvidia.com
        nodeName: gke-cluster-1-dra-gpu-pool-b56c4961-7vnm
        pool:
          generation: 1
          name: gke-cluster-1-dra-gpu-pool-b56c4961-7vnm
          resourceSliceCount: 1
    kind: List
    metadata:
      resourceVersion: ""
    

    TPU

    apiVersion: v1
    items:
    - apiVersion: resource.k8s.io/v1beta1
      kind: ResourceSlice
      metadata:
        # lines omitted for clarity
      spec:
        devices:
        - basic:
            attributes:
              index:
                int: 0
              tpuGen:
                string: v6e
              uuid:
                string: tpu-54de4859-dd8d-f67e-6f91-cf904d965454
          name: "0"
        - basic:
            attributes:
              index:
                int: 1
              tpuGen:
                string: v6e
              uuid:
                string: tpu-54de4859-dd8d-f67e-6f91-cf904d965454
          name: "1"
        - basic:
            attributes:
              index:
                int: 2
              tpuGen:
                string: v6e
              uuid:
                string: tpu-54de4859-dd8d-f67e-6f91-cf904d965454
          name: "2"
        - basic:
            attributes:
              index:
                int: 3
              tpuGen:
                string: v6e
              uuid:
                string: tpu-54de4859-dd8d-f67e-6f91-cf904d965454
          name: "3"
        driver: tpu.google.com
        nodeName: gke-tpu-b4d4b61b-fwbg
        pool:
          generation: 1
          name: gke-tpu-b4d4b61b-fwbg
          resourceSliceCount: 1
    kind: List
    metadata:
      resourceVersion: ""
    

המאמרים הבאים