במאמר הזה מוסבר איך משתמשים בתמונות מצב של Pod ב-GKE כדי לשמור את המצב של סביבת Agent Sandbox שפועלת ב-GKE.
Agent Sandbox ב-GKE משפר את האבטחה כי הוא מספק סביבה מבודדת להרצת קוד לא מהימן, כמו קוד שנוצר על ידי מודלים גדולים של שפה (LLM). הפעלת קוד מהסוג הזה ישירות באשכול כרוכה בסיכוני אבטחה, כי קוד לא מהימן עלול לגשת לאפליקציות אחרות או לצומת האשכול הבסיסי עצמו, או להפריע להם.
תמונות מצב של Pod ב-GKE מאפשרות לשמור ולשחזר את המצב של סביבות בארגז חול. הפונקציונליות הזו שימושית מהסיבות הבאות:
- הפעלה מהירה: הפחתת זמן ההפעלה של ארגז החול על ידי שחזור מתמונת מצב שחוממה מראש.
- סוכנים למשימות מתמשכות: השהיית ארגז חול שההרצה שלו נמשכת זמן רב והמשך ההרצה מאוחר יותר, או העברה שלו לצומת אחר, בלי לאבד את ההתקדמות.
- עומסי עבודה עם שמירת מצב (stateful): שומרים את ההקשר של הסוכן, כמו היסטוריית השיחות או חישובי ביניים, על ידי שמירה ושחזור של המצב של סביבת ארגז החול שלו.
- יכולת שחזור: תיעוד של מצב ספציפי ושימוש בו כבסיס להפעלת כמה ארגזי חול חדשים עם אותו מצב מאותחל.
יש שתי דרכים להפעיל תמונת מצב:
- טריגר ידני: אתם יוצרים משאב
PodSnapshotManualTriggerכדי להפעיל את ה-snapshot. - טריגר של עומס עבודה: האפליקציה בארגז החול מאותתת בעצמה כשהיא מוכנה לשמירה.
במאמר הזה מוסבר איך להפעיל ידנית תמונת מצב.
לפני שמתחילים
-
בדף לבחירת הפרויקט במסוף Google Cloud , בוחרים פרויקט ב- Google Cloud או יוצרים אותו.
התפקידים שנדרשים כדי לבחור או ליצור פרויקט
- בחירת פרויקט: כדי לבחור פרויקט לא נדרש תפקיד IAM ספציפי – אתם יכולים לבחור כל פרויקט שקיבלתם בו תפקיד.
-
יצירת פרויקט: כדי ליצור פרויקט, צריך את התפקיד "יצירת פרויקטים" (
roles/resourcemanager.projectCreator), שכולל את ההרשאהresourcemanager.projects.create. איך מקצים תפקידים?
מפעילים את ממשקי ה-API של Google Kubernetes Engine, Cloud Storage וניהול זהויות והרשאות גישה (IAM), אם הם עדיין לא מופעלים.
התפקידים שנדרשים כדי להפעיל ממשקי API
כדי להפעיל ממשקי API, צריך את ההרשאה
serviceusage.services.enable. אם אתם יצרתם את הפרויקט, סביר להניח שכבר יש לכם את ההרשאה הזו דרך התפקיד "בעלים" (roles/owner). אחרת, אתם יכולים לקבל את ההרשאה הזו דרך התפקיד "אדמין בממשק 'שימוש בשירות'" (roles/serviceusage.serviceUsageAdmin). איך מקצים תפקידים?-
מפעילים את Cloud Shell במסוף Google Cloud .
דרישות
כדי להשתמש בתמונות מצב של פודים ב-GKE, צריך את גרסה 1.35.3-gke.1234000 או גרסה חדשה יותר של GKE. יש תמיכה גם במצב Autopilot וגם במצב רגיל.
כדי ליצור קובצי snapshot של Pod צריך להשתמש ב-gVisor, והם לא פועלים עם ארגזי חול של microVM.
מכיוון שתמונות מצב של Pod דורשות את GKE Sandbox, הסביבה שלכם כפופה למגבלות מסוימות. לדוגמה, אי אפשר להשתמש בסוגי מכונות E2 עם קובצי snapshot של Pod. לכן, במדריך הזה יוצרים מאגר צמתים שמורכב ממכונות 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 ZONE="us-central1-a"
export AGENT_SANDBOX_VERSION="v1.0.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 . הפקודות במסמך הזה משתמשות במזהה הזה כדי לתת שמות למשאבים ולהעניק הרשאות IAM. -
CLUSTER_NAME: השם של אשכול GKE (לדוגמה,agent-sandbox-cluster). -
GKE_LOCATION: האזור של הקטגוריה של Cloud Storage (לדוגמה,us-central1). אם יוצרים אשכול Autopilot, גם האשכול משתמש באזור הזה. Google Cloud -
ZONE: האזור של אשכול GKE. אם יוצרים אשכול Standard, מגדירים אותו לאזור ב-GKE_LOCATION(לדוגמה,us-central1-a). כדי להפחית את העלויות, במסמך הזה יוצרים אשכול Standard אזורי. -
AGENT_SANDBOX_VERSION: גרסת הבקר של Agent Sandbox בקוד פתוח שרוצים להתקין. במסמך הזה אנחנו משתמשים בגרסה 1.0.6. -
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 וחשבון השירות. -
SNAPSHOT_KSA_NAME: השם של חשבון השירות ב-Kubernetes שעומס העבודה ישתמש בו לאימות. -
SNAPSHOT_FOLDER: הספרייה בתוך הקטגוריה של Cloud Storage שבה יאורגנו קובצי ה-snapshot. -
PROJECT_NUMBER: המזהה המספרי הייחודי של הפרויקט, שמשמש לקישורי הרשאות IAM.
סקירה כללית של שלבי ההגדרה
כדי להפעיל תמונות מצב של Pods ב-Agent Sandbox בסביבות GKE, צריך לבצע כמה שלבי הגדרה. כדי להבין את השלבים האלה, כדאי קודם להבין כמה מושגי מפתח ואז את תהליך יצירת קובץ snapshot:
מושגים מרכזיים
- סביבה: אפליקציה בארגז חול פועלת בתוך Pod של Kubernetes בצומת של אשכול GKE.
- זהות: ה-Pod משויך לחשבון שירות של Kubernetes ופועל במרחב שמות מיוחד שאתם יוצרים. ביחד, חשבון השירות של Kubernetes והמרחב השמות יוצרים זהות ייחודית שמשמשת כדי לתת ל-Pod גישה מאובטחת למשאבים של Google Cloud .
- הרשאות: כדי לאפשר שמירת קובצי snapshot ב-Cloud Storage, צריך לתת לזהות של ה-Pod הרשאות IAM ספציפיות שמאפשרות לו לכתוב בקטגוריה של Cloud Storage.
תהליך יצירת תמונת המצב
- טריגר: הפעלה של קובץ snapshot, באופן ידני (חיצוני) או על ידי עומס העבודה בארגז החול עצמו. במאמר הזה מוסבר איך להפעיל טריגר ידני באמצעות יצירת משאב
PodSnapshotManualTrigger. - תיעוד: GKE מתעד את מצב ההפעלה של ה-Pod, כמו מצב הזיכרון של ה-Pod ומערכת הקבצים שלו.
- העלאה: באמצעות ההרשאות שניתנו לחשבון השירות של Kubernetes ב-Pod, GKE מעלה את המצב שצולם כקובצי תמונת מצב לקטגוריה הייעודית של Cloud Storage.
במאמר אימות ל-Google Cloud APIs מעומסי עבודה ב-GKE מוסבר איך משתמשים ב-GKE בחשבונות שירות של Kubernetes ובתפקידי IAM כדי לגשת למשאבים ב- Google Cloud .
כדי להפעיל תמונות מצב של Pod ב-Agent Sandbox בסביבות GKE, מבצעים את ההגדרה הבאה. קודם מכינים סביבת אשכול על ידי יצירת אשכול GKE עם התכונות "איחוד זהויות של עומסי עבודה ל-GKE" ו"תמונות מצב של Pod". בשלב הבא מגדירים את כללי המדיניות של Cloud Storage ו-IAM כדי לוודא שהתמונות של המצב הנוכחי מאוחסנות בצורה מאובטחת, ושלסביבת ה-Sandbox יש את ההרשאות הנדרשות. לבסוף, יוצרים את משאבי הסנאפשוט שמציינים את מיקום האחסון ואת כללי המדיניות של ארגז החול.
בטבלה הבאה מפורטים שלבי ההגדרה שצריך לבצע, וכל שלב מוסבר בקטעים שאחריה:
הגדרת האשכול
אפליקציה בארגז חול פועלת בתוך Pod בצומת של אשכול GKE, ולכן צריך להגדיר סביבת אשכול. בקטע הזה מוסבר איך ליצור אשכול GKE ולפרוס את הבקר של Agent Sandbox.
יצירת אשכול GKE חדש שעומד בדרישות
יוצרים אשכול GKE חדש עם תמונות מצב של Pods. כדי להשתמש בתמונות מצב של Pod, צריך את גרסה 1.35.3-gke.1234000 או גרסה חדשה יותר של GKE. הפקודות הבאות רושמות את האשכול לערוץ ההפצה המהירה, שגרסת ברירת המחדל שלו עומדת בדרישה הזו:
טייס אוטומטי
יוצרים אשכול Autopilot עם התכונות הנדרשות:
gcloud container clusters create-auto ${CLUSTER_NAME} \
--release-channel=rapid \
--enable-pod-snapshots \
--location=${GKE_LOCATION}
רגילה
יוצרים אשכול Standard עם התכונות הנדרשות. כדי להפחית את העלויות, הפקודה הבאה יוצרת אשכול אזורי שמריץ את מישור הבקרה והצמתים שלו באזור אחד:
gcloud container clusters create ${CLUSTER_NAME} \
--release-channel=rapid \
--enable-pod-snapshots \
--machine-type=${MACHINE_TYPE} \
--workload-pool=${PROJECT_ID}.svc.id.goog \
--workload-metadata=GKE_METADATA \
--num-nodes=1 \
--location=${ZONE}
יוצרים מאגר צמתים שבו GKE Sandbox מופעל. GKE Sandbox הוא אמצעי אבטחה לקונטיינרים שמבוסס על פרויקט gVisor בקוד פתוח, שמוסיף שכבת בידוד בין האפליקציות שפועלות לבין מערכת ההפעלה המארחת:
gcloud container node-pools create ${NODE_POOL_NAME} \
--cluster ${CLUSTER_NAME} \
--num-nodes=1 \
--location=${ZONE} \
--project=${PROJECT_ID} \
--machine-type=${MACHINE_TYPE} \
--sandbox type=gvisor
אחזור פרטי הכניסה
מאחזרים את פרטי הכניסה של האשכול כדי שממשק ה-CLI של kubectl יוכל להתחבר לאשכול:
טייס אוטומטי
gcloud container clusters get-credentials ${CLUSTER_NAME} \
--location=${GKE_LOCATION}
רגילה
gcloud container clusters get-credentials ${CLUSTER_NAME} \
--location=${ZONE}
פריסת Agent Sandbox Controller באשכול
כדי לפרוס את הבקר של Agent Sandbox ואת הרכיבים הנדרשים שלו, צריך להחיל את המניפסט של הגרסה הרשמית על האשכול. המניפסט הזה הוא קובץ תצורה שמורה ל-Kubernetes להוריד את כל הרכיבים שנדרשים כדי לפרוס ולהריץ את בקר Agent Sandbox באשכול.
כדי לפרוס את Agent Sandbox באשכול GKE, מריצים את הפקודה הבאה:
# Apply the release manifest for the controller and its CustomResourceDefinitions
kubectl apply -f https://github.com/kubernetes-sigs/agent-sandbox/releases/download/${AGENT_SANDBOX_VERSION}/sandbox-with-extensions.yaml
איך מתקינים את Agent Sandbox ב-GKE
אימות הבקר
אחרי שמחילים את המניפסט, בודקים ש-Pod של בקר Agent Sandbox פועל כמו שצריך במרחב השמות agent-sandbox-system. המניפסט יצר באופן אוטומטי את מרחב השמות agent-sandbox-system כשהחלתם אותו בשלב הקודם.
kubectl get pods -n agent-sandbox-system
ממתינים עד שבעמודה STATUS של ה-Pod יופיע הערך Running ובעמודה READY יופיע הערך 1/1. כשה-Pod פועל בצורה תקינה, הפלט נראה בערך כך:
NAME READY STATUS RESTARTS AGE
agent-sandbox-controller-7d5c9b8f6d-x2k9p 1/1 Running 0 2m
עכשיו, כשהבקר של Agent Sandbox פועל, הוא יכול ליצור ולנהל באופן אוטומטי סביבות של ארגז חול לכל משאבי Sandbox שאתם יוצרים באשכול.
הגדרת האחסון וההרשאות
בקטע הזה מוסבר איך להגדיר את האחסון וההרשאות שנדרשים לתמונות מצב של Pod. יוצרים קטגוריה של Cloud Storage ותיקייה מנוהלת כדי לאחסן את נתוני קובץ ה-snapshot. לאחר מכן, נותנים לארגז החול ולבקר של קובץ ה-snapshot את ההרשאות שנדרשות כדי לגשת לאחסון הזה.
יצירת קטגוריה של Cloud Storage
יוצרים קטגוריה לאחסון קובצי ה-snapshot. כדי שתהליך יצירת קובץ ה-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}"
יצירת תיקייה מנוהלת
יוצרים תיקייה מנוהלת כדי לארגן את קובצי ה-snapshot בקטגוריה. תיקיות מנוהלות מאפשרות להחיל הרשאות IAM על תיקייה ספציפית, במקום על הקטגוריה כולה. הגישה ברמת התיקייה מגבילה את הגישה של ארגז החול רק לתמונות המצב שלו, ומבודדת את תמונות המצב האלה מנתונים אחרים בקטגוריה.
כדי ליצור תיקייה מנוהלת, מריצים את הפקודה הבאה:
gcloud storage managed-folders create "gs://${SNAPSHOTS_BUCKET_NAME}/${SNAPSHOT_FOLDER}/"
הגדרת חשבון השירות ותפקידי IAM
כדי לאפשר ל-GKE לשמור תמונות מצב באופן מאובטח, חשבון השירות של Kubernetes שמשמש את ה-Pods שמריצים את עומס העבודה בארגז החול צריך הרשאה לכתוב בקטגוריה. כדי לתת את ההרשאה הזו, צריך לקשר תפקידי IAM ב- Google Cloudלחשבון השירות ב-Kubernetes שמשמש את ה-Pods. בקטע הזה מוסבר איך ליצור תפקיד IAM בהתאמה אישית, ליצור את חשבון השירות של Kubernetes ולהגדיר את ההרשאות הנדרשות.
יוצרים תפקיד 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אם הפקודה נכשלת עם שגיאת
FAILED_PRECONDITIONשאומרת שמזהה התפקיד סומן למחיקה, סימן שמחקתם לאחרונה תפקיד עם המזהה הזה, למשל בשלבי הניקוי של הרצה קודמת של המסמך הזה. ב-IAM אי אפשר להשתמש שוב במזהה הזה במשך עד 37 ימים. מריצים שוב את הפקודה עם מזהה תפקיד אחר, כמוpodSnapshotGcsReadWriter2, ומשתמשים במזהה הזה במקוםpodSnapshotGcsReadWriterבשאר המסמך.יוצרים את מרחב השמות שבו יימצאו ארגז החול וחשבון השירות שלו:
kubectl create namespace "${SNAPSHOT_NAMESPACE}"יוצרים את חשבון השירות של Kubernetes במרחב השמות שיצרתם. ביחד, חשבון השירות של Kubernetes ומרחב השמות יוצרים זהות ייחודית שמשמשת כדי לתת לארגז החול גישה מאובטחת למשאבים ב- Google Cloud:
kubectl create serviceaccount "${SNAPSHOT_KSA_NAME}" \ --namespace "${SNAPSHOT_NAMESPACE}"מקצים את התפקיד
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"מקצים את התפקיד
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"מקצים לחשבון השירות ב-Kubernetes את התפקיד
roles/storage.objectUser. התפקיד הזה נדרש כדי שסוכן תמונת המצב של 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. ההרשאה הזו מאפשרת לבקר לנהל את מחזור החיים של קובץ ה-snapshot, למשל למחוק אובייקטים של קובץ ה-snapshot כשמוחקים משאב 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"
הגדרת משאבים של תמונות מצב
בקטע הזה מוסבר איך להגדיר את משאבי הסנאפשוט של Agent Sandbox בעומס העבודה ב-GKE.
הגדרת אחסון וכללים לתמונות המצב
כדי לציין איפה GKE שומר את קובצי ה-snapshot ואילו כללים חלים על תהליך ה-snapshot, צריך ליצור שני משאבים בהתאמה אישית:
-
PodSnapshotStorageConfig: המשאב הזה מציין את המיקום של הקטגוריה והתיקייה ב-Cloud Storage שבהם GKE שומר את קובצי הסנאפשוט. -
PodSnapshotPolicy: המשאב הזה מגדיר אילו Pods מתאימים לתמונות מצב, על סמך התוויות שלהם ב-Kubernetes. היא גם מציינת את כללי הטריגר, למשל אם תמונות המצב הן ידניות או שהן נוצרות על ידי עומס העבודה בארגז החול. בדוגמה הזו, קובצי ה-snapshot מקובצים לפי התוויתagents.x-k8s.io/sandbox-name-hash, שהבקר של Agent Sandbox מוסיף ל-Pod של כל ארגז חול. הקיבוץ הזה אומר ש-GKE משחזר כל ארגז חול רק מהתמונות שלו.
כדי להחיל את שני המשאבים בשלב אחד, מריצים את הפקודה הבאה ב-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
snapshotGroupingRules:
groupByLabelValue:
labels:
- agents.x-k8s.io/sandbox-name-hash
EOF
אימות ההגדרות האישיות
אחרי שמחילים את המדיניות וההגדרות של אחסון קובצי ה-snapshot, מוודאים שהמשאבים מוכנים לשימוש. בקטע הזה מוסבר איך לבדוק את הסטטוס של המשאבים האלה בהתאמה אישית.
בודקים את הסטטוס של המשאב
PodSnapshotStorageConfig:kubectl get podsnapshotstorageconfigs.podsnapshot.gke.io cpu-pssc-gcs -o yamlהפלט אמור להכיל תנאי עם
type: Readyו-status: "True":status: conditions: - lastTransitionTime: "2025-10-31T18:18:02Z" message: Valid PodSnapshotStorageConfig reason: StorageConfigValid status: "True" type: Readyבודקים את הסטטוס של המשאב
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, SandboxWarmPool ו-SandboxClaim. המשאב SandboxWarmPool שומר על ארגז חול (sandbox) פעיל, והמשאב SandboxClaim תובע את ארגז החול הזה מהמאגר. כדי שתהליך יצירת קובץ ה-snapshot יפעל, צריך להריץ את ארגז החול עם חשבון השירות של Kubernetes שיצרתם קודם לכן במסמך הזה. בארגז החול צריכות להיות גם התוויות שציינתם קודם במשאב PodSnapshotPolicy.
בדוגמה הזו משתמשים באפליקציית Python שמדפיסה מונה מצטבר ביומנים. המונה הזה מאפשר לכם לוודא שהמצב נשמר בהצלחה ומשוחזר מאוחר יותר.
טייס אוטומטי
אי אפשר להשתמש בתמונות מצב של Pod במכונות מסוג E2. במצב Autopilot, יכול להיות ש-GKE יבחר כברירת מחדל סוגי מכונות שלא תומכים בתמונות מצב של Pod. כדי לוודא שעומסי העבודה פועלים בחומרה תואמת, כדאי להשתמש ב-ComputeClass בהתאמה אישית כדי לתת עדיפות למשפחות מכונות תואמות.
שומרים את המניפסט הבא בתור
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מחילים את המניפסט:
kubectl apply -f non-e2-class.yamlכדי ליצור את המשאבים
SandboxTemplateו-SandboxWarmPool, צריך להחיל את המניפסט הבא. שימו לב שהמשאבSandboxTemplateמתייחס ל-ComputeClassשיצרתם באמצעות בורר הצמתיםcloud.google.com/compute-class: non-e2-class.kubectl apply -f - <<EOF --- apiVersion: extensions.agents.x-k8s.io/v1beta1 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/v1beta1 kind: SandboxWarmPool metadata: name: python-sandbox-warmpool namespace: ${SNAPSHOT_NAMESPACE} spec: replicas: 1 sandboxTemplateRef: name: python-runtime-template EOF
רגילה
כדי ליצור את המשאבים SandboxTemplate ו-SandboxWarmPool, מפעילים את המניפסט הבא:
kubectl apply -f - <<EOF
---
apiVersion: extensions.agents.x-k8s.io/v1beta1
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/v1beta1
kind: SandboxWarmPool
metadata:
name: python-sandbox-warmpool
namespace: ${SNAPSHOT_NAMESPACE}
spec:
replicas: 1
sandboxTemplateRef:
name: python-runtime-template
EOF
אחרי שיוצרים את המשאבים, תובעים בעלות על ארגז חול מהמאגר החם:
מחכים עד שארגז החול של המאגר החם יהיה מוכן:
kubectl wait sandboxwarmpool python-sandbox-warmpool \ --namespace "${SNAPSHOT_NAMESPACE}" \ --for=jsonpath='{.status.readyReplicas}'=1 \ --timeout=600sיוצרים משאב
SandboxClaimשתובע את ארגז החול מהמאגר החם:kubectl apply -f - <<EOF apiVersion: extensions.agents.x-k8s.io/v1beta1 kind: SandboxClaim metadata: name: python-sandbox-example namespace: ${SNAPSHOT_NAMESPACE} spec: warmPoolRef: name: python-sandbox-warmpool EOFמחכים עד שהתביעה מוכנה, ואז שומרים את שם ארגז החול שבו התביעה משתמשת. ה-Pod של ארגז החול נקרא באותו שם כמו ארגז החול:
kubectl wait sandboxclaim python-sandbox-example \ --namespace "${SNAPSHOT_NAMESPACE}" \ --for=condition=Ready \ --timeout=300s export SANDBOX_NAME=$(kubectl get sandboxclaim python-sandbox-example \ --namespace "${SNAPSHOT_NAMESPACE}" \ -o jsonpath='{.status.sandbox.name}') echo "${SANDBOX_NAME}"
עכשיו ארגז החול פועל עם הזהות הנכונה ומוכן ליצירת קובץ snapshot.
יצירת תמונת מצב
בקטע הזה מוסבר איך להפעיל באופן ידני קובץ snapshot של ארגז החול שפועל. אתם יוצרים משאב טריגר שמטרגט את ה-Pod של ארגז החול, ואז מוודאים שתהליך יצירת קובץ ה-snapshot הושלם בהצלחה.
בדיקת היומנים הראשוניים של המונה: לפני שמפעילים את קובץ ה-snapshot, בודקים את היומנים של ארגז החול שפועל כדי לראות את הערך הנוכחי של המונה. הצגת היומנים יוצרת בסיס להשוואה אחרי השחזור.
kubectl logs "${SANDBOX_NAME}" --namespace "${SNAPSHOT_NAMESPACE}" --tail=5בפלט מוצגות השורות האחרונות של המונה, לדוגמה:
Count: 15 Count: 16 Count: 17שימו לב לערכי ה-Count האחרונים שהודפסו.
יצירת משאב
PodSnapshotManualTrigger: הפעלת קובץ ה-snapshot:kubectl apply -f - <<EOF apiVersion: podsnapshot.gke.io/v1 kind: PodSnapshotManualTrigger metadata: name: cpu-snapshot-trigger namespace: ${SNAPSHOT_NAMESPACE} spec: targetPod: ${SANDBOX_NAME} EOFמוודאים שההפעלה הידנית הצליחה:
kubectl get podsnapshotmanualtriggers.podsnapshot.gke.io \ --namespace "${SNAPSHOT_NAMESPACE}"הפלט אמור להציג את הסטטוס
Complete, שמציין ש-GKE הפעיל בהצלחה את קובץ ה-snapshot של ה-Pod המטורגט:NAME TARGET POD STATUS AGE cpu-snapshot-trigger python-sandbox-warmpool-x7k2p Complete XXsכדי לקבל פרטים נוספים על המצב שצולם, מתארים את הטריגר:
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>
שחזור מתמונת מצב
אחרי שיוצרים קובץ Snapshot, אפשר להשעות את ארגז החול כדי לפנות את משאבי המחשוב שלו, ואחר כך להמשיך את ארגז החול מהמצב השמור שלו. כשמשעים ארגז חול, הבקר של Agent Sandbox מוחק את ה-Pod של ארגז החול אבל שומר את המשאב Sandbox. כשממשיכים את ארגז החול, הבקר יוצר מחדש את ה-Pod, ובקר תמונת המצב של ה-Pod משחזר באופן אוטומטי את ה-Pod מתמונת המצב האחרונה של ארגז החול הזה.
מחכים עד שתמונת המצב מוכנה. GKE משחזר Pod רק מ-snapshot שמוכן. אם תשעו את ארגז החול לפני שהתמונה תהיה מוכנה, ארגז החול יתחיל בלי המצב השמור כשתפעילו אותו מחדש.
export SNAPSHOT_NAME=$(kubectl get podsnapshotmanualtriggers.podsnapshot.gke.io cpu-snapshot-trigger \ --namespace "${SNAPSHOT_NAMESPACE}" \ -o jsonpath='{.status.snapshotCreated.name}') kubectl wait podsnapshots.podsnapshot.gke.io "${SNAPSHOT_NAME}" \ --namespace "${SNAPSHOT_NAMESPACE}" \ --for=condition=Ready \ --timeout=600sכדי להשעות את ארגז החול, מגדירים את השדה
operatingModeשלו לערךSuspended, ואז מחכים עד שהבקר ימחק את ה-Pod של ארגז החול:kubectl patch sandbox "${SANDBOX_NAME}" \ --namespace "${SNAPSHOT_NAMESPACE}" \ --type=merge \ -p '{"spec":{"operatingMode":"Suspended"}}' kubectl wait pod "${SANDBOX_NAME}" \ --namespace "${SNAPSHOT_NAMESPACE}" \ --for=delete \ --timeout=120sכדי להמשיך את ארגז החול, מגדירים את השדה
operatingModeשלו ל-Running, ואז ממתינים עד שארגז החול יהיה מוכן:kubectl patch sandbox "${SANDBOX_NAME}" \ --namespace "${SNAPSHOT_NAMESPACE}" \ --type=merge \ -p '{"spec":{"operatingMode":"Running"}}' kubectl wait sandbox "${SANDBOX_NAME}" \ --namespace "${SNAPSHOT_NAMESPACE}" \ --for=condition=Ready \ --timeout=300sכדי לוודא שהשחזור בוצע, בודקים את היומנים. שימו לב שהמונה ממשיך מהנקודה שבה נוצר קובץ ה-snapshot:
kubectl logs "${SANDBOX_NAME}" --namespace "${SNAPSHOT_NAMESPACE}"בפלט אמור להופיע המונה שממשיך לפעול, לדוגמה:
Count: 18 Count: 19 Count: 20 Count: 21אם המונה מתחיל מ-
0, ה-Pod התחיל בלי לשחזר מתמונת המצב.
מחיקת משאבים
כדי להימנע מצבירת חיובים בחשבון Google Cloud על המשאבים שבהם השתמשתם במסמך הזה, מחקו את המשאבים שיצרתם באמצעות הפעולות הבאות:
מוחקים את בקשות ה-sandbox ואת המאגרים החמים כדי להפסיק את כל ה-Pods שפועלים, ולאפשר לבקר של Agent Sandbox לסגור את הקונטיינרים בצורה תקינה.
kubectl delete sandboxclaims --all --namespace "${SNAPSHOT_NAMESPACE}" kubectl delete sandboxwarmpools --all --namespace "${SNAPSHOT_NAMESPACE}"מוחקים את התבניות של ארגזי החול ואת הטריגרים הידניים ששימשו ליצירת ארגזי החול ולהפעלת תמונות המצב.
# Delete the blueprints kubectl delete sandboxtemplates --all --namespace "${SNAPSHOT_NAMESPACE}" # Delete the snapshot initiation objects kubectl delete podsnapshotmanualtriggers --all --namespace "${SNAPSHOT_NAMESPACE}"מוחקים את כללי המדיניות של קובצי ה-Snapshot שמגדירים אילו Pods מתאימים לקובצי Snapshot במרחב השמות.
kubectl delete podsnapshotpolicy cpu-psp --namespace "${SNAPSHOT_NAMESPACE}"מוחקים את הגדרת האחסון של קובץ ה-snapshot, שהיא ההגדרה הגלובלית של הקצה העורפי של אחסון קובץ ה-snapshot. מכיוון שהמשאב הזה מוגדר ברמת האשכול, אל תשתמשו בדגל של מרחב שמות.
kubectl delete podsnapshotstorageconfig cpu-pssc-gcsאם יצרתם אחד ל-Autopilot, מחקו את ComputeClass.
kubectl delete computeclass non-e2-classמוחקים את מרחב השמות של Kubernetes כדי להסיר באופן אוטומטי את חשבון השירות של Kubernetes ואת כל המטא-נתונים שנותרו במרחב השמות.
kubectl delete namespace "${SNAPSHOT_NAMESPACE}"מוחקים את אשכול GKE כדי להסיר את התשתית הבסיסית ואת כל הצמתים שמשויכים למדריך.
טייס אוטומטי
gcloud container clusters delete "${CLUSTER_NAME}" \ --location="${GKE_LOCATION}" --quietרגילה
gcloud container clusters delete "${CLUSTER_NAME}" \ --location="${ZONE}" --quietאם רוצים לאפס לגמרי את האחסון, מוחקים את הקטגוריה של Cloud Storage (אופציונלי) באמצעות פקודת ההסרה הרקורסיבית. הערה: אפשר לדלג על השלב הזה אם אתם מתכוונים להשתמש שוב בקטגוריה שהגדרתם בצורה נכונה לבדיקות עתידיות.
gcloud storage rm --recursive "gs://${SNAPSHOTS_BUCKET_NAME:?Error: SNAPSHOTS_BUCKET_NAME is not set. Please re-define the environment variables you defined earlier.}"אם רוצים להחזיר את הפרויקט למצב נקי לחלוטין, מוחקים את תפקיד ה-IAM בהתאמה אישית (אופציונלי). תפקידי IAM נשארים גם אחרי שמוחקים את האשכול, לכן צריך למחוק אותם בנפרד.
gcloud iam roles delete podSnapshotGcsReadWriter --project="${PROJECT_ID}"
המאמרים הבאים
- מידע נוסף על קובצי Snapshot של Pod ב-GKE
- GitHub
- איך מבודדים את הרצת הקוד של ה-AI באמצעות Agent Sandbox ב-GKE