ניהול של GPU Stack באמצעות NVIDIA GPU Operator ב-Google Kubernetes Engine‏ (GKE)

בדף הזה מוסבר מתי כדאי להשתמש באופרטור NVIDIA GPU ואיך להפעיל את האופרטור NVIDIA GPU ב-GKE.

סקירה כללית

אופרטורים הם תוספי תוכנה ל-Kubernetes שמאפשרים למשתמשים ליצור משאבים מותאמים אישית שמנהלים אפליקציות ואת הרכיבים שלהן. אפשר להשתמש באופרטורים כדי לבצע אוטומציה של משימות מורכבות שלא נכללות ב-Kubernetes, כמו פריסה ושדרוג של אפליקציות.

‫NVIDIA GPU Operator הוא אופרטור של Kubernetes שמספק תשתית משותפת וממשק API לפריסה, להגדרה ולניהול של רכיבי תוכנה שנדרשים להקצאת GPU של NVIDIA באשכול Kubernetes. ה-NVIDIA GPU Operator מספק חוויה עקבית, מפשט את ניהול משאבי ה-GPU ומייעל את השילוב של עומסי עבודה שמואצים באמצעות GPU ב-Kubernetes.

למה כדאי להשתמש ב-NVIDIA GPU Operator?

מומלץ להשתמש בניהול GPU ב-GKE עבור צמתי ה-GPU, כי GKE מנהל באופן מלא את מחזור החיים של צמתי ה-GPU. כדי להתחיל להשתמש ב-GKE לניהול צמתי GPU, בוחרים באחת מהאפשרויות הבאות:

לחלופין, אם אתם מחפשים חוויה עקבית אצל כמה ספקי שירותי ענן, אם אתם כבר משתמשים ב-NVIDIA GPU Operator או אם אתם משתמשים בתוכנה שתלויה ב-NVIDIA GPU Operator, יכול להיות שהאפשרות הזו מתאימה לכם.

לשיקולים נוספים שיעזרו לכם להחליט בין האפשרויות האלה, תוכלו לעיין במאמר ניהול מחסנית ה-GPU דרך GKE או NVIDIA GPU Operator ב-GKE.

מגבלות

ה-NVIDIA GPU Operator נתמך בקובצי אימג' של צמתים של מערכת הפעלה שמותאמת לקונטיינרים (COS) ושל Ubuntu, עם המגבלות הבאות:

  • החל מגרסה 24.6.0 של GPU Operator ואילך, יש תמיכה ב-NVIDIA GPU Operator ב-GKE.
  • האופרטור של NVIDIA GPU לא נתמך באשכולות של Autopilot.
  • ה-NVIDIA GPU Operator לא נתמך בתמונות של צומתי Windows.
  • ה-Operator של NVIDIA GPU לא מנוהל על ידי GKE. כדי לשדרג את NVIDIA GPU Operator, אפשר לעיין בתיעוד של NVIDIA.

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

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

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

    אין דרישה ספציפית לגרסת Helm, אבל אפשר להשתמש בפקודה הבאה כדי לוודא ש-Helm מותקן.

    helm version
    

    אם הפלט דומה ל-Command helm not found, אפשר להתקין את Helm CLI באמצעות הפקודה הבאה:

    curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 \
      && chmod 700 get_helm.sh \
      && ./get_helm.sh
    

יצירה והגדרה של מאגר צמתים של GPU

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

  1. כדי ליצור מאגר צמתים של GPU, פועלים לפי ההוראות במאמר בנושא יצירת מאגר צמתים של GPU עם השינויים הבאים:

    • מגדירים את gpu-driver-version=disabled כדי לדלג על התקנה אוטומטית של מנהל התקן (דרייבר) ל-GPU, כי היא לא נתמכת כשמשתמשים באופרטור NVIDIA GPU.
    • מגדירים את הערך של --node-labels="gke-no-default-nvidia-gpu-device-plugin=true" ל-Set כדי להשבית את Daemonset של פלאגין המכשיר של GPU מנוהל ב-GKE.

    מריצים את הפקודה הבאה ומצרפים דגלים אחרים ליצירת מאגר צמתים של GPU לפי הצורך:

    gcloud container node-pools create POOL_NAME \
      --accelerator type=GPU_TYPE,count=AMOUNT,gpu-driver-version=disabled \
      --node-labels="gke-no-default-nvidia-gpu-device-plugin=true"
    

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

    • POOL_NAME השם שבחרתם למאגר הצמתים.
    • GPU_TYPE: סוג ה-GPU המואץ שרוצים להשתמש בו. לדוגמה, nvidia-h100-80gb.
    • AMOUNT: מספר יחידות ה-GPU לצירוף לצמתים במאגר הצמתים.

    לדוגמה, הפקודה הבאה יוצרת מאגר צמתים של GKE‏, a3nodepool, עם מעבדי GPU מסוג H100 באשכול אזורי a3-cluster. בדוגמה הזו, ה-Daemonset של פלאגין מכשיר ה-GPU של GKE וההתקנה האוטומטית של מנהל ההתקן מושבתים.

    gcloud container node-pools create a3nodepool \
      --cluster=a3-cluster \
      --location=us-central1 \
      --node-locations=us-central1-a \
      --accelerator=type=nvidia-h100-80gb,count=8,gpu-driver-version=disabled \
      --machine-type=a3-highgpu-8g \
      --node-labels="gke-no-default-nvidia-gpu-device-plugin=true" \
      --num-nodes=1
    
  2. מריצים את הפקודה הבאה כדי לקבל את פרטי הכניסה לאימות של האשכול:

    USE_GKE_GCLOUD_AUTH_PLUGIN=True \
    gcloud container clusters get-credentials CLUSTER_NAME \
      --location CONTROL_PLANE_LOCATION
    

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

    • CLUSTER_NAME: שם האשכול שמכיל את מאגר הצמתים.
    • CONTROL_PLANE_LOCATION: המיקום של מישור הבקרה של האשכול ב-Compute Engine. מציינים אזור לאשכולות אזוריים או אזור זמין לאשכולות אזוריים.

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

    Fetching cluster endpoint and auth data.
    kubeconfig entry generated for CLUSTER_NAME.
    
  3. (אופציונלי) מוודאים שאפשר להתחבר לאשכול.

    kubectl get nodes -o wide
    

    אמורה להופיע רשימה של כל הצמתים שפועלים באשכול הזה.

  4. כדי ליצור את מרחב השמות gpu-operator עבור NVIDIA GPU Operator, מריצים את הפקודה הבאה:

    kubectl create ns gpu-operator
    

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

    namespace/gpu-operator created
    
  5. כדי ליצור מכסת משאבים במרחב השמות gpu-operator, מריצים את הפקודה הבאה:

    kubectl apply -n gpu-operator -f - << EOF
    apiVersion: v1
    kind: ResourceQuota
    metadata:
      name: gpu-operator-quota
    spec:
      hard:
        pods: 100
      scopeSelector:
        matchExpressions:
        - operator: In
          scopeName: PriorityClass
          values:
            - system-node-critical
            - system-cluster-critical
    EOF
    

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

    resourcequota/gpu-operator-quota created
    
  6. כדי לראות את מכסת המשאבים של מרחב השמות gpu-operator:

    kubectl get -n gpu-operator resourcequota gpu-operator-quota
    

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

    NAME                 AGE     REQUEST       LIMIT
    gpu-operator-quota   2m27s   pods: 0/100
    
  7. מתקינים את הדרייברים באופן ידני בצמתים של מערכת הפעלה שמותאמת לקונטיינרים או של Ubuntu. הוראות מפורטות זמינות במאמר בנושא התקנה ידנית של מנהלי התקנים (דרייברים) של NVIDIA GPU.

    • אם משתמשים ב-COS, מריצים את הפקודות הבאות כדי לפרוס את ההתקנה של DaemonSet ולהתקין את גרסת ברירת המחדל של מנהל ההתקן (דרייבר) של ה-GPU:

      kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/nvidia-driver-installer/cos/daemonset-preloaded.yaml
      
    • אם משתמשים ב-Ubuntu, ה-DaemonSet להתקנה שפורסים תלוי בסוג ה-GPU ובגרסת הצומת של GKE, כמו שמתואר בקטע Ubuntu בהוראות.

  8. מריצים את הפקודה הבאה כדי לוודא מהי גרסת הדרייבר של ה-GPU:

    kubectl logs -l k8s-app=nvidia-driver-installer  \
      -c "nvidia-driver-installer" --tail=-1 -n kube-system
    

    אם התקנת מנהל ההתקן של ה-GPU מסתיימת בהצלחה, הפלט דומה לזה:

    I0716 03:17:38.863927    6293 cache.go:66] DRIVER_VERSION=535.183.01
    …
    I0716 03:17:38.863955    6293 installer.go:58] Verifying GPU driver installation
    I0716 03:17:41.534387    6293 install.go:543] Finished installing the drivers.
    

התקנת NVIDIA GPU Operator

בקטע הזה מוסבר איך להתקין את NVIDIA GPU Operator באמצעות Helm. מידע נוסף זמין במסמכי התיעוד של NVIDIA בנושא התקנת NVIDIA GPU Operator.

  1. מוסיפים את מאגר NVIDIA Helm:

    helm repo add nvidia https://helm.ngc.nvidia.com/nvidia \
      && helm repo update
    
  2. מתקינים את NVIDIA GPU Operator באמצעות Helm עם אפשרויות ההגדרה הבאות:

    • מוודאים שגרסת GPU Operator היא 24.6.0 ואילך.
    • מגדירים את נתיב ההתקנה של הדרייבר ב-GPU Operator באמצעות hostPaths.driverInstallDir=/home/kubernetes/bin/nvidia.
    • מגדירים את נתיב ההתקנה של ערכת הכלים toolkit.installDir=/home/kubernetes/bin/nvidia גם ל-COS וגם ל-Ubuntu. ב-COS, התיקייה /home ניתנת לכתיבה ומשמשת כמקום עם שמירת מצב לאחסון קבצים בינאריים של זמן הריצה של NVIDIA. מידע נוסף זמין במאמר סקירה כללית על דיסקים ומערכת קבצים ב-COS.

    גרסה 25.10.0 ואילך

    helm install --wait --generate-name \
      -n gpu-operator \
      nvidia/gpu-operator \
      --set hostPaths.driverInstallDir=/home/kubernetes/bin/nvidia \
      --set toolkit.installDir=/home/kubernetes/bin/nvidia \
      --set driver.enabled=false
    

    גרסה v25.3.4 או גרסה ישנה יותר

    • מפעילים את Container Device Interface ‏ (CDI) ב-GPU Operator באמצעות cdi.enabled=true ו-cdi.default=true כי מצב Legacy לא נתמך. נדרש CDI גם ב-COS וגם ב-Ubuntu ב-GKE.
    helm install --wait --generate-name \
      --version=v25.3.4 \
      -n gpu-operator \
      nvidia/gpu-operator \
      --set hostPaths.driverInstallDir=/home/kubernetes/bin/nvidia \
      --set toolkit.installDir=/home/kubernetes/bin/nvidia \
      --set cdi.enabled=true \
      --set cdi.default=true \
      --set driver.enabled=false \
      --set operator.runtimeClass=containerd \
      --set 'toolkit.env[0].name=CONTAINERD_CONFIG' \
      --set 'toolkit.env[0].value=/etc/containerd/config.toml' \
      --set 'toolkit.env[1].name=CONTAINERD_SOCKET' \
      --set 'toolkit.env[1].value=/run/containerd/containerd.sock' \
      --set 'toolkit.env[2].name=RUNTIME_CONFIG_SOURCE' \
      --set 'toolkit.env[2].value="command\, file"'
    

    מידע נוסף על ההגדרות האלה זמין במאמרים Common Chart Customization Options ו-Common Deployment Scenarios במסמכי NVIDIA.

  3. מוודאים שהאופרטור של NVIDIA GPU הותקן בהצלחה.

    1. כדי לוודא שהאופרנדים של GPU Operator פועלים בצורה תקינה, מריצים את הפקודה הבאה.

      kubectl get pods -n gpu-operator
      

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

      NAME                                                          READY    STATUS
      RESTARTS   AGE
      gpu-operator-5c7cf8b4f6-bx4rg                                 1/1      Running   0          11m
      gpu-operator-node-feature-discovery-gc-79d6d968bb-g7gv9       1/1      Running   0          11m
      gpu-operator-node-feature-discovery-master-6d9f8d497c-thhlz   1/1      Running   0          11m
      gpu-operator-node-feature-discovery-worker-wn79l              1/1      Running   0          11m
      gpu-feature-discovery-fs9gw                                   1/1      Running   0          8m14s
      gpu-operator-node-feature-discovery-worker-bdqnv              1/1      Running   0          9m5s
      nvidia-container-toolkit-daemonset-vr8fv                      1/1      Running   0          8m15s
      nvidia-cuda-validator-4nljj                                   0/1      Completed 0          2m24s
      nvidia-dcgm-exporter-4mjvh                                    1/1      Running   0          8m15s
      nvidia-device-plugin-daemonset-jfbcj                          1/1      Running   0          8m15s
      nvidia-mig-manager-kzncr                                      1/1      Running   0          2m5s
      nvidia-operator-validator-fcrr6                               1/1      Running   0          8m15s
      
    2. כדי לוודא שמספר ה-GPU מוגדר בצורה נכונה בשדה 'Allocatable' של הצומת, מריצים את הפקודה הבאה:

      kubectl describe node GPU_NODE_NAME | grep Allocatable -A7
      

      מחליפים את GPU_NODE_NAME בשם הצומת שיש בו כרטיסי GPU.

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

      Allocatable:
      cpu:                11900m
      ephemeral-storage:  47060071478
      hugepages-1Gi:      0
      hugepages-2Mi:      0
      memory:             80403000Ki
      nvidia.com/gpu:     1           # showing correct count of GPU associated with the nods
      pods:               110
      
    3. כדי לוודא שעומס העבודה של ה-GPU פועל בצורה תקינה, אפשר להשתמש בכלי cuda-vectoradd:

      cat << EOF | kubectl create -f -
      apiVersion: v1
      kind: Pod
      metadata:
        name: cuda-vectoradd
      spec:
        restartPolicy: OnFailure
        containers:
        - name: vectoradd
          image: nvidia/samples:vectoradd-cuda11.2.1
          resources:
            limits:
              nvidia.com/gpu: 1
      EOF
      

      לאחר מכן, מריצים את הפקודה הבאה:

      kubectl logs cuda-vectoradd
      

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

      [Vector addition of 50000 elements]
      Copy input data from the host memory to the CUDA device
      CUDA kernel launch with 196 blocks of 256 threads
      Copy output data from the CUDA device to the host memory
      Test PASSED
      Done
      

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