Interromper ou reiniciar uma instância do Compute Engine

Neste documento, explicamos como interromper ou reiniciar manualmente uma instância do Compute Engine. Como alternativa, para automatizar quando uma instância de computação é interrompida ou reiniciada, consulte o seguinte:

É possível interromper manualmente uma instância de computação. Depois que uma operação de parada for concluída e o estado da instância de computação mudar para TERMINATED, será possível reiniciar a instância de computação para retomar a carga de trabalho ou excluí-la permanentemente se ela não for mais necessária. Interromper manualmente uma instância de computação é útil quando você quer fazer o seguinte:

  • Economizar custos sem perder as configurações: você não quer mais executar cargas de trabalho na instância de computação. No entanto, você quer manter a instância de computação e os discos anexados, as definições de configuração, os endereços IP, os endereços MAC e os metadados. Se você também precisar manter os dados na memória e o estado do aplicativo, suspenda a instância de computação.

  • Atualizar propriedades: você quer modificar uma ou mais propriedades que exigem que você interrompa e reinicie a instância de computação antes que as mudanças entrem em vigor. Por exemplo, você quer mudar o tipo de máquina ou remover um disco. Para mais informações, consulte Propriedades que podem ser atualizadas.

Limitações

Quando você interrompe uma instância de computação, as seguintes limitações se aplicam:

  • Só é possível interromper ou reiniciar uma instância de computação se o estado dela permitir.

  • Só é possível reiniciar uma instância de computação se houver recursos suficientes na zona em que ela está.

  • Não é possível reiniciar instâncias de computação de TPU. Depois de interromper as instâncias de computação de TPU, só é possível excluí-las.

Antes de começar

Funções exigidas

Para receber as permissões necessárias para interromper ou reiniciar uma instância de computação, peça ao administrador para conceder a você o papel do IAM de Administrador da instância do Compute (v1) (roles/compute.instanceAdmin.v1) no projeto. Para mais informações sobre a concessão de papéis, consulte Gerenciar o acesso a projetos, pastas e organizações.

Esse papel predefinido contém as permissões necessárias para interromper ou reiniciar uma instância de computação. Para acessar as permissões exatas necessárias, expanda a seção Permissões necessárias:

Permissões necessárias

As permissões a seguir são necessárias para interromper ou reiniciar uma instância de computação:

  • Para interromper uma instância de computação: compute.instances.stop na instância de computação
  • Para interromper uma instância de computação no SO convidado: compute.instances.setMetadata na instância de computação se ela usar chaves SSH públicas no nível da instância.
  • Para reiniciar uma instância de computação: compute.instances.start na instância de computação
  • Para reiniciar uma instância de computação que usa chaves de criptografia: compute.instances.startWithEncryptionKey na instância de computação

Essas permissões também podem ser concedidas com funções personalizadas ou outros papéis predefinidos.

Interromper uma instância de computação

Para interromper a instância de computação, use um dos métodos a seguir. A melhor abordagem para seu caso de uso depende de você ter discos SSD locais anexados à instância de computação e de como quer lidar com os scripts de encerramento:

  • Interromper uma instância de computação de Cloud de Confiance. É possível interromper uma ou mais instâncias de computação simultaneamente em Cloud de Confiance. Se as instâncias de computação tiverem discos SSD locais anexados, será possível descartar ou preservar (pré-lançamento) os dados do SSD local. Todos os scripts de encerramento na instância de computação precisam terminar de ser executados antes que a instância de computação seja interrompida. Para ver instruções, consulte uma das seguintes opções:

  • Interrompa uma instância de computação no SO convidado. Essa abordagem garante que os scripts de encerramento terminem de ser executados antes que a instância de computação seja interrompida. Se você tiver ativado o encerramento completo, pode pular ou encerrar o processo. No entanto, interromper uma instância de computação no SO convidado descarta os dados em todos os discos SSD locais anexados, a menos que você faça backup dos dados em um armazenamento durável. Para instruções, consulte Interromper uma instância de computação no SO convidado.

Interromper uma instância de computação sem discos SSD locais

Para interromper uma instância de computação que não tem discos SSD locais anexados, consulte as seguintes opções:

  • Se você tiver ativado o encerramento completo na instância de computação, poderá economizar custos pulando ou encerrando um encerramento completo em andamento. Para isso, use o Cloud de Confiance console, a CLI gcloud ou a API REST.

  • Para interromper várias instâncias de computação simultaneamente, use o Cloud de Confiance console ou, para instâncias de computação que existem na mesma zona, a CLI gcloud.

Para interromper uma ou mais instâncias de computação, selecione uma das seguintes opções:

Console

  1. No console do Cloud de Confiance , acesse a página Instâncias de VM.

    Acessar instâncias de VM

  2. Selecione as instâncias de computação em execução que você quer interromper.

  3. Clique em Interromper. Se não houver a opção Parar, clique em Mais ações e selecione Parar.

  4. Na caixa de diálogo exibida, execute as ações a seguir:

    1. Opcional: para interromper as instâncias de computação sem realizar o encerramento completo delas ou para encerrar um encerramento completo em andamento, marque a caixa de seleção Ignorar encerramento completo (se aplicável).

    2. Para confirmar, clique em Interromper.

gcloud

Para interromper uma ou mais instâncias de computação que estão na mesma zona, use o comando gcloud compute instances stop:

gcloud compute instances stop INSTANCE_NAMES \
    --zone=ZONE

Substitua:

  • INSTANCE_NAMES: uma lista de nomes de instâncias de computação que você quer interromper, separados por espaços. Por exemplo, especifique instance-01 instance-02 instance-03.

  • ZONE: a zona em que as instâncias de computação estão.

Se você quiser pular ou encerrar um encerramento completo em andamento, use o mesmo comando com a flag --no-graceful-shutdown:

gcloud compute instances stop INSTANCE_NAMES \
    --no-graceful-shutdown \
    --zone=ZONE

Go

import (
	"context"
	"fmt"
	"io"

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

// stopInstance stops a started Google Compute Engine instance
func stopInstance(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.StopInstanceRequest{
		Project:  projectID,
		Zone:     zone,
		Instance: instanceName,
	}

	op, err := instancesClient.Stop(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to stop 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 stopped\n")

	return nil
}

Java


import com.google.api.gax.longrunning.OperationFuture;
import com.google.cloud.compute.v1.InstancesClient;
import com.google.cloud.compute.v1.Operation;
import com.google.cloud.compute.v1.Operation.Status;
import com.google.cloud.compute.v1.StopInstanceRequest;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class StopInstance {

  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 stop.
     */
    String project = "your-project-id";
    String zone = "zone-name";
    String instanceName = "instance-name";

    stopInstance(project, zone, instanceName);
  }

  // Stops a started Google Compute Engine instance.
  public static void stopInstance(String project, String zone, String instanceName)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    /* Initialize client that will be used to send requests. This client only needs to be created
       once, and can be reused for multiple requests. After completing all of your requests, call
       the `instancesClient.close()` method on the client to safely
       clean up any remaining background resources. */
    try (InstancesClient instancesClient = InstancesClient.create()) {

      StopInstanceRequest stopInstanceRequest = StopInstanceRequest.newBuilder()
          .setProject(project)
          .setZone(zone)
          .setInstance(instanceName)
          .build();

      OperationFuture<Operation, Operation> operation = instancesClient.stopAsync(
          stopInstanceRequest);
      Operation response = operation.get(3, TimeUnit.MINUTES);

      if (response.getStatus() == Status.DONE) {
        System.out.println("Instance stopped successfully ! ");
      }
    }
  }
}

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');

async function stopInstance() {
  const instancesClient = new compute.InstancesClient();

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

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

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

stopInstance();

PHP

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

/**
 * Stops 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 stop.
  *
 * @throws \Google\ApiCore\ApiException if the remote call fails.
 * @throws \Google\ApiCore\ValidationException if local error occurs before remote call.
 */
function stop_instance(
    string $projectId,
    string $zone,
    string $instanceName
) {
    // Stop the Compute Engine instance using InstancesClient.
    $instancesClient = new InstancesClient();
    $request = (new StopInstanceRequest())
        ->setInstance($instanceName)
        ->setProject($projectId)
        ->setZone($zone);
    $operation = $instancesClient->stop($request);

    // Wait for the operation to complete.
    $operation->pollUntilComplete();
    if ($operation->operationSucceeded()) {
        printf('Instance %s stopped successfully' . PHP_EOL, $instanceName);
    } else {
        $error = $operation->getError();
        printf('Failed to stop 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 stop_instance(project_id: str, zone: str, instance_name: str) -> None:
    """
    Stops 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 your want to stop.
    """
    instance_client = compute_v1.InstancesClient()

    operation = instance_client.stop(
        project=project_id, zone=zone, instance=instance_name
    )
    wait_for_extended_operation(operation, "instance stopping")

REST

Para interromper uma instância de computação, faça uma solicitação POST ao método instances.stop:

POST https://compute.s3nsapis.fr/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_NAME/stop

Substitua:

  • INSTANCE_NAME: o nome da instância de computação.

  • PROJECT_ID: o ID do projeto em que a instância de computação está.

  • ZONE: a zona em que a instância de computação está.

Se você quiser pular ou encerrar um encerramento completo em andamento, inclua o parâmetro de consulta noGracefulShutdown=true no URL da solicitação:

POST https://compute.s3nsapis.fr/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME/stop?noGracefulShutdown=true

Interromper uma instância de computação com discos SSD locais

O melhor método para interromper uma instância de computação com discos SSD locais anexados depende do seu caso de uso. Use uma das seguintes opções:

  • Se você tiver ativado o encerramento completo em uma instância de computação, poderá economizar custos pulando ou encerrando um encerramento completo em andamento. Para isso, use o Cloud de Confiance console, a CLI gcloud ou a API REST.

  • Para preservar os dados do SSD local (exceto para tipos de máquina que usam SSD Titanium), use a CLI gcloud ou a API REST.

  • Para interromper várias instâncias de computação simultaneamente, use o Cloud de Confiance console ou, para instâncias de computação que existem na mesma zona, a CLI gcloud.

Para interromper uma ou mais instâncias de computação que têm discos SSD locais anexados, selecione uma das seguintes opções:

Console

  1. No console do Cloud de Confiance , acesse a página Instâncias de VM.

    Acessar instâncias de VM

  2. Selecione as instâncias de computação em execução que você quer interromper.

  3. Clique em Interromper. Se não houver a opção Parar, clique em Mais ações e selecione Parar.

  4. Na caixa de diálogo exibida, execute as ações a seguir:

    1. Opcional: para interromper as instâncias de computação sem realizar o encerramento completo ou para encerrar um encerramento completo em andamento, marque a caixa de seleção Ignorar encerramento completo (se aplicável).

    2. Para confirmar, clique em Interromper.

gcloud

Ao interromper uma ou mais instâncias de computação na mesma zona que têm discos SSD locais anexados, especifique se os dados do SSD local serão descartados ou preservados da seguinte maneira:

  • Para descartar dados do SSD local, use o comando gcloud compute instances stop com a flag --discard-local-ssd=true:

    gcloud compute instances stop INSTANCE_NAMES \
        --discard-local-ssd=true \
        --zone=ZONE
    
  • Para preservar os dados do SSD local, use o comando gcloud beta compute instances stop com a flag --discard-local-ssd=false:

    gcloud beta compute instances stop INSTANCE_NAMES \
        --discard-local-ssd=false \
        --zone=ZONE
    

Substitua:

  • INSTANCE_NAMES: uma lista de nomes de instâncias de computação que você quer interromper, separados por espaços. Por exemplo, especifique instance-01 instance-02 instance-03.

  • ZONE: a zona em que as instâncias de computação estão.

Se você quiser pular ou encerrar um encerramento completo em andamento, inclua a flag --no-graceful-shutdown no comando:

gcloud compute instances stop INSTANCE_NAMES \
    --discard-local-ssd=DISCARD_LOCAL_SSD \
    --no-graceful-shutdown \
    --zone=ZONE

Substitua DISCARD_LOCAL_SSD por true para descartar os dados nos discos SSD locais ou por false para preservá-los. Se você especificar false, use o comando gcloud beta compute instances stop.

REST

Ao interromper uma ou mais instâncias de computação na mesma zona que têm discos SSD locais anexados, especifique se os dados do SSD local serão descartados ou preservados da seguinte maneira:

  • Para descartar dados do SSD local, faça uma solicitação POST ao método instances.stop. No URL da solicitação, inclua o parâmetro de consulta discardLocalSsd definido como true:

    POST https://compute.s3nsapis.fr/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_NAME/stop?discardLocalSsd=true
    
  • Para preservar os dados do SSD local, faça uma solicitação POST ao método beta.instances.stop. No URL da solicitação, inclua o parâmetro de consulta discardLocalSsd definido como false:

    POST https://compute.s3nsapis.fr/compute/beta/projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_NAME/stop?discardLocalSsd=false
    

Substitua:

  • PROJECT_ID: o ID do projeto em que a instância de computação está.

  • ZONE: a zona em que a instância de computação está.

  • INSTANCE_NAME: o nome da instância de computação.

Se você quiser pular ou encerrar um encerramento completo em andamento, inclua o parâmetro de consulta noGracefulShutdown=true no URL da solicitação:

POST https://compute.s3nsapis.fr/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME/stop?discardLocalSsd=DISCARD_LOCAL_SSD&noGracefulShutdown=true

Substitua DISCARD_LOCAL_SSD por true para descartar os dados nos discos SSD locais ou por false para preservá-los. Se você especificar false, faça uma solicitação POST ao método beta.instances.stop.

Interromper uma instância de computação no SO convidado

Se uma instância de computação tiver discos SSD locais anexados, o encerramento do SO convidado descartará automaticamente os dados do SSD local. Para preservar esses dados, copie-os manualmente para uma opção de armazenamento permanente antes de interromper a instância de computação.

Para interromper uma instância de computação no SO convidado, selecione uma das seguintes opções:

Linux

  1. Conecte-se à instância de computação, caso ainda não tenha feito isso.

  2. Para interromper a instância de computação no SO convidado, selecione um dos seguintes métodos:

    • Para encerrar o SO convidado de maneira limpa somente depois que todos os scripts de encerramento forem executados, execute o seguinte comando:

      sudo shutdown -h now
      
    • Para forçar o encerramento do SO convidado, execute o seguinte comando:

      sudo poweroff
      

Windows

  1. Se ainda não tiver feito isso, conecte-se à instância de computação usando um dos seguintes métodos:

  2. Para interromper a instância de computação no SO convidado, selecione um dos seguintes métodos:

    • Para encerrar o SO convidado de maneira limpa somente depois que todos os scripts de encerramento forem executados, execute o seguinte comando:

      shutdown /s
      
    • Para forçar o encerramento do SO convidado, execute o seguinte comando:

      shutdown /f
      

Reiniciar uma instância de computação

É possível reiniciar uma instância de computação que foi totalmente interrompida, ou seja, quando o estado dela é TERMINATED. Se você optou por preservar os dados do SSD local ao interromper a instância de computação, talvez seja necessário remontar os discos SSD locais depois de reiniciar a instância de computação. Para mais informações, consulte Formatar e ativar um dispositivo SSD local.

Para reiniciar uma instância de computação, use um dos métodos a seguir. O melhor método para seu caso de uso depende se a instância de computação tem discos que foram criptografados com chaves de criptografia fornecidas pelo cliente (CSEK):

Reiniciar uma instância de computação que não tem discos criptografados com CSEK

Para reiniciar várias instâncias de computação ao mesmo tempo em diferentes zonas, use o console do Cloud de Confiance . Para instâncias de computação que existem na mesma zona, use a CLI gcloud. Para outros cenários de reinicialização, selecione uma das seguintes opções:

Console

  1. No console do Cloud de Confiance , acesse a página Instâncias de VM.

    Acessar instâncias de VM

  2. Selecione as instâncias de computação que você quer reiniciar.

  3. Clique em Iniciar / continuar .

gcloud

Para reiniciar uma ou mais instâncias de computação que estão na mesma zona, use o comando gcloud compute instances start:

gcloud compute instances start INSTANCE_NAMES \
    --zone=ZONE

Substitua:

  • INSTANCE_NAMES: uma lista de nomes de instâncias de computação que você quer reiniciar, separados por espaços. Por exemplo, especifique instance-01 instance-02 instance-03.

  • ZONE: a zona em que as instâncias de computação estão.

Go

import (
	"context"
	"fmt"
	"io"

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

// startInstance starts a stopped Google Compute Engine instance (with unencrypted disks).
func startInstance(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.StartInstanceRequest{
		Project:  projectID,
		Zone:     zone,
		Instance: instanceName,
	}

	op, err := instancesClient.Start(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to start 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 started\n")

	return nil
}

Java


import com.google.api.gax.longrunning.OperationFuture;
import com.google.cloud.compute.v1.InstancesClient;
import com.google.cloud.compute.v1.Operation;
import com.google.cloud.compute.v1.Operation.Status;
import com.google.cloud.compute.v1.StartInstanceRequest;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class StartInstance {

  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 start. */
    String project = "your-project-id";
    String zone = "zone-name";
    String instanceName = "instance-name";

    startInstance(project, zone, instanceName);
  }

  // Starts a stopped Google Compute Engine instance (with unencrypted disks).
  public static void startInstance(String project, String zone, String instanceName)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    /* Initialize client that will be used to send requests. This client only needs to be created
       once, and can be reused for multiple requests. After completing all of your requests, call
       the `instancesClient.close()` method on the client to safely
       clean up any remaining background resources. */
    try (InstancesClient instancesClient = InstancesClient.create()) {

      // Create the request.
      StartInstanceRequest startInstanceRequest = StartInstanceRequest.newBuilder()
          .setProject(project)
          .setZone(zone)
          .setInstance(instanceName)
          .build();

      OperationFuture<Operation, Operation> operation = instancesClient.startAsync(
          startInstanceRequest);

      // Wait for the operation to complete.
      Operation response = operation.get(3, TimeUnit.MINUTES);

      if (response.getStatus() == Status.DONE) {
        System.out.println("Instance started successfully ! ");
      }
    }
  }
}

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');

async function startInstance() {
  const instancesClient = new compute.InstancesClient();

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

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

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

startInstance();

PHP

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

/**
 * Starts a stopped 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 stop.
  *
 * @throws \Google\ApiCore\ApiException if the remote call fails.
 * @throws \Google\ApiCore\ValidationException if local error occurs before remote call.
 */
function start_instance(
    string $projectId,
    string $zone,
    string $instanceName
) {
    // Start the Compute Engine instance using InstancesClient.
    $instancesClient = new InstancesClient();
    $request = (new StartInstanceRequest())
        ->setInstance($instanceName)
        ->setProject($projectId)
        ->setZone($zone);
    $operation = $instancesClient->start($request);

    // Wait for the operation to complete.
    $operation->pollUntilComplete();
    if ($operation->operationSucceeded()) {
        printf('Instance %s started successfully' . PHP_EOL, $instanceName);
    } else {
        $error = $operation->getError();
        printf('Failed to start 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 start_instance(project_id: str, zone: str, instance_name: str) -> None:
    """
    Starts a stopped 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 your want to start.
    """
    instance_client = compute_v1.InstancesClient()

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

    wait_for_extended_operation(operation, "instance start")

REST

Para reiniciar uma instância de computação, faça uma solicitação POST ao método instances.start:

 POST https://compute.s3nsapis.fr/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_NAME/start

Substitua:

  • INSTANCE_NAME: o nome da instância de computação.

  • PROJECT_ID: o ID do projeto em que a instância de computação está.

  • ZONE: a zona em que a instância de computação está.

Reiniciar uma instância de computação com discos criptografados por CSEK

Ao reiniciar uma instância de computação interrompida que tenha discos anexados que foram criptografados usando chaves de criptografia fornecidas pelo cliente, é necessário fornecer as informações da chave de criptografia.

Para reiniciar várias instâncias de computação ao mesmo tempo em diferentes zonas, use o console do Cloud de Confiance . Para instâncias de computação que existem na mesma zona, use a CLI gcloud. Para outros cenários de reinicialização, selecione uma das seguintes opções:

Console

  1. No console do Cloud de Confiance , acesse a página Instâncias de VM.

    Acessar instâncias de VM

  2. Selecione as instâncias de computação que você quer reiniciar.

  3. Clique em Iniciar / continuar .

  4. Na caixa de diálogo exibida, execute as ações a seguir:

    1. Especifique as chaves de criptografia para cada um dos discos criptografados anexados às instâncias de computação.

    2. Clique em Iniciar.

gcloud

Para reiniciar uma ou mais instâncias de computação que usam discos criptografados que existem na mesma zona, use o comando gcloud compute instances start com a flag --csek-key-file. Se você estiver usando uma chave incorporada por RSA, use o comando gcloud beta compute instances start com a flag --csek-key-file:

gcloud compute instances start INSTANCE_NAMES \
    --csek-key-file=ENCRYPTION_KEY_FILE \
    --zone=ZONE

Substitua:

  • INSTANCE_NAMES: uma lista de nomes de instâncias de computação que você quer reiniciar, separados por espaços. Por exemplo, especifique instance-01 instance-02 instance-03.

  • ENCRYPTION_KEY_FILE: o caminho relativo para o arquivo JSON que contém a chave de criptografia fornecida pelo cliente. Só é possível reiniciar várias instâncias de computação simultaneamente se elas usarem a mesma chave de criptografia fornecida pelo cliente. O formato do arquivo é descrito em Formato do arquivo de chave.

  • ZONE: a zona em que as instâncias de computação estão.

Go

import (
	"context"
	"fmt"
	"io"

	compute "cloud.google.com/go/compute/apiv1"
	computepb "cloud.google.com/go/compute/apiv1/computepb"
	"google.golang.org/protobuf/proto"
)

// startInstanceWithEncKey starts a stopped Google Compute Engine instance (with encrypted disks).
func startInstanceWithEncKey(w io.Writer, projectID, zone, instanceName, key string) error {
	// projectID := "your_project_id"
	// zone := "europe-central2-b"
	// instanceName := "your_instance_name"
	// key := "your_encryption_key"

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

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

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

	req := &computepb.StartWithEncryptionKeyInstanceRequest{
		Project:  projectID,
		Zone:     zone,
		Instance: instanceName,
		InstancesStartWithEncryptionKeyRequestResource: &computepb.InstancesStartWithEncryptionKeyRequest{
			Disks: []*computepb.CustomerEncryptionKeyProtectedDisk{
				{
					Source: proto.String(instance.GetDisks()[0].GetSource()),
					DiskEncryptionKey: &computepb.CustomerEncryptionKey{
						RawKey: proto.String(key),
					},
				},
			},
		},
	}

	op, err := instancesClient.StartWithEncryptionKey(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to start instance with encryption key: %w", err)
	}

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

	fmt.Fprintf(w, "Instance with encryption key started\n")

	return nil
}

Java


import com.google.api.gax.longrunning.OperationFuture;
import com.google.cloud.compute.v1.CustomerEncryptionKey;
import com.google.cloud.compute.v1.CustomerEncryptionKeyProtectedDisk;
import com.google.cloud.compute.v1.GetInstanceRequest;
import com.google.cloud.compute.v1.Instance;
import com.google.cloud.compute.v1.InstancesClient;
import com.google.cloud.compute.v1.InstancesStartWithEncryptionKeyRequest;
import com.google.cloud.compute.v1.Operation;
import com.google.cloud.compute.v1.Operation.Status;
import com.google.cloud.compute.v1.StartWithEncryptionKeyInstanceRequest;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class StartEncryptedInstance {

  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 start.
       key: bytes object representing a raw base64 encoded key to your machines boot disk.
            For more information about disk encryption see:
            https://cloud.google.com/compute/docs/disks/customer-supplied-encryption#specifications
     */
    String project = "your-project-id";
    String zone = "zone-name";
    String instanceName = "instance-name";
    String key = "raw-key";

    startEncryptedInstance(project, zone, instanceName, key);
  }

  // Starts a stopped Google Compute Engine instance (with encrypted disks).
  public static void startEncryptedInstance(String project, String zone, String instanceName,
      String key)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    /* Initialize client that will be used to send requests. This client only needs to be created
       once, and can be reused for multiple requests. After completing all of your requests, call
       the `instancesClient.close()` method on the client to safely
       clean up any remaining background resources. */
    try (InstancesClient instancesClient = InstancesClient.create()) {

      GetInstanceRequest getInstanceRequest = GetInstanceRequest.newBuilder()
          .setProject(project)
          .setZone(zone)
          .setInstance(instanceName).build();

      Instance instance = instancesClient.get(getInstanceRequest);

      // Prepare the information about disk encryption.
      CustomerEncryptionKeyProtectedDisk protectedDisk = CustomerEncryptionKeyProtectedDisk
          .newBuilder()
          /* Use raw_key to send over the key to unlock the disk
             To use a key stored in KMS, you need to provide:
             `kms_key_name` and `kms_key_service_account`
           */
          .setDiskEncryptionKey(CustomerEncryptionKey.newBuilder()
              .setRawKey(key).build())
          .setSource(instance.getDisks(0).getSource())
          .build();

      InstancesStartWithEncryptionKeyRequest startWithEncryptionKeyRequest =
          InstancesStartWithEncryptionKeyRequest.newBuilder()
              .addDisks(protectedDisk).build();

      StartWithEncryptionKeyInstanceRequest encryptionKeyInstanceRequest =
          StartWithEncryptionKeyInstanceRequest.newBuilder()
              .setProject(project)
              .setZone(zone)
              .setInstance(instanceName)
              .setInstancesStartWithEncryptionKeyRequestResource(startWithEncryptionKeyRequest)
              .build();

      OperationFuture<Operation, Operation> operation = instancesClient.startWithEncryptionKeyAsync(
          encryptionKeyInstanceRequest);
      Operation response = operation.get(3, TimeUnit.MINUTES);

      if (response.getStatus() == Status.DONE) {
        System.out.println("Encrypted instance started successfully ! ");
      }
    }
  }

}

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 key = 'YOUR_KEY_STRING'

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

async function startInstanceWithEncryptionKey() {
  const instancesClient = new compute.InstancesClient();

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

  const [response] = await instancesClient.startWithEncryptionKey({
    project: projectId,
    zone,
    instance: instanceName,
    instancesStartWithEncryptionKeyRequestResource: {
      disks: [
        {
          source: instance.disks[0].source,
          diskEncryptionKey: {
            rawKey: key,
          },
        },
      ],
    },
  });
  let operation = response.latestResponse;
  const operationsClient = new compute.ZoneOperationsClient();

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

  console.log('Instance with encryption key started.');
}

startInstanceWithEncryptionKey();

PHP

use Google\Cloud\Compute\V1\Client\InstancesClient;
use Google\Cloud\Compute\V1\CustomerEncryptionKey;
use Google\Cloud\Compute\V1\CustomerEncryptionKeyProtectedDisk;
use Google\Cloud\Compute\V1\GetInstanceRequest;
use Google\Cloud\Compute\V1\InstancesStartWithEncryptionKeyRequest;
use Google\Cloud\Compute\V1\StartWithEncryptionKeyInstanceRequest;

/**
 * Starts a stopped Google Compute Engine instance (with encrypted 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 stop.
 * @param string $key Bytes object representing a raw base64 encoded key to your instance's boot disk.
 *                    For more information about disk encryption see:
 *                    https://cloud.google.com/compute/docs/disks/customer-supplied-encryption#specifications
 *
 * @throws \Google\ApiCore\ApiException if the remote call fails.
 * @throws \Google\ApiCore\ValidationException if local error occurs before remote call.
 */
function start_instance_with_encryption_key(
    string $projectId,
    string $zone,
    string $instanceName,
    string $key
) {
    // Initiate the InstancesClient.
    $instancesClient = new InstancesClient();

    // Get data about the instance.
    $request = (new GetInstanceRequest())
        ->setInstance($instanceName)
        ->setProject($projectId)
        ->setZone($zone);
    $instanceData = $instancesClient->get($request);

    // Use `setRawKey` to send over the key to unlock the disk
    // To use a key stored in KMS, you need to use `setKmsKeyName` and `setKmsKeyServiceAccount`
    $customerEncryptionKey = (new CustomerEncryptionKey())
        ->setRawKey($key);

    /** @var \Google\Cloud\Compute\V1\AttachedDisk */
    $disk = $instanceData->getDisks()[0];

    // Prepare the information about disk encryption.
    $diskData = (new CustomerEncryptionKeyProtectedDisk())
        ->setSource($disk->getSource())
        ->setDiskEncryptionKey($customerEncryptionKey);

    // Set request with one disk.
    $instancesStartWithEncryptionKeyRequest = (new InstancesStartWithEncryptionKeyRequest())
        ->setDisks(array($diskData));

    // Start the instance with encrypted disk.
    $request2 = (new StartWithEncryptionKeyInstanceRequest())
        ->setInstance($instanceName)
        ->setInstancesStartWithEncryptionKeyRequestResource($instancesStartWithEncryptionKeyRequest)
        ->setProject($projectId)
        ->setZone($zone);
    $operation = $instancesClient->startWithEncryptionKey($request2);

    // Wait for the operation to complete.
    $operation->pollUntilComplete();
    if ($operation->operationSucceeded()) {
        printf('Instance %s started successfully' . PHP_EOL, $instanceName);
    } else {
        $error = $operation->getError();
        printf('Starting instance failed: %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 start_instance_with_encryption_key(
    project_id: str, zone: str, instance_name: str, key: bytes
) -> None:
    """
    Starts a stopped Google Compute Engine instance (with encrypted 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 your want to start.
        key: bytes object representing a raw base64 encoded key to your machines boot disk.
            For more information about disk encryption see:
            https://cloud.google.com/compute/docs/disks/customer-supplied-encryption#specifications
    """
    instance_client = compute_v1.InstancesClient()

    instance_data = instance_client.get(
        project=project_id, zone=zone, instance=instance_name
    )

    # Prepare the information about disk encryption
    disk_data = compute_v1.CustomerEncryptionKeyProtectedDisk()
    disk_data.source = instance_data.disks[0].source
    disk_data.disk_encryption_key = compute_v1.CustomerEncryptionKey()
    # Use raw_key to send over the key to unlock the disk
    # To use a key stored in KMS, you need to provide `kms_key_name` and `kms_key_service_account`
    disk_data.disk_encryption_key.raw_key = key
    enc_data = compute_v1.InstancesStartWithEncryptionKeyRequest()
    enc_data.disks = [disk_data]

    operation = instance_client.start_with_encryption_key(
        project=project_id,
        zone=zone,
        instance=instance_name,
        instances_start_with_encryption_key_request_resource=enc_data,
    )

    wait_for_extended_operation(operation, "instance start (with encrypted disk)")

REST

Para reiniciar uma instância de computação que usa discos criptografados, faça uma solicitação POST para o método instances.startWithEncryptionKey:

POST  https://compute.s3nsapis.fr/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_NAME/startWithEncryptionKey

{
  "disks": [
    {
      "source": "DISK_URL",
      "diskEncryptionKey": {
        "ENCRYPTION_TYPE": "ENCRYPTION_KEY"
      }
    }
  ]
}

Substitua:

  • PROJECT_ID: o ID do projeto em que a instância de computação está.

  • ZONE: a zona em que a instância de computação está.

  • INSTANCE_NAME: o nome da instância de computação.

  • DISK_URL: o URL do recurso correspondente ao nome completo do recurso do disco anexado, criptografado com uma chave de criptografia fornecida pelo cliente

  • ENCRYPTION_TYPE: o tipo de criptografia de disco que você está usando, que pode ser uma das seguintes opções: rawKey, kmsKeyName ou rsaEncryptedKey. Se você usar o tipo rsaEncryptedKey, faça uma solicitação POST ao método beta.instances.startWithEncryptionKey.

  • ENCRYPTION_KEY: a chave de criptografia usada para criptografar os discos permanentes anexados à instância de computação. As chaves rawKey ou rsaEncryptedKey precisam ser codificadas em base64. Além disso, para preparar uma rsaEncryptedKey Chave RSA, consulte Encapsulamento de chaves por RSA.

A seguir