Configurer les routines de démarrage de la VM

Lorsque vous utilisez GKE sur une solution Bare Metal version 1.13.0 ou ultérieure, vous pouvez spécifier des routines de démarrage pour personnaliser l'initialisation de votre VM au démarrage. Vous pouvez configurer votre VM pour créer des clés SSH, ajouter des utilisateurs et des mots de passe, installer des packages, écrire des fichiers, configurer des paramètres réseau, etc.

Ces tâches de démarrage sont configurées avec l'API cloud-init ou avec les API de scripts de démarrage (mais pas les deux). Ces instructions de démarrage sont spécifiées dans le fichier manifeste YAML VirtualMachine et s'exécutent automatiquement à chaque démarrage de votre VM.

Prérequis

Pour configurer une VM avec des instructions de démarrage, vous devez remplir les conditions préalables suivantes :

  • Activez l'environnement d'exécution des VM sur GDC.

  • Utilisez un OS invité Linux validé et définissez osType sur Linux dans le fichier manifeste de la VM. Les systèmes d'exploitation invités Windows ne sont pas compatibles avec cette fonctionnalité, car ils ne sont pas compatibles avec cloud-init.

  • Assurez-vous que cloud-init est installé sur le système d'exploitation invité. Les derniers systèmes d'exploitation Linux incluent cloud-init.

Les sections suivantes expliquent comment spécifier des routines de démarrage dans le fichier manifeste de la VM avec l'API cloud-init ou des scripts de démarrage.

Utiliser l'API cloud-init pour initialiser les VM

Cloud-init est souvent utilisé pour l'initialisation d'instances cloud et pour personnaliser les VM au démarrage. L'initialisation de la VM implique généralement des tâches telles que l'installation de packages, la configuration d'un dépôt, la création de clés SSH, l'écriture de données dans des fichiers et la configuration d'autres aspects de votre VM. Vous intégrez la configuration YAML de cloud-init dans la ressource personnalisée VirtualMachine avec le champ spec.cloudInit. Lorsque votre instance de VM démarre, cloud-init lit les données fournies et initialise la VM en conséquence.

Voici les détails de notre mise en œuvre de cloud-init :

  • Vous spécifiez les données cloud-init dans le fichier manifeste YAML VirtualMachine lorsque vous créez ou mettez à jour une VM. Pour savoir comment créer une VM en appliquant un fichier manifeste, consultez le tutoriel Créer et gérer une VM Linux dans l'environnement d'exécution de VM sur GDC.

  • Nous utilisons la source de données NoCloud, spec.cloudInit.noCloud, dans la spécification de VM.

  • Vous spécifiez les données utilisateur et les données réseau dans des sections distinctes du fichier manifeste VirtualMachine. La dénomination et la structure de la section dépendent du format de données que vous décidez d'utiliser.

  • Vous pouvez spécifier des informations de configuration de cloud-init dans les formats de données suivants :

    • Effacer le texte
    • Chaîne avec un encodage en base64
    • Secret Kubernetes

Pour vous aider à démarrer, nous vous avons fourni des exemples de configuration pour les tâches d'initialisation de VM courantes.

Données utilisateur cloud-init

L'environnement d'exécution de VM sur GDC accepte les données utilisateur cloud-init dans la syntaxe cloud-config. Vous devez donc commencer vos données utilisateur par #cloud-config. Vous pouvez formater les données utilisateur en texte clair, en chaîne encodée en base64 ou en tant que secret Kubernetes.

Pour en savoir plus sur la syntaxe des données utilisateur et la documentation de référence du module, consultez la documentation cloud-init.

Données utilisateur cloud-init sous forme de texte clair

L'exemple de fichier manifeste suivant montre comment définir des données utilisateur sous forme de texte clair. Dans ce cas, cloud-init exécute une commande au démarrage de la VM :

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

Données utilisateur cloud-init sous forme de chaîne encodée en base64

L'exemple suivant montre comment spécifier des données utilisateur au format base64. Dans cet exemple, les données utilisateur sont constituées de la même commande echo hello que dans l'exemple de texte clair :

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

Données utilisateur cloud-init en tant que secret Kubernetes

L'exemple suivant montre un fichier manifeste YAML pour VirtualMachine et pour Secret. La section spec.cloudInit.noCloud.secretRef de la configuration VirtualMachine indique que les données utilisateur cloud-init se trouvent dans un secret Kubernetes nommé my-sec. La configuration Secret correspondante spécifie les données utilisateur sous la forme d'une paire clé/valeur. Dans ce cas, la valeur encodée en base64 correspond aux données utilisateur cloud-init dans la syntaxe cloud-config.

Dans le secret référencé, utilisez la clé de données userData (affichée) ou userdata pour spécifier les données de l'utilisateur cloud-init.

Dans cet exemple, les données utilisateur sont constituées de la même commande echo hello que dans l'exemple de texte clair :

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

Si le secret référencé est introuvable ou si la clé de données userData ou userdata n'existe pas dans le secret, notez le comportement de démarrage de la VM suivant :

  • Lors de la création de la VM, celle-ci est à l'état ErrorConfiguration avec un motif détaillé et un message.

  • Dans d'autres cas, la VM continue à utiliser les anciennes données utilisateur cloud-init jusqu'à ce que la VM soit correctement configurée. Par conséquent, l'activation ou la désactivation des mises à jour de l'agent invité ne prend effet que lorsque la VM est correctement configurée.

Pour récupérer les informations relatives aux VM, y compris les données utilisateur cloud-init utilisées, exécutez la commande suivante :

kubectl get vm VM_NAME -o yaml --kubeconfig KUBECONFIG_PATH

Remplacez les éléments suivants :

  • VM_NAME : nom de votre VM.

  • KUBECONFIG_PATH : chemin d'accès au fichier kubeconfig du cluster contenant votre VM.

Pour récupérer l'événement d'avertissement Kubernetes associé, utilisez kubectl get event ou kubectl describe gvm.

Données réseau cloud-init

Comme pour les données utilisateur, vous pouvez formater les données réseau en texte clair, en chaîne encodée en base64 ou en tant que secret Kubernetes. Contrairement aux données utilisateur, les données réseau n'utilisent pas la syntaxe cloud-config.

Lorsque vous utilisez du texte clair ou une chaîne encodée en base64, la taille maximale autorisée est de 2 048 octets. Si la taille des données utilisateur est proche ou supérieure à 2 048 octets, spécifiez-la en tant que secret Kubernetes.

Pour en savoir plus sur la syntaxe des données réseau et les détails associés, consultez la page Configuration de la mise en réseau (version 2) dans la documentation cloud-init.

Données réseau cloud-init sous forme de texte clair

L'exemple de fichier manifeste suivant montre comment définir des données réseau en texte clair. Ici, cloud-init active DHCP pour tous les appareils Ethernet dont le nom commence par "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

Données réseau cloud-init en tant que chaîne codée en base64

L'exemple suivant montre comment spécifier des données de réseau au format base64. Dans cet exemple, les données réseau sont constituées de la même configuration DHCP spécifiée dans l'exemple de texte clair :

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

Données réseau cloud-init en tant que secret Kubernetes

L'exemple suivant montre un fichier manifeste YAML pour VirtualMachine et pour Secret. La section spec.cloudInit.noCloud.networkDataSecretRef de la configuration VirtualMachine indique que les données réseau cloud-init se trouvent dans un secret Kubernetes nommé my-sec. La configuration Secret correspondante spécifie les données du réseau en tant que paire clé/valeur. Dans ce cas, la valeur encodée en base64 est les données réseau cloud-init.

Dans le secret référencé, utilisez les clés de données networkData (affichées) ou networkdata pour spécifier les données réseau cloud-init.

Dans cet exemple, les données réseau sont constituées de la même configuration DHCP spécifiée dans l'exemple de texte clair :

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

Exemples cloud-init

Les sections suivantes contiennent des exemples en texte clair de certains cas d'utilisation courants de l'initialisation de VM avec cloud-init :

Configurer des clés SSH autorisées

L'exemple de données utilisateur suivant attribue la clé SSH autorisée ssh-rsa AAAAB3NzaK8L93bWxnyp à l'utilisateur par défaut.

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

Ajouter un utilisateur

L'exemple de données utilisateur suivant crée un utilisateur test et accorde à test un accès sudo complet. Cet exemple attribue à l'utilisateur un mot de passe pwd n'expirant pas.

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

Exécuter des commandes au premier démarrage

L'exemple de données utilisateur suivant exécute une commande echo et une commande ls. Vous pouvez utiliser des commandes pour installer des packages et plus encore au démarrage de votre VM.

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

Écrire des fichiers

L'exemple de données utilisateur suivant écrit un script bash dans le fichier test dans le répertoire /var/lib/google de votre VM. Les instructions cloud-init définissent les autorisations de fichier pour lire, écrire et exécuter (0744) pour le propriétaire du fichier.

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

Résoudre les problèmes liés à cloud-init

Si vous rencontrez des problèmes avec votre initialisation de VM et que vous utilisez cloud-init, vérifiez les journaux cloud-init suivants dans votre VM :

  • /var/log/cloud-init.log : par défaut, cloud-init écrit tous les événements de niveau DEBUG ou supérieur dans ce journal.

  • /var/log/cloud-init-output.log : par défaut, cloud-init dirige à la fois stdout et stderr de toutes les étapes cloud-init vers ce journal.

Utiliser des scripts de démarrage pour initialiser les VM

Les scripts de démarrage effectuent des tâches pendant le processus de démarrage d'une instance de machine virtuelle (VM). Vous pouvez spécifier un ou plusieurs scripts dans la section spec.startupScripts de la spécification VirtualMachine. Les scripts de démarrage permettent d'initialiser votre VM. L'initialisation de la VM implique généralement des tâches telles que l'installation de packages, la configuration d'un dépôt, la création de clés SSH, l'écriture de données dans des fichiers et la configuration d'autres aspects de votre VM.

Notez les points suivants pour les scripts de démarrage :

  • Vous spécifiez des scripts de démarrage dans le fichier manifeste VirtualMachine YAML lorsque vous créez ou mettez à jour une VM. Pour savoir comment créer une VM en appliquant un fichier manifeste, consultez le tutoriel Créer et gérer une VM Linux dans l'environnement d'exécution de VM sur GDC.

  • Les scripts spécifiés s'exécutent à chaque démarrage de la VM.

  • Incluez #!/bin/... en haut du script pour indiquer l'interpréteur du script. Par exemple, incluez #!/bin/bash pour exécuter le script avec le shell Bash.

  • Vous ne pouvez pas spécifier à la fois les instructions de l'API cloud-init (spec.cloudInit) et les scripts de démarrage (spec.startupScripts) dans le même fichier manifeste VirtualMachine.

Formats de script

Vous pouvez spécifier des scripts de démarrage dans les formats de données suivants :

  • Effacer le texte
  • Chaîne avec un encodage en base64
  • Secret Kubernetes

Notez les règles suivantes pour travailler avec différents formats de script :

  • Lorsque vous utilisez du texte clair ou une chaîne encodée en base64, la taille maximale autorisée pour le contenu du script est de 2 048 octets. Si la taille du contenu de votre script est proche ou supérieure à 2 048 octets, spécifiez les scripts en tant que secrets Kubernetes.

  • Lorsque vous utilisez un secret Kubernetes, utilisez la clé de données script dans le secret référencé pour spécifier le contenu du script.

  • Si un secret référencé est introuvable ou si la clé de données script n'existe pas dans le secret référencé, la VM continue d'exécuter le script. Cependant, la VM n'écrit ni ne met à jour le contenu du script. Dans ce cas, vous pouvez trouver l'événement d'avertissement Kubernetes avec kubectl get event ou kubectl describe gvm.

L'exemple de fichier manifeste YAML VirtualMachine suivant contient trois scripts, un dans chacun des formats compatibles. Dans ce cas, chaque script exécute la commande echo hello affichée dans myscript1, l'exemple de texte clair.

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=

Dépannage de scripts

Pour vérifier les résultats du script ou les journaux, exécutez la commande suivante :

journalctl -u cloud-final

Les entrées du journal de script de démarrage commencent par le texte suivant :

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

L'entrée de journal inclut SCRIPT_NAME, le nom du script de démarrage.