Suspender y reanudar una VM


En este documento, se describe cómo suspender y reanudar una instancia de máquina virtual (VM). Para obtener información sobre cómo iniciar y detener una instancia, consulta Inicia y detén una instancia. Para obtener más información sobre el ciclo de vida de las instancias, consulta la documentación del Ciclo de vida de la instancia.

Si deseas conservar tu instancia de VM, pero no deseas que se te cobre por ella cuando no esté en uso, puedes suspenderla. Cuando suspendes una VM, Google conserva la VM en tu proyecto y mueve el contenido de la memoria de la VM al almacenamiento. Mientras la VM está suspendida, Google solo cobra por el almacenamiento usado para conservar la memoria de la VM. Los atributos, como las direcciones IP estáticas, permanecen en su lugar para que las funciones de red funcionen como se espera cuando reanudas la VM. Después de reanudar, Google migra la memoria de la VM del almacenamiento a la instancia y comienza a cobrarte por la instancia de VM en ejecución.

La suspensión de una instancia es ideal en los siguientes casos:

  • Entornos de prueba y desarrollo que no se usan por completo durante los períodos de inactividad, como las noches o los fines de semana, para reducir los costos o hacer una inicialización más rápida que la creación de instancias de VM nuevas.
  • Aplicaciones que requieren un largo período de inicialización después de que la instancia termina de iniciarse, pero antes de que la aplicación esté lista para hacer su primera solicitud, como estaciones de trabajo de desarrolladores virtuales o aplicaciones complejas de Java.

Cómo funciona la suspensión

Cuando suspendes una instancia, se envía una señal de suspensión S3 de ACPI al sistema operativo de la instancia. La suspensión de una instancia es similar al cierre de la tapa de tu laptop, que pone la instancia en un estado SUSPENDED.

La suspensión de una instancia difiere de la detención de una instancia de las siguientes maneras:

Todos los recursos que están conectados a esta permanecen conectados y se cobrarán, incluidos los discos persistentes y las direcciones IP externas estáticas o reservadas. Todos estos recursos se cobran según la hoja de precios, incluso si se suspende una instancia.

No puedes suspender una instancia mediante los procesos estándar integrados en el entorno invitado. Los comandos, como el comando systemctl suspend en Ubuntu 16.04 y versiones posteriores, no están disponibles. Solo puedes usar Google Cloud CLI o REST para suspender una instancia.

Si no te importa restablecer la memoria de una instancia y el estado del dispositivo cuando reanudes la instancia más tarde, puedes detenerla, lo que no genera cargos adicionales de almacenamiento.

Antes de empezar

  • Configura la autenticación si aún no lo hiciste. La autenticación es el proceso mediante el cual se verifica tu identidad para acceder a los servicios y las API de Google Cloud. Para ejecutar un código o muestras desde un entorno de desarrollo local, puedes autenticarte en Compute Engine de la siguiente manera.

    Selecciona la pestaña para saber cómo planeas usar las muestras en esta página:

    Consola

    Cuando usas la consola de Google Cloud para acceder a los servicios y las APIs de Google Cloud, no necesitas configurar la autenticación.

    gcloud

    1. Instala Google Cloud CLI y, luego, inicializa la ejecución del siguiente comando:

      gcloud init
    2. Configura una región y una zona predeterminadas.

    Go

    Para usar las muestras de Go de esta página desde un entorno de desarrollo local, instala e inicializa la CLI de gcloud y, luego, configura las credenciales predeterminadas de la aplicación con tus credenciales de usuario.

    1. Instala Google Cloud CLI.
    2. Para inicializar la CLI de gcloud, ejecuta el siguiente comando:

      gcloud init
    3. Crea credenciales de autenticación locales para tu Cuenta de Google:

      gcloud auth application-default login

    Para obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

    Java

    Para usar las muestras de Java de esta página desde un entorno de desarrollo local, instala e inicializa la CLI de gcloud y, luego, configura las credenciales predeterminadas de la aplicación con tus credenciales de usuario.

    1. Instala Google Cloud CLI.
    2. Para inicializar la CLI de gcloud, ejecuta el siguiente comando:

      gcloud init
    3. Crea credenciales de autenticación locales para tu Cuenta de Google:

      gcloud auth application-default login

    Para obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

    Node.js

    Para usar las muestras de Node.js de esta página desde un entorno de desarrollo local, instala e inicializa la CLI de gcloud y, luego, configura las credenciales predeterminadas de la aplicación con tus credenciales de usuario.

    1. Instala Google Cloud CLI.
    2. Para inicializar la CLI de gcloud, ejecuta el siguiente comando:

      gcloud init
    3. Crea credenciales de autenticación locales para tu Cuenta de Google:

      gcloud auth application-default login

    Para obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

    PHP

    Para usar las muestras de PHP de esta página desde un entorno de desarrollo local, instala e inicializa la CLI de gcloud y, luego, configura las credenciales predeterminadas de la aplicación con tus credenciales de usuario.

    1. Instala Google Cloud CLI.
    2. Para inicializar la CLI de gcloud, ejecuta el siguiente comando:

      gcloud init
    3. Crea credenciales de autenticación locales para tu Cuenta de Google:

      gcloud auth application-default login

    Para obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

    Python

    Para usar las muestras de Python de esta página desde un entorno de desarrollo local, instala e inicializa la CLI de gcloud y, luego, configura las credenciales predeterminadas de la aplicación con tus credenciales de usuario.

    1. Instala Google Cloud CLI.
    2. Para inicializar la CLI de gcloud, ejecuta el siguiente comando:

      gcloud init
    3. Crea credenciales de autenticación locales para tu Cuenta de Google:

      gcloud auth application-default login

    Para obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

    REST

    Para usar las muestras de la API de REST en esta página en un entorno de desarrollo local, debes usar las credenciales que proporcionas a la CLI de gcloud.

      Instala Google Cloud CLI y, luego, inicializa la ejecución del siguiente comando:

      gcloud init

Limitaciones

Se aplican las siguientes limitaciones a esta función:

  • No puedes suspender una instancia que usa una GPU.
  • No puedes suspender una instancia mediante los procesos estándar integrados en el entorno invitado. Los comandos, como el comando systemctl suspend en Ubuntu 16.04 y versiones posteriores, no están disponibles. Se ignora la señal del invitado.
  • Solo puedes suspender una instancia durante un máximo de 60 días antes de que se detenga la VM de forma automática.
  • No puedes suspender instancias con más de 208 GB de memoria.
  • Puedes suspender instancias interrumpibles, pero es posible que se finalicen antes de suspenderse de forma correcta.
  • No puedes suspender una Confidential VM.
  • No puedes suspender una VM que tenga discos protegidos por CSEK adjuntos.

SSD locales

Por lo general, la suspensión de una instancia de VM que usa SSD local descartará todos los datos de las unidades de SSD local; el mismo comportamiento que si se detiene la instancia.

Consulta la documentación de SSD local para obtener más detalles.

VMs interrumpibles

Puedes suspender una VM interrumpible, pero si la interrupción (no la advertencia previa) sucede antes de que se complete la operación de suspensión, la suspensión finaliza y la instancia se interrumpe.

Compatibilidad con los SO

La mayoría de los sistemas operativos que se ofrecen en Compute Engine son compatibles con la funcionalidad de suspensión y reanudación, pero algunos SO no lo son. Revisa la página Detalles del SO para ver la lista completa.

Precios

Cuando suspendes una instancia, se te cobra por lo siguiente:

  • Memoria de la instancia (consulta los precios de instancias de VMs suspendidas)
  • Cualquier uso del disco persistente para el disco de arranque y cualquier disco adicional conectado a la instancia (consulta Precios de discos persistentes)
  • Cualquier IP estática conectada a la instancia
  • Suspender las VM podría ayudarte a ahorrar en tus tarifas de licencias de software. Por ejemplo, si suspendes las VM de Windows, no incurrirás en tarifas de licencia de Windows. Las tarifas de licencia para otras imágenes pueden tener términos y condiciones diferentes y pueden generar cargos, incluso cuando se suspenden.

Suspende una instancia

Para suspender una instancia, usa la consola de Google Cloud, el CLI de gcloud, la API o las bibliotecas cliente de Cloud.

No puedes suspender una instancia mediante los procesos estándar integrados en el entorno invitado. Puedes usar la consola de Google Cloud, Google Cloud CLI o la API para suspender una instancia.

La operación de suspensión puede fallar si se activa demasiado pronto después de que se inició la instancia. La instancia debe iniciarse por completo (incluidos los procesos como el Agente invitado) para que la operación de suspensión se ejecute correctamente.

Console

  1. En la consola de Google Cloud, ve a la página Instancias de VM.

    Ir a la página Instancias de VM

  2. Elige una o más instancias que desees suspender.

  3. Haz clic en Suspender.

  4. Cuando se te solicite, si deseas descartar datos del SSD local, elige Discard the SSD content. Cuando se reanuda tu instancia, todos los datos del SSD local en la instancia se habrán descartado.

gcloud

Para suspender una instancia en Google Cloud CLI, sigue estos pasos:

 gcloud compute instances suspend VM_NAME

Una vez que hayas realizado una solicitud para suspender una instancia, puede transcurrir un tiempo hasta que se conserven todos los datos necesarios para la instancia en Compute Engine. Durante este tiempo, se te seguirá cobrando por la instancia mientras siga en ejecución.

Una instancia suspendida presenta la marca de estado SUSPENDED. Para verificar el estado de una instancia, haz una solicitud describe:

gcloud compute instances describe VM_NAME

Para suspender una instancia con datos de SSD local, debes proporcionar la marca --discard-local-ssd:

gcloud compute instances suspend VM_NAME --discard-local-ssd

El uso de --discard-local-ssd o --discard-local-ssd=True descartará el contenido del SSD local. --discard-local-ssd=False de Compute Engine se encuentra actualmente en vista preliminar pública. El uso de esta marca guardará el contenido de hasta 16 discos SSD locales durante la suspensión. Consulta la documentación de SSD local para obtener más detalles.

Go

import (
	"context"
	"fmt"
	"io"

	compute "cloud.google.com/go/compute/apiv1"
	computepb "cloud.google.com/go/compute/apiv1/computepb"
)

// suspendInstance suspends a running Google Compute Engine instance.
func suspendInstance(w io.Writer, projectID, zone, instanceName string) error {
	// projectID := "your_project_id"
	// zone := "europe-central2-b"
	// instanceName := "your_instance_name"

	ctx := context.Background()
	instancesClient, err := compute.NewInstancesRESTClient(ctx)
	if err != nil {
		return fmt.Errorf("NewInstancesRESTClient: %w", err)
	}
	defer instancesClient.Close()

	req := &computepb.SuspendInstanceRequest{
		Project:  projectID,
		Zone:     zone,
		Instance: instanceName,
	}

	op, err := instancesClient.Suspend(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to suspend instance: %w", err)
	}

	if err = op.Wait(ctx); err != nil {
		return fmt.Errorf("unable to wait for the operation: %w", err)
	}

	fmt.Fprintf(w, "Instance suspended\n")

	return nil
}

Java


import com.google.cloud.compute.v1.Instance.Status;
import com.google.cloud.compute.v1.InstancesClient;
import com.google.cloud.compute.v1.Operation;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class SuspendInstance {

  public static void main(String[] args)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // TODO(developer): Replace these variables before running the sample.
    // project: project ID or project number of the Cloud project your instance belongs to.
    // zone: name of the zone your instance belongs to.
    // instanceName: name of the instance your want to suspend.

    String project = "your-project-id";
    String zone = "zone-name";
    String instanceName = "instance-name";

    suspendInstance(project, zone, instanceName);
  }

  // Suspend a running Google Compute Engine instance.
  // For limitations and compatibility on which instances can be suspended,
  // see: https://cloud.google.com/compute/docs/instances/suspend-resume-instance#limitations
  public static void suspendInstance(String project, String zone, String instanceName)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // Instantiates a client.
    try (InstancesClient instancesClient = InstancesClient.create()) {

      Operation operation = instancesClient.suspendAsync(project, zone, instanceName)
          .get(300, TimeUnit.SECONDS);

      if (operation.hasError() || !instancesClient.get(project, zone, instanceName).getStatus()
          .equalsIgnoreCase(Status.SUSPENDED.toString())) {
        System.out.println("Cannot suspend instance. Try again!");
        return;
      }

      System.out.printf("Instance suspended successfully ! %s", instanceName);
    }
  }
}

Node.js

/**
 * TODO(developer): Uncomment and replace these variables before running the sample.
 */
// const projectId = 'YOUR_PROJECT_ID';
// const zone = 'europe-central2-b';
// const instanceName = 'YOUR_INSTANCE_NAME';

const compute = require('@google-cloud/compute');

// Suspends a running Google Compute Engine instance.
async function suspendInstance() {
  const instancesClient = new compute.InstancesClient();

  const [response] = await instancesClient.suspend({
    project: projectId,
    zone,
    instance: instanceName,
  });
  let operation = response.latestResponse;
  const operationsClient = new compute.ZoneOperationsClient();

  // Wait for the create operation to complete.
  while (operation.status !== 'DONE') {
    [operation] = await operationsClient.wait({
      operation: operation.name,
      project: projectId,
      zone: operation.zone.split('/').pop(),
    });
  }

  console.log('Instance suspended.');
}

suspendInstance();

PHP

use Google\Cloud\Compute\V1\Client\InstancesClient;
use Google\Cloud\Compute\V1\SuspendInstanceRequest;

/**
 * Suspend a running Google Compute Engine instance.
 *
 * @param string $projectId Project ID or project number of the Cloud project your instance belongs to.
 * @param string $zone Name of the zone your instance belongs to.
 * @param string $instanceName Name of the instance you want to suspend.
  *
 * @throws \Google\ApiCore\ApiException if the remote call fails.
 * @throws \Google\ApiCore\ValidationException if local error occurs before remote call.
 */
function suspend_instance(
    string $projectId,
    string $zone,
    string $instanceName
) {
    // Suspend the running Compute Engine instance using InstancesClient.
    $instancesClient = new InstancesClient();
    $request = (new SuspendInstanceRequest())
        ->setInstance($instanceName)
        ->setProject($projectId)
        ->setZone($zone);
    $operation = $instancesClient->suspend($request);

    // Wait for the operation to complete.
    $operation->pollUntilComplete();
    if ($operation->operationSucceeded()) {
        printf('Instance %s suspended successfully' . PHP_EOL, $instanceName);
    } else {
        $error = $operation->getError();
        printf('Failed to suspend instance: %s' . PHP_EOL, $error?->getMessage());
    }
}

Python

from __future__ import annotations

import sys
from typing import Any

from google.api_core.extended_operation import ExtendedOperation
from google.cloud import compute_v1


def wait_for_extended_operation(
    operation: ExtendedOperation, verbose_name: str = "operation", timeout: int = 300
) -> Any:
    """
    Waits for the extended (long-running) operation to complete.

    If the operation is successful, it will return its result.
    If the operation ends with an error, an exception will be raised.
    If there were any warnings during the execution of the operation
    they will be printed to sys.stderr.

    Args:
        operation: a long-running operation you want to wait on.
        verbose_name: (optional) a more verbose name of the operation,
            used only during error and warning reporting.
        timeout: how long (in seconds) to wait for operation to finish.
            If None, wait indefinitely.

    Returns:
        Whatever the operation.result() returns.

    Raises:
        This method will raise the exception received from `operation.exception()`
        or RuntimeError if there is no exception set, but there is an `error_code`
        set for the `operation`.

        In case of an operation taking longer than `timeout` seconds to complete,
        a `concurrent.futures.TimeoutError` will be raised.
    """
    result = operation.result(timeout=timeout)

    if operation.error_code:
        print(
            f"Error during {verbose_name}: [Code: {operation.error_code}]: {operation.error_message}",
            file=sys.stderr,
            flush=True,
        )
        print(f"Operation ID: {operation.name}", file=sys.stderr, flush=True)
        raise operation.exception() or RuntimeError(operation.error_message)

    if operation.warnings:
        print(f"Warnings during {verbose_name}:\n", file=sys.stderr, flush=True)
        for warning in operation.warnings:
            print(f" - {warning.code}: {warning.message}", file=sys.stderr, flush=True)

    return result


def suspend_instance(project_id: str, zone: str, instance_name: str) -> None:
    """
    Suspend a running Google Compute Engine instance.
    Args:
        project_id: project ID or project number of the Cloud project your instance belongs to.
        zone: name of the zone your instance belongs to.
        instance_name: name of the instance you want to suspend.
    """
    instance_client = compute_v1.InstancesClient()

    operation = instance_client.suspend(
        project=project_id, zone=zone, instance=instance_name
    )

    wait_for_extended_operation(operation, "suspend instance")

REST

En la API, haz una solicitud mediante el método instances.suspend:

https://www.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME/suspend

Reemplaza los siguientes elementos:

  • PROJECT_ID: El ID del proyecto
  • ZONE: La zona de la VM
  • VM_NAME: La instancia que deseas suspender

Una vez que hayas realizado una solicitud para suspender una instancia, puede transcurrir un tiempo hasta que se conserven todos los datos necesarios para la instancia en Compute Engine. Durante este tiempo, se te cobra por la instancia mientras siga en ejecución.

En Compute Engine, se marca la instancia suspendida con el estado SUSPENDED. Para verificar el estado de una instancia, haz una solicitud GET como la siguiente:

GET https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME

El estado de la instancia se puede ver en el campo de estado. Por ejemplo:

...
"zone": "https://content.googleapis.com/compute/v1/projects/example-project/zones/us-central1-a",
"status": "SUSPENDED",
"name": "example-vm",
...

Para suspender una instancia con más de {maximum_local_ssd_disks_for_suspend}} disco SSD local, debes descartar los datos de SSD local mediante el parámetro de consulta discardLocalSsd:

https://www.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME/suspend?discardLocalSsd=true

Reanuda una instancia suspendida

Solo puedes reanudar una instancia si hay capacidad suficiente en la zona en la que reside la VM. En la mayoría de los casos, esto no es un problema, pero si tienes problemas de capacidad, vuelve a intentar la solicitud de reanudación más adelante.

Para reanudar una instancia suspendida, usa la consola de Google Cloud, la CLI de gcloud, la API o las bibliotecas cliente de Cloud.

Console

  1. En la consola de Google Cloud, ve a la página Instancias de VM.

    Ir a la página Instancias de VM

  2. Elige una o más instancias que desees reanudar.

  3. Haz clic en Iniciar/Reanudar.

gcloud

Para reanudar una instancia en Google Cloud CLI, sigue estos pasos:

 gcloud compute instances resume VM_NAME

Una vez que hayas realizado una solicitud para reanudar una instancia, puede transcurrir un tiempo hasta que se restablezcan todos los datos necesarios para la instancia en Compute Engine. Durante este tiempo, se te cobra por la instancia mientras se reanuda.

Una instancia se reanuda cuando presenta la marca RUNNING. Para comprobar el estado de una instancia, haz la siguiente solicitud de descripción:

gcloud compute instances describe VM_NAME

Go

import (
	"context"
	"fmt"
	"io"

	compute "cloud.google.com/go/compute/apiv1"
	computepb "cloud.google.com/go/compute/apiv1/computepb"
)

// resumeInstance resumes a suspended Google Compute Engine instance
// (with unencrypted disks).
func resumeInstance(w io.Writer, projectID, zone, instanceName string) error {
	// projectID := "your_project_id"
	// zone := "europe-central2-b"
	// instanceName := "your_instance_name"

	ctx := context.Background()
	instancesClient, err := compute.NewInstancesRESTClient(ctx)
	if err != nil {
		return fmt.Errorf("NewInstancesRESTClient: %w", err)
	}
	defer instancesClient.Close()

	getInstanceReq := &computepb.GetInstanceRequest{
		Project:  projectID,
		Zone:     zone,
		Instance: instanceName,
	}

	instance, err := instancesClient.Get(ctx, getInstanceReq)
	if err != nil {
		return fmt.Errorf("unable to get instance: %w", err)
	}

	if instance.GetStatus() != "SUSPENDED" {
		return fmt.Errorf(
			"only suspended instances can be resumed, instance %s is in %s state",
			instanceName,
			instance.GetStatus(),
		)
	}

	resumeInstanceReq := &computepb.ResumeInstanceRequest{
		Project:  projectID,
		Zone:     zone,
		Instance: instanceName,
	}

	op, err := instancesClient.Resume(ctx, resumeInstanceReq)
	if err != nil {
		return fmt.Errorf("unable to resume instance: %w", err)
	}

	if err = op.Wait(ctx); err != nil {
		return fmt.Errorf("unable to wait for the operation: %w", err)
	}

	fmt.Fprintf(w, "Instance resumed\n")

	return nil
}

Java


import com.google.cloud.compute.v1.Instance.Status;
import com.google.cloud.compute.v1.InstancesClient;
import com.google.cloud.compute.v1.Operation;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class ResumeInstance {

  public static void main(String[] args)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // TODO(developer): Replace these variables before running the sample.
    // project: project ID or project number of the Cloud project your instance belongs to.
    // zone: name of the zone your instance belongs to.
    // instanceName: name of the instance your want to resume.

    String project = "your-project-id";
    String zone = "zone-name";
    String instanceName = "instance-name";

    resumeInstance(project, zone, instanceName);
  }

  // Resume a suspended Google Compute Engine instance (with unencrypted disks).
  // Instance state changes to RUNNING, if successfully resumed.
  public static void resumeInstance(String project, String zone, String instanceName)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // Instantiates a client.
    try (InstancesClient instancesClient = InstancesClient.create()) {

      String currentInstanceState = instancesClient.get(project, zone, instanceName).getStatus();

      // Check if the instance is currently suspended.
      if (!currentInstanceState.equalsIgnoreCase(Status.SUSPENDED.toString())) {
        throw new RuntimeException(
            String.format("Only suspended instances can be resumed. Instance %s is in %s state.",
                instanceName, currentInstanceState));
      }

      Operation operation = instancesClient.resumeAsync(project, zone, instanceName)
          .get(300, TimeUnit.SECONDS);

      if (operation.hasError() || !instancesClient.get(project, zone, instanceName).getStatus()
          .equalsIgnoreCase(
              Status.RUNNING.toString())) {
        System.out.println("Cannot resume instance. Try again!");
        return;
      }

      System.out.printf("Instance resumed successfully ! %s", instanceName);
    }
  }
}

Node.js

/**
 * TODO(developer): Uncomment and replace these variables before running the sample.
 */
// const projectId = 'YOUR_PROJECT_ID';
// const zone = 'europe-central2-b';
// const instanceName = 'YOUR_INSTANCE_NAME';

const compute = require('@google-cloud/compute');

// Resumes a suspended Google Compute Engine instance (with unencrypted disks).
async function resumeInstance() {
  const instancesClient = new compute.InstancesClient();

  const [instance] = await instancesClient.get({
    project: projectId,
    zone,
    instance: instanceName,
  });

  if (instance.status !== 'SUSPENDED') {
    throw new Error(
      'Only suspended instances can be resumed.' +
        `Instance ${instanceName} is in ${instance.status} state.`
    );
  }

  const [response] = await instancesClient.resume({
    project: projectId,
    zone,
    instance: instanceName,
  });
  let operation = response.latestResponse;
  const operationsClient = new compute.ZoneOperationsClient();

  // Wait for the create operation to complete.
  while (operation.status !== 'DONE') {
    [operation] = await operationsClient.wait({
      operation: operation.name,
      project: projectId,
      zone: operation.zone.split('/').pop(),
    });
  }

  console.log('Instance resumed.');
}

resumeInstance();

PHP

use Google\Cloud\Compute\V1\Client\InstancesClient;
use Google\Cloud\Compute\V1\ResumeInstanceRequest;

/**
 * Resume a suspended Google Compute Engine instance (with unencrypted disks).
 *
 * @param string $projectId Project ID or project number of the Cloud project your instance belongs to.
 * @param string $zone Name of the zone your instance belongs to.
 * @param string $instanceName Name of the instance you want to resume.
  *
 * @throws \Google\ApiCore\ApiException if the remote call fails.
 * @throws \Google\ApiCore\ValidationException if local error occurs before remote call.
 */
function resume_instance(
    string $projectId,
    string $zone,
    string $instanceName
) {
    // Resume the suspended Compute Engine instance using InstancesClient.
    $instancesClient = new InstancesClient();
    $request = (new ResumeInstanceRequest())
        ->setInstance($instanceName)
        ->setProject($projectId)
        ->setZone($zone);
    $operation = $instancesClient->resume($request);

    // Wait for the operation to complete.
    $operation->pollUntilComplete();
    if ($operation->operationSucceeded()) {
        printf('Instance %s resumed successfully' . PHP_EOL, $instanceName);
    } else {
        $error = $operation->getError();
        printf('Failed to resume instance: %s' . PHP_EOL, $error?->getMessage());
    }
}

Python

from __future__ import annotations

import sys
from typing import Any

from google.api_core.extended_operation import ExtendedOperation
from google.cloud import compute_v1


def wait_for_extended_operation(
    operation: ExtendedOperation, verbose_name: str = "operation", timeout: int = 300
) -> Any:
    """
    Waits for the extended (long-running) operation to complete.

    If the operation is successful, it will return its result.
    If the operation ends with an error, an exception will be raised.
    If there were any warnings during the execution of the operation
    they will be printed to sys.stderr.

    Args:
        operation: a long-running operation you want to wait on.
        verbose_name: (optional) a more verbose name of the operation,
            used only during error and warning reporting.
        timeout: how long (in seconds) to wait for operation to finish.
            If None, wait indefinitely.

    Returns:
        Whatever the operation.result() returns.

    Raises:
        This method will raise the exception received from `operation.exception()`
        or RuntimeError if there is no exception set, but there is an `error_code`
        set for the `operation`.

        In case of an operation taking longer than `timeout` seconds to complete,
        a `concurrent.futures.TimeoutError` will be raised.
    """
    result = operation.result(timeout=timeout)

    if operation.error_code:
        print(
            f"Error during {verbose_name}: [Code: {operation.error_code}]: {operation.error_message}",
            file=sys.stderr,
            flush=True,
        )
        print(f"Operation ID: {operation.name}", file=sys.stderr, flush=True)
        raise operation.exception() or RuntimeError(operation.error_message)

    if operation.warnings:
        print(f"Warnings during {verbose_name}:\n", file=sys.stderr, flush=True)
        for warning in operation.warnings:
            print(f" - {warning.code}: {warning.message}", file=sys.stderr, flush=True)

    return result


def resume_instance(project_id: str, zone: str, instance_name: str) -> None:
    """
    Resume a suspended Google Compute Engine instance (with unencrypted disks).
    Args:
        project_id: project ID or project number of the Cloud project your instance belongs to.
        zone: name of the zone your instance belongs to.
        instance_name: name of the instance you want to resume.
    """
    instance_client = compute_v1.InstancesClient()

    instance = instance_client.get(
        project=project_id, zone=zone, instance=instance_name
    )
    if instance.status != compute_v1.Instance.Status.SUSPENDED.name:
        raise RuntimeError(
            f"Only suspended instances can be resumed. "
            f"Instance {instance_name} is in {instance.status} state."
        )

    operation = instance_client.resume(
        project=project_id, zone=zone, instance=instance_name
    )

    wait_for_extended_operation(operation, "instance resumption")

REST

Realiza una solicitud al método instances.resume.

https://www.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME/resume

Reemplaza los siguientes elementos:

  • PROJECT_ID: El ID del proyecto de esta solicitud
  • ZONE: La zona de la VM
  • VM_NAME: La instancia que se reanudará

Una vez que hayas realizado una solicitud para reanudar una instancia, puede transcurrir un tiempo hasta que se restablezcan todos los datos necesarios para la instancia en Compute Engine. Durante este tiempo, se te cobra por la instancia mientras se reanuda.

Una vez que la instancia se reanuda, en Compute Engine, se marca con el estado RUNNING. Para verificar el estado de una instancia, haz una solicitud GET como la siguiente:

GET https://compute.googleapis.com/compute/v1/projects/example-project/zones/us-central1-a/instances/example-instance

El estado de la instancia se puede ver en el campo de estado. Por ejemplo:

...
"zone": "https://content.googleapis.com/compute/v1/projects/example-project/zones/us-central1-a",
"status": "RUNNING",
"name": "example-instance",
...

Proceso de suspensión

Cuando realizas una solicitud de suspensión, envías una señal de suspensión de ACPI a la instancia de VM. Si la VM no responde a la señal de suspensión S3 de ACPI en un par de minutos, Compute Engine cancela el intento de suspensión y la VM vuelve al estado RUNNING.

En la siguiente tabla, se describe el efecto de suspender una instancia de VM en sus recursos asociados:

Recurso Compatibilidad
Memoria Solo se pueden suspender las VM menores o iguales a 208 GB de memoria.
SSD local Se descartan los datos de los SSD locales.
Disco persistente Se conservan los discos SSD y HDD persistentes.
Direcciones IP Las IP efímeras se liberan durante la suspensión, pero las IP estáticas permanecen conectadas a las instancias de VM. Si deseas conservar tu IP efímera, promuévela.
Configuración de VM (como tipo de máquina, metadatos, etiquetas, etcétera) Todas las opciones de configuración de VM, excepto las direcciones IP efímeras, se conservan y restablecen cuando se reanuda la instancia.

Configura una VM de Debian para que admita la suspensión y la reanudación

Las VM que ejecutan Debian 8 y 9 pueden suspenderse y reanudarse, pero deben configurarse con anticipación. Para configurar tu instancia de Debian, completa uno de los siguientes conjuntos de instrucciones, opción A o B. Recomendamos configurar el ACPID si es posible (opción A).

Opción A

Esta opción configura el ACPID para controlar el evento del botón de suspensión y agrega una secuencia de comandos de shell con el fin de controlar el evento de suspensión.

  1. Conéctate a tu instancia de VM mediante SSH:

    gcloud compute ssh VM_NAME
    
  2. En la instancia de VM, crea un directorio en la carpeta acpi:

    sudo mkdir -p /etc/acpi/events/
    
  3. Configura el ACPID para controlar el evento del botón de suspensión:

    cat <<EOF | sudo tee /etc/acpi/events/sleepbtn-acpi-support
    event=button[ /]sleep
    action=/etc/acpi/sleepbtn-acpi-support.sh
    EOF
    
  4. Crea la secuencia de comandos para controlar eventos de suspensión:

    cat <<EOF | sudo tee /etc/acpi/sleepbtn-acpi-support.sh
    #!/bin/sh
    echo mem > /sys/power/state
    EOF
    
  5. Configura los permisos para la secuencia de comandos:

    sudo chmod 755 /etc/acpi/sleepbtn-acpi-support.sh
    
  6. Reinicia ACPID:

    sudo systemctl restart acpid.service
    

Opción B

  1. Conéctate a tu instancia de VM mediante SSH:

    gcloud compute ssh VM_NAME
    
  2. En la instancia de VM, instala dbus:

    sudo apt-get install dbus
    
  3. Reinicia logind:

    sudo systemctl restart systemd-logind.service
    

¿Qué sigue?