הפעלת עומסי עבודה של מחשוב עתיר ביצועים (HPC) באמצעות H4D

במאמר הזה מוסבר איך להריץ עומסי עבודה של מחשוב עתיר ביצועים (HPC) באשכולות של Google Kubernetes Engine (GKE) שמשתמשים בסדרת המכונות H4D ובגישה ישירה מרחוק לזיכרון (RDMA).

‫H4D היא סדרת מכונות במשפחת המכונות שמותאמות לצריכת מעבד גבוהה ב-Compute Engine. סדרת המכונות עברה אופטימיזציה לביצועים גבוהים, עלות נמוכה ומדרגיות. ‫H4D מתאים לאפליקציות שניתנות להרחבה על פני צמתים מרובים. מכונות H4D שהוגדרו לשימוש ב-RDMA תומכות ברוחב פס של עד ‎200 Gbps ברשת בין הצמתים.

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

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

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

הגדרת אשכולות GKE ורשתות

אתם יכולים להשתמש ב-Cluster Toolkit כדי ליצור במהירות אשכול GKE מוכן לייצור, שמשתמש במכונות וירטואליות מסוג H4D שקשורות להזמנה. ההוראות ל-Cluster Toolkit בקטע הזה מתבססות על GKE H4D Blueprint.

לחלופין, אפשר להשתמש ב-Google Cloud CLI כדי להגדיר את סביבת האשכול עם מכונות וירטואליות שמוגבלות להזמנה או עם Flex-start VMs, וליהנות מגמישות מקסימלית.

Cluster Toolkit

  1. הגדרת Cluster Toolkit. מומלץ להשתמש ב-Cloud Shell כי יחסי התלות כבר מותקנים מראש ב-Cluster Toolkit.

  2. מקבלים את כתובת ה-IP של המכונה המארחת שבה התקנתם את Cluster Toolkit:

    curl ifconfig.me
    

    שומרים את כתובת ה-IP הזו כדי להשתמש בה למשתנה IP_ADDRESS בשלב מאוחר יותר.

  3. יוצרים קטגוריה של Cloud Storage לאחסון המצב של פריסת Terraform:

    gcloud storage buckets create gs://BUCKET_NAME \
        --default-storage-class=STANDARD \
        --project=PROJECT_ID \
        --location=COMPUTE_REGION_TERRAFORM_STATE \
        --uniform-bucket-level-access
    gcloud storage buckets update gs://BUCKET_NAME --versioning
    

    מחליפים את המשתנים הבאים:

    • ‫BUCKET_NAME: השם של קטגוריית Cloud Storage החדשה.
    • ‫PROJECT_ID: מזהה הפרויקט ב- Google Cloud .
    • ‫COMPUTE_REGION_TERRAFORM_STATE: אזור המחשוב שבו רוצים לאחסן את המצב של פריסת Terraform.
  4. ב-examples/gke-h4d/gke-h4d-deployment.yaml blueprint מתוך מאגר GitHub, ממלאים את ההגדרות הבאות בקטעים terraform_backend_defaults ו-vars בהתאם לערכים הספציפיים של הפריסה:

    • ‫DEPLOYMENT_NAME: שם ייחודי לפריסה, באורך של 6 עד 30 תווים. אם שם הפריסה לא ייחודי בפרויקט, יצירת האשכול נכשלת. ערך ברירת המחדל הוא gke-h4d.
    • ‫BUCKET_NAME: השם של קטגוריית Cloud Storage שיצרתם בשלב הקודם.
    • ‫PROJECT_ID: מזהה הפרויקט ב- Google Cloud .
    • ‫COMPUTE_REGION: אזור החישוב של האשכול, שחייב להיות זהה לאזור שבו המכונות זמינות לשמירת המקום.
    • ‫COMPUTE_ZONE: אזור החישוב של מאגר הצמתים של מכונות H4D. שימו לב שאזור הזמן הזה צריך להיות זהה לאזור הזמן שבו המכונות זמינות בהזמנה.
    • ‫NODE_COUNT: מספר הצמתים מסוג H4D באשכול.
    • ‫IP_ADDRESS/SUFFIX: טווח כתובות ה-IP שרוצים לאפשר להן להתחבר לאשכול. בלוק ה-CIDR הזה חייב לכלול את כתובת ה-IP של המכונה שבה רוצים להשתמש כדי להפעיל את Terraform. מידע נוסף זמין במאמר בנושא הסבר על רשתות מורשות.
    • בשדה reservation, משתמשים באחת מהאפשרויות הבאות, בהתאם לשאלה אם רוצים לטרגט בלוקים ספציפיים בהזמנה כשמבצעים הקצאה של מאגר הצמתים:

      • כדי למקם את מאגר הצמתים בכל מקום בהזמנה, צריך לציין את שם ההזמנה (RESERVATION_NAME).
      • כדי לטרגט בלוק ספציפי בתוך ההזמנה, משתמשים בשמות של ההזמנה והבלוק בפורמט הבא:

          RESERVATION_NAME/reservationBlocks/BLOCK_NAME
        

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

  5. יוצרים Application Default Credentials ‏ (ADC) כדי לספק גישה ל-Terraform. אם אתם משתמשים ב-Cloud Shell, אתם יכולים להריץ את הפקודה הבאה:

    gcloud auth application-default login
    
  6. פורסים את תוכנית האב כדי להקצות את התשתית של GKE באמצעות סוגי המכונות H4D:

    ./gcluster deploy -d examples/gke-h4d/gke-h4d-deployment.yaml examples/gke-h4d/gke-h4d.yaml
    
  7. כשמופיעה בקשה, לוחצים על (A)pply (החלה) כדי לפרוס את תוכנית האב.

  8. בנוסף, תוכנית ה-blueprint הזו מספקת מופע של Filestore ומקשרת אותו לאשכול GKE עם נפח אחסון קבוע (PV). התבנית הזו כוללת תבנית לדוגמה של Job. בתבנית הזו מופעלת משימה מקבילית שקוראת נתונים וכותבת אותם בנפח האחסון המשותף הזה. הפלט של הפריסה כולל kubectl create שאפשר להשתמש בו כדי להפעיל את עבודת הדגימה.

Google Cloud CLI

מחליפים את הערכים הבאים בפקודות שבקטע הזה:

  • ‫PROJECT_ID: מזהה הפרויקט ב- Google Cloud .
  • ‫CLUSTER_NAME: השם של האשכול.
  • ‫CONTROL_PLANE_LOCATION: המיקום ב-Compute Engine של מישור הבקרה של האשכול. מציינים אזור לאשכולות אזוריים או אזור זמין לאשכולות אזוריים. מומלץ להשתמש באשכולות אזוריים לעומסי עבודה בסביבת ייצור. במקרה של אשכולות אזוריים, האזור צריך לכלול אזור שבו זמין H4D. במקרה של אשכולות אזוריים, האזור צריך להיות זמין לשימוש ב-H4D. אם אתם משתמשים בהזמנה, האזור והתחום צריכים להיות זהים לאזור ולתחום של ההזמנה.
  • ‫COMPUTE_ZONE: האזור של מאגר הצמתים. האזור הזה חייב להיות אזור שבו זמין H4D. אם משתמשים בשמירת משאבים, האזור והתחום צריכים להיות זהים לאזור ולתחום של שמירת המשאבים. אי אפשר ליצור מאגר צמתים מרובה אזורים אם רוצים שהצמתים מסוג H4D יעבדו עם Cloud RDMA.
  • ‫RDMA_NETWORK_PREFIX: הקידומת של רשת ה-RDMA (לדוגמה, h4d-rdma).
  • ‫RDMA_SUBNET_CIDR: טווח ה-CIDR של תת-רשת RDMA. מוודאים שהטווח הזה לא חופף לרשתות ברירת המחדל של האשכול.
  • ‫NODE_POOL_NAME: השם של מאגר הצמתים H4D.
  • ‫NODE_COUNT: מספר צמתי H4D שייווצרו במאגר הצמתים.
  • ‫H4D_MACHINE_TYPE: סוג מכונת H4D לשימוש (לדוגמה, h4d-highmem-192-lssd).

כדי ליצור אשכול באמצעות ה-CLI של gcloud:

  1. יצירת רשתות VPC ורשתות משנה: מגדירים את ברירת המחדל של הענן הווירטואלי הפרטי (VPC) ושל רשת המשנה של האשכול. עבור כרטיס רשת (NIC) של IRDMA, יוצרים VPC ותת-רשת ייעודיים. רשת ה-VPC שנוצרת באמצעות ההוראות הבאות משתמשת בפרופיל של רשת Falcon VPC, כנדרש.

    1. יוצרים VPC לממשק הרשת של IRDMA שמשתמש בפרוטוקול התעבורה RDMA over Falcon:

      gcloud compute --project=PROJECT_ID \
        networks create RDMA_NETWORK_PREFIX-net \
        --network-profile=COMPUTE_ZONE-vpc-falcon \
        --subnet-mode=custom
      
    2. יוצרים תת-רשת לרשת ה-VPC של Falcon:

      gcloud compute --project=PROJECT_ID \
        networks subnets create \
        RDMA_NETWORK_PREFIX-sub-0 \
        --network=RDMA_NETWORK_PREFIX-net \
        --region=CONTROL_PLANE_LOCATION \
        --range=RDMA_SUBNET_CIDR
      
  2. יצירת אשכול GKE עם כמה רשתות: יוצרים את האשכול. אפשר גם להשתמש בפקודה הזו כדי לציין במפורש את טווחי ה-CIDR המשניים של השירותים וה-Pods.

    מריצים את הפקודה הבאה:

    gcloud container clusters create CLUSTER_NAME --project PROJECT_ID \
      --enable-dataplane-v2 --enable-ip-alias --location=CONTROL_PLANE_LOCATION \
      --enable-multi-networking \
      [--services-ipv4-cidr=SERVICE_CIDR \
      --cluster-ipv4-cidr=POD_CIDR]
    

    אם משתמשים בדגלים האופציונליים האלה, צריך להחליף את הערכים הנוספים הבאים:

    • ‫SERVICE_CIDR: טווח ה-CIDR המשני של השירותים.
    • ‫POD_CIDR: טווח ה-CIDR המשני של ה-Pods.

    כשמשתמשים בדגלים האלה, צריך לוודא שאין חפיפה בין טווחי ה-CIDR לבין טווחי רשתות המשנה של רשתות צמתים נוספות. לדוגמה, SERVICE_CIDR=10.65.0.0/19 ו-POD_CIDR=10.64.0.0/19.

  3. יצירת אובייקטים של רשת GKE: מגדירים את רשת ה-VPC באמצעות קבוצות של פרמטרים של רשת GKE. החלת האובייקטים GKENetworkParamSet ו-Network:

    kubectl apply -f - <<EOF
    apiVersion: networking.gke.io/v1
    kind: GKENetworkParamSet
    metadata:
      name: rdma-0
    spec:
      vpc: RDMA_NETWORK_PREFIX-net
      vpcSubnet: RDMA_NETWORK_PREFIX-sub-0
      deviceMode: RDMA
    ---
    apiVersion: networking.gke.io/v1
    kind: Network
    metadata:
      name: rdma-0
    spec:
      type: "Device"
      parametersRef:
        group: networking.gke.io
        kind: GKENetworkParamSet
        name: rdma-0
    EOF
    
  4. יצירת מאגר צמתים מסוג H4D: יוצרים מאגר צמתים שמשתמש ב-H4D ומתחבר לרשת ה-VPC של Falcon. אפשר להשתמש בצמתי H4D שמוגבלים להזמנה ובמיקום קומפקטי. אפשר גם להשתמש בצמתי H4D שהוקצו עם flex-start. בוחרים את הכרטיסייה שמתאימה לאפשרות הצריכה שלכם:

    הזמנה מראש

    1. יוצרים מדיניות משאבים למיקום קומפקטי. מיקום קומפקטי מאפשר אופטימיזציה של הביצועים לעומסי עבודה של HPC עם צימוד חזק, שפועלים בכמה צמתים, על ידי הבטחה שהצמתים ממוקמים פיזית זה ביחס לזה בתוך אזור.

      מריצים את הפקודה הבאה:

      gcloud compute resource-policies create group-placement POLICY_NAME \
          --region REGION --collocation collocated
      

      מחליפים את הערכים הבאים:

      • ‫POLICY_NAME: שם מדיניות המשאבים (לדוגמה, h4d-compact).
      • ‫REGION: האזור של האשכול.
    2. יוצרים מאגר צמתים שמשתמש ב-H4D ומתחבר לרשת RDMA:

      gcloud container node-pools create NODE_POOL_NAME --project PROJECT_ID \
        --location=CONTROL_PLANE_LOCATION --cluster CLUSTER_NAME --num-nodes=NODE_COUNT \
        --node-locations=COMPUTE_ZONE \
        --machine-type H4D_MACHINE_TYPE \
        --additional-node-network network=RDMA_NETWORK_PREFIX-net,subnetwork=RDMA_NETWORK_PREFIX-sub-0 \
        --placement-policy POLICY_NAME \
        --max-surge-upgrade 0  \
        --max-unavailable-upgrade MAX_UNAVAILABLE
      

      מחליפים את MAX_UNAVAILABLE במספר המקסימלי של הצמתים שיכולים להיות לא זמינים בו-זמנית במהלך שדרוג של מאגר צמתים. כדי להשתמש במיקום קומפקטי, מומלץ לבצע שדרוגים מהירים ללא עליות פתאומיות כדי להגדיל את הסיכוי למצוא צמתים במיקום משותף במהלך השדרוגים.

    התחלה גמישה (Flex-start)

    יוצרים מאגר צמתים שמשתמש בצומתי H4D שהוקצו עם התחלה גמישה (Flex-start), ומתחבר לרשת ה-VPC של Falcon:

    gcloud container node-pools create NODE_POOL_NAME --project PROJECT_ID \
        --location=CONTROL_PLANE_LOCATION --cluster CLUSTER_NAME \
        --node-locations=COMPUTE_ZONE \
        --machine-type H4D_MACHINE_TYPE \
        --additional-node-network network=RDMA_NETWORK_PREFIX-net,subnetwork=RDMA_NETWORK_PREFIX-sub-0 \
        --flex-start --enable-autoscaling \
        --min-nodes=0 --max-nodes=MAX_NODES --num-nodes=0
    

    מחליפים את MAX_NODES במספר הצמתים המקסימלי להתאמה אוטומטית לעומס (automatic scaling) במאגר הצמתים שצוין בכל אזור.

הכנת קובץ האימג' של Docker

מכינים את קובץ האימג' באמצעות קובץ ה-Dockerfile לדוגמה הבא:

FROM docker.io/rockylinux/rockylinux:8.10

RUN dnf -y install https://depot.ciq.com/public/download/ciq-sigcloud-next-8/ciq-sigcloud-next-8.x86_64/Packages/c/ciq-sigcloud-next-release-6-1.el8_10.cld_next.noarch.rpm
    && dnf -y update ciq-sigcloud-next-release
    && dnf clean all

RUN dnf install rdma-core libibverbs-utils librdmacm-utils infiniband-diags perftest -y

CMD ["sleep", "infinity"]

כדי לדעת אילו קובצי אימג' תומכים ב-IRDMA, קראו את הכרטיסיות Interfaces בטבלאות שבמאמר פרטים על מערכת ההפעלה.

הגדרת המניפסטים ל-RDMA

כדי להפעיל את Cloud RDMA, מוסיפים את ההערות הבאות למטא-נתונים של ה-Pod:

metadata:
  annotations:
    networking.gke.io/default-interface: 'eth0'
    networking.gke.io/interfaces: |
      [
        {"interfaceName":"eth0","network":"default"},
        {"interfaceName":"eth1","network":"rdma-0"},
      ]

בדיקת RDMA באמצעות rping

כדי לוודא שהפונקציונליות של Cloud RDMA פועלת, מריצים את rping בין Pod של שרת ל-Pod של לקוח:

  1. ב-Pod של השרת, מריצים את הפקודה rping:

    rping -s
    
  2. משיגים את כתובת ה-IP הפנימית המשנית של ה-RDMA של ה-Pod של השרת (eth1). צריך להשתמש בכתובת ה-IP המשנית הזו כדי לנתב את התנועה דרך חומרת ה-RDMA, ולא להשתמש בכתובת ה-IP שמוגדרת כברירת מחדל של ה-Pod:

    kubectl exec SERVER_POD_NAME -- ip -4 -o addr show eth1
    

    שימו לב לכתובת ה-IP inet מהפלט. משתמשים בכתובת ה-IP הזו ככתובת ה-IP של eth1 בשלב הבא.

  3. ב-Pod של הלקוח, מריצים את הפקודה rping:

    rping -c -C 2 -d -a SERVER_IP
    

    מחליפים את SERVER_IP בכתובת ה-IP של eth1 שאחזרתם בשלב הקודם.

    אם הפעולה בוצעה ללא שגיאות, הפלט ייראה כך:

    created cm_id 0x5b597bf94800
    cma_event type RDMA_CM_EVENT_ADDR_RESOLVED cma_id 0x5b597bf94800 (parent)
    cma_event type RDMA_CM_EVENT_ROUTE_RESOLVED cma_id 0x5b597bf94800 (parent)
    rdma_resolve_addr - rdma_resolve_route successful
    created pd 0x5b597bf94fa0
    created channel 0x5b597bf96830
    created cq 0x5b597bf94ff0
    created qp 0x5b597bf96c00
    rping_setup_buffers called on cb 0x5b597bf8c820
    allocated & registered buffers...
    cq_thread started.
    cma_event type RDMA_CM_EVENT_ESTABLISHED cma_id 0x5b597bf94800 (parent)
    ESTABLISHED
    rdma_connect successful
    RDMA addr 5b597bf8cd80 rkey dadac8c4 len 64
    send completion
    recv completion
    RDMA addr 5b597bf8cff0 rkey 86ef015f len 64
    send completion
    recv completion
    RDMA addr 5b597bf8cd80 rkey dadac8c4 len 64
    send completion
    recv completion
    RDMA addr 5b597bf8cff0 rkey 86ef015f len 64
    send completion
    recv completion
    rping_free_buffers called on cb 0x5b597bf8c820
    destroy cm_id 0x5b597bf94800
    

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