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

במאמר הזה מוסבר איך משתמשים בסקריפטים לטעינה בזמן ההפעלה כדי להפעיל מכונה וירטואלית (VM) ואת התוכנות שמשויכות אליה ב-Google Distributed Cloud (GDC) עם air gap.

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

המסמך הזה מיועד למפתחים בקבוצות של אדמינים של פלטפורמות או של מפעילי אפליקציות, שרוצים להשתמש בסקריפטים לטעינה בזמן ההפעלה של מכונות וירטואליות בסביבת Distributed Cloud. מידע נוסף מופיע במאמר קהלים למסמכי תיעוד של GDC עם air gap.

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

כדי להשתמש בפקודות של ממשק שורת הפקודה (CLI) של gdcloud, צריך לוודא שהורדתם, התקנתם והגדרתם את ה-CLI של gdcloud. כל הפקודות של Distributed Cloud משתמשות ב-CLI של gdcloud או kubectl, ודורשות סביבה של מערכת הפעלה (OS).

קבלת נתיב הקובץ של kubeconfig

כדי להריץ פקודות בשרת Management API, צריך לוודא שיש לכם את המשאבים הבאים:

  1. אם אין לכם קובץ kubeconfig לשרת Management API, נכנסים לחשבון ויוצרים אותו.

  2. בהוראות הבאות, מחליפים את MANAGEMENT_API_SERVER בנתיב לקובץ kubeconfig של שרת Management API.

בקשת תפקידים ב-IAM

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

  • אדמין של פרויקט מכונות וירטואליות (project-vm-admin): יצירה, שינוי, הצגה ומחיקה של מכונות וירטואליות במרחב השמות של הפרויקט.

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

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

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

אפשר להשתמש בסקריפטים של bash או בסקריפטים שהם לא של bash כסקריפטים לטעינה בזמן ההפעלה. כדי לעשות את זה, צריך לכלול את #!/bin/… בתחילת הסקריפט כדי לציין את מפרש הסקריפט. לדוגמה, כדי להשתמש בסקריפט לטעינה בזמן ההפעלה של Python 3, מוסיפים את #! /usr/bin/python3 לתחילת הסקריפט.

ב-Google Distributed Cloud (GDC) במודל Air-gapped, הסקריפטים לטעינה בזמן ההפעלה פועלים לפי הסדר שבו הם מופיעים במערך startupScripts.

בטבלה הבאה מוצג הפורמט של הסקריפט שבו צריך להשתמש בהתאם לגודל הסקריפט:

גודל הסקריפט פורמט הסקריפט
סקריפטים בגודל של עד 2,048 בייטים מחיקת הטקסט
סקריפטים שגדולים מ-2,048 בייטים סוד ב-Kubernetes

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

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

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

apiVersion: virtualmachine.gdc.goog/v1
kind: VirtualMachine
metadata:
  name: "my-vm"
spec:
  # …
  startupScripts:
  - name: hello-world
    script: |
      #!/bin/bash
      echo hello
  - name: add-user
    scriptSecretRef:
      name: add-user
---

apiVersion: v1
kind: Secret
type: Opaque
metadata:
  name: add-user
data:
  script:
    IyEvYmluL2Jhc2gKYWRkdXNlciB1c2VyCg==

כדאי להביא בחשבון את השיקולים הבאים:

  • הסקריפט לטעינה בזמן ההפעלה פועל בכל הפעלה.
  • לסקריפט לטעינה בזמן ההפעלה יש הרשאות בסיסיות כברירת מחדל.
  • בסוד של Kubernetes, השם של scriptSecretRef במכונה הווירטואלית spec צריך להיות זהה לשדה metadata.name.
  • בסוד של Kubernetes, מציינים את תוכן הסקריפט לטעינה בזמן ההפעלה על ידי הוספת מפתח script לשדה data.

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

ההוראות האלה רלוונטיות לכל קובץ אימג' שבו משתמשים כדי ליצור את ה-VM. צריך לבצע את השלבים הבאים:

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

    cat <<EOF >>FILE_NAME
    STARTUP_SCRIPT_CONTENT
    EOF
    
    kubectl --kubeconfig MANAGEMENT_API_SERVER \
      -n PROJECT \
      create secret generic SECRET_NAME \
      --from-file=script=FILE_NAME
    
    rm FILE_NAME
    
  2. מבצעים את השלבים ליצירת מכונה וירטואלית, כמו שמתואר בדף יצירת מכונה וירטואלית. בשלב הראשון, מוסיפים את הסקריפט או הסקריפטים לטעינה בזמן ההפעלה לשדה spec לפני שמריצים את הפקודה ליצירת מכונה וירטואלית.

    בדוגמה הזו מוגדר סקריפט לטעינה בזמן ההפעלה עם טקסט ברור וגם עם סוד של Kubernetes:

    apiVersion: virtualmachine.gdc.goog/v1
    kind: VirtualMachine
    metadata:
      name: VM_NAME
      namespace: PROJECT
    spec:
      # …
      startupScripts:
      - name: CLEAR_TEXT_SCRIPT_NAME
        script: |
          #!/bin/bash
          CLEAR_TEXT_SCRIPT
      - name: SECRET_SCRIPT_NAME
        scriptSecretRef:
          name: SECRET_NAME
    

    המשתנים האלה מוגדרים כך:

    משתנההגדרה
    MANAGEMENT_API_SERVER קובץ kubeconfig של שרת Management API.
    PROJECT הפרויקט ב-Distributed Cloud שבו רוצים ליצור את המכונה הווירטואלית.
    VM_NAME שם המכונה הווירטואלית.
    FILE_NAME שם הקובץ שבו מאוחסן הסקריפט לטעינה בזמן ההפעלה.
    STARTUP_SCRIPT_CONTENT הפקודות שצריך להריץ כחלק מהסקריפט לטעינה בזמן ההפעלה
    CLEAR_TEXT_SCRIPT_NAME השם של הסקריפט לטעינה בזמן ההפעלה בטקסט פשוט.
    CLEAR_TEXT_SCRIPT הסקריפט בטקסט פשוט שאתם מגדירים.
    SECRET_NAME השם של הסוד ב-Kubernetes.
    SECRET_SCRIPT_NAME שם הסקריפט לטעינה בזמן ההפעלה כסוד של Kubernetes.
  3. כדי ליצור מכונה וירטואלית, פועלים לפי השלבים הבאים.

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

    kubectl --kubeconfig MANAGEMENT_API_SERVER \
      -n PROJECT \
      apply -f - <<EOF
    apiVersion: virtualmachine.gdc.goog/v1
    kind: VirtualMachineDisk
    metadata:
      name: VM_BOOT_DISK_NAME
    spec:
      source:
        image:
          name: BOOT_DISK_IMAGE_NAME
          namespace: vm-system
      size: BOOT_DISK_SIZE
    ---
    apiVersion: v1
    kind: Secret
    type: Opaque
    metadata:
      name: add-user
    data:
      script:
        IyEvYmluL2Jhc2gKYWRkdXNlciB1c2VyCg==
    ---
    apiVersion: virtualmachine.gdc.goog/v1
    kind: VirtualMachine
    metadata:
      name: VM_NAME
    spec:
      compute:
        virtualMachineType: MACHINE_TYPE
      disks:
      - virtualMachineDiskRef:
          name: VM_BOOT_DISK_NAME
        boot: true
        autoDelete: BOOT_DISK_AUTO_DELETE
      startupScripts:
      - name: add-user
        scriptSecretRef:
          name: add-user
      - name: add-to-sudoers
        script: |
          #!/bin/bash
          usermod -aG sudo user
    EOF
    

    בדוגמה הזו, המשתנים מוגדרים כך:

    משתנההגדרה
    MANAGEMENT_API_SERVER קובץ kubeconfig של שרת Management API.
    PROJECT הפרויקט ב-Distributed Cloud שבו רוצים ליצור את ה-VM.
    VM_NAME השם של המכונה הווירטואלית החדשה.
    VM_BOOT_DISK_NAME השם של דיסק האתחול של ה-VM החדש.
    BOOT_DISK_IMAGE_NAME שם קובץ האימג' שישמש לדיסק האתחול של ה-VM החדש.
    BOOT_DISK_SIZE גודל דיסק האתחול, למשל 20G.
    הערך הזה תמיד חייב להיות גדול או שווה ל-minimumDiskSize של קובץ האימג' של דיסק האתחול.
    BOOT_DISK_AUTO_DELETE ‫true או false, כדי לציין אם דיסק האתחול נמחק באופן אוטומטי כשמכונת ה-VM נמחקת.
    MACHINE_TYPE סוג המכונה עם הקונפיגורציה המוגדרת (predefined) של המכונה הווירטואלית החדשה. כדי לבחור סוג מכונה זמין, מריצים את הפקודה הבאה:
    kubectl --kubeconfig MANAGEMENT_API_SERVER get virtualmachinetype.virtualmachine.gdc.goog --namespace vm-system

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

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

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

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

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

    sudo journalctl -u cloud-final
    

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

    Started to run the command: /var/lib/google/startup-scripts/<script-name> ...