VM-Startroutinen konfigurieren

Wenn Sie Google Distributed Cloud Version 1.13.0 und höher verwenden, können Sie Startroutinen angeben, um die Initialisierung Ihrer VM beim Start anzupassen. Sie können Ihre VM so konfigurieren, dass SSH-Schlüssel erstellt, Nutzer und Passwörter hinzugefügt, Pakete installiert, Dateien geschrieben und Netzwerkeinstellungen konfiguriert werden.

Diese Startaufgaben werden entweder mit der cloud-init API oder mit der Startscripts API konfiguriert (nicht mit beiden). Diese Startanweisungen werden in der YAML-Manifestdatei von VirtualMachine angegeben und werden bei jedem Start der VM automatisch ausgeführt.

Voraussetzungen

Damit Sie eine VM mit Startanweisungen konfigurieren können, müssen die folgenden Voraussetzungen erfüllt sein:

  • Aktivieren Sie die VM Runtime auf GDC.

  • Verwenden Sie ein verifiziertes Linux-Gastbetriebssystem und legen Sie im VM-Manifest osType auf Linux fest. Windows-Gastbetriebssysteme werden für diese Funktion nicht unterstützt, da sie cloud-init nicht unterstützen.

  • Achten Sie darauf, dass auf dem Gastbetriebssystem cloud-init installiert ist. Die meisten aktuellen Linux-Betriebssysteme enthalten cloud-init.

In den folgenden Abschnitten wird beschrieben, wie Sie Startroutinen im VM-Manifest entweder mit der cloud-init API oder mit Startscripts angeben.

VMs mit der cloud-init API initialisieren

Cloud-init wird häufig für die Initialisierung von Cloud-Instanzen und für die Anpassung von VMs beim Start verwendet. Die VM-Initialisierung umfasst in der Regel Aufgaben wie Paketinstallationen, Repository-Einrichtung, SSH-Schlüsselerstellung, Datenausgabe in Dateien und die Einrichtung anderer Aspekte Ihrer VM. Sie fügen die YAML-Konfiguration von cloud-init in die benutzerdefinierte Ressource VirtualMachine mit dem Feld spec.cloudInit ein. Wenn Ihre VM-Instanz gestartet wird, liest cloud-init die bereitgestellten Daten und initialisiert die VM entsprechend.

Beachten Sie die folgenden Details zur cloud-init-Implementierung:

  • Sie geben Cloud-Init-Daten im VirtualMachine-YAML-Manifest an, wenn Sie eine VM erstellen oder aktualisieren. Eine Anleitung zum Erstellen einer VM durch Anwenden eines Manifests finden Sie unter Anleitung: Linux-VM in VM Runtime on GDC erstellen und verwalten.

  • In unserer VM-Spezifikation verwenden wir die NoCloud-Datenquelle, spec.cloudInit.noCloud.

  • Sie geben Nutzerdaten und Netzwerkdaten in separaten Abschnitten im VirtualMachine-Manifest an. Die Benennung und Struktur des Abschnitts hängt vom verwendeten Datenformat ab.

  • Sie können Cloud-init-Konfigurationsinformationen in den folgenden Datenformaten angeben:

    • Klartext
    • String mit base64-Codierung
    • Kubernetes Secret

Um Ihnen den Einstieg zu erleichtern, haben wir einige Konfigurationsbeispiele für gängige VM-Initialisierungsaufgaben zusammengestellt.

Cloud-init-Nutzerdaten

VM Runtime on GDC unterstützt cloud-init-Nutzerdaten in cloud-config-Syntax. Beginnen Sie Ihre Nutzerdaten daher mit #cloud-config. Sie können die Nutzerdaten als Klartext, als base64-codierten String oder als Kubernetes-Secret formatieren.

Weitere Informationen zur Syntax von Nutzerdaten und zur Modulreferenz finden Sie in der cloud-init-Dokumentation.

Cloud-init-Nutzerdaten als Klartext

Das folgende Beispielmanifest zeigt, wie Nutzerdaten als Klartext angegeben werden. In diesem Fall führt cloud-init beim Starten der VM einen Befehl aus:

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

Cloud-init-Nutzerdaten als base64-codierter String

Das folgende Beispiel zeigt, wie Nutzerdaten im base64-codierten Format angegeben werden. In diesem Beispiel bestehen die Nutzerdaten aus demselben echo hello-Befehl wie im Beispiel für Klartext:

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

Cloud-init-Nutzerdaten als Kubernetes-Secret

Das folgende Beispiel zeigt ein YAML-Manifest sowohl für ein VirtualMachine als auch für ein Secret. Der Abschnitt spec.cloudInit.noCloud.secretRef in der VirtualMachine-Konfiguration gibt an, dass sich die cloud-init-Nutzerdaten in einem Kubernetes-Secret namens my-sec befinden. In der entsprechenden Secret-Konfiguration werden die Nutzerdaten als Schlüssel/Wert-Paar angegeben. Der base64-codierte Wert ist in diesem Fall die cloud-init-Nutzerdaten in der cloud-config-Syntax.

Verwenden Sie im referenzierten Secret den Datenschlüssel userData (siehe Abbildung) oder userdata, um die cloud-init-Nutzerdaten anzugeben.

In diesem Beispiel bestehen die Nutzerdaten aus demselben echo hello-Befehl wie im Beispiel für Klartext:

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==

Wenn das referenzierte Secret nicht gefunden wird oder der Datenschlüssel userData oder userdata nicht im Secret vorhanden ist, beachten Sie das folgende Verhalten beim Starten der VM:

  • Beim Erstellen einer VM wird der Status der VM in ErrorConfiguration geändert und eine detaillierte Begründung und Nachricht hinzugefügt.

  • In anderen Fällen werden die alten cloud-init-Nutzerdaten so lange von der VM verwendet, bis die VM richtig konfiguriert ist. Daher werden Aktualisierungen für die Aktivierung oder Deaktivierung des Gast-Agents erst wirksam, wenn die VM richtig konfiguriert ist.

Mit dem folgenden Befehl können Sie VM-Informationen abrufen, einschließlich der verwendeten cloud-init-Nutzerdaten:

kubectl get vm VM_NAME -o yaml --kubeconfig KUBECONFIG_PATH

Ersetzen Sie Folgendes:

  • VM_NAME ist der Name Ihrer VM.

  • KUBECONFIG_PATH: der Pfad zur kubeconfig-Datei für den Cluster, der Ihre VM enthält.

Verwenden Sie entweder kubectl get event oder kubectl describe gvm, um das zugehörige Kubernetes-Warnereignis abzurufen.

Cloud-init-Netzwerkdaten

Ähnlich wie bei Nutzerdaten können Sie die Netzwerkdaten als Klartext, als base64-codierten String oder als Kubernetes-Secret formatieren. Anders als bei Nutzerdaten wird für Netzwerkdaten keine cloud-config-Syntax verwendet.

Bei der Verwendung von Klartext oder einem base64-codierten String beträgt die maximale Größe 2.048 Byte. Wenn die Größe der Nutzerdaten 2.048 Byte erreicht oder überschreitet, geben Sie sie als Kubernetes-Secret an.

Weitere Informationen zur Syntax von Netzwerkdaten und zugehörigen Details finden Sie in der cloud-init-Dokumentation unter Networking Config Version 2.

Cloud-init-Netzwerkdaten als Klartext

Das folgende Beispielmanifest zeigt, wie Netzwerkdaten als Klartext angegeben werden. In diesem Fall aktiviert cloud-init DHCP für alle Ethernet-Geräte mit Namen, die mit „e“ beginnen (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-Netzwerkdaten als base64-codierter String

Das folgende Beispiel zeigt, wie Netzwerkdaten im base64-codierten Format angegeben werden. In diesem Beispiel bestehen die Netzwerkdaten aus derselben DHCP-Konfiguration, die im Beispiel im Klartext angegeben wurde:

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

Cloud-init-Netzwerkdaten als Kubernetes-Secret

Das folgende Beispiel zeigt ein YAML-Manifest sowohl für ein VirtualMachine als auch für ein Secret. Der Abschnitt spec.cloudInit.noCloud.networkDataSecretRef in der VirtualMachine-Konfiguration gibt an, dass sich die cloud-init-Netzwerkdaten in einem Kubernetes-Secret namens my-sec befinden. In der entsprechenden Secret-Konfiguration werden die Netzwerkdaten als Schlüssel/Wert-Paar angegeben. Der base64-codierte Wert sind in diesem Fall die cloud-init-Netzwerkdaten.

Verwenden Sie im referenzierten Secret den Datenschlüssel networkData (siehe Abbildung) oder networkdata, um die cloud-init-Netzwerkdaten anzugeben.

In diesem Beispiel bestehen die Netzwerkdaten aus derselben DHCP-Konfiguration, die im Beispiel im Klartext angegeben wurde:

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-Beispiele

In den folgenden Abschnitten finden Sie Beispiele in Klartext für einige gängige Anwendungsfälle der VM-Initialisierung mit cloud-init:

Autorisierte SSH-Schlüssel konfigurieren

Im folgenden Beispiel für Nutzerdaten wird dem Standardnutzer der autorisierte SSH-Schlüssel ssh-rsa AAAAB3NzaK8L93bWxnyp zugewiesen.

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

Neuen Nutzer hinzufügen

Im folgenden Beispiel für Nutzerdaten wird der Nutzer test erstellt und ihm der volle sudo-Zugriff gewährt.test In diesem Beispiel wird dem Nutzer das nicht ablaufende Passwort pwd zugewiesen.

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

Befehle beim ersten Start ausführen

Im folgenden Beispiel für Nutzerdaten werden ein echo-Befehl und ein ls-Befehl ausgeführt. Sie können Befehle verwenden, um beim Starten der VM Pakete und mehr zu installieren.

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

Dateien schreiben

Im folgenden Beispiel für Nutzerdaten wird ein Bash-Script in die Datei test im Verzeichnis /var/lib/google Ihrer VM geschrieben. Die cloud-init-Anweisung legt die Dateiberechtigungen für den Inhaber der Datei auf Lesen, Schreiben und Ausführen (0744) fest.

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

Fehlerbehebung bei cloud-init

Wenn bei der VM-Initialisierung Probleme auftreten und Sie cloud-init verwenden, prüfen Sie die folgenden cloud-init-Logs in Ihrer VM:

  • /var/log/cloud-init.log: Standardmäßig schreibt cloud-init alle Ereignisse mit einer Ebene von DEBUG oder höher in dieses Protokoll.

  • /var/log/cloud-init-output.log: Standardmäßig leitet cloud-init sowohl stdout als auch stderr aus allen cloud-init-Phasen an dieses Protokoll weiter.

Startskripts zum Initialisieren von VMs verwenden

Startscripts führen während des Startvorgangs einer VM-Instanz Aufgaben aus. Sie können ein oder mehrere Scripts im Abschnitt spec.startupScripts der VirtualMachine-Spezifikation angeben. Mit Startscripts können Sie Ihre VM initialisieren. Die VM-Initialisierung umfasst in der Regel Aufgaben wie Paketinstallationen, Repository-Einrichtung, SSH-Schlüsselerstellung, Datenausgabe in Dateien und die Einrichtung anderer Aspekte Ihrer VM.

Beachten Sie die folgenden Hinweise zu Startscripts:

  • Sie geben Startscripts im VirtualMachine-YAML-Manifest an, wenn Sie eine VM erstellen oder aktualisieren. Eine Anleitung zum Erstellen einer VM durch Anwenden eines Manifests finden Sie unter Anleitung: Linux-VM in VM Runtime on GDC erstellen und verwalten.

  • Die angegebenen Scripts werden bei jedem Start der VM ausgeführt.

  • Fügen Sie oben im Script #!/bin/... ein, um den Script-Interpreter anzugeben. Fügen Sie beispielsweise #!/bin/bash hinzu, um das Script mit der Bash-Shell auszuführen.

  • Sie können nicht sowohl cloud-init-API-Anweisungen (spec.cloudInit) als auch Startscripts (spec.startupScripts) im selben VirtualMachine-Manifest angeben.

Scriptformate

Sie können Startscripts in den folgenden Datenformaten angeben:

  • Klartext
  • String mit base64-Codierung
  • Kubernetes Secret

Beachten Sie die folgenden Regeln für die Arbeit mit verschiedenen Scriptformaten:

  • Bei der Verwendung von Klartext oder einem base64-codierten String beträgt die maximale Größe des Script-Inhalts 2.048 Byte. Wenn die Größe des Script-Inhalts 2048 Byte erreicht oder überschreitet, geben Sie Scripts als Kubernetes-Secret an.

  • Wenn Sie ein Kubernetes-Secret verwenden, verwenden Sie den Datenschlüssel script im referenzierten Secret, um den Script-Inhalt anzugeben.

  • Wenn ein referenziertes Secret nicht gefunden wird oder der Datenschlüssel script im referenzierten Secret nicht vorhanden ist, führt die VM das Script fort. Die VM schreibt oder aktualisiert den Scriptinhalt jedoch nicht. In diesem Fall finden Sie das Kubernetes-Warnereignis entweder mit kubectl get event oder kubectl describe gvm.

Das folgende VirtualMachine-YAML-Beispielmanifest enthält drei Scripts, eines in jedem der unterstützten Formate. In diesem Fall wird in jedem Script der echo hello-Befehl ausgeführt, der in myscript1, dem Beispiel in Klartext, zu sehen ist.

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=

Fehlerbehebung für Scripts

Führen Sie den folgenden Befehl aus, um die Skriptergebnisse oder ‑protokolle zu prüfen:

journalctl -u cloud-final

Die Logeinträge des Startscripts beginnen mit dem folgenden Text:

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

Der Logeintrag enthält SCRIPT_NAME, den Namen des Startscripts.