הרצת קוד ב-Cloud Run

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

יתרונות עיקריים

לארגזי החול של Cloud Run יש כמה יתרונות מרכזיים:

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

  • אבטחה: ארגזי חול מבודדים את הרצת התהליכים. כברירת מחדל, לארגזי חול אין גישה לעומס העבודה הראשי, למשתני הסביבה, לסודות או לשרת המטא-נתונים של Google Cloud . כל ארגזי החול מבודדים לחלוטין זה מזה.

  • בקרת גישה וסביבה: תהליכים פועלים עם הרשאות sudo כמשתמש שאינו משתמש Root, ומאפשרים לכם להתקין כלים באמצעות מנהלי חבילות כמו apt,‏ pip או npm במהלך ההפעלה. סביבת ארגז החול היא זמנית ונמחקת בסיום, אבל אתם יכולים להשתמש בספריות קבועות או בתמונות מצב כדי לשמור סביבות עבודה ספציפיות או למפות נתונים לקטגוריה של Cloud Storage.

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

  1. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  2. Verify that billing is enabled for your Google Cloud project.

  3. מתקינים ומפעילים את ה-CLI של gcloud.
  4. פורסים משאב של Cloud Run, כמו שירות, משימה, מאגר של Worker או מכונה מהדור השני .

הפעלת ארגזי חול

כדי להשתמש בארגזי חול, קודם צריך להפעיל אותם במשאב Cloud Run באמצעות הדגל --sandbox-launcher או המאפיין sandboxLauncher ב-YAML. כדי לראות את השלבים המפורטים להגדרה, בחרו את סוג המשאב הרלוונטי:

הפעלת ארגזי חול

אחרי שמפעילים את ארגזי החול, אפשר להפעיל אותם מתוך סביבת ההרצה של הקונטיינר. הקובץ הבינארי של ארגז החול נמצא ב-/usr/local/gcp/bin/sandbox.

בדוגמאות במדריך הזה נעשה שימוש בפקודה sandbox במקום בנתיב המוחלט שלה /usr/local/gcp/bin/sandbox.

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

Node.js

כדי להריץ את פקודת ארגז החול מאפליקציית Node.js, צריך לכלול את הקוד הבא:

exec(`sandbox do -- /bin/echo "Hello"`, (e, stdout, stderr) => {
    res.send({ stdout, stderr });
});

Python

כדי להריץ את פקודת ארגז החול מאפליקציית Python, צריך לכלול את הקוד הבא:

import subprocess
result = subprocess.run(
    ["sandbox", "do", "--", "/bin/echo", "Hello"],
    capture_output=True,
    text=True,
)
return {"stdout": result.stdout, "stderr": result.stderr}

המשך

כדי להריץ את פקודת ארגז החול מאפליקציית Go, צריך לכלול את הקוד הבא:

cmd := exec.Command("sandbox", "do", "--", "/bin/echo", "Hello")
out, err := cmd.CombinedOutput()

Sandbox CLI

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

sandbox do -- /bin/echo "Hello"

כדי לראות את הרשימה המלאה של הפקודות הזמינות, מריצים את הפקודה sandbox -h.

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

כלי שורת הפקודה sandbox מכיל פקודות להרצה, להגדרה ולניהול של ארגזי חול.

הרצת פקודה בארגז החול

אתם יכולים להריץ הוראה בארגז חול זמני חדש באמצעות הפקודה sandbox do. הפקודה sandbox do מבצעת את המשימות הבאות:

  1. מפעיל סביבת ארגז חול (sandbox run).
  2. מריץ את הפקודה שציינתם (sandbox exec).
  3. מחיקת ארגז החול אחרי הפעלה מוצלחת (sandbox delete).

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

Node.js

כדי להריץ את פקודת ארגז החול מאפליקציית Node.js:

exec(`sandbox do -- /usr/bin/python3 -c "print(1+2)"`, (e, stdout, stderr) => {
    res.send({ stdout, stderr });
});

Python

כדי להריץ את פקודת ארגז החול מאפליקציית Python:

import subprocess
result = subprocess.run(
    ["sandbox", "do", "--", "/usr/bin/python3", "-c", "print(1+2)"],
    capture_output=True,
    text=True,
)
return {"stdout": result.stdout, "stderr": result.stderr}

המשך

כדי להריץ את פקודת ארגז החול מאפליקציית Go:

cmd := exec.Command("sandbox", "do", "--", "/usr/bin/python3", "-c", "print(1+2)")
out, err := cmd.CombinedOutput()

Sandbox CLI

כדי להריץ את פקודת ארגז החול ישירות משורת הפקודה:

sandbox do -- /usr/bin/python3 -c "print(1+2)"

אם מריצים פקודה לפי שם בלי הנתיב המוחלט שלה, למשל python3 במקום /usr/bin/python3, צריך להגדיר במפורש את משתנה הסביבה PATH בארגז החול באמצעות הדגל --env.

שמירת נתונים בין הרצות שונות

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

משתמשים בדגלים הבאים כשמריצים את הפקודה sandbox do:

  • --export-tar: בסיום, מתעד קובצי שכבת-על ששונו בקובץ ארכיון tar.
  • --import-tar: חילוץ קבצים מקובץ ארכיון בפורמט tar לארגז החול לפני ההפעלה.
  • ‫--sync-tar: מבצע סנכרון דו-כיווני על ידי ייבוא לפני ההפעלה וייצוא בסיום.

הספרייה /tmp בתוך ארגז החול היא לא חלק משכבת-העל של מערכת הקבצים ברמה הבסיסית (root), ולכן קובצי הארכיון לא כוללים קבצים שנכתבו ב-/tmp. כדי לשמור נתונים, צריך לכתוב אותם בספרייה אחרת, כמו /workspace.

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

  1. כתיבת נתונים בתוך ארגז חול וייצוא המצב לקובץ ארכיון:

    sandbox do --write --export-tar=/tmp/work.tar \
      -- /usr/bin/bash -c "mkdir -p /workspace && echo 'task-complete' > /workspace/status.txt"
    
  2. מייבאים את קובץ הארכיון בקריאה הבאה כדי לאחזר את הנתונים:

    sandbox do --write --import-tar=/tmp/work.tar \
      -- /usr/bin/bash -c "cat /workspace/status.txt"
    

לחלופין, כדי לייבא באופן אוטומטי את מצב הארכיון הקיים ולייצא שינויים חדשים בפקודה אחת, משתמשים ב---sync-tar=/tmp/work.tar. כשמסתיים תהליך בארגז החול, Cloud Run מוחק באופן סופי קובצי שכבת-על זמניים שלא יוצאו לקובץ ארכיון.

הרצת פקודה ברקע

כדי להריץ תהליכים ארוכים, דפדפנים ללא GUI או שרתי רקע, כמו לולאת סוכן ברקע שמאזינה כל הזמן לבקשות נכנסות, משתמשים בדגל --detach.

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

sandbox run my-web-server --detach -- /usr/bin/long_running_or_idle_program

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

לדוגמה, כדי להריץ פקודת בדיקה בתוך ארגז החול הקיים של my-web-server ברקע, מריצים את הפקודה הבאה:

sandbox exec my-web-server -- /usr/bin/python3 -c "print('test-complete')"

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

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

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

sandbox do --env AGENT_MODE="test" -- /usr/bin/bash -c "echo \$AGENT_MODE"

אל תעבירו סודות באמצעות הדגל env, כי יכול להיות שהם יהיו גלויים לתהליכים של ארגז החול.

יצירת תמונות מצב של מערכת הקבצים

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

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

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

    sandbox run --write my-sandbox --detach -- /usr/bin/bash -c "echo 'hi' > /workspace/hello.txt && sleep 1h"
    
  2. יוצרים קובץ snapshot של מערכת הקבצים ששונתה בארגז החול שפועל, באמצעות הפקודה sandbox tar:

    sandbox tar my-sandbox --file=/tmp/foo.tar
    
  3. מחלצים את קובץ הארכיון של קובץ ה-snapshot ומוודאים שהוא מכיל את הנתונים שנכתבו בתוך ארגז החול:

    tar -xvf /tmp/foo.tar
    

    אמורות להתקבל התוצאות הבאות:

    ./
    ./workspace/
    ./workspace/hello.txt
    

הגדרה של רשתות

כברירת מחדל, כל התנועה היוצאת מארגז החול חסומה. כדי לאפשר גישה לרשת יוצאת, משתמשים בדגל --allow-egress:

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

sandbox do --allow-egress -- /usr/bin/python3 -c 'import urllib.request; print(urllib.request.urlopen("https://google.com").getcode())'

הפקודה הזו מחזירה את קוד סטטוס של HTTP‏ 200, שמציין שהחיבור הצליח.

גישה למערכת הקבצים

כברירת מחדל, לתהליכים שאתם מריצים בתוך ארגז החול יש גישת קריאה בלבד למערכת הקבצים ברמה הבסיסית (root) של מארח הקונטיינר. אתם יכולים להשתמש בדגל --write כדי לאפשר כתיבה לשכבת-על של מערכת קבצים זמנית (tmpfs). עם זאת, פעולות הכתיבה יאבדו כשארגז החול יימחק. כדי לאפשר כתיבה מתמשכת לקונטיינר המארח, אתם יכולים להגדיר נקודות טעינה מקושרות.

תמיד אפשר לכתוב לספרייה /tmp בתוך ארגז החול, גם בלי הדגל --write. הספרייה /tmp נמחקת כשארגז החול נמחק, והיא לא נכללת בתמונות מצב או בקובצי ארכיון.

הרשאת קריאה בלבד כברירת מחדל

בתוך ארגז החול, תהליכים יכולים לקרוא קבצים מהקונטיינר המארח, והם לא יכולים לכתוב למערכת הקבצים ברמה הבסיסית (root) מחוץ ל-/tmp.

בדוגמאות הבאות, נניח שאתם מריצים פקודות מתיקיית השורש (/) של הקונטיינר המארח.

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

  1. יוצרים סקריפט Python בקונטיינר המארח:

    mkdir -p /tmp/my-scripts
    echo "print('hi')" > /tmp/my-scripts/task.py
    
  2. מוודאים שהקובץ קיים באופן מקומי:

    cat /tmp/my-scripts/task.py
    
  3. מריצים את הקובץ בתוך ארגז החול:

    sandbox do -- /usr/bin/python3 /tmp/my-scripts/task.py
    

    הפקודה הזו מחזירה את הערך hi, שמאשר שלארגז החול יש גישת קריאה.

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

    מריצים את הפקודה הבאה כדי לכתוב למערכת הקבצים ברמה הבסיסית (root):

    sandbox do -- /usr/bin/bash -c "echo 'hi' > /testfile.txt"
    

    הפקודה נכשלת ומופיעה השגיאה הבאה:

    /usr/bin/bash: line 1: /testfile.txt: Read-only file system
    Error: failed to exec in container: cmd.Wait(exec) failed: exit status 1
    

שיתוף נתונים באמצעות נקודות טעינה מקושרות

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

  1. יוצרים ספריית אמצעי אחסון משותף במאגר המארח ומזינים בה קובץ ראשוני:

    mkdir -p /tmp/my-volume
    echo 'read' > /tmp/my-volume/readwrite.txt
    
  2. מריצים את ארגז החול כדי לקרוא את הקובץ מנתיב הטעינה המקושר:

    sandbox do --mount type=bind,source=/tmp/my-volume,destination=/mnt/my-mount -- /usr/bin/bash -c "cat /mnt/my-mount/readwrite.txt"
    

    הפקודה הזו מחזירה את הערך read.

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

    sandbox do --mount type=bind,source=/tmp/my-volume,destination=/mnt/my-mount -- /usr/bin/bash -c "echo 'write' > /mnt/my-mount/readwrite.txt"
    
  4. מוודאים במאגר המארח שארגז החול שינה את הקובץ:

    cat /tmp/my-volume/readwrite.txt
    

    הפקודה הזו מחזירה את הערך write.

הגדרת טעינות לקריאה בלבד

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

לדוגמה, מריצים את הפקודה הבאה כדי לבדוק את מגבלות הכתיבה ב-bind mount לקריאה בלבד:

sandbox do --mount type=bind,source=/tmp/my-volume,destination=/mnt/my-mount,readonly -- /usr/bin/bash -c "echo 'fails' > /mnt/my-mount/hello.txt"

ניסיון הכתיבה נכשל ומוצגת השגיאה הבאה:

/usr/bin/bash: line 1: /mnt/my-mount/hello.txt: Read-only file system
Error: failed to exec in container: cmd.Wait(exec) failed: exit status 1

צפייה ביומנים

‫Cloud Run מתעד באופן אוטומטי אירועים במחזור החיים של ארגז החול, כמו התחלה ויציאה מהפעלה, ב-Cloud Logging.

ה-CLI של sandbox כותב פלט סטנדרטי (stdout) ושגיאה סטנדרטית (stderr) מפקודות בארגז חול ישירות לסטרימים הסטנדרטיים של התהליך שמופעל. כדי לראות את היומנים האלה ב-Cloud Logging, צריך לנתב את הסטרימינג לפלט הסטנדרטי (stdout) ולשגיאה הסטנדרטית (stderr) של הקונטיינר:

Node.js

const { exec } = require('child_process');
const child = exec('sandbox do -- /usr/bin/python3 -c "print(1+2)"');
child.stdout.pipe(process.stdout);
child.stderr.pipe(process.stderr);

Python

subprocess.run(
    ["sandbox", "do", "--", "/usr/bin/python3", "-c", "print(1+2)"],
    stdout=sys.stdout,
    stderr=sys.stderr,
)

המשך

cmd := exec.Command("sandbox", "do", "--", "/usr/bin/python3", "-c", "print(1+2)")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Run()

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