שמירה ושחזור של סביבות ארגז חול של סוכנים באמצעות תמונות מצב של Pod

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

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

תמונות מצב של Pod ב-GKE מאפשרות לשמור ולשחזר את המצב של סביבות בארגז חול. הפונקציונליות הזו שימושית מהסיבות הבאות:

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

אפשר לצלם תמונה בשתי דרכים:

  • טריגר ידני: אתם יוצרים משאב PodSnapshotManualTrigger כדי להפעיל את ה-snapshot.
  • טריגר של עומס עבודה: האפליקציה בסביבת ארגז החול עצמה מסמנת מתי היא מוכנה לשמירה.

במאמר הזה נסביר איך להפעיל צילום תמונת מצב באופן ידני.

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

  1. בדף לבחירת הפרויקט במסוף Google Cloud , בוחרים פרויקט ב- Google Cloud או יוצרים אותו.

    תפקידים שנדרשים כדי לבחור או ליצור פרויקט

    • Select a project: כדי לבחור פרויקט לא צריך תפקיד IAM ספציפי – אפשר לבחור כל פרויקט שקיבלתם בו תפקיד.
    • יצירת פרויקט: כדי ליצור פרויקט, צריך את התפקיד Project Creator (roles/resourcemanager.projectCreator), שכולל את ההרשאה resourcemanager.projects.create. איך מקצים תפקידים

    כניסה לדף לבחירת הפרויקט

  2. מוודאים שהחיוב מופעל בפרויקט ב- Google Cloud .

  3. מפעילים את ממשקי ה-API של Google Kubernetes Engine,‏ Cloud Storage וניהול זהויות והרשאות גישה (IAM), אם הם עדיין לא מופעלים.

    תפקידים שנדרשים להפעלת ממשקי API

    כדי להפעיל ממשקי API, צריך את ההרשאה serviceusage.services.enable. אם יצרתם את הפרויקט, סביר להניח שכבר יש לכם את ההרשאה הזו דרך התפקיד "בעלים" (roles/owner). אחרת, תוכלו לקבל את ההרשאה הזו דרך התפקיד "אדמין בממשק 'שימוש בשירות'" (roles/serviceusage.serviceUsageAdmin). איך מקצים תפקידים

    הפעלת ממשקי ה-API

  4. במסוף Google Cloud , מפעילים את Cloud Shell.

    הפעלת Cloud Shell

דרישות

כדי ליצור תמונות מצב של Pod ב-GKE, צריך להשתמש בגרסה ‎1.35.3-gke.1234000 ואילך של GKE. יש תמיכה גם במצב Autopilot וגם במצב רגיל.

מכיוון שתמונות מצב של Pod דורשות את GKE Sandbox, הסביבה שלכם כפופה למגבלות מסוימות. לדוגמה, תמונות מצב של Pod לא תומכות בסוגי מכונות E2. לכן, במדריך הזה נוצר מאגר צמתים שמורכב ממכונות N2.

רשימה מלאה של ההגבלות, כולל מידע על שימוש בסוגי מכונות מבוססי-GPU, מופיעה במאמר הגבלות ודרישות.

הגדרת משתני סביבה

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

אחרי שמגדירים את המשתנים האלה, אפשר להשתמש בהם שוב בכמה פקודות על ידי הפניה לשם המשתנה (לדוגמה, $CLUSTER_NAME) במקום להקליד מחדש או להחליף ערכים בכל פעם. הגישה הזו מקלה על המעקב אחרי התהליך ומפחיתה את הסיכון לשגיאות.

כדי להגדיר את משתני הסביבה השימושיים הבאים ב-Cloud Shell, מריצים את הפקודות הבאות:

export PROJECT_ID=$(gcloud config get project)
export CLUSTER_NAME="agent-sandbox-cluster"
export GKE_LOCATION="us-central1"
export CLUSTER_VERSION="1.35.3-gke.1234000"
export AGENT_SANDBOX_VERSION="v0.4.6"
export NODE_POOL_NAME="agent-sandbox-node-pool"
export MACHINE_TYPE="n2-standard-2"
export SNAPSHOTS_BUCKET_NAME="agent-sandbox-snapshots-${PROJECT_ID}"
export SNAPSHOT_NAMESPACE="pod-snapshots-ns"
export SNAPSHOT_KSA_NAME="pod-snapshot-sa"
export SNAPSHOT_FOLDER="my-snapshots"
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")

הנה הסבר על משתני הסביבה האלה:

  • ‫PROJECT_ID: המזהה של הפרויקט הנוכחי ב- Google Cloud . הגדרת המשתנה הזה עוזרת לוודא שכל המשאבים, כמו אשכול GKE, נוצרים בפרויקט הנכון.
  • ‫CLUSTER_NAME: השם של אשכול GKE (לדוגמה, agent-sandbox-cluster).
  • ‫GKE_LOCATION: האזור שבו ייצור אשכול Google Cloud GKE (לדוגמה, us-central1).
  • ‫CLUSTER_VERSION: הגרסה של אשכול GKE, שצריכה להיות גרסה 1.35.3-gke.1234000 ואילך.
  • ‫AGENT_SANDBOX_VERSION: הגרסה של בקר ארגז החול של הסוכן שרוצים לפרוס באשכול.
  • ‫NODE_POOL_NAME: השם של מאגר הצמתים שיפעיל עומסי עבודה בסביבת ארגז חול (לדוגמה, agent-sandbox-node-pool).
  • ‫MACHINE_TYPE: סוג המכונה של הצמתים במאגר הצמתים (לדוגמה, n2-standard-2). קובצי Snapshot של Pod לא תומכים בסוגי מכונות E2. אם רוצים להשתמש בסוגי מכונות מבוססי-GPU לצמתים במאגר הצמתים, אפשר לעיין במאמר מגבלות ודרישות. לפרטים על סדרות שונות של מכונות ולמידע על בחירה בין אפשרויות שונות, אפשר לעיין במאמר השוואה בין משפחות של מכונות ומשאבים.
  • ‫SNAPSHOTS_BUCKET_NAME: השם של קטגוריה של Cloud Storage שתיצרו כדי לאחסן קובצי snapshot.
  • ‫SNAPSHOT_NAMESPACE: מרחב השמות של Kubernetes שבו יימצאו עומס העבודה וחשבון השירות של התמונה.
  • ‫SNAPSHOT_KSA_NAME: השם של חשבון השירות ב-Kubernetes שעומס העבודה ישתמש בו לאימות.
  • ‫SNAPSHOT_FOLDER: הספרייה בתוך הקטגוריה של Cloud Storage שבה יאורגנו התמונות.
  • ‫PROJECT_NUMBER: המזהה המספרי הייחודי של הפרויקט, שמשמש לקישורי הרשאות IAM.

סקירה כללית של שלבי ההגדרה

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

מושגים מרכזיים

  • סביבה: אפליקציה בארגז חול פועלת בתוך Pod של Kubernetes בצומת של אשכול GKE.
  • זהות: ה-Pod משויך לחשבון שירות של Kubernetes ופועל במרחב שמות מיוחד שאתם יוצרים. חשבון השירות של Kubernetes ומרחב השמות יוצרים יחד זהות ייחודית שמשמשת להענקת גישה מאובטחת של ה-Pod ל Google Cloud משאבים.
  • הרשאות: כדי לאפשר שמירת תמונות מצב ב-Cloud Storage, צריך לתת לזהות של ה-Pod הרשאות IAM ספציפיות שמאפשרות לה לכתוב לקטגוריה של Cloud Storage.

תהליך יצירת תמונת המצב

  1. טריגר: צילום מצב מתחיל, באופן ידני (מחוץ לארגז החול) או על ידי עומס העבודה בארגז החול עצמו. במסמך הזה מוצג טריגר ידני שמופעל על ידי יצירת מקור נתונים מסוג PodSnapshotManualTrigger.
  2. תיעוד: GKE מתעד את מצב ההפעלה של ה-Pod, כמו מצב הזיכרון של ה-Pod ומערכת הקבצים שלו.
  3. העלאה: באמצעות ההרשאות שניתנו לחשבון השירות של Kubernetes של ה-Pod, ‏ GKE מעלה את המצב שתועד כקבצים של תמונת מצב לקטגוריה של Cloud Storage שצוינה.

מידע נוסף על השימוש בחשבונות שירות של Kubernetes ובתפקידי IAM ב-GKE כדי לגשת למשאבים Google Cloud זמין במאמר אימות ל- Google Cloud APIs מעומסי עבודה ב-GKE.

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

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

נושא משימה
הגדרת אשכול 1. יוצרים אשכול GKE ומפעילים את התכונות "תמונות מצב של Pod" ו"איחוד זהויות של עומסי עבודה ל-GKE".
‫2. פורסים את ארגז החול של הסוכן.
הגדרת אחסון והרשאות 1. יוצרים את הקטגוריה של Cloud Storage ואת התיקייה המנוהלת.
2. יוצרים את תפקיד ה-IAM בהתאמה אישית.
3. יוצרים את מרחב השמות של Kubernetes ואת חשבון השירות של Kubernetes‏ (KSA).
‫4. מקשרים את התפקיד ב-IAM לחשבון השירות ב-Kubernetes.
‫5. מעניקים הרשאות לבקר של התמונה המיידית.
הגדרת משאבי תמונת מצב 1. יצירה PodSnapshotStorageConfig
2. יצירה PodSnapshotPolicy
3. יצירה של SandboxTemplate

הגדרת אשכול

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

יצירת אשכול GKE חדש שעומד בדרישות

יוצרים אשכול GKE חדש עם הפעלת תמונות מצב של Pod. כדי להבטיח תאימות מלאה של התכונות, צריך לציין גרסת אשכול ‎1.35.3-gke.1234000 ואילך:

טייס אוטומטי

יוצרים אשכול Autopilot עם התכונות הנדרשות:

gcloud container clusters create-auto ${CLUSTER_NAME} \
   --cluster-version=${CLUSTER_VERSION} \
   --enable-pod-snapshots \
   --location=${GKE_LOCATION}

רגילה

יוצרים אשכול Standard עם התכונות הנדרשות:

gcloud container clusters create ${CLUSTER_NAME} \
   --cluster-version=${CLUSTER_VERSION} \
   --enable-pod-snapshots \
   --machine-type=${MACHINE_TYPE} \
   --workload-pool=${PROJECT_ID}.svc.id.goog \
   --workload-metadata=GKE_METADATA \
   --num-nodes=1 \
   --location=${GKE_LOCATION}

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

gcloud container node-pools create ${NODE_POOL_NAME} \
   --cluster ${CLUSTER_NAME} \
   --num-nodes=1 \
   --location=${GKE_LOCATION} \
   --project=${PROJECT_ID} \
   --machine-type=${MACHINE_TYPE} \
   --sandbox type=gvisor

אחזור פרטי הכניסה

מאחזרים את פרטי הכניסה של האשכול כדי שממשק ה-CLI של kubectl יוכל להתחבר לאשכול:

gcloud container clusters get-credentials ${CLUSTER_NAME} \
    --location=${GKE_LOCATION}

פריסת Agent Sandbox Controller באשכול

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

כדי לפרוס את Agent Sandbox לאשכול GKE, מריצים את הפקודה הבאה:

# Apply the main manifest for the controller and its Custom Resource Definitions (CRDs)
kubectl apply \
-f https://github.com/kubernetes-sigs/agent-sandbox/releases/download/${AGENT_SANDBOX_VERSION}/manifest.yaml \
-f https://github.com/kubernetes-sigs/agent-sandbox/releases/download/${AGENT_SANDBOX_VERSION}/extensions.yaml

אימות הבקר

אחרי שמחילים את המניפסטים, בודקים שה-Pod של בקר Agent Sandbox פועל כמו שצריך במרחב השמות agent-sandbox-system. קובצי המניפסט יצרו אוטומטית את מרחב השמות agent-sandbox-system כשמחילים אותם בשלב הקודם.

kubectl get pods -n agent-sandbox-system

מחכים עד שהסטטוס של ה-Pod יהיה Running (פועל) בעמודה STATUS, ועד שיופיע הערך 1/1 בעמודה READY. כשה-Pod פועל בצורה תקינה, הפלט נראה כך:

NAME                         READY   STATUS    RESTARTS   AGE
agent-sandbox-controller-0      1/1     Running   0          44d

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

הגדרת האחסון וההרשאות

בקטע הזה מוסבר איך להגדיר את האחסון וההרשאות שנדרשים לצילומי מצב של Pod. יוצרים קטגוריה של Cloud Storage ותיקייה מנוהלת כדי לאחסן את נתוני קובץ ה-snapshot. לאחר מכן, מעניקים לארגז החול ולבקר של התמונה המיידית את ההרשאות שהם צריכים כדי לגשת לאחסון הזה.

יצירת קטגוריה של Cloud Storage

יוצרים קטגוריה לאחסון קובצי ה-snapshot. כדי להבטיח שתהליך יצירת התמונה יהיה מהיר וחסכוני, מומלץ ליצור את הדלי עם ההגדרות הבאות:

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

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

gcloud storage buckets create "gs://${SNAPSHOTS_BUCKET_NAME}" \
    --uniform-bucket-level-access \
    --enable-hierarchical-namespace \
    --soft-delete-duration=0d \
    --location="${GKE_LOCATION}"

יצירת תיקייה מנוהלת

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

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

gcloud storage managed-folders create "gs://${SNAPSHOTS_BUCKET_NAME}/${SNAPSHOT_FOLDER}/"

הגדרת חשבון השירות ותפקידי IAM

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

  1. יוצרים תפקיד IAM בהתאמה אישית בשם podSnapshotGcsReadWriter שמכיל את ההרשאות שנדרשות לכתיבת נתוני תמונת מצב:

    gcloud iam roles create podSnapshotGcsReadWriter \
        --project="${PROJECT_ID}" \
        --permissions="storage.objects.get,storage.objects.create,storage.objects.delete,storage.folders.create"
    

    כשהתפקיד נוצר, הפלט נראה כך:

    Created role [podSnapshotGcsReadWriter].
    etag: BwZJUfjNbew=
    includedPermissions:
    - storage.folders.create
    - storage.objects.create
    - storage.objects.delete
    - storage.objects.get
    name: projects/${PROJECT_ID}/roles/podSnapshotGcsReadWriter
    stage: ALPHA
    title: podSnapshotGcsReadWriter
    
  2. יוצרים את מרחב השמות שבו יימצאו ארגז החול וחשבון השירות שלו:

    kubectl create namespace "${SNAPSHOT_NAMESPACE}"
    
  3. יוצרים את חשבון השירות של Kubernetes במרחב השמות שיצרתם. ביחד, חשבון השירות של Kubernetes ומרחב השמות יוצרים זהות ייחודית שמשמשת להענקת גישה מאובטחת לארגז החול שלכם למשאבים הבאים: Google Cloud

    kubectl create serviceaccount "${SNAPSHOT_KSA_NAME}" \
        --namespace "${SNAPSHOT_NAMESPACE}"
    
  4. מקצים את התפקיד roles/storage.bucketViewer לכל חשבונות השירות במרחב השמות. התפקיד הזה מאפשר לחשבונות להציג את המטא-נתונים של הקטגוריה, אבל לא לקרוא או לכתוב את הנתונים עצמם:

    gcloud storage buckets add-iam-policy-binding "gs://${SNAPSHOTS_BUCKET_NAME}" \
        --member="principalSet://iam.googleapis.com/projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/${PROJECT_ID}.svc.id.goog/namespace/${SNAPSHOT_NAMESPACE}" \
        --role="roles/storage.bucketViewer"
    
  5. מקצים את התפקיד podSnapshotGcsReadWriter בהתאמה אישית לחשבון השירות של Kubernetes בסביבת הארגז. הקישור הזה מאפשר רק לחשבון הספציפי הזה לכתוב נתונים בתיקייה המנוהלת:

    gcloud storage buckets add-iam-policy-binding "gs://${SNAPSHOTS_BUCKET_NAME}" \
        --member="principal://iam.googleapis.com/projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/${PROJECT_ID}.svc.id.goog/subject/ns/${SNAPSHOT_NAMESPACE}/sa/${SNAPSHOT_KSA_NAME}" \
        --role="projects/${PROJECT_ID}/roles/podSnapshotGcsReadWriter"
    
  6. מקצים את התפקיד roles/storage.objectUser לחשבון השירות של Kubernetes. התפקיד הזה נדרש כדי שסוכן תמונת המצב של Pod יוכל לבצע פעולות בתיקיות מנוהלות:

    gcloud storage buckets add-iam-policy-binding "gs://${SNAPSHOTS_BUCKET_NAME}" \
        --member="principal://iam.googleapis.com/projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/${PROJECT_ID}.svc.id.goog/subject/ns/${SNAPSHOT_NAMESPACE}/sa/${SNAPSHOT_KSA_NAME}" \
        --role="roles/storage.objectUser"
    

מתן הרשאות לבקר של תמונת המצב

נותנים את התפקיד objectUser לבקר של תמונת המצב של מערכת GKE. ההרשאה הזו מאפשרת לבקר לנהל את מחזור החיים של התמונה, למשל למחוק אובייקטים של תמונות מצב כשמוחקים משאב PodSnapshot:

gcloud storage buckets add-iam-policy-binding "gs://${SNAPSHOTS_BUCKET_NAME}" \
    --member="serviceAccount:service-${PROJECT_NUMBER}@container-engine-robot.iam.gserviceaccount.com" \
    --role="roles/storage.objectUser"

הגדרת משאבי snapshot

בקטע הזה מוסבר איך להגדיר את משאבי התמונות של עומס העבודה של Agent Sandbox.

הגדרת אחסון וכללים לצילום מסך

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

  • ‫PodSnapshotStorageConfig: המשאב הזה מציין את המיקום של הקטגוריה והתיקייה ב-Cloud Storage שבהם GKE שומר את קובצי התמונות של מצב המערכת.
  • ‫PodSnapshotPolicy: המשאב הזה מגדיר אילו Pods מתאימים לתמונות מצב על סמך תוויות ה-Kubernetes שלהם. היא גם מציינת את כללי ההפעלה, למשל אם הצילומים הם ידניים או מופעלים על ידי עומס העבודה של ארגז החול.

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

kubectl apply -f - <<EOF
apiVersion: podsnapshot.gke.io/v1
kind: PodSnapshotStorageConfig
metadata:
  name: cpu-pssc-gcs
spec:
  snapshotStorageConfig:
    gcs:
      bucket: "${SNAPSHOTS_BUCKET_NAME}"
      path: "${SNAPSHOT_FOLDER}"
EOF

sleep 5

kubectl apply -f - <<EOF
apiVersion: podsnapshot.gke.io/v1
kind: PodSnapshotPolicy
metadata:
  name: cpu-psp
  namespace: ${SNAPSHOT_NAMESPACE}
spec:
  storageConfigName: cpu-pssc-gcs
  selector:
    matchLabels:
      app: agent-sandbox-workload
  triggerConfig:
    type: manual
    postCheckpoint: resume
EOF

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

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

  1. בודקים את הסטטוס של המשאב PodSnapshotStorageConfig:

    kubectl get podsnapshotstorageconfigs.podsnapshot.gke.io cpu-pssc-gcs \
      --namespace "${SNAPSHOT_NAMESPACE}" -o yaml
    

    הפלט צריך לכלול תנאי עם type: Ready ו-status: "True":

    status:
      conditions:
      - lastTransitionTime: "2025-10-31T18:18:02Z"
        message: Valid PodSnapshotStorageConfig
        reason: StorageConfigValid
        status: "True"
        type: Ready
    
  2. בודקים את הסטטוס של המשאב PodSnapshotPolicy:

    kubectl get podsnapshotpolicies.podsnapshot.gke.io cpu-psp \
      --namespace "${SNAPSHOT_NAMESPACE}" -o yaml
    

    הפלט צריך לכלול תנאי עם type: Ready ו-status: "True". בנוסף, צריך לציין שההפניה אל PodSnapshotStorageConfig נמצאה:

    status:
      conditions:
      - lastTransitionTime: "2025-10-31T18:19:47Z"
        message: The referenced PodSnapshotStorageConfig "cpu-pssc-gcs" was found
        reason: StorageConfigValid
        status: "True"
        type: Ready
    

יצירת תבנית של ארגז חול

אחרי שהגדרתם את כללי המדיניות וההרשאות של האחסון, אתם יכולים ליצור את המשאבים SandboxTemplate ו-SandboxClaim. כדי שתהליך יצירת קובץ ה-snapshot יפעל, צריך להריץ את ארגז החול עם חשבון השירות של Kubernetes שיצרתם קודם לכן במסמך הזה. בארגז החול צריכות להיות גם התוויות שציינתם קודם בPodSnapshotPolicy.

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

טייס אוטומטי

תמונות מצב של Pod לא תומכות בסוגי מכונות E2. ב-Autopilot, יכול להיות ש-GKE יגדיר כברירת מחדל סוגי מכונות שלא תומכים בתמונות מצב של Pod. כדי לוודא שעומסי העבודה שלכם יפעלו על חומרה תואמת, מומלץ להשתמש בComputeClass מותאם אישית כדי לתת עדיפות לסדרות מכונות תואמות.

  1. שומרים את קובץ המניפסט הבא בשם non-e2-class.yaml:

    apiVersion: cloud.google.com/v1
    kind: ComputeClass
    metadata:
      name: non-e2-class
    spec:
      priorities:
      - machineFamily: n2
      - machineFamily: c3
      activeMigration:
        optimizeRulePriority: false
      whenUnsatisfiable: DoNotScaleUp
    
  2. החלת המניפסט:

    kubectl apply -f non-e2-class.yaml
    
  3. כדי ליצור את המשאבים SandboxTemplate ו-SandboxClaim, צריך להחיל את המניפסט הבא. שימו לב שהמחרוזת SandboxTemplate מתייחסת ל-ComputeClass שיצרתם באמצעות בורר הצומת cloud.google.com/compute-class: non-e2-class.

    kubectl apply -f - <<EOF
    ---
    apiVersion: extensions.agents.x-k8s.io/v1alpha1
    kind: SandboxTemplate
    metadata:
      name: python-runtime-template
      namespace: ${SNAPSHOT_NAMESPACE}
    spec:
      podTemplate:
        metadata:
          labels:
            app: agent-sandbox-workload
        spec:
          serviceAccountName: ${SNAPSHOT_KSA_NAME}
          runtimeClassName: gvisor
          nodeSelector:
            cloud.google.com/compute-class: non-e2-class
          containers:
          - name: my-container
            image: python:3.10-slim
            command: ["python3", "-c"]
            args:
              - |
                import time
                i = 0
                while True:
                  print(f"Count: {i}", flush=True)
                  i += 1
                  time.sleep(1)
    ---
    apiVersion: extensions.agents.x-k8s.io/v1alpha1
    kind: SandboxClaim
    metadata:
      name: python-sandbox-example
      namespace: ${SNAPSHOT_NAMESPACE}
      labels:
        app: agent-sandbox-workload
    spec:
      sandboxTemplateRef:
        name: python-runtime-template
    EOF
    

רגילה

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

kubectl apply -f - <<EOF
---
apiVersion: extensions.agents.x-k8s.io/v1alpha1
kind: SandboxTemplate
metadata:
  name: python-runtime-template
  namespace: ${SNAPSHOT_NAMESPACE}
spec:
  podTemplate:
    metadata:
      labels:
        app: agent-sandbox-workload
    spec:
      serviceAccountName: ${SNAPSHOT_KSA_NAME}
      runtimeClassName: gvisor
      containers:
      - name: my-container
        image: python:3.10-slim
        command: ["python3", "-c"]
        args:
          - |
            import time
            i = 0
            while True:
              print(f"Count: {i}", flush=True)
              i += 1
              time.sleep(1)
---
apiVersion: extensions.agents.x-k8s.io/v1alpha1
kind: SandboxClaim
metadata:
  name: python-sandbox-example
  namespace: ${SNAPSHOT_NAMESPACE}
  labels:
    app: agent-sandbox-workload
spec:
  sandboxTemplateRef:
    name: python-runtime-template
EOF

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

יצירת תמונת מצב

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

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

    kubectl logs python-sandbox-example --namespace "${SNAPSHOT_NAMESPACE}" --tail=5
    

    בדוגמה הבאה מוצגות השורות האחרונות של המונה:

    Count: 15
    Count: 16
    Count: 17
    

    שימו לב לכמה ערכי Count (ספירה) האחרונים שהודפסו.

  2. יוצרים משאב PodSnapshotManualTrigger: מפעילים את ה-snapshot:

    kubectl apply -f - <<EOF
    apiVersion: podsnapshot.gke.io/v1
    kind: PodSnapshotManualTrigger
    metadata:
      name: cpu-snapshot-trigger
      namespace: ${SNAPSHOT_NAMESPACE}
    spec:
      targetPod: python-sandbox-example
    EOF
    
  3. מוודאים שהפעלת הטריגר הידנית בוצעה בהצלחה:

    kubectl get podsnapshotmanualtriggers.podsnapshot.gke.io \
      --namespace "${SNAPSHOT_NAMESPACE}"
    

    הפלט צריך להראות סטטוס של Complete, שמציין ש-GKE הפעיל בהצלחה את הצילום של תמונת המצב של ה-Pod של היעד:

    NAME                   TARGET POD               STATUS     AGE
    cpu-snapshot-trigger   python-sandbox-example   Complete   XXs
    
  4. כדי לראות פרטים נוספים על המצב שתועד, צריך לתאר את הטריגר:

    kubectl describe podsnapshotmanualtriggers.podsnapshot.gke.io cpu-snapshot-trigger \
      --namespace "${SNAPSHOT_NAMESPACE}"
    

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

    Status:
      Conditions:
        Last Transition Time:  2026-01-30T19:11:04Z
        Message:               checkpoint completed successfully
        Reason:                Complete
        Status:                True
        Type:                  Triggered
      Observed Generation:     1
      Snapshot Created:
        Name:  <UNIQUE_SNAPSHOT_NAME>
    

שחזור מתמונת מצב

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

  1. כדי לשחזר את ארגז החול, צריך ליצור SandboxClaim חדש:

    kubectl apply -f - <<EOF
    apiVersion: extensions.agents.x-k8s.io/v1alpha1
    kind: SandboxClaim
    metadata:
      name: python-sandbox-from-snapshot
      namespace: ${SNAPSHOT_NAMESPACE}
      labels:
        app: agent-sandbox-workload
    spec:
      sandboxTemplateRef:
        name: python-runtime-template
    EOF
    
  2. כדי לוודא שהשחזור בוצע, בודקים את היומנים. שימו לב שהמונה ממשיך מהנקודה שבה נוצר קובץ ה-snapshot:

    kubectl logs python-sandbox-from-snapshot --namespace "${SNAPSHOT_NAMESPACE}"
    

    בפלט אמור להופיע המונה שממשיך לפעול, לדוגמה:

    Count: 18
    Count: 19
    Count: 20
    Count: 21
    

מחיקת משאבים

כדי להימנע מצבירת חיובים בחשבון Google Cloud על המשאבים שבהם השתמשתם במסמך הזה, מחקו את המשאבים שיצרתם באמצעות הפעולות הבאות:

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

    kubectl delete sandboxclaims --all --namespace "${SNAPSHOT_NAMESPACE}"
    
  2. מוחקים את התבניות של ארגזי החול ואת הטריגרים הידניים ששימשו ליצירת ארגזי החול ולהפעלת תמונות המצב.

    # Delete the blueprints
    kubectl delete sandboxtemplates --all --namespace "${SNAPSHOT_NAMESPACE}"
    
    # Delete the snapshot initiation objects
    kubectl delete podsnapshotmanualtriggers --all --namespace "${SNAPSHOT_NAMESPACE}"
    
  3. מוחקים את מדיניות הצילום שקובעת אילו פודים עומדים בדרישות לצילום תמונות במרחב השמות.

    kubectl delete podsnapshotpolicy cpu-psp --namespace "${SNAPSHOT_NAMESPACE}"
    
  4. מחיקת הגדרת האחסון של הצילום מהמצלמה, שהיא ההגדרה הגלובלית של הקצה העורפי של אחסון הצילום מהמצלמה. מכיוון שהמשאב הזה הוא בהיקף האשכול, אל תשתמשו בדגל של מרחב שמות.

    kubectl delete podsnapshotstorageconfig cpu-pssc-gcs
    
  5. אם יצרתם אחד ל-Autopilot, מחקו את ComputeClass.

    kubectl delete computeclass non-e2-class
    
  6. מחיקת מרחב השמות של Kubernetes כדי להסיר באופן אוטומטי את חשבון השירות של Kubernetes ואת כל המטא-נתונים שנותרו במרחב השמות.

    kubectl delete namespace "${SNAPSHOT_NAMESPACE}"
    
  7. מוחקים את אשכול GKE כדי להסיר את התשתית הבסיסית ואת כל הצמתים שמשויכים למדריך.

    gcloud container clusters delete "${CLUSTER_NAME}" --location="${GKE_LOCATION}" --quiet
    
  8. אם רוצים לאפס את האחסון באופן מלא, אפשר למחוק את הקטגוריה של Cloud Storage (אופציונלי) באמצעות הפקודה recursive remove. שימו לב: אפשר לדלג על השלב הזה אם אתם מתכוונים להשתמש שוב בדלי שהגדרתם בצורה נכונה לבדיקות עתידיות.

    gcloud storage rm --recursive "gs://${SNAPSHOTS_BUCKET_NAME:?Error: SNAPSHOTS_BUCKET_NAME is not set. Please re-define the environment variables you defined earlier.}"
    
  9. אם רוצים להחזיר את הפרויקט למצב נקי לחלוטין, אפשר למחוק את תפקיד ה-IAM המותאם אישית (אופציונלי). תפקידי IAM נשמרים גם אחרי שמוחקים את האשכול, לכן צריך למחוק אותם בנפרד.

    gcloud iam roles delete podSnapshotGcsReadWriter --project="${PROJECT_ID}"
    

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