שימוש במכונות preemptible VM להרצת עומסי עבודה (workloads) עמידים בכשלים

בדף הזה מוסבר איך להשתמש במכונות וירטואליות שניתנות להפסקת פעולה ב-Google Kubernetes Engine ‏ (GKE).

שיטה מומלצת:

מכונות וירטואליות (VM) מסוג Spot הן הגרסה העדכנית של מכונות וירטואליות (VM) זמניות. במקום מכונות וירטואליות שניתנות להפסקת פעולה, מומלץ להשתמש בתאי Spot באשכולות Autopilot או במכונות וירטואליות מסוג Spot באשכולות רגילים. ‫GKE ממשיך לתמוך במכונות וירטואליות שניתן לקטוע את הפעולה שלהן, שבהן נעשה שימוש באותו מודל תמחור כמו במכונות וירטואליות מסוג Spot.

סקירה כללית

מכונות וירטואליות שניתן לקטוע הן מכונות וירטואליות של Compute Engine שמחירן נמוך ממכונות וירטואליות רגילות, ואין עליהן הבטחה לזמינות. מכונות VM שניתן להפסיק מראש מציעות פונקציונליות דומה לזו של מכונות VM זמניות, אבל הן זמינות למשך עד 24 שעות בלבד אחרי היצירה.

במקרים מסוימים, VM זמני עשוי לפעול יותר מ-24 שעות. המצב הזה יכול לקרות אם מופעל מופע חדש של Compute Engine מהר מדי, ו-Kubernetes לא מזהה שנוצרה מכונה וירטואלית אחרת ב-Compute Engine. למופע הבסיסי של Compute Engine יהיה משך זמן מקסימלי של 24 שעות, והוא יפעל בהתאם להתנהגות הצפויה של VM זמני.

השוואה ל-VMs במודל Spot

יש הרבה דמיון בין מכונות וירטואליות זמניות לבין מכונות וירטואליות מסוג Spot, כולל:

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

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

סיום וכיבוי מבוקר של מכונות וירטואליות זמניות

כש-Compute Engine צריך להחזיר את המשאבים שבהם נעשה שימוש במכונות וירטואליות שניתנות להפסקת פעולה, נשלחת הודעה על הפסקת פעולה ל-GKE. מכונות וירטואליות שניתנות להפסקה מסיימות את הפעולה 30 שניות אחרי קבלת הודעת סיום.

כברירת מחדל, באשכולות נעשה שימוש בכיבוי הדרגתי של הצמתים. ‫kubelet מבחין בהודעה על סיום הפעולה ומסיים בצורה מסודרת את הפעלת ה-Pods בצומת. אם הפודים הם חלק מעומס עבודה מנוהל, כמו Deployment, בקר יוצר ומתזמן פודים חדשים כדי להחליף את הפודים שהופסקו.

במקרה הטוב, kubelet מעניק תקופת סיום הדרגתית של 15 שניות ל-Pods שאינם מערכתיים, ולאחר מכן ל-Pods מערכתיים (עם priorityClasses‏ system-cluster-critical או system-node-critical) יש 15 שניות לסיום הדרגתי. במהלך סיום תקין של צומת, ‏ kubelet מעדכן את הסטטוס של ה-Pods ומקצה שלב Failed וסיבה Terminated ל-Pods שהופסקו.

התקופה להפסקת הפעולה של Pods שאינם מערכתיים היא עד 15 שניות. ציון ערך גדול מ-15 שניות בשדה terminationGracePeriodSeconds במניפסט של הפוד לא משפיע. המכונה הווירטואלית כולה מושבתת 30 שניות אחרי הודעת ההקצאה מראש.

שינויים בהתנהגות של Kubernetes

השימוש במכונות וירטואליות שניתנות להפסקת פעולה ב-GKE משנה את ההגנות שמסופקות על ידי Kubernetes PodDisruptionBudgets. החזרת מכונות וירטואליות שניתנות להפסקת פעולה היא לא רצונית ולא נכללת בהגנות של PodDisruptionBudgets. יכול להיות שתיתקלו בבעיות זמינות חמורות יותר מהערך PodDisruptionBudget שהגדרתם.

מגבלות

  • מכונות וירטואליות שניתן לקטוע לא תומכות במאגרי צמתים של Windows Server.
  • במכונות וירטואליות שניתן להפסיק את הפעולה שלהן, אי אפשר לשנות את תקופת החסד של 15 שניות עבור פודים שאינם פודים של המערכת, ואת התקופה הבאה של 15 שניות עבור פודים של המערכת. שדות ההגדרה הבסיסיים shutdownGracePeriod ו-shutdownGracePeriodCriticalPods kubelet לא ניתנים לשינוי. עם זאת, במכונות וירטואליות מסוג Spot אפשר לשנות את ההגדרות האלה. מידע נוסף זמין במאמר סיום והשבתה מסודרת של מכונות וירטואליות מסוג Spot.

יצירת אשכול או מאגר צמתים עם מכונות וירטואליות זמניות

אפשר להשתמש ב-Google Cloud CLI כדי ליצור אשכול או מאגר צמתים עם מכונות וירטואליות שניתנות להפסקת פעולה.

כדי ליצור אשכול עם מכונות וירטואליות שניתנות להפסקת פעולה, מריצים את הפקודה הבאה:

gcloud container clusters create CLUSTER_NAME \
    --preemptible

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

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

gcloud container node-pools create POOL_NAME \
    --cluster=CLUSTER_NAME \
    --preemptible

מחליפים את POOL_NAME בשם של מאגר הצמתים החדש.

שימוש ב-nodeSelector לתזמון של Pods במכונות וירטואליות זמניות

‫GKE מוסיף את התוויות cloud.google.com/gke-preemptible=true ו-cloud.google.com/gke-provisioning=preemptible לצמתים שמשתמשים במכונות וירטואליות שניתנות להפסקת פעולה. אתם יכולים להשתמש ב-nodeSelector בפריסות כדי להנחות את GKE לתזמן Pods במכונות וירטואליות שניתן להפסיק את הפעולה שלהן.

לדוגמה, הפריסה הבאה מסננת מכונות וירטואליות שניתנות להפסקת פעולה באמצעות התווית cloud.google.com/gke-preemptible:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello-app
  template:
    metadata:
      labels:
        app: hello-app
    spec:
      containers:
      - name: hello-app
        image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0
        resources:
          requests:
            cpu: 200m
      nodeSelector:
        cloud.google.com/gke-preemptible: "true"

שימוש ב-taints של צמתים למכונות וירטואליות (VM) זמניות

אפשר להוסיף כתם לצמתים שמשתמשים במכונות וירטואליות שניתנות להפסקת פעולה, כדי ש-GKE יוכל להציב בצמתים האלה רק קבוצות Pod עם הסבילות המתאימה.

כדי להוסיף taint לצומת למאגר צמתים שמשתמש במכונות וירטואליות זמניות, משתמשים בדגל --node-taints כשיוצרים את מאגר הצמתים, בדומה לפקודה הבאה:

gcloud container node-pools create POOL2_NAME \
    --cluster=CLUSTER_NAME \
    --node-taints=cloud.google.com/gke-preemptible="true":NoSchedule

מעכשיו, רק פודים שיכולים לפעול עם ההכתמה של הצומת מתוזמנים לצומת.

כדי להוסיף את ה-toleration הרלוונטי ל-Pods, משנים את הפריסות ומוסיפים את השורה הבאה למפרט ה-Pod:

tolerations:
- key: cloud.google.com/gke-preemptible
  operator: Equal
  value: "true"
  effect: NoSchedule

Node taints for GPU preemptible VMs

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

אם יוצרים אשכול חדש עם מאגרי צמתים של GPU שמשתמשים ב-VM שניתן להפסיק, או אם מוסיפים מאגר צמתים חדש של GPU שמשתמש ב-VM שניתן להפסיק לאשכול שעדיין אין לו מאגר צמתים רגיל, GKE לא מוסיף אוטומטית את ה-taint‏ nvidia.com/gpu=present:NoSchedule לצמתים. יכול להיות ש-GKE יתזמן Pods של המערכת במכונות וירטואליות זמניות, וזה עלול לגרום לשיבושים. ההתנהגות הזו גם מגדילה את צריכת המשאבים, כי צמתים של GPU יקרים יותר מצמתים ללא GPU.

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