Exécuter des scripts d'arrêt

Créez et exécutez des scripts d'arrêt exécutant des commandes juste avant l'arrêt ou le redémarrage d'une instance de machine virtuelle (VM). Cette fonctionnalité est utile si vous utilisez des scripts automatisés pour démarrer et arrêter des instances, ce qui permet à celles-ci d'effectuer un nettoyage ou d'exécuter des tâches telles que l'exportation de journaux ou la synchronisation avec d'autres systèmes.

Les scripts d'arrêt sont particulièrement utiles pour les VM d'un groupe d'instances géré avec autoscaler. Si l'autoscaler arrête une VM du groupe, le script d'arrêt s'exécute avant l'arrêt de la VM et effectue les actions que vous définissez. Le script s'exécute pendant la courte période de temps précédent l'arrêt de la VM. Par exemple, le script d'arrêt peut copier des données traitées dans Cloud Storage ou sauvegarder des journaux.

Les scripts d'arrêt fonctionnent de manière semblable aux scripts de démarrage. Une grande partie de la documentation au sujet des scripts de démarrage s'applique également aux scripts d'arrêt.

Pour les tâches d'arrêt et de redémarrage, les VM exécutent toujours les scripts d'arrêt comme suit :

  • Pour les VM Linux, avec l'utilisateur root.
  • Pour les VM Windows, avec le compte System.

Prérequis

Pour exécuter des scripts stockés dans les métadonnées d'une instance de VM, l'environnement invité doit être installé et en cours d'exécution.

  • L'environnement invité inclut l'agent invité (par exemple, google-guest-agent sur Linux) qui lit le contenu du script ou l'URL à partir des métadonnées de l'instance et lance l'exécution.
  • Toutes les images publiques Compute Engine sont fournies avec l'environnement invité préinstallé.
  • Si vous créez une image personnalisée, vous devez installer manuellement l'environnement invité Google pour vous assurer que les scripts issus des métadonnées et d'autres fonctionnalités Google Cloud fonctionnent correctement.

Avant de commencer

  • Obtenez des informations sur les scripts de démarrage.
  • Découvrez le serveur de métadonnées.
  • Si ce n'est pas déjà fait, configurez l'authentification. L'authentification permet de valider votre identité pour accéder aux services et aux API Google Cloud . Pour exécuter du code ou des exemples depuis un environnement de développement local, vous pouvez vous authentifier auprès de Compute Engine en sélectionnant l'une des options suivantes :

    Sélectionnez l'onglet correspondant à la façon dont vous prévoyez d'utiliser les exemples de cette page :

    Console

    Lorsque vous utilisez la console Google Cloud pour accéder aux services et aux API Google Cloud , vous n'avez pas besoin de configurer l'authentification.

    gcloud

    1. Installez la Google Cloud CLI. Une fois l'installation terminée, initialisez la Google Cloud CLI en exécutant la commande suivante :

      gcloud init

      Si vous utilisez un fournisseur d'identité (IdP) externe, vous devez d'abord vous connecter à la gcloud CLI avec votre identité fédérée.

  • Définissez une région et une zone par défaut.
  • Terraform

    Pour utiliser les exemples Terraform de cette page dans un environnement de développement local, installez et initialisez la gcloud CLI, puis configurez les Identifiants par défaut de l'application avec vos identifiants utilisateur.

    1. Installez la Google Cloud CLI.

    2. Si vous utilisez un fournisseur d'identité (IdP) externe, vous devez d'abord vous connecter à la gcloud CLI avec votre identité fédérée.

    3. Si vous utilisez un shell local, créez des identifiants d'authentification locaux pour votre compte utilisateur :

      gcloud auth application-default login

      Vous n'avez pas besoin de le faire si vous utilisez Cloud Shell.

      Si une erreur d'authentification est renvoyée et que vous utilisez un fournisseur d'identité (IdP) externe, vérifiez que vous vous êtes connecté à la gcloud CLI avec votre identité fédérée.

    Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.

    REST

    Pour utiliser les exemples API REST de cette page dans un environnement de développement local, vous devez utiliser les identifiants que vous fournissez à la gcloud CLI.

      Installez la Google Cloud CLI.

      Si vous utilisez un fournisseur d'identité (IdP) externe, vous devez d'abord vous connecter à la gcloud CLI avec votre identité fédérée.

    Pour en savoir plus, consultez la section S'authentifier pour utiliser REST dans la documentation sur l'authentification Google Cloud .

Autorisations requises pour cette tâche

Pour effectuer cette tâche, vous devez disposer des autorisations suivantes :

  • Toutes les autorisations requises pour créer une instance
  • compute.instances.setMetadata sur l'instance

Spécifications

Les sections suivantes décrivent les spécifications des scripts d'arrêt.

Limites

Tenez compte de l'existence de certaines limites lors de l'utilisation de scripts d'arrêt :

  • Compute Engine exécute les scripts d'arrêt de façon la plus optimale possible. Dans de rares cas, Compute Engine ne peut pas garantir l'exécution du script d'arrêt.
  • Sous Windows, la stratégie de groupe locale est utilisée pour lancer le script d'arrêt.
    • Le package d'installation configure le paramètre de stratégie de groupe locale Computer Configuration/Windows Setting/Scripts (Startup/Shutdown) pour lancer le script lors de l'arrêt du système.

Appel du script d'arrêt

Les scripts d'arrêt sont déclenchés lorsque l'instance s'arrête après l'un des événements suivants :

  • Vous effectuez les opérations suivantes :

  • Compute Engine arrête une instance dans le cadre d'une opération d'arrêt ou de suppression programmée.

  • Compute Engine arrête une VM Spot ou une instance préemptive dans le cadre du processus de préemption.

Un script d'arrêt peut être constitué de n'importe quel type de fichier. Si un script d'arrêt est présent dans l'instance, Compute Engine effectue les opérations suivantes :

  1. Copie le script dans un fichier local de l'instance.
  2. Définit les autorisations sur le fichier pour rendre le script exécutable.
  3. Exécute le fichier lorsque l'instance s'arrête.

Vous pouvez, par exemple, fournir un script Python au lieu d'un script bash. Sachez que Compute Engine exécutera le script intégralement, quel que soit son type.

Pour exécuter un script qui n'est pas bash, ajoutez une ligne shebang en haut du fichier pour que le système d'exploitation sache quel interpréteur utiliser. Par exemple, pour un script Python, vous pouvez ajouter une ligne shebang comme :

#!/usr/bin/python

Temps d'exécution du script d'arrêt

Vos scripts d'arrêt commencent à s'exécuter lorsque Compute Engine définit l'état de l'instance sur STOPPING. Vos scripts doivent se terminer avant l'arrêt complet de l'instance, c'est-à-dire lorsque son état passe à TERMINATED. Le temps nécessaire à l'instance pour atteindre l'état TERMINATED varie en fonction du type d'instance.

Si l'exécution de vos scripts prend plus de temps que l'arrêt de l'instance, Compute Engine force l'arrêt des scripts, ce qui peut entraîner une perte de données ou des tâches incomplètes. Pour éviter cela, arrêtez l'instance à partir de son OS invité. Cette approche maintient l'état de l'instance sur STOPPING jusqu'à ce que l'exécution de vos scripts d'arrêt soit terminée.

Utiliser un script d'arrêt local

Un script d'arrêt local est un script qui réside sur votre ordinateur local. Passez en mode script d'arrêt local via un fichier ou en basculant le contenu directement dans Compute Engine.

Les scripts d'arrêt peuvent effectuer autant d'actions que nécessaire, mais en cas de transmission locale de fichier, la durée de votre script ne peut pas dépasser la valeur de métadonnées limite de 256 ko. Pour utiliser un script qui excède cette durée, stockez votre fichier sur Cloud Storage. Pour plus d'informations, reportez-vous à la section Utiliser le script d'arrêt à partir de Cloud Storage.

Fournir un fichier de script d'arrêt

Vous ne pouvez transmettre un fichier de script d'arrêt local que via l'outil de ligne de commande gcloud.

gcloud

Pour transmettre un fichier de script d'arrêt local, fournissez l'option --metadata-from-file, suivi d'une paire de clés de métadonnées, shutdown-script=PATH/TO/FILE, où PATH/TO/FILE est un chemin relatif au script d'arrêt. Exemple :

gcloud compute instances create example-instance \
    --metadata-from-file shutdown-script=examples/scripts/install.sh

Terraform

Pour spécifier directement un script d'arrêt, utilisez la ressource google_compute_instance avec le chemin d'accès au script d'arrêt dans les métadonnées.

resource "google_compute_instance" "shutdown_content_from_file" {
  name         = "instance-name-shutdown-content-from-file"
  machine_type = "f1-micro"
  zone         = "us-central1-c"
  metadata = {
    # Shuts down Apache server
    shutdown-script = file("${path.module}/shutdown-script.sh")
  }
  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-13"
    }
  }
  network_interface {
    # A default network is created for all Google Cloud projects
    network = "default"
    access_config {
    }
  }
}

Pour savoir comment appliquer ou supprimer une configuration Terraform, consultez Commandes Terraform de base.

Fournir le contenu du script d'arrêt directement

Vous pouvez également transmettre directement le contenu de votre script d'arrêt.

Console

Dans la console Google Cloud , spécifiez un script d'arrêt directement à l'aide de la clé de métadonnées shutdown-script :

  1. Accéder à la page Créer une instance.

    Accéder à la page Créer une instance

  2. Spécifiez les détails de la VM.

  3. Développez la section Options avancées.

  4. Développez Gestion, puis procédez comme suit :

    1. Dans la section Métadonnées, cliquez sur Ajouter un élément.
    2. Dans le champ Clé, saisissez shutdown-script comme clé de métadonnées.
    3. Dans le champ Valeur, ajoutez le contenu de votre script d'arrêt.
  5. Poursuivez le processus de création de la VM.

gcloud

Avec Google Cloud CLI, utilisez l'indicateur --metadata pour fournir le contenu de votre script d'arrêt, suivi de la paire de clés shutdown-script=CONTENTS, où CONTENTS est le contenu de votre script d'arrêt.

gcloud compute instances create example-instance --metadata shutdown-script="#! /bin/bash
> # Shuts down Apache server
> /etc/init.d/apache2 stop"

Terraform

Pour spécifier directement un script d'arrêt, utilisez la ressource google_compute_instance avec le script d'arrêt dans les métadonnées.

resource "google_compute_instance" "default" {
  name         = "instance-name-shutdown-content-directly"
  machine_type = "f1-micro"
  zone         = "us-central1-c"
  metadata = {
    # Shuts down Apache server
    shutdown-script = "#! /bin/bash /etc/init.d/apache2 stop"
  }
  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-13"
    }
  }
  network_interface {
    # A default network is created for all Google Cloud projects
    network = "default"
    access_config {
    }
  }
}

Pour savoir comment appliquer ou supprimer une configuration Terraform, consultez Commandes Terraform de base.

REST

Dans l'API, fournissez un script d'arrêt au niveau de la propriété des métadonnées dans votre requête de création d'instance. Utilisez shutdown-script comme clé de métadonnées :

POST https://compute.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/instances

{...
  "metadata": {
    "items": [
      {
       "key": "shutdown-script",
       "value": "#! /bin/bash\n\n# Shuts down Apache server\n/etc/init.d/apache2 stop"
      }
    ]
  }...
}

Fournir un script d'arrêt sur les instances Windows

Exécutez des scripts d'arrêt sur des instances Windows à l'aide des clés de métadonnées spécifiques à Windows. Choisissez l'une des clés spécialisées répertoriées ci-dessous. Chaque clé doit correspondre au type de script que vous souhaitez exécuter.

Vous pouvez spécifier plusieurs scripts d'arrêt en transmettant différentes clés à votre instance, mais chaque clé ne peut être spécifiée qu'une seule fois par machine virtuelle.

Les clés suivantes peuvent être utilisées avec un script d'arrêt local, en suivant les mêmes instructions que celles fournies précédemment dans ce document.

scripts d'arrêt cmd scripts d'arrêt bat scripts d'arrêt ps1
windows-shutdown-script-cmd windows-shutdown-script-bat windows-shutdown-script-ps1

Utiliser un script d'arrêt de Cloud Storage

Vous pouvez stocker et utiliser un script d'arrêt à partir de Cloud Storage. Suivez les instructions de la documentation Scripts de démarrage, mais remplacez startup-script-url par shutdown-script-url.

Pour les instances Windows, remplacez windows-startup-script-url par windows-shutdown-script-url.

Appliquer un script d'arrêt à des instances en cours d'exécution

Pour ajouter un script d'arrêt à une instance en cours d'exécution, suivez les instructions de la documentation Application d'un script de démarrage à des instances en cours d'exécution, mais remplacez les clés de métadonnées par l'une des clés suivantes :

  • shutdown-script : fournissez le contenu du script d'arrêt directement avec cette clé. À l'aide de Google Cloud CLI, vous pouvez fournir le chemin d'accès à un fichier de script d'arrêt, en utilisant l'indicateur --metadata-from-file et la clé de métadonnées shutdown-script.
  • shutdown-script-url : indiquez une URL Cloud Storage dans le fichier de script d'arrêt à l'aide de cette clé.

Exécuter un script d'arrêt lors d'un arrêt progressif

Par défaut, si l'arrêt progressif est activé sur une instance de calcul, tous les scripts d'arrêt que vous configurez dans les clés de métadonnées s'exécutent une fois l'arrêt progressif terminé.

Pour exécuter des commandes lors d'un arrêt progressif, vous devez utiliser un script de surveillance personnalisé qui interroge en continu le serveur de métadonnées en arrière-plan, comme indiqué dans cette section. Pour donner à vos scripts suffisamment de temps pour s'exécuter et éviter toute perte de données ou tâche incomplète, nous vous recommandons de modifier vos scripts d'arrêt en déplaçant votre logique vers ce script de surveillance.

Pour exécuter un script d'arrêt lors d'un arrêt progressif, sélectionnez l'une des options suivantes en fonction de l'OS invité utilisé par votre instance de calcul :

Linux

  1. Si ce n'est pas déjà fait, connectez-vous à l'instance de calcul.

  2. Exécutez un script de surveillance ou configurez-le pour qu'il s'exécute au démarrage, comme suit. Ajoutez votre logique d'arrêt spécifique à l'endroit indiqué :

    #!/bin/bash
    
    # --------------------------------------------------------
    # Script for graceful shutdown based on the metadata value
    # --------------------------------------------------------
    #
    # This script monitors the metadata key `shutdown-status` and
    # waits for its value to change to `PENDING_STOP`. After the script
    # runs a series of user-defined commands, it runs `sudo shutdown -h now`
    # to signal to Compute Engine that the shutdown process is
    # complete.
    #
    # To run this script, you must have passwordless sudo privileges.
    
    METADATA_URL="http://metadata.google.internal/computeMetadata/v1/instance/attributes/shutdown-status"
    LAST_ETAG="0"
    
    echo "Starting shutdown status watcher"
    
    while true; do
      # Wait for the metadata value to change.
      # The metadata server blocks the request until a change occurs or a timeout is reached.
      RESPONSE=$(curl -H "Metadata-Flavor: Google" -s -i "${METADATA_URL}?wait_for_change=true&last_etag=${LAST_ETAG}")
      CURL_EXIT_STATUS=$?
    
      if [[ ${CURL_EXIT_STATUS} -ne 0 ]]; then
        echo "Error: curl command failed with exit status ${CURL_EXIT_STATUS}. Retrying in 5 seconds..."
        sleep 5
        continue
      fi
    
      # Strip carriage returns (\r) immediately to prevent CRLF line endings from corrupting string comparisons
      RESPONSE=$(echo "$RESPONSE" | tr -d '\r')
    
      # Extract the HTTP status code from the first line of the response
      HTTP_STATUS=$(echo "$RESPONSE" | head -n 1 | awk '{print $2}')
    
      if [[ "${HTTP_STATUS}" -eq 200 ]]; then
        # Read the new etag value to re-subscribe on the next poll.
        NEW_ETAG=$(echo "$RESPONSE" | grep -i "^ETag:" | awk '{print $2}')
        if [[ -n "${NEW_ETAG}" ]]; then
          LAST_ETAG="${NEW_ETAG}"
        fi
    
        # Extract the value of the shutdown status from the last line of the response body.
        SHUTDOWN_STATUS=$(echo "$RESPONSE" | tail -n 1)
    
        echo "Metadata changed. New ETag: ${LAST_ETAG}, shutdown-status: '${SHUTDOWN_STATUS}'"
    
        if [[ "${SHUTDOWN_STATUS}" == "PENDING_STOP" ]]; then
          echo "Shutdown signal 'PENDING_STOP' received. Exiting watcher loop."
          break
        fi
      elif [[ "${HTTP_STATUS}" -eq 503 ]]; then
        # 503 Service Unavailable: wait_for_change timed out with no change. Sleep and loop again.
        echo "Service temporarily unavailable or request timed out. Retrying in 2 seconds..."
        sleep 2
        continue
      else
        # Unexpected HTTP status
        echo "Warning: Unexpected HTTP status ${HTTP_STATUS}. Retrying in 5 seconds..."
        sleep 5
      fi
    done
    
    # --------------------------------------------------------
    # Graceful shutdown commands section
    # --------------------------------------------------------
    echo "Watcher loop exited. Starting graceful shutdown procedures..."
    
    # --- ADD YOUR GRACEFUL SHUTDOWN COMMANDS HERE ---
    
    echo "Graceful shutdown commands executed."
    
    # --------------------------------------------------------
    # Signal OS to stop
    # --------------------------------------------------------
    echo "Shutting down the guest OS to turn off the compute instance..."
    sudo shutdown -h now
    

Windows

  1. Si vous ne l'avez pas encore fait, connectez-vous à l'instance de calcul à l'aide de l'une des méthodes suivantes :

  2. Exécutez un script de surveillance ou configurez-le pour qu'il s'exécute au démarrage, comme suit. Ajoutez votre logique d'arrêt spécifique à l'endroit indiqué :

    <#
    .SYNOPSIS
    pre-shutdown-script.ps1
    #>
    
    # --------------------------------------------------------
    # Script for graceful shutdown based on the metadata value
    # --------------------------------------------------------
    #
    # This script monitors the metadata key `shutdown-status` and
    # waits for its value to change to `PENDING_STOP`. After the script
    # runs a series of user-defined commands, it runs `Stop-Computer -Force`
    # to signal to Compute Engine that the shutdown process is
    # complete.
    
    $METADATA_URL = "http://metadata.google.internal/computeMetadata/v1/instance/attributes/shutdown-status"
    $LAST_ETAG = "0"
    
    Write-Host "Starting shutdown status watcher"
    
    while ($true) {
        $Response = $null
        $HTTP_STATUS = 0
    
        # Wait for the metadata value to change.
        # The metadata server blocks the request until a change occurs or a timeout is reached.
        try {
            $Response = Invoke-WebRequest `
                -Headers @{"Metadata-Flavor" = "Google"} `
                -Uri "${METADATA_URL}?wait_for_change=true&last_etag=${LAST_ETAG}" `
                -TimeoutSec 320 `
                -ErrorAction Stop
    
            if ($null -ne $Response) {
                $HTTP_STATUS = [int]$Response.StatusCode
            }
        } catch {
            # Invoke-WebRequest throws an error for non-2xx status codes or connection failures.
            $Exception = $_.Exception
            if ($null -ne $Exception -and $null -ne $Exception.Response) {
                $HTTP_STATUS = [int]$Exception.Response.StatusCode
            } else {
                $HTTP_STATUS = 0
            }
        }
    
        if ($HTTP_STATUS -eq 0) {
            Write-Host "Error: Request failed. Retrying in 5 seconds..."
            Start-Sleep -Seconds 5
            continue
        }
    
        if ($HTTP_STATUS -eq 200) {
            # Read the new etag value to re-subscribe on the next poll.
            $NEW_ETAG = $Response.Headers["ETag"]
            if ($null -ne $NEW_ETAG) {
                $LAST_ETAG = $NEW_ETAG
            }
    
            # Extract the value of the shutdown status from the response body.
            $SHUTDOWN_STATUS = $Response.Content.Trim()
    
            Write-Host "Metadata changed. New ETag: ${LAST_ETAG}, shutdown-status: '${SHUTDOWN_STATUS}'"
    
            if ($SHUTDOWN_STATUS -eq "PENDING_STOP") {
                Write-Host "Shutdown signal 'PENDING_STOP' received. Exiting watcher loop."
                break
            }
        } elseif ($HTTP_STATUS -eq 503) {
            # 503 Service Unavailable: wait_for_change timed out with no change. Sleep and loop again.
            Write-Host "Service temporarily unavailable or request timed out. Retrying in 2 seconds..."
            Start-Sleep -Seconds 2
            continue
        } else {
            # Unexpected HTTP status
            Write-Host "Warning: Unexpected HTTP status ${HTTP_STATUS}. Retrying in 5 seconds..."
            Start-Sleep -Seconds 5
        }
    }
    
    # --------------------------------------------------------
    # Graceful shutdown commands section
    # --------------------------------------------------------
    Write-Host "Watcher loop exited. Starting graceful shutdown procedures..."
    
    # --- ADD YOUR GRACEFUL SHUTDOWN COMMANDS HERE ---
    
    Write-Host "Graceful shutdown commands executed."
    
    # --------------------------------------------------------
    # Signal OS to Halt
    # --------------------------------------------------------
    Write-Host "Shutting down the guest OS to turn off the compute instance..."
    Stop-Computer -Force
    

Afficher le résultat d'un script d'arrêt

Linux

Vous pouvez afficher le résultat d'un script d'arrêt Linux en effectuant l'une des opérations suivantes :

Windows

Affichez le résultat d'un script d'arrêt Windows Server à l'aide de l'un des éléments suivants et en vérifiant la présence d'événements GCEMetadataScripts :