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

התמיכה בסוכן הפעלת הקונטיינר ב-Compute Engine תופסק. הסוכן הזה מאפשר לכם לפרוס קונטיינרים במכונות ב-Compute Engine כשאתם יוצרים מכונות וירטואליות.

במאמר הזה מוסבר איך להעביר קונטיינרים קיימים שסוכן ההפעלה יצר במכונות הווירטואליות או בקבוצות של מכונות מנוהלות (MIG) לשירותים אחרים שלCloud de Confiance by S3NS .

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

  • אם רוצים להמשיך להריץ קונטיינרים במכונות וירטואליות ובקבוצות של מכונות וירטואליות לניהול מופעים (MIG) נפרדות, צריך להשתמש בסקריפטים להפעלה או ב-cloud-init.
  • אם יש לכם אפליקציות בקונטיינרים ללא שמירת מצב ועבודות קטנות עד בינוניות, כדאי להשתמש ב-Cloud Run.
  • אם הקונטיינר הוא משימה באצווה עם מצב סיום מוגדר ונדרשים משאבי מחשוב נוספים, צריך להשתמש ב-Batch.
  • אם אתם צריכים שליטה מתקדמת ומדרגיות, או אם אתם לא יכולים לעמוד בדרישות שלכם באמצעות האפשרויות האחרות, אתם יכולים להשתמש ב-GKE ב-Google Cloud.

תרחישי שימוש נוספים ופתרונות חלופיים מפורטים במאמר השוואה בין אפשרויות הפריסה של מאגרי תגים.

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

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

אפשרויות שיצאו משימוש להגדרת מאגרי VM

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

האפשרויות הבאות לפריסת קונטיינרים ישירות במכונה וירטואלית או בקבוצת מופעים מנוהלת שמשתמשות בסוכן להפעלת קונטיינרים וב-gce-container-metadata הוצאו משימוש.

המסוף

האפשרות Deploy container בדף Create an instance הוצאה משימוש:

האפשרות 'פריסת מאגר תגים'.

gcloud

הפקודות הבאות של gcloud שמשמשות להגדרת קונטיינר במכונה וירטואלית או בתבנית של הגדרות מכונה הוצאו משימוש:

Terraform

הוצאנו משימוש את מודול Terraform‏ gce-container ואת מפתח המטא-נתונים gce-container-declaration להגדרת קונטיינרים.

איך מונעים יצירה של מכונות וירטואליות שמשתמשות בסוכן להפעלת קונטיינרים

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

זיהוי מקרים שבהם נעשה שימוש במטא-נתונים של מאגר שהוצא משימוש

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

  1. מריצים אחת מהפקודות הבאות:

    • כדי להציג רשימה של כל המכונות בפרויקט שמשתמשות במפתח ובערך המטא-נתונים gce-container-declaration, מריצים את הפקודה הבאה ב-CLI של gcloud:

      gcloud compute instances list --filter="metadata.items.key:gce-container-declaration"
      

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

    • כדי לאמת מופע ספציפי, מריצים את הפקודה הבאה ב-CLI של gcloud:

      gcloud compute instances describe VM_NAME --format="(metadata.items)"
      

      מחליפים את VM_NAME בשם של מופע המכונה הווירטואלית שרוצים לאמת.

  2. אם בפלט של הפקודה מהשלב הקודם מופיעים מופעים שמשתמשים במפתח המטא-נתונים gce-container-declaration, מריצים את הפקודה הבאה כדי לקבל פרטים נוספים על הצהרת הקונטיינר במכונות הווירטואליות:

    gcloud compute instances list \
      --filter='metadata.items.key:gce-container-declaration AND (metadata.items.value~"image:")' \
      --format="table(name, zone, metadata.items.filter(key='gce-container-declaration').extract(value).slice(0):label=CONTAINER_DECLARATION)"
    
  3. על סמך הפלט של הפקודה, כדאי לשים לב לנקודות הבאות:

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

    • אם מפתח המטא-נתונים gce-container-declaration קיים, אבל אתם לא משתמשים בו לסוכן הפעלת הקונטיינר, צריך לבצע את הפעולות הבאות:

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

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

השוואה בין אפשרויות הפריסה של מאגרי תגים

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

תרחישים לדוגמה סוג ההחלפה עלות פתרון מומלץ
  • להמשיך להריץ את הקונטיינר במכונה וירטואלית או בקבוצת מופעים מנוהלת.
  • פחות מכירים פתרונות ללא שרת או פתרונות מנוהלים.
  • מריצים את מאגר התגים לבדיקה ולפיתוח.
  • עומס העבודה מורכב ממכונה וירטואלית אחת.
  • הפעלת מאגר הנתונים במצב הרשאה.
  • החלפה ישירה ללא עלות נוספת שימוש בסקריפטים לטעינה בזמן ההפעלה כדי לפרוס קונטיינרים במכונות וירטואליות
  • להמשיך להריץ את הקונטיינר במכונה וירטואלית או בקבוצת מופעים מנוהלת.
  • להריץ כמה קונטיינרים במכונה וירטואלית אחת.
  • הגדרת תרחישים מתקדמים במכולות או במכונות וירטואליות.
    לדוגמה, ליצור משתמשים, לייבא קבצים, לטעון דיסקים או להשתמש במצב הרשאות.
  • עומס העבודה מורכב מכמה מכונות וירטואליות או קבוצות מופעים מנוהלות.
  • החלפה ישירה ללא עלות נוספת שימוש ב-cloud-init להרצת משימות במהלך מחזור החיים של המכונה הווירטואלית.
    להריץ משימה באצווה שיש לה מצב סיום מוגדר ונדרשים לה משאבי מחשוב נוספים. שירות מנוהל תלוי במאפיינים של עומס העבודה ובמורכבות של הגדרות הקונטיינר. Batch
  • הפעלת אפליקציות בלי שמירת מצב.
  • הפעלת משימות קטנות עד בינוניות.
  • שירות מנוהל פתרון בעלות נמוכה או ללא עלות לעומסי עבודה קטנים יותר. Cloud Run
  • כבר יש לכם אשכול GKE.
  • אתם צריכים שליטה מתקדמת ויכולת הרחבה.
  • שירות מנוהל תלוי במאפיינים של עומס העבודה ובמורכבות של הגדרת הקונטיינר. Google Kubernetes Engine

    כשעוברים מסוכן ההפעלה של קונטיינר Compute Engine לפתרון חלופי, צריך לשים לב לשינויים הנדרשים הבאים ולמאמץ הפוטנציאלי שנדרש כדי להטמיע אותם:

    • מכונות וירטואליות שמופעלת בהן מערכת הפעלה שמותאמת לקונטיינרים: אתם מקבלים בעלות מלאה על ההגדרה, התצורה, האבטחה והתחזוקה של מכונת ה-VM ושל זמן הריצה של הקונטיינר, ולרוב זה כולל סקריפטים עם סקריפטים להפעלה או cloud-init.
    • Cloud Run או Batch: מוודאים שהאפליקציות שלכם הן stateless ומתאימות למודל הביצוע מבוסס-הבקשות או מבוסס-העבודות. הגישה הזו עשויה לכלול התאמה של אפליקציות כדי שיפעלו עם שירותים חיצוניים לניהול מצב.
    • GKE: אימוץ עקרונות Kubernetes, הגדרת עומסי עבודה באמצעות קובצי מניפסט של Kubernetes וניהול משאבי האשכול.

    שימוש בסקריפטים לטעינה בזמן ההפעלה כדי לפרוס קונטיינרים במכונות וירטואליות

    אפשר להריץ קונטיינר בסיסי במכונה וירטואלית באמצעות סקריפט לטעינה בזמן ההפעלה.

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

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

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

    1. מיפוי של הקונטיינר הנוכחי במטא-נתונים של המכונה הווירטואלית לפקודה בסקריפט ההפעלה
    2. יצירת סקריפט לטעינה בזמן ההפעלה על סמך הגדרת המטא-נתונים הקיימת
    3. יצירת מכונה וירטואלית באמצעות סקריפט לטעינה בזמן ההפעלה או יצירת קבוצת MIG באמצעות סקריפט לטעינה בזמן ההפעלה.

    מיפוי המטא-נתונים של מאגר התגים לפקודה docker run

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

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

      # Get your existing VM instance configuration in yaml format
      gcloud compute instances describe VM_NAME --format="(metadata.items)"
    

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

      metadata:
        items:
        - key: gce-container-declaration
          value: |
            spec:
              containers:
              - args:
                - '"hello world!"'
                command:
                - echo
                env:
                - name: ONE
                  value: '1'
                image: docker.io/library/busybox
                name: my-instance
                securityContext:
                  privileged: true
                stdin: true
                tty: true
              restartPolicy: Always
        - key: google-logging-enabled
          value: 'true'
    

    אתם יכולים להיעזר בטבלה הבאה כדי למפות מפרט קיים לפקודות docker run:

    דגל של ה-CLI של gcloud מפתח מטא-נתונים של מכונה וירטואלית פקודת Docker run
    --container-image containers.image מציינים כארגומנט ללא דגל.
    לדוגמה:
    docker run gcr.io/google-containers/busybox
    --container-command command מציינים כארגומנט ללא דגל, אחרי שם קובץ האימג' בקונטיינר.
    לדוגמה:
    docker run gcr.io/google-containers/busybox echo "hello world"
    --container-arg args מציינים כארגומנט בלי דגל, אחרי הפקודה.
    לדוגמה:
    docker run gcr.io/google-containers/busybox echo "hello world"
    --container-env containers.env array --env KEY=VALUE [--env KEY=VALUE ...]
    --container-restart-policy restartPolicy --restart
    הערכים האפשריים הם no,‏ on-failure ו-always. ערך ברירת המחדל הוא no.
    --container-stdin containers.stdin -i
    תכונה ניסיונית בוליאנית, הערך הוא true אם היא קיימת, אחרת הערך הוא false (ברירת מחדל).
    --container-tty containers.tty -t
    תכונה ניסיונית בוליאנית, הערך הוא true אם היא קיימת, אחרת הערך הוא false (ברירת מחדל).
    --container-privileged containers.securityContext.privileged --privileged
    תכונה ניסיונית בוליאנית, הערך הוא true אם היא קיימת, אחרת הערך הוא false (ברירת מחדל).
    --container-mount-disk - אין פקודה מקבילה ל-docker run.
    אפשר לטעון את הדיסק בנפרד.

    דוגמאות לסקריפטים לטעינה בזמן ההפעלה

    בדוגמאות הבאות אפשר לראות איך לכלול את הפקודות docker בסקריפט ההפעלה:

    • דוגמה 1: הרצת קונטיינר עצמאי במכונה וירטואלית שמבוססת על מערכת הפעלה שמותאמת לקונטיינרים.
    • דוגמה 2: הפעלת קונטיינר של שרת אינטרנט במכונה וירטואלית שמבוססת על מערכת הפעלה שמותאמת לקונטיינרים.

    דוגמה 1

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

    #!/bin/bash
    
    # A name for the container
    CONTAINER_NAME="my-app-container"
    
    # Stop and remove the container if it exists
    docker stop $CONTAINER_NAME || true
    docker rm $CONTAINER_NAME || true
    
    # Pull the latest version of the container image from Docker Hub
    docker pull busybox:latest
    
    # Run docker container from image in docker hub
    docker run busybox:latest \
      echo "hello world!"
    

    דוגמה 2

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

    #!/bin/bash
    
    # Enable incoming traffic
    iptables -A INPUT -j ACCEPT
    
    # A name for the container
    CONTAINER_NAME="my-app-container"
    
    # Stop and remove the container if it exists
    docker stop $CONTAINER_NAME || true
    docker rm $CONTAINER_NAME || true
    
    # Pull the latest version of the container image from Docker Hub
    docker pull nginx:latest
    
    # Run docker container from image in docker hub
    docker run \
      --name=$CONTAINER_NAME \
      --privileged \
      --restart=always \
      --tty \
      --detach \
      --network="host" \
      nginx:latest
    

    אפשרויות הגדרה נוספות לפריסת מאגר תגים

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

    מידע נוסף על האפשרויות האלה זמין במאמר הגדרת אפשרויות להפעלת קונטיינר.

    גישה לתמונות ב-Artifact Registry

    אם אתם צריכים לגשת לקובצי אימג' של קונטיינרים מ-gcr.io או מ-pkg.dev, השתמשו בכלי docker-credential-gcr, שמותקן מראש במערכת הפעלה שמותאמת לקונטיינרים, והגדירו אימות ל-Artifact Registry עבור Docker. הריצו את הפקודה הבאה לפני שאתם מריצים את הקונטיינר:

      # Set home directory to save docker credentials
      export HOME=/home/appuser
    
      # Configure docker with credentials for gcr.io and pkg.dev
      docker-credential-gcr configure-docker --registries LOCATION-docker.pkg.dev
    

    מחליפים את LOCATION במיקום של המאגר.

    למידע נוסף, ראו הגדרת אימות ל-Artifact Registry עבור Docker.

    הגדרת רישום ביומן

    מומלץ להשתמש ב-Cloud Logging על ידי הפעלת סוכן רישום ביומן במכונת VM.

    לחלופין, אם רוצים לשנות את מנהל ההתקן של הרישום ביומן, אפשר לכלול את הפרמטר --log-driver בפקודה docker run:

      # Use Cloud Logging logging driver
      docker run --log-driver=gcplogs nginx:latest
    

    מידע נוסף מופיע במאמר בנושא שימוש ב-Cloud Logging עם מערכת הפעלה שמותאמת לקונטיינרים

    הגדרת חומת אש פנימית

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

    מידע נוסף זמין במאמר שימוש בכללים של חומת האש ב-VPC.

      # Enable all incoming and routed traffic
      iptables -A INPUT -j ACCEPT
      iptables -A FORWARD -j ACCEPT
    

    מידע נוסף מופיע במאמר בנושא הגדרת חומת האש של המארח.

    צירוף אמצעי אחסון למאגר

    אם כרכים מצורפים למאגר, המטא-נתונים של המאגר כוללים את הרשומה volumes ומערך volumeMounts. השם name של רשומה ב-volumes תואם לשם של רשומה ב-volumeMounts, ולהפך. לכל נפח שאתם אוספים, אתם צריכים לאסוף את המידע הנדרש מvolumes או מהרשומה volumeMounts.

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

    מידע נוסף על דיסקים ומערכת קבצים ב-Container-Optimized OS זמין במאמר סקירה כללית על דיסקים ומערכת קבצים.

    הרכבת מערכת קבצים מסוג tmpfs

    כדי לטעון מערכת קבצים ריקה של tmpfs לקונטיינר, מציינים את הארגומנט --tmpfs עם הפקודה docker run. לדוגמה, כדי לטעון מערכת קבצים של מטמון לקונטיינר nginx, מריצים את הפקודה הבאה:

      # mount a cache file system to the nginx container
      docker run -d --name=$CONTAINER_NAME --tmpfs /var/cache/nginx:rw,size=512m,noexec,nosuid,nodev --network="host" nginx:latest
    

    מידע נוסף על טעינת מערכות קבצים של tmpfs זמין במאמר טעינות tmpfs.

    טעינת ספרייה של מארח

    כדי לטעון ספרייה ממכונה וירטואלית מארחת למאגר, מציינים את הארגומנט --mount עם הפקודה docker run:

      # mount a read-only directory to the nginx container
      docker run -d --name=$CONTAINER_NAME --mount type=bind,source=/var/www/html,target=/usr/share/nginx/html,ro nginx:latest
    

    מידע נוסף זמין במאמר בנושא Bind mounts.

    טעינת דיסק אחסון מתמיד (persistent disk) לקונטיינר

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

    1. כדי לטעון את הדיסק למכונת ה-VM, מריצים את הפקודה הבאה:

      #!/bin/bash
      
      DISK_DEVICE_NAME="my-persistent-disk" # This name MUST match the 'device-name' in the gcloud --disk flag
      DISK_BY_ID_PATH="/dev/disk/by-id/google-${DISK_DEVICE_NAME}"
      HOST_MOUNT_POINT="/mnt/disks/my-persistent-disk" # This is the path where the disk will be mounted on the VM
      CONTAINER_MOUNT_PATH="/usr/share/my-persistent-disk" # This is the path where the disk will be mounted in the container
      
      # format a disk as an ext4 filesystem, if it doesn't already contain one
      file -sL $DISK_BY_ID_PATH | grep -q filesystem || \
              mkfs.ext4 -m 0 -E lazy_itable_init=0,lazy_journal_init=0,discard $DISK_BY_ID_PATH
      
      # create a directory for mounting point
      sudo mkdir -p "${HOST_MOUNT_POINT}"
      
      # mount a disk to the VM
      sudo mount -o defaults,discard "${DISK_BY_ID_PATH}" "${HOST_MOUNT_POINT}"
      
    2. אחרי שמצמידים את הדיסק ל-VM, מוסיפים את הדגל --mount לפקודה docker run כדי להצמיד את הדיסק למאגר:

      docker run -d --name=$CONTAINER_NAME --mount type=bind,source="${HOST_MOUNT_POINT}",target="${CONTAINER_MOUNT_PATH}",readonly nginx:latest
      

    יצירת סקריפט לטעינה בזמן ההפעלה בעזרת Gemini

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

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

    1. עוברים לדף Compute Engine.

      מעבר אל Compute Engine

    2. בסרגל הכלים Cloud de Confiance , לוחצים על spark Open or close Gemini AI chat כדי לפתוח את הצ'אט עם Gemini Cloud Assist.

      לחצן Gemini Cloud Assist בסרגל הכלים של Compute Engine.

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

    4. לוחצים על שליחת ההנחיה.

    מידע נוסף על הגדרה ושימוש ב-Gemini Cloud Assist זמין במאמר הגדרת Gemini Cloud Assist.

    הנחיה לדוגמה ליצירת סקריפט לטעינה בזמן ההפעלה מתוך הגדרת הקונטיינר הקיימת

          <OBJECTIVE_AND_PERSONA>
          You are a senior systems architect migrating container deployments on Compute Engine. The legacy container startup agent, Konlet, is deprecated, which is the reason for this migration. Your task is to process the input YAML specification, which is the existing container declaration being migrated, and translate it into a robust Bash startup script for Container-Optimized OS on Compute Engine. You must ensure complete functional equivalence with 1:1 Konlet parity by following the `<INSTRUCTIONS>` and referring to the `<CONTEXT>` element below.
          </OBJECTIVE_AND_PERSONA>
    
          <INSTRUCTIONS>
          To complete this task, follow these instructions in sequence:
          1. Initialize the script with the shebang `#!/bin/bash` and options `set -euo pipefail`.
          2. Integrate the "Existing Script" input verbatim immediately after the initialization.
          3. Add a blank line, then define a function wrapper: `start_gce_container() { ... }`.
          4. Inside the function, include the mandatory logic blocks for Firewall, Cleanup, and Authentication provided in the `<CONTEXT>`.
          5. Translate the provided YAML "Container Declaration" using the mapping rules in the `<CONTEXT>`.
          6. Generate HostPath, EmptyDir, or Persistent Disk volume preparation steps using the patterns provided in the `<CONTEXT>`.
          7. Finalize the function, add a blank line, and provide the invocation and completion echo statements as specified in the `<OUTPUT_FORMAT>`.
          </INSTRUCTIONS>
    
          <CONSTRAINTS>
          1. Do not simplify: Ensure all logic steps and verbatim blocks are included. Omitting any block constitutes a functional failure.
          2. UI link protection: Define all URLs using split-string variables to prevent the UI from breaking the script with Markdown links:
             `KLT_URL="http""://metadata.google.internal/..."`
          3. Nsenter prefix: You must prefix every `mkdir`, `mount`, `umount`, `blkid`, `mkfs`, and `grep` (when checking `/proc/mounts`) with: `nsenter -t 1 -m --`.
          4. One command per line: Every single Bash command must be on its own separate line. Do not split a single command's arguments across multiple lines (e.g. keep `docker run` and its flags on one line, or use backslash `\` line continuations if you split the command).
          5. Comment style: Include headers and comments using the `#` symbol for clarity.
          6. Docker execution rules: Always run containers in detached mode using `docker run -d`. Never use the `--rm` flag. Never use the shell background operator (`&`) at the end of the `docker run` command.
          </CONSTRAINTS>
    
          <CONTEXT>
    
          ## Translation dictionary (1:1 Konlet parity)
          1. Restart policy:
             - Always: `--restart always`
             - OnFailure: `--restart on-failure`
             - Never: `--restart no`
          2. Security context:
             - privileged: true -> Add `--privileged` flag.
             - If disk name contains 'local-ssd', use dev path: `/dev/disk/by-id/google-local-nvme-ssd-0`
          3. Multi-container support:
             - If `spec.containers` has multiple entries, generate a separate `docker run` command for EACH container.
          4. Background execution:
             - To run containers in the background, you must use the `docker run -d` (detached) flag. Do not use `--rm` or `&`.
    
          ## Verbatim logic blocks (Use as-is inside function)
          Firewall:
          /sbin/iptables -C INPUT -j ACCEPT 2>/dev/null || /sbin/iptables -A INPUT -j ACCEPT
          /sbin/iptables -C FORWARD -j ACCEPT 2>/dev/null || /sbin/iptables -A FORWARD -j ACCEPT
    
          Cleanup:
          /usr/bin/docker ps -a --filter "name=klt-" -q | xargs -r /usr/bin/docker rm -f
          nsenter -t 1 -m -- /bin/sh -c 'for m in $(/bin/grep "/mnt/disks/gce-containers-mounts/" /proc/mounts | /usr/bin/awk '\''{print $2}'\'' | /bin/sort -r); do /bin/umount "$m" || true; done'
    
          Authentication (Hardened for boot-time race conditions):
          export DOCKER_CONFIG="/var/lib/docker-config"
          /bin/mkdir -p "$DOCKER_CONFIG"
          KLT_URL_TOKEN="http""://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token"
          KLT_URL_REG="https""://gcr.io"
          /bin/sleep 2
          KLT_TOKEN=$(/usr/bin/curl -s -H "Metadata-Flavor: Google" "$KLT_URL_TOKEN" | /bin/grep -o '"access_token":"[^"]*' | /bin/grep -o '[^"]*$')
          if [ -n "$KLT_TOKEN" ]; then
            echo "$KLT_TOKEN" | /usr/bin/docker login -u oauth2accesstoken --password-stdin "$KLT_URL_REG"
          fi
    
          ## Volume preparation patterns
          Pattern A (GcePersistentDisk):
          nsenter -t 1 -m -- /bin/mkdir -p [MNT_PATH]
          nsenter -t 1 -m -- /sbin/blkid [DEV_PATH] || nsenter -t 1 -m -- /sbin/mkfs.ext4 -m 0 -E lazy_itable_init=0,lazy_journal_init=0,discard [DEV_PATH]
          nsenter -t 1 -m -- /bin/mount -t ext4 -o discard,defaults [DEV_PATH] [MNT_PATH]
          nsenter -t 1 -m -- /bin/grep -q " [MNT_PATH] " /proc/mounts || exit 1
    
          Pattern B (EmptyDir Memory):
          nsenter -t 1 -m -- /bin/mkdir -p [MNT_PATH]
          nsenter -t 1 -m -- /bin/mount -t tmpfs tmpfs [MNT_PATH]
          nsenter -t 1 -m -- /bin/grep -q " [MNT_PATH] " /proc/mounts || exit 1
    
          Pattern C (HostPath):
          nsenter -t 1 -m -- /bin/mkdir -p [HOST_PATH]
          </CONTEXT>
    
          <OUTPUT_FORMAT>
          1. Shebang & Opts: `#!/bin/bash` and `set -euo pipefail`.
          2. Existing Script: Integrated verbatim.
          3. [BLANK LINE]
          4. Function Wrapper: `start_gce_container() { ... }`
          5. [BLANK LINE]
          6. Invocation: `start_gce_container || echo "Error: Container failed to start..."`
          7. Completion: `echo "Startup script finished."`
          </OUTPUT_FORMAT>
    
          <FEW_SHOT_EXAMPLES>
          <INPUT_YAML>
          ```yaml
          spec: \
            containers: \
            - name: klt-main \
              image: gcr.io/my-proj/app:v1 \
              volumeMounts: \
              - name: data \
                mountPath: /data \
            volumes: \
            - name: data \
              gcePersistentDisk: \
                pdName: data-disk \
                fsType: ext4
          ```
          </INPUT_YAML>
    
          <OUTPUT_THOUGHTS>
          The model should identify Pattern A for GcePersistentDisk and use the `nsenter` prefix for mounts.
          </OUTPUT_THOUGHTS>
    
          <OUTPUT_SNIPPETS>
          <SAMPLE_STARTUP_SCRIPT>
          #!/bin/bash \
          set -euo pipefail \
          echo "=== STARTING CUSTOM PRE-STARTUP ===" \
          mkdir -p /tmp/test-marker \
          echo "marker-content" > /tmp/test-marker/ok.txt \
          echo "=== FINISHED CUSTOM PRE-STARTUP ==="
    
          start_gce_container() {
          # Firewall:
          /sbin/iptables -C INPUT -j ACCEPT 2>/dev/null || /sbin/iptables -A INPUT -j ACCEPT
          /sbin/iptables -C FORWARD -j ACCEPT 2>/dev/null || /sbin/iptables -A FORWARD -j ACCEPT
    
          # Cleanup:
          /usr/bin/docker ps -a --filter "name=klt-" -q | xargs -r /usr/bin/docker rm -f
          nsenter -t 1 -m -- /bin/sh -c 'for m in $(/bin/grep "/mnt/disks/gce-containers-mounts/" /proc/mounts | /usr/bin/awk '\''{print $2}'\'' | /bin/sort -r); do /bin/umount "$m" || true; done'
    
          # Authentication (Hardened for boot-time race conditions):
          export DOCKER_CONFIG="/var/lib/docker-config"
          /bin/mkdir -p "$DOCKER_CONFIG"
          KLT_URL_TOKEN="http""://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token"
          KLT_URL_REG="https""://gcr.io"
          /bin/sleep 2
          KLT_TOKEN=$(/usr/bin/curl -s -H "Metadata-Flavor: Google" "$KLT_URL_TOKEN" | /bin/grep -o '"access_token":"[^"]*' | /bin/grep -o '[^"]*$')
          if [ -n "$KLT_TOKEN" ]; then
            echo "$KLT_TOKEN" | /usr/bin/docker login -u oauth2accesstoken --password-stdin "$KLT_URL_REG"
          fi
    
          </SAMPLE_STARTUP_SCRIPT>
          </OUTPUT_SNIPPETS>
          </FEW_SHOT_EXAMPLES>
    
          <RECAP>
          As the systems architect leading this migration on Compute Engine, you must ensure that the final script retains full functional equivalence with the deprecated Konlet agent. This requires applying the host-level execution constraints using `nsenter` specified in the `<CONTEXT>` element, protecting URLs with string splitting, and strictly conforming to the `<OUTPUT_FORMAT>` without skipping any logic blocks.
          </RECAP>
    
          # Input
          1. Existing script: EXISTING_SCRIPT
          2. Container declaration (YAML): CONTAINER_YAML
      

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

    • EXISTING_SCRIPT: התוכן של סקריפט לטעינה בזמן ההפעלה הקיים. מוסיפים קו נטוי הפוך (‎\‎) בסוף כל שורה במקום מעבר שורה.
    • CONTAINER_YAML: מפרט ה-YAML של פריסת מאגר התגים מתוך מפתח המטא-נתונים gce-container-declaration. מוסיפים לוכסן נטוי (‎/‎) בסוף כל שורה במקום מעבר שורה.

    יצירת מכונה וירטואלית באמצעות סקריפט לטעינה בזמן ההפעלה

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

    מידע נוסף על שימוש בסקריפטים לטעינה בזמן ההפעלה זמין במאמר שימוש בסקריפטים לטעינה בזמן ההפעלה במכונות וירטואליות של Linux.

    המסוף

    1. נכנסים לדף Create an instance במסוף Cloud de Confiance .

      כניסה לדף Create an instance

      אם מוצגת בקשה לעשות זאת, בוחרים פרויקט ולוחצים על המשך. הדף Create an instance מופיע ובו החלונית Machine configuration.

    2. בחלונית Machine configuration, בוחרים את סוג המכונה ואת משפחת המכונות של מכונת ה-VM.

    3. בתפריט הניווט, לוחצים על מערכת הפעלה ואחסון. בחלונית Operating system and storage שמופיעה, מגדירים את דיסק האתחול באופן הבא:

      1. לוחצים על Change. מופיעה החלונית דיסק אתחול עם הכרטיסייה Public images.
      2. ברשימה Operating system בוחרים באפשרות Container Optimized OS.
      3. ברשימה Version בוחרים את גרסת מערכת ההפעלה.
      4. ברשימה Boot disk type בוחרים את סוג דיסק האתחול.
      5. (אופציונלי) אם אתם צריכים דיסקים נוספים, מוסיפים אותם בקטע דיסקים נוספים.
      6. לוחצים על בחירה.
    4. בתפריט הניווט, לוחצים על מתקדם.

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

    gcloud

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

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

      gcloud compute instances create VM_NAME \
          --zone=ZONE \
          --image-family=IMAGE_FAMILY \
          --image-project=IMAGE_PROJECT \
          --machine-type=MACHINE_TYPE \
          --metadata-from-file=startup-script=STARTUP_SCRIPT_FILE
      

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

      • VM_NAME: name של המכונה הווירטואלית החדשה.
      • ZONE: האזור שבו רוצים ליצור את המכונה.
      • IMAGE_PROJECT: פרויקט האימג' של מערכת ההפעלה שמותאמת לקונטיינרים שמכיל את האימג', לדוגמה, cos-cloud.
      • IMAGE_FAMILY: משפחת התמונות של מערכת ההפעלה שמותאמת לקונטיינרים, לדוגמה, cos-stable.
      • MACHINE_TYPE: סוג המכונה של המכונה הווירטואלית החדשה, שיכול להיות סוג מכונה מוגדר מראש או סוג מכונה בהתאמה אישית.
      • STARTUP_SCRIPT_FILE: הנתיב היחסי במחשב לקובץ סקריפט לטעינה בזמן ההפעלה, לדוגמה, ./startup_script.sh.

      לדוגמה:

      # Create COS-based VM by using a startup script
      gcloud compute instances create "cos-instance-with-startup-script" \
      --zone="us-central1-c" \
      --machine-type="e2-medium" \
      --image-family="cos-stable" \
      --image-project="cos-cloud" \
      --metadata-from-file=startup-script="./startup_script.sh"
      
    2. מריצים את הפקודה הבאה כדי לוודא ש-Compute Engine יצר את מכונת ה-VM:

      gcloud compute instances describe VM_NAME
      

      מחליפים את VM_NAME בשם של המכונה הווירטואלית שיצרתם.

    Terraform

    כדי ליצור מכונה וירטואלית, אפשר להשתמש בgoogle_compute_instance משאב.

    provider "google" {
    project = "PROJECT_ID"
    }
    
    resource "google_compute_instance" "cos_vm_instance" {
    name         = "VM_NAME"
    machine_type = "MACHINE_TYPE"
    zone         = "ZONE"
    
    # Use a Container-Optimized OS image for the boot disk
    boot_disk {
      initialize_params {
        image = "IMAGE_PROJECT/IMAGE_FAMILY"
      }
    }
    
    # Attaches the instance to the default network
    network_interface {
      network = "default"
    }
    
    # Specify the relative path to the startup script on your local machine
    metadata = {
      startup-script = file("STARTUP_SCRIPT_FILE")
    }
    }
    

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

    לדוגמה:

    provider "google" {
      project = "my-project"
    }
    
    resource "google_compute_instance" "my_container_vm" {
      name = "my-container-vm-startup"
      machine_type = "e2-medium"
      zone = "us-central1-a"
    
      boot_disk {
        initialize_params {
          image = "cos-cloud/cos-stable"
        }
      }
    
      network_interface {
        network = "default"
      }
    
      metadata = {
        startup-script = file("./startup_script.sh")
      }
    }
    

    יצירת קבוצת MIG באמצעות סקריפט לטעינה בזמן ההפעלה

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

    מידע נוסף על יצירת קבוצות MIG זמין במאמר יצירה של קבוצת מופעי מכונה מנוהלים.

    המסוף

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

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

    gcloud

    1. יוצרים תבנית של הגדרות מכונה באמצעות הפקודה instance-templates create.

      חובה להשתמש בתמונה של מערכת הפעלה שמותאמת לקונטיינרים עבור מכונת ה-VM. אפשר לציין את הנתיב היחסי לקובץ הסקריפט לטעינה בזמן ההפעלה באמצעות הדגל --metadata-from-file.

    2. יוצרים קבוצת MIG באמצעות תבנית של הגדרות מכונה שנוצרה בשלב הקודם.

    לדוגמה:

      # Create the instance template that uses a startup script
      gcloud compute instance-templates create startup-template \
          --machine-type=e2-medium \
          --image-family=cos-stable \
          --image-project=cos-cloud \
          --metadata-from-file=startup-script=./startup_script.sh
    
      # Create the managed instance group
        gcloud compute instance-groups managed create startup-mig \
          --template=startup-template \
          --size=2 \
          --zone=us-central1-a
    

    Terraform

    משתמשים במשאבים google_compute_instance_template ו-google_compute_instance_group_manager כדי ליצור תבנית של הגדרות מכונה וקבוצת MIG, כמו בדוגמה הבאה:

    דוגמה:

    resource "google_compute_instance_template" "startup_template" {
      name_prefix = "startup-template-"
      machine_type = "e2-medium"
      disk {
        source_image = "cos-cloud/cos-stable"
        auto_delete  = true
        boot         = true
      }
    
      network_interface {
        network = "default"
      }
      metadata = {
        startup-script = file("./startup_script.sh")
    }
    }
    
    resource "google_compute_instance_group_manager" "startup_mig" {
      name               = "startup-mig"
      base_instance_name = "startup-vm"
      zone               = "us-central1-a"
      version {
        instance_template = google_compute_instance_template.startup_template.id
      }
      target_size = 2
    }
    

    בדיקה וניקוי

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

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

    פתרון בעיות בסקריפטים לטעינה בזמן ההפעלה

    בקטע הזה מפורט מידע לפתרון בעיות שאתם עשויים להיתקל בהן במהלך השימוש בסקריפטים להפעלה.

    לא ניתן לשמור את הגדרת Docker

    כשמריצים את הפקודה docker-credential-gcr configure-docker בסקריפט לטעינה בזמן ההפעלה, יכול להיות שתוצג הודעת השגיאה הבאה:

    ERROR: Unable to save docker config: mkdir /root/.docker: read-only file system

    השגיאה הזו מתרחשת כי docker-credential-gcr מנסה לכתוב פרטי כניסה לקובץ /root/.docker/config.json. מערכת הקבצים root במערכת הפעלה שמותאמת לקונטיינרים היא לקריאה בלבד, ולכן אי אפשר לכתוב בה.

    כדי לפתור את הבעיה, צריך להגדיר את משתנה הסביבה $HOME כך שיצביע על ספריית בית מותאמת אישית לפני שמריצים את הפקודות docker.

    דוגמה:

      export HOME=/home/appuser
      docker-credential-gcr configure-docker
      

    צפייה ביומנים כדי לנפות באגים

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

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

      sudo journalctl | grep "startup-script"
      
    • כדי להציג את היומנים מהקונטיינר של Docker, מריצים את הפקודה docker logs:

      docker logs CONTAINER_NAME
      

      מחליפים את CONTAINER_NAME בשם הקונטיינר.

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

    שימוש ב-cloud-init עם מערכת הפעלה שמותאמת לקונטיינרים

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

    שימוש בשירותים מנוהלים לפריסת קונטיינרים

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

    Cloud Run

    ‫Cloud Run הוא אפשרות טובה לאפליקציות בקונטיינרים ללא שמירת מצב ולעבודות קטנות עד בינוניות.

    התכונות העיקריות של Cloud Run כוללות את התכונות הבאות:

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

    מידע נוסף על פריסת קונטיינרים ב-Cloud Run זמין במאמר פריסת קובצי אימג' של קונטיינרים ב-Cloud Run

    Batch

    ‫Batch הוא שירות שמנוהל במלואו ומאפשר לתזמן, להוסיף לתור ולהפעיל עומסי עבודה של עיבוד באצווה במשאבי Cloud de Confiance . הוא מיועד להפעלת עומסי עבודה מקבילים בסגנון עיבוד באצווה, כולל עומסי עבודה שמוכלים בקונטיינרים.

    מידע נוסף על פריסת קונטיינרים ב-Batch זמין במסמכים הבאים:

    GKE

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

    פנייה לתמיכה

    אם יש לך שאלות לגבי תהליך המיגרציה או שדרושה לך עזרה, אפשר לעיין בשאלות הנפוצות או ליצור קשר עם Cloud de Confiance התמיכה.