הגדרת תרחישי הפעלה של מכונות וירטואליות

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

מגדירים את משימות ההפעלה האלה באמצעות cloud-init API או באמצעות startup scripts API (לא שניהם). הנחיות ההפעלה האלה מצוינות בקובץ המניפסט VirtualMachine YAML ומופעלות אוטומטית בכל פעם שמכונת ה-VM מופעלת.

דרישות מוקדמות

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

  • הפעלת VM Runtime ב-GDC.

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

  • מוודאים ש-cloud-init מותקן במערכת ההפעלה של האורח. רוב מערכות ההפעלה העדכניות של Linux כוללות cloud-init.

בקטעים הבאים מוסבר איך מציינים שגרות הפעלה במניפסט של מכונה וירטואלית באמצעות cloud-init API או סקריפטים להפעלה.

שימוש ב-cloud-init API כדי לאתחל מכונות וירטואליות

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

חשוב לשים לב לפרטים הבאים לגבי ההטמעה של cloud-init:

  • מציינים את נתוני cloud-init במניפסט YAML‏ VirtualMachine כשיוצרים או מעדכנים מכונה וירטואלית. הוראות ליצירת מכונה וירטואלית באמצעות מניפסט מפורטות במאמר הדרכה: יצירה וניהול של מכונת Linux וירטואלית ב-VM Runtime ב-GDC.

  • אנחנו משתמשים בNoCloud מקור הנתונים,‏ spec.cloudInit.noCloud, במפרט של מכונת ה-VM.

  • מציינים נתוני משתמש ונתונים מהרשת בקטעים נפרדים במניפסט VirtualMachine. השם והמבנה של הקטע תלויים בפורמט הנתונים שבוחרים להשתמש.

  • אפשר לציין את פרטי ההגדרה של cloud-init בפורמטים הבאים של נתונים:

    • טקסט גלוי
    • מחרוזת בקידוד Base64
    • סוד ב-Kubernetes

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

נתוני משתמש של Cloud-init

‫VM Runtime ב-GDC תומך בנתוני משתמש ב-cloud-init בתחביר של cloud-config, לכן צריך להתחיל את נתוני המשתמש ב-#cloud-config. אפשר לעצב את נתוני המשתמש כטקסט רגיל, כמחרוזת מקודדת ב-Base64 או כ-Kubernetes Secret.

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

נתוני משתמש של Cloud-init כטקסט גלוי

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

apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
  name: "my-vm"
spec:
  ...
  cloudInit:
    noCloud:
      userData: |
        #cloud-config
        runcmd:
          - echo hello

נתוני משתמש ב-Cloud-init כמחרוזת בקידוד Base64

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

apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
  name: "my-vm"
spec:
  ...
  cloudInit:
    noCloud:
      userDataBase64: I2Nsb3VkLWNvbmZpZwpydW5jbWQ6CiAgLSBlY2hvIGhlbGxvCg==

נתוני משתמש של Cloud-init כסוד ב-Kubernetes

בדוגמה הבאה מוצג מניפסט YAML גם ל-VirtualMachine וגם ל-Secret. הקטע spec.cloudInit.noCloud.secretRef בהגדרה VirtualMachine מציין שנתוני המשתמש של cloud-init נמצאים ב-Kubernetes Secret בשם my-sec. ההגדרה התואמת Secret מציינת את נתוני המשתמש כצמד מפתח-ערך. הערך בקידוד base64 במקרה הזה הוא נתוני המשתמש של cloud-init בתחביר cloud-config.

בסוד שאליו יש הפניה, משתמשים במפתח הנתונים userData (שמוצג) או userdata כדי לציין את נתוני המשתמש של cloud-init.

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

apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
  name: "my-vm"
spec:
  ...
  cloudInit:
    noCloud:
      secretRef:
        name: my-sec
---
apiVersion: v1
kind: Secret
type: Opaque
metadata:
  name: my-sec
data:
  userData: I2Nsb3VkLWNvbmZpZwpydW5jbWQ6CiAgLSBlY2hvIGhlbGxvCg==

אם לא נמצא סוד שההפניה אליו מופיעה או שמפתח הנתונים userData או userdata לא קיים בסוד, שימו לב להתנהגות הבאה של הפעלת מכונת ה-VM:

  • במהלך יצירת מכונה וירטואלית, המכונה הווירטואלית מועברת למצב ErrorConfiguration עם סיבה והודעה מפורטות.

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

כדי לאחזר את פרטי מכונת ה-VM, כולל נתוני המשתמש של cloud-init שהיו בשימוש, משתמשים בפקודה הבאה:

kubectl get vm VM_NAME -o yaml --kubeconfig KUBECONFIG_PATH

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

  • VM_NAME: השם של ה-VM.

  • KUBECONFIG_PATH: הנתיב לקובץ kubeconfig של האשכול שמכיל את מכונת ה-VM.

כדי לאחזר את אירוע האזהרה שקשור ל-Kubernetes, משתמשים ב-kubectl get event או ב-kubectl describe gvm.

נתוני רשת של Cloud-init

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

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

מידע נוסף על תחביר נתוני הרשת ופרטים קשורים זמין במאמר Networking Config Version 2 בתיעוד של cloud-init.

נתוני רשת של Cloud-init כטקסט גלוי

קובץ המניפסט הבא מראה איך לציין נתוני רשת כטקסט גלוי. במקרה הזה, cloud-init מפעיל DHCP לכל מכשירי ה-Ethernet עם שמות שמתחילים באות e (e*):

apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
  name: "my-vm"
spec:
  ...
  cloudInit:
    noCloud:
      userData: |
        #cloud-config
        runcmd:
          - echo hello
      networkData: |
        version: 2
        ethernets:
          alleths:
            match:
              name: e*
            dhcp4: true

נתוני רשת של Cloud-init כמחרוזת בקידוד Base64

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

apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
  name: "my-vm"
spec:
  ...
  cloudInit:
    noCloud:
      networkDataBase64: dmVyc2lvbjogMgpldGhlcm5ldHM6CiAgYWxsZXRoczoKICAgIG1hdGNoOgogICAgICBuYW1lOiBlKgogICAgZGhjcDQ6IHRydWUK

נתוני רשת של Cloud-init כסוד ב-Kubernetes

בדוגמה הבאה מוצג מניפסט YAML גם ל-VirtualMachine וגם ל-Secret. הקטע spec.cloudInit.noCloud.networkDataSecretRef בהגדרה VirtualMachine מציין שנתוני הרשת של cloud-init נמצאים ב-Kubernetes Secret בשם my-sec. ההגדרה התואמת Secret מציינת את נתוני הרשת כצמד מפתח/ערך. הערך בקידוד Base64 במקרה הזה הוא נתוני הרשת של cloud-init.

בסוד שאליו יש הפניה, משתמשים במפתח הנתונים networkData (כפי שמוצג) או networkdata כדי לציין את נתוני הרשת של cloud-init.

בדוגמה הזו, נתוני הרשת כוללים את אותה הגדרת DHCP שצוינה בדוגמה של טקסט גלוי:

apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
  name: "my-vm"
spec:
  ...
  cloudInit:
    noCloud:
      networkDataSecretRef:
        name: my-sec
---
apiVersion: v1
kind: Secret
type: Opaque
metadata:
  name: my-sec
data:
  networkData: dmVyc2lvbjogMgpldGhlcm5ldHM6CiAgYWxsZXRoczoKICAgIG1hdGNoOgogICAgICBuYW1lOiBlKgogICAgZGhjcDQ6IHRydWUK

דוגמאות ל-cloud-init

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

הגדרת מפתחות SSH מורשים

בדוגמה הבאה של נתוני משתמשים, מפתח ה-SSH המורשה ssh-rsa AAAAB3NzaK8L93bWxnyp מוקצה למשתמש ברירת המחדל.

apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
  name: "my-vm"
spec:
  ...
  cloudInit:
    noCloud:
      userData: |
        #cloud-config
        ssh_authorized_keys:
          - ssh-rsa AAAAB3NzaK8L93bWxnyp

הוספת משתמש חדש

בדוגמה הבאה של נתוני משתמש נוצר משתמש test וניתנת לו גישת sudo מלאה test. בדוגמה הזו, למשתמש מוקצית סיסמה שלא פגה, pwd.

apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
  name: "my-vm"
spec:
  ...
  cloudInit:
    noCloud:
      userData: |
        #cloud-config
        users:
        - default
        - name: test
          sudo: ALL=(ALL) NOPASSWD:ALL
        chpasswd:
          list: |
            test:pwd
          expire: False

הרצת פקודות בהפעלה הראשונה

בדוגמה הבאה של נתוני משתמשים מריצים פקודה של echo ופקודה של ls. אתם יכולים להשתמש בפקודות כדי להתקין חבילות ועוד כשמכונת ה-VM מופעלת.

apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
  name: "my-vm"
spec:
  ...
  cloudInit:
    noCloud:
      userData: |
        #cloud-config
        runcmd:
          - [ echo, hello ]
          - [ ls, -l, / ]

כתיבת קבצים

בדוגמה הבאה של נתוני משתמשים, סקריפט bash נכתב לקובץ test בספרייה /var/lib/google של מכונת ה-VM. ההנחיות של cloud-init מגדירות את הרשאות הקובץ לקריאה, כתיבה והרצה (0744) עבור בעלי הקובץ.

apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
  name: "my-vm"
spec:
  ...
  cloudInit:
    noCloud:
      userData: |
        #cloud-config
        write_files:
        - path: /var/lib/google/test
          permissions: 0744
          content: |
            #!/bin/bash
            echo hello

פתרון בעיות ב-cloud-init

אם נתקלתם בבעיות באתחול של המכונה הווירטואלית ואתם משתמשים ב-cloud-init, כדאי לבדוק את יומני cloud-init הבאים במכונה הווירטואלית:

  • /var/log/cloud-init.log: כברירת מחדל, cloud-init כותב ביומן הזה את כל האירועים ברמה DEBUG ומעלה.

  • /var/log/cloud-init-output.log: כברירת מחדל, cloud-init מפנה את stdout ואת stderr מכל השלבים של cloud-init ליומן הזה.

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

סקריפטים להפעלה מבצעים משימות במהלך תהליך ההפעלה של מכונה וירטואלית (VM). אפשר לציין סקריפט אחד או יותר בקטע spec.startupScripts של מפרט VirtualMachine. אפשר להשתמש בסקריפטים להפעלה כדי לאתחל את המכונה הווירטואלית. אתחול של מכונה וירטואלית כולל בדרך כלל משימות כמו התקנת חבילות, הגדרת מאגר, יצירת מפתח SSH, כתיבת נתונים לקבצים והגדרת היבטים אחרים של המכונה הווירטואלית.

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

  • מציינים סקריפטים לטעינה בזמן ההפעלה במניפסט VirtualMachine YAML כשיוצרים או מעדכנים מכונה וירטואלית. הוראות ליצירת מכונה וירטואלית באמצעות מניפסט מפורטות במאמר הדרכה: יצירה וניהול של מכונת Linux וירטואלית ב-VM Runtime ב-GDC.

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

  • כוללים את #!/bin/... בחלק העליון של הסקריפט כדי לציין את מפענח הסקריפט. לדוגמה, אפשר לכלול #!/bin/bash כדי להריץ את הסקריפט באמצעות מעטפת Bash.

  • אי אפשר לציין גם הנחיות ל-cloud-init API (spec.cloudInit) וגם סקריפטים להפעלה (spec.startupScripts) באותו מניפסט VirtualMachine.

פורמטים של סקריפטים

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

  • טקסט גלוי
  • מחרוזת בקידוד Base64
  • סוד ב-Kubernetes

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

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

  • כשמשתמשים ב-Kubernetes Secret, צריך להשתמש במפתח הנתונים script ב-Secret שאליו מתייחסים כדי לציין את תוכן הסקריפט.

  • אם לא נמצא סוד שמופנה אליו או שמפתח הנתונים script לא קיים בסוד שמופנה אליו, מכונת ה-VM ממשיכה להריץ את הסקריפט. עם זאת, המכונה הווירטואלית לא כותבת או מעדכנת את תוכן הסקריפט. במקרה כזה, אפשר למצוא את אירוע האזהרה של Kubernetes באמצעות kubectl get event או kubectl describe gvm.

קובץ המניפסט הבא לדוגמה בפורמט YAML מכיל שלושה סקריפטים, אחד בכל אחד מהפורמטים הנתמכים.VirtualMachine במקרה הזה, כל סקריפט מריץ את הפקודה echo hello שמוצגת בmyscript1, בדוגמה של הטקסט הגלוי.

apiVersion: vm.cluster.gke.io/v1
kind: VirtualMachine
metadata:
  name: "my-vm"
spec:
  ...
  startupScripts:
  - name: myscript1
    script: |
      #!/bin/bash
      echo hello
  - name: myscript2
    scriptBase64: IyEvYmluL2Jhc2gKICAgICAgZWNobyBoZWxsbwo=
  - name: myscript3
    scriptSecretRef:
      name: my-sec
---
apiVersion: v1
kind: Secret
type: Opaque
metadata:
  name: my-sec
data:
  script: IyEvYmluL2Jhc2gKICAgICAgZWNobyBoZWxsbwo=

פתרון בעיות בסקריפטים

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

journalctl -u cloud-final

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

started to run the command /var/lib/google/startup-scripts/SCRIPT_NAME ...

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