הגדרת צמתים לשימוש בנפח האחסון כזיכרון וירטואלי

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

מתי כדאי להשתמש בהחלפת זיכרון של צומת

כדאי להשתמש בהחלפת זיכרון של צומת כדי לספק מאגר נתונים זמני (buffer) נגד שגיאות OOM באפליקציות שצורכות הרבה זיכרון, במיוחד במהלך עליות חדות ובלתי צפויות בשימוש. החלפת זיכרון של צומת יכולה לעזור לשפר את העמידות של עומס העבודה, למשל בתרחישים הבאים:

  • להריץ עומסי עבודה עם דפוסי זיכרון בלתי צפויים.
  • להפחית את הסיכון לקריסת אפליקציות בגלל ניצול מלא של זיכרון הצומת.
  • אופטימיזציה של העלויות – לא צריך להקצות יותר מדי זיכרון בשביל שיאים מזדמנים.

איך פועלת החלפת הזיכרון של הצומת

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

‫GKE מחשב את מגבלות ההחלפה של קונטיינרים על סמך מגבלות משאבי הזיכרון של הקונטיינר והזיכרון הכולל של הצומת.

אפשר להגדיר החלפה בסוגי אחסון שונים כדי לאזן בין הביצועים לעלות:

  • ‫Boot disk: דיסק האתחול של הצומת משמש כשטח החלפה.
  • Ephemeral Local SSD: משתמש ב-SSD מקומי שמשותף גם עם האחסון הזמני של Pod. אם הצומת משתמש בקיבולת מעורבת של כונני SSD מקומיים, ההחלפה משתמשת רק בחלק של האחסון הזמני בכונני ה-SSD המקומיים.
  • ‫Dedicated Local SSD: הקצאה של כונן SSD מקומי אחד או יותר באופן בלעדי להחלפה.

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

דרישות ומגבלות

אלה הדרישות והמגבלות של החלפת זיכרון בצומת:

  • אשכולות GKE חייבים להיות בגרסה 1.34.1-gke.1341000 ואילך.
  • רק Pods עם מחלקת Burstable Quality of Service (QoS) יכולים להשתמש בהחלפת זיכרון של צומת. מידע נוסף על מחלקות QoS זמין במסמכי התיעוד של Kubernetes בנושא מחלקות איכות השירות של Pod.
  • כדי לשנות את הגודל של משאבי הזיכרון של קונטיינרים, צריך להגדיר את מדיניות שינוי הגודל של הקונטיינר לערך RestartContainer.
  • אם מגדירים החלפת זיכרון של צומת לשימוש בדיסק אתחול, גודל ההחלפה לא יכול להיות יותר מ-50% מהקיבולת הכוללת של דיסק האתחול.

אם אתם מגדירים החלפת זיכרון של צומת לשימוש ב-SSD מקומי, אתם צריכים לוודא שהדרישות הבאות מתקיימות:

  • סוג המכונה חייב לתמוך בכונני SSD מקומיים. אפשר להשתמש רק בכונני SSD מקומיים שהוקצו כאחסון זמני או כאחסון מעורב. אי אפשר להשתמש ב-SSD מקומי שהוקצה כאחסון של מכשיר לאחסון ולאחזור בלוקים גולמיים. לרשימה של פרופילי ההחלפה הנתמכים במצב הזה, ראו החלפת זיכרון צומת עם קיבולת SSD מקומית מעורבת.
  • צריך להקצות לצמתים כונני SSD מקומיים. שיטת ההקצאה תלויה בסדרת המכונות:
    • בסדרות מכונות מהדור הראשון או השני, מגדירים את הדגל --ephemeral-storage-local-ssd=count.
    • בסדרות מכונות מהדור השלישי או הרביעי, בוחרים סוג מכונה שכולל כונני SSD מקומיים.
  • סוג המכונה שמוגדר כברירת מחדל, e2-medium, לא תומך בכונני SSD מקומיים, ולכן צריך לבחור סוג מכונה אחר.
  • במאמר הקצאה ושימוש באחסון זמני שמגובה ב-SSD מקומי מוסבר איך ליצור או לעדכן אשכול כדי להקצות כונני SSD מקומיים.

שיטות מומלצות

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

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

  • מבודדים את הצמתים שבהם מופעלת החלפת זיכרון של צומת, על ידי החלת taint על מאגר הצמתים, לדוגמה gke-swap=enabled:NoSchedule, ומוסיפים toleration תואם לעומסי העבודה שבהם רוצים להשתמש בהחלפה.
  • צריך להגדיר את שטח ההחלפה של זיכרון הצומת בצורה מתאימה. אם אין מספיק זיכרון בצומת, יכול להיות ששטח ההחלפה לא ימנע שגיאות OOM, ושימוש מוגזם עלול לפגוע בביצועים.
  • מעקב אחרי השימוש בשטח ההחלפה של הזיכרון בצומת בעומסי העבודה. שימוש תכוף בהחלפת זיכרון של צומת יכול להעיד על עומס בזיכרון.

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

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

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

הפעלת החלפת זיכרון של צומת

אפשר להפעיל החלפת זיכרון של צומת על בסיס אשכול או מאגר צמתים. כדי להפעיל החלפת זיכרון של צומת, יוצרים או מעדכנים קובץ system-config.yaml שמכיל את הגדרת החלפת הזיכרון של הצומת שרוצים. בדוגמה הבאה מופעלת החלפת זיכרון של צומת עם הגדרות ברירת המחדל:

linuxConfig:
  swapConfig:
    enabled: true

יש הגדרות נוספות שאפשר לקבוע. בדוגמה הזו מגדירים החלפה לא מוצפנת לשימוש ב-30% מהאחסון של כונן SSD מקומי זמני:

linuxConfig:
  swapConfig:
    enabled: true
    encryptionConfig:
      disabled: true
    ephemeralLocalSsdProfile:
      swapSizePercent: 30

רשימה של שדות אופציונליים שאפשר להגדיר מופיעה במסמכי התיעוד של ה-API של LinuxNodeConfig.

הפעלת החלפת זיכרון של צומת באשכול

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

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

    gcloud container clusters create CLUSTER_NAME \
        --location=LOCATION \
        --cluster-version=1.34.1-gke.1341000 \
        --system-config-from-file=system-config.yaml
    

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

    • ‫CLUSTER_NAME: השם של האשכול החדש.
    • ‫LOCATION: האזור או התחום של האשכול.
  • כדי לעדכן אשכול קיים ולהפעיל החלפת זיכרון של צומת, מריצים את הפקודה הבאה:

    gcloud container clusters update CLUSTER_NAME \
        --location=LOCATION \
        --system-config-from-file=system-config.yaml
    

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

    • ‫CLUSTER_NAME: השם של האשכול החדש.
    • ‫LOCATION: האזור או התחום של האשכול.

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

כדי להפעיל החלפת זיכרון של צומת במאגר צמתים, מבצעים את אחת מהפעולות הבאות:

  • כדי ליצור מאגר צמתים חדש עם החלפת זיכרון מופעלת, מריצים את הפקודה הבאה:

    gcloud container node-pools create NODEPOOL_NAME \
        --cluster=CLUSTER_NAME \
        --location=LOCATION \
        --node-version=1.34.1-gke.1293000 \
        --system-config-from-file=system-config.yaml \
        --machine-type=MACHINE_TYPE
    

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

    • ‫NODEPOOL_NAME: השם של מאגר הצמתים החדש.
    • ‫CLUSTER_NAME: שם האשכול.
    • ‫LOCATION: האזור או התחום של האשכול.
    • ‫MACHINE_TYPE: סוג מכונה תואם. ל-SSD מקומיים, חשוב לבחור סוג מכונה שכולל SSD מקומיים, לדוגמה n1-standard-1.
  • כדי לעדכן מאגר צמתים קיים ולהפעיל החלפת זיכרון של צמתים, מריצים את הפקודה הבאה:

    gcloud container node-pools update NODEPOOL_NAME \
        --cluster=CLUSTER_NAME \
        --location=LOCATION \
        --system-config-from-file=system-config.yaml
    

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

    • ‫NODEPOOL_NAME: השם של מאגר הצמתים.
    • ‫CLUSTER_NAME: שם האשכול.
    • ‫LOCATION: האזור או התחום של האשכול.

אימות ההגדרות האישיות

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

  1. כדי לוודא שה-system-config.yaml מופעל עם ההגדרות של swapConfig, מריצים את הפקודה הבאה:

    gcloud container node-pools describe NODEPOOL_NAME \
        --cluster=CLUSTER_NAME \
        --location=LOCATION \
        --format='yaml(config.linuxNodeConfig.swapConfig)'
    
  2. כדי לוודא שההגדרה של kubelet קיימת בצומת, מריצים את הפקודה הבאה:

    kubectl get --raw "/api/v1/nodes/NODE_NAME/proxy/configz" | jq .kubeletconfig.memorySwap
    

מעקב אחרי השימוש בהחלפת זיכרון

אתם יכולים לעקוב אחרי הזיכרון של הצומת באמצעות Cloud Monitoring או kubectl.

מעקב

כברירת מחדל, מדדי המערכת הבאים זמינים לצפייה בשימוש ב-swap:

  • kubernetes.io/node/memory/swap_used_bytes
  • kubernetes.io/container/memory/swap_used_bytes

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

  • prometheus.googleapis.com/container_memory_swap/gauge

kubectl

כדי לעקוב אחרי השימוש ב-swap באמצעות פקודות kubectl:

  1. כדי לבדוק את התנאי SwapDetected באובייקט הצומת, מריצים את הפקודה הבאה:

    kubectl get node NODE_NAME -o jsonpath='{.status.conditions[?(@.type=="Swap")]}' | jq .
    

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

    {
      "lastHeartbeatTime": "2025-07-11T00:14:52Z",
      "lastTransitionTime": "2025-06-25T05:20:10Z",
      "message": "Swap is active: Total=49Gi Used=0B Free=49Gi",
      "reason": "SwapDetected",
      "status": "True",
      "type": "Swap"
    }
    
  2. כדי לבדוק את קיבולת ההחלפה, מריצים את הפקודה הבאה:

    kubectl get node NODE_NAME -o jsonpath='{.status.nodeInfo.swap}'
    

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

    {"capacity":53687087104}
    

החלפת זיכרון של צומת עם קיבולת מעורבת של כונני SSD מקומיים

אפשר להפעיל החלפת זיכרון של צמתים במאגרי צמתים שמקצים כונני SSD מקומיים מעורבים. ‫GKE תומך בפרופילי ההחלפה הבאים:

  • דיסק אתחול (bootDiskProfile)
  • ‫Ephemeral Local SSD (ephemeralLocalSsdProfile): GKE מקצה שטח החלפה מהחלק של האחסון הזמני בכונני ה-SSD המקומיים, ולא מהמחיצות של הבלוקים הגולמיים.

ב-GKE אין תמיכה בפרופיל ההחלפה הייעודי של כונני SSD מקומיים (dedicatedLocalSsdProfile) עם כונני SSD מקומיים משולבים.

אם אתם משתמשים בפרופיל הזמני של Local SSD, חשוב לשים לב לדברים הבאים:

  • השדה swapSizePercent הוא אחוז מהקיבולת הזמנית שהגדרתם בשדה המשנה capacity, ולא הקיבולת הפיזית הכוללת של ה-SSD המקומי. לדוגמה, עם הגדרות כמו capacity=200GB ו-swapSizePercent: 20, ‏GKE מקצה 40GiB של החלפה.
  • שטח ההחלפה מקטין את האחסון הזמני שזמין ל-Pods. ‫GKE מחשב את האחסון הארעי השמור לפי הקיבולת הארעית פחות גודל ההחלפה.
  • גודל ההחלפה לא יכול להיות יותר מ-80% מהקיבולת הזמנית, פחות מהאחסון הזמני ש-GKE שומר לשימוש המערכת. אם הקיבולת הזמנית קטנה מדי בשביל ההחלפה, הבקשה תיכשל.

בקובץ system-config.yaml לדוגמה הבא, 20% מהקיבולת הזמנית מוקצים להחלפה:

linuxConfig:
  swapConfig:
    enabled: true
    ephemeralLocalSsdProfile:
      swapSizePercent: 20

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

gcloud container node-pools create POOL_NAME \
    --cluster=CLUSTER_NAME \
    --machine-type=MACHINE_TYPE \
    --ephemeral-storage-local-ssd count=NUMBER_OF_DISKS,capacity=CAPACITY \
    --system-config-from-file=system-config.yaml

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

  • ‫POOL_NAME: השם של מאגר הצמתים החדש שרוצים ליצור.
  • ‫CLUSTER_NAME: שם האשכול.
  • ‫MACHINE_TYPE: סוג המכונה שבה משתמשים. אי אפשר להשתמש בכונני SSD מקומיים עם סוג המכונה שמוגדר כברירת מחדל (e2-medium), כי סוגי מכונות עם ליבה משותפת (shared-core) לא תומכים בהם.
  • ‫NUMBER_OF_DISKS: מספר הדיסקים מסוג SSD מקומי שצריך להקצות בכל צומת.
  • ‫CAPACITY: הקיבולת הכוללת של כונן ה-SSD המקומי שצריך לפרמט לאחסון זמני. הערך הזה חייב להיות גדול מ-0 וקטן מהקיבולת הפיזית הכוללת של ה-SSD המקומי (מספר הדיסקים × הגודל של כל דיסק), למשל 200GB.

השבתת החלפת הזיכרון של הצומת

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

  1. מעדכנים את הקובץ system-config.yaml כדי להגדיר את swapConfig.enabled לערך false:

    linuxConfig:
      swapConfig:
        enabled: false
    
  2. מעדכנים את מאגר הצמתים עם ההגדרות החדשות:

    gcloud container node-pools update NODEPOOL_NAME \
        --cluster=CLUSTER_NAME \
        --location=LOCATION \
        --system-config-from-file=system-config.yaml
    

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