Crie imagens personalizadas


Você pode criar imagens personalizadas de discos de origem, imagens, snapshots ou imagens armazenadas no Cloud Storage e usar essas imagens para criar instâncias de máquinas virtuais (VM). As imagens personalizadas são ideais para situações em que você criou e modificou um disco de inicialização persistente ou uma imagem específica para um determinado estado e precisa salvar esse estado para criar VMs.

Como alternativa, você pode usar a ferramenta de importação de disco virtual para importar imagens de disco de inicialização dos seus sistemas existentes para o Compute Engine e adicioná-las à sua lista de imagens personalizadas.

Antes de começar

Crie uma imagem personalizada

Esta seção descreve como criar uma imagem personalizada em uma VM Linux. Para obter informações sobre como criar uma imagem do Windows, consulte Criando uma imagem do Windows .

Selecione um local de armazenamento de imagens

Ao criar uma imagem personalizada, você pode especificar o local do Cloud Storage da imagem, excluindo locais birregionais. Ao especificar o local de armazenamento de imagens, você pode atender aos seus requisitos regulatórios e de conformidade para localidade de dados, bem como às suas necessidades de alta disponibilidade, garantindo redundância entre regiões. Para criar, modificar e excluir imagens armazenadas no Cloud Storage, você precisa ter roles/compute.storageAdmin .

O recurso de local de armazenamento é opcional. Se você não selecionar um local, o Compute Engine armazenará sua imagem na multirregião mais próxima da origem da imagem. Por exemplo, quando você cria uma imagem de um disco de origem localizado em us-central1 e não especifica um local para a imagem personalizada, o Compute Engine armazena a imagem na multirregião us .

Se a imagem não estiver disponível em uma região onde você está criando uma VM, o Compute Engine armazenará a imagem em cache nessa região na primeira vez que você criar uma VM.

Para ver o local onde uma imagem está armazenada, use o comando images describe do gcloud compute :

gcloud compute images describe IMAGE_NAME \
    --project=PROJECT_ID

Substitua o seguinte:

  • IMAGE_NAME : o nome da sua imagem.

  • PROJECT_ID : o ID do projeto ao qual a imagem pertence.

Todas as suas imagens existentes antes do lançamento deste recurso permanecem onde estão, a única mudança é que você pode visualizar a localização de todas as suas imagens. Se você tiver uma imagem existente que deseja mover, deverá recriá-la no novo local.

Prepare sua VM para uma imagem

Você pode criar uma imagem de um disco mesmo quando ele estiver conectado a uma VM em execução. No entanto, sua imagem será mais confiável se você colocar a VM em um estado que seja mais fácil de ser capturada pela imagem. Esta seção descreve como preparar seu disco de inicialização para a imagem.

Minimize a gravação de dados no disco permanente

Use um dos seguintes processos para reduzir as gravações em disco:

  • Pare a VM para que ela possa ser desligada e parar de gravar dados no disco permanente.

  • Se não for possível parar a VM antes de criar a imagem, minimize a quantidade de gravações no disco e sincronize o sistema de arquivos. Para minimizar a gravação no disco permanente, siga estas etapas:

    1. Pause aplicativos ou processos do sistema operacional que gravam dados nesse disco permanente.
    2. Execute uma liberação de aplicativo no disco, se necessário. Por exemplo, o MySQL possui uma instrução FLUSH . Outros aplicativos podem ter processos semelhantes.
    3. Impeça que seus aplicativos gravem no disco permanente.
    4. Execute sudo sync .

Desative a opção de exclusão automática do disco

Por padrão, a opção de exclusão automática está habilitada nos discos de inicialização. Antes de criar uma imagem de um disco, desative a exclusão automática para garantir que o disco não seja excluído automaticamente quando você excluir a VM.

Use um dos métodos a seguir para desativar a exclusão automática do disco.

Console

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

    Acesse a página de instâncias de VM

  2. Clique no nome da VM que você está usando como origem para criar uma imagem.

    A página de detalhes da instância de VM é exibida.

  3. Clique em Editar .

  4. Na seção Disco de inicialização , para Regra de exclusão , certifique-se de que a opção Manter disco esteja selecionada.

  5. Clique em Salvar .

gcloud

Na CLI do Google Cloud, use o comando gcloud compute instances set-disk-auto-delete para desativar a opção de exclusão automática do disco.

gcloud compute instances set-disk-auto-delete VM_NAME \
    --no-auto-delete \
    --disk=SOURCE_DISK

Substitua o seguinte:

  • VM_NAME : o nome da sua instância de VM.
  • SOURCE_DISK : o nome do disco a partir do qual você deseja criar a imagem.

Ir

Go

Antes de testar este exemplo, siga as instruções de configuração Go no guia de início rápido do Compute Engine usando bibliotecas de cliente . Para mais informações, consulte a documentação de referência da API Compute Engine Go .

Para autenticar no Compute Engine, configure as credenciais padrão do aplicativo. Para obter mais informações, consulte Configurar autenticação para um ambiente de desenvolvimento local .

import (
	"context"
	"fmt"
	"io"

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

// setDiskAutodelete sets the autodelete flag of a disk to given value.
func setDiskAutoDelete(
	w io.Writer,
	projectID, zone, instanceName, diskName string, autoDelete bool,
) error {
	// projectID := "your_project_id"
	// zone := "us-west3-b"
	// instanceName := "your_instance_name"
	// diskName := "your_disk_name"
	// autoDelete := true

	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)
	}

	diskExists := false

	for _, disk := range instance.GetDisks() {
		if disk.GetDeviceName() == diskName {
			diskExists = true
			break
		}
	}

	if !diskExists {
		return fmt.Errorf(
			"instance %s doesn't have a disk named %s attached",
			instanceName,
			diskName,
		)
	}

	req := &computepb.SetDiskAutoDeleteInstanceRequest{
		Project:    projectID,
		Zone:       zone,
		Instance:   instanceName,
		DeviceName: diskName,
		AutoDelete: autoDelete,
	}

	op, err := instancesClient.SetDiskAutoDelete(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to set disk autodelete field: %w", err)
	}

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

	fmt.Fprintf(w, "disk autoDelete field updated.\n")

	return nil
}

Java

Java

Antes de testar este exemplo, siga as instruções de configuração Java no guia de início rápido do Compute Engine usando bibliotecas de cliente . Para mais informações, consulte a documentação de referência da API Java do Compute Engine .

Para autenticar no Compute Engine, configure as credenciais padrão do aplicativo. Para obter mais informações, consulte Configurar autenticação para um ambiente de desenvolvimento local .


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

public class SetDiskAutodelete {

  public static void main(String[] args)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // TODO(developer): Replace these variables before running the sample.

    // Project ID or project number of the Cloud project you want to use.
    String projectId = "YOUR_PROJECT_ID";

    // The zone of the disk that you want to modify.
    String zone = "europe-central2-b";

    // Name of the instance the disk is attached to.
    String instanceName = "YOUR_INSTANCE_NAME";

    // The name of the disk for which you want to modify the autodelete flag.
    String diskName = "YOUR_DISK_NAME";

    // The new value of the autodelete flag.
    boolean autoDelete = true;

    setDiskAutodelete(projectId, zone, instanceName, diskName, autoDelete);
  }

  // Sets the autodelete flag of a disk to given value.
  public static void setDiskAutodelete(String projectId, String zone, String instanceName,
      String diskName, boolean autoDelete)
      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()) {

      // Retrieve the instance given by the instanceName.
      Instance instance = instancesClient.get(projectId, zone, instanceName);

      // Check if the instance contains a disk that matches the given diskName.
      boolean diskNameMatch = instance.getDisksList()
          .stream()
          .anyMatch(disk -> disk.getDeviceName().equals(diskName));

      if (!diskNameMatch) {
        throw new Error(
            String.format("Instance %s doesn't have a disk named %s attached", instanceName,
                diskName));
      }

      // Create the request object.
      SetDiskAutoDeleteInstanceRequest request = SetDiskAutoDeleteInstanceRequest.newBuilder()
          .setProject(projectId)
          .setZone(zone)
          .setInstance(instanceName)
          .setDeviceName(diskName)
          // Update the autodelete property.
          .setAutoDelete(autoDelete)
          .build();

      // Wait for the update instance operation to complete.
      Operation response = instancesClient.setDiskAutoDeleteAsync(request)
          .get(3, TimeUnit.MINUTES);

      if (response.hasError()) {
        System.out.println("Failed to update Disk autodelete field!" + response);
        return;
      }
      System.out.println(
          "Disk autodelete field updated. Operation Status: " + response.getStatus());
    }
  }
}

Node.js

Node.js

Antes de testar este exemplo, siga as instruções de configuração Node.js no guia de início rápido do Compute Engine usando bibliotecas de cliente . Para mais informações, consulte a documentação de referência da API Node.js do Compute Engine .

Para autenticar no Compute Engine, configure as credenciais padrão do aplicativo. Para obter mais informações, consulte Configurar autenticação para um ambiente de desenvolvimento local .

/**
 * 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 diskName = 'YOUR_DISK_NAME';
// const autoDelete = true;

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

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

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

  if (!instance.disks.some(disk => disk.deviceName === diskName)) {
    throw new Error(
      `Instance ${instanceName} doesn't have a disk named ${diskName} attached.`
    );
  }

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

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

  console.log('Disk autoDelete field updated.');
}

setDiskAutodelete();

Pitão

Python

Antes de testar este exemplo, siga as instruções de configuração Python no guia de início rápido do Compute Engine usando bibliotecas de cliente . Para mais informações, consulte a documentação de referência da API Python do Compute Engine .

Para autenticar no Compute Engine, configure as credenciais padrão do aplicativo. Para obter mais informações, consulte Configurar autenticação para um ambiente de desenvolvimento local .

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 set_disk_autodelete(
    project_id: str, zone: str, instance_name: str, disk_name: str, autodelete: bool
) -> None:
    """
    Set the autodelete flag of a disk to given value.

    Args:
        project_id: project ID or project number of the Cloud project you want to use.
        zone: name of the zone in which is the disk you want to modify.
        instance_name: name of the instance the disk is attached to.
        disk_name: the name of the disk which flag you want to modify.
        autodelete: the new value of the autodelete flag.
    """
    instance_client = compute_v1.InstancesClient()
    instance = instance_client.get(
        project=project_id, zone=zone, instance=instance_name
    )

    for disk in instance.disks:
        if disk.device_name == disk_name:
            break
    else:
        raise RuntimeError(
            f"Instance {instance_name} doesn't have a disk named {disk_name} attached."
        )

    disk.auto_delete = autodelete

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

    wait_for_extended_operation(operation, "disk update")

DESCANSAR

Para definir a opção de exclusão automática de um disco, faça uma solicitação POST para o método instances.setDiskAutoDelete .

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME/setDiskAutoDelete?autoDelete=false&deviceName=SOURCE_DISK

Substitua o seguinte:

  • PROJECT_ID : o ID do projeto ao qual pertence a VM de origem.
  • ZONE : a zona onde a VM de origem está localizada.
  • VM_NAME : o nome da VM de origem.
  • SOURCE_DISK : o nome do dispositivo do disco a partir do qual você deseja criar a imagem.

Depois de preparar a VM, crie a imagem .

Crie a imagem

Você pode criar imagens de disco das seguintes fontes:

  • Um disco permanente, mesmo quando esse disco está anexado a uma VM
  • Um instantâneo de um disco permanente
  • Outra imagem em seu projeto
  • Uma imagem compartilhada de outro projeto
  • Uma imagem RAW compactada no Cloud Storage

Você pode criar uma imagem de disco a cada 10 minutos. Se quiser emitir uma série de solicitações para criar uma imagem de disco, você poderá emitir no máximo 6 solicitações em 60 minutos. Para obter mais informações, consulte Limites de frequência de instantâneo .

Console

  1. No console do Google Cloud, acesse a página Criar uma imagem .

    Vá para Criar uma imagem

  2. Especifique o nome da sua imagem.

  3. Especifique a fonte da qual você deseja criar uma imagem. Pode ser um disco permanente, um snapshot, outra imagem ou um arquivo disk.raw no Cloud Storage.

  4. Se você estiver criando uma imagem de um disco anexado a uma VM em execução, marque Manter a instância em execução para confirmar que deseja criar a imagem enquanto a VM estiver em execução. Você pode preparar sua VM antes de criar a imagem.

  5. Na lista suspensa Com base no local do disco de origem (padrão) , especifique o local para armazenar a imagem. Por exemplo, especifique us para armazenar a imagem na multirregião us ou us-central1 para armazená-la na região us-central1 . Se você não fizer uma seleção, o Compute Engine armazenará a imagem na multirregião mais próxima do local de origem da imagem.

  6. Opcional: especifique as propriedades da sua imagem.

    • Família : a família de imagens à qual esta nova imagem pertence.
    • Descrição : uma descrição para sua imagem personalizada.
    • Rótulo : um rótulo para agrupar recursos.
  7. Especifique a chave de criptografia. Você pode escolher entre um Google-owned and Google-managed encryption key, uma chave do Cloud Key Management Service (Cloud KMS) ou uma chave de criptografia fornecida pelo cliente (CSEK) . Se nenhuma chave de criptografia for especificada, as imagens serão criptografadas usando um Google-owned and Google-managed encryption key.

  8. Clique em Criar para criar a imagem.

gcloud

Na CLI do Google Cloud, use o comando gcloud compute images create para criar uma imagem personalizada.

Crie uma imagem de um disco de origem:

O sinalizador --force é um sinalizador opcional que permite criar a imagem a partir de uma instância em execução. Por padrão, não é possível criar imagens de instâncias em execução. Especifique esse sinalizador somente se tiver certeza de que deseja criar a imagem enquanto a instância estiver em execução.

gcloud compute images create IMAGE_NAME \
    --source-disk=SOURCE_DISK \
    --source-disk-zone=ZONE \
    [--family=IMAGE_FAMILY] \
    [--storage-location=LOCATION] \
    [--force]

Substitua o seguinte:

  • IMAGE_NAME : um nome para a nova imagem
  • SOURCE_DISK : o disco a partir do qual você deseja criar a imagem
  • ZONE : a zona onde o disco está localizado
  • IMAGE_FAMILY : Opcional: um sinalizador que especifica a qual família de imagens esta imagem pertence
  • LOCATION : Opcional: um sinalizador que permite designar a região ou multirregião onde sua imagem está armazenada. Por exemplo, especifique us para armazenar a imagem na multirregião us ou us-central1 para armazená-la na região us-central1 . Se você não fizer uma seleção, o Compute Engine armazenará a imagem na multirregião mais próxima do local de origem da imagem.

Crie uma imagem a partir de uma imagem de origem:

gcloud compute images create IMAGE_NAME \
  --source-image=SOURCE_IMAGE \
  [--source-image-project=IMAGE_PROJECT] \
  [--family=IMAGE_FAMILY] \
  [--storage-location=LOCATION]

Substitua o seguinte:

  • IMAGE_NAME : um nome para a nova imagem.
  • SOURCE_IMAGE : a imagem a partir da qual você deseja criar a nova imagem.
  • IMAGE_PROJECT : Opcional: o projeto onde a imagem de origem está localizada. Use este parâmetro se desejar copiar uma imagem de outro projeto.
  • IMAGE_FAMILY : Opcional: a família de imagens à qual esta nova imagem pertence.
  • LOCATION : Opcional: permite designar a região ou multirregião onde sua imagem será armazenada. Por exemplo, especifique us para armazenar a imagem na multirregião us ou us-central1 para armazená-la na região us-central1 . Se você não fizer uma seleção, o Compute Engine armazenará a imagem na multirregião mais próxima do local de origem da imagem.

Crie uma imagem a partir de um instantâneo:

gcloud compute images create IMAGE_NAME \
    --source-snapshot=SOURCE_SNAPSHOT \
    [--storage-location=LOCATION]

Substitua o seguinte:

  • IMAGE_NAME : um nome para a nova imagem
  • SOURCE_SNAPSHOT : o instantâneo a partir do qual você deseja criar a imagem
  • LOCATION : Opcional: um sinalizador que permite designar a região ou multirregião onde sua imagem está armazenada. Por exemplo, especifique us para armazenar a imagem na multirregião us ou us-central1 para armazená-la na região us-central1 . Se você não fizer uma seleção, o Compute Engine armazenará a imagem na multirregião mais próxima do local de origem da imagem.

Ver um local de imagem:

Use o comando gcloud compute images describe para visualizar o local de uma imagem.

gcloud compute images describe IMAGE_NAME

Substitua IMAGE_NAME pelo nome da imagem que você deseja revisar.

Ir

Go

Antes de testar este exemplo, siga as instruções de configuração Go no guia de início rápido do Compute Engine usando bibliotecas de cliente . Para mais informações, consulte a documentação de referência da API Compute Engine Go .

Para autenticar no Compute Engine, configure as credenciais padrão do aplicativo. Para obter mais informações, consulte Configurar autenticação para um ambiente de desenvolvimento local .

import (
	"context"
	"fmt"
	"io"

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

// Creates a disk image from an existing disk
func createImageFromDisk(
	w io.Writer,
	projectID, zone, sourceDiskName, imageName string,
	storageLocations []string,
	forceCreate bool,
) error {
	// projectID := "your_project_id"
	// zone := "us-central1-a"
	// sourceDiskName := "your_disk_name"
	// imageName := "my_image"
	// // If storageLocations empty, automatically selects the closest one to the source
	// storageLocations = []string{}
	// // If forceCreate is set to `true`, proceeds even if the disk is attached to
	// // a running instance. This may compromise integrity of the image!
	// forceCreate = false

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

	// Get the source disk
	source_req := &computepb.GetDiskRequest{
		Disk:    sourceDiskName,
		Project: projectID,
		Zone:    zone,
	}

	disk, err := disksClient.Get(ctx, source_req)
	if err != nil {
		return fmt.Errorf("unable to get source disk: %w", err)
	}

	// Create the image
	req := computepb.InsertImageRequest{
		ForceCreate: &forceCreate,
		ImageResource: &computepb.Image{
			Name:             &imageName,
			SourceDisk:       disk.SelfLink,
			StorageLocations: storageLocations,
		},
		Project: projectID,
	}

	op, err := imagesClient.Insert(ctx, &req)

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

	fmt.Fprintf(w, "Disk image %s created\n", imageName)

	return nil
}

Java

Java

Antes de testar este exemplo, siga as instruções de configuração Java no guia de início rápido do Compute Engine usando bibliotecas de cliente . Para mais informações, consulte a documentação de referência da API Java do Compute Engine .

Para autenticar no Compute Engine, configure as credenciais padrão do aplicativo. Para obter mais informações, consulte Configurar autenticação para um ambiente de desenvolvimento local .


import com.google.cloud.compute.v1.Disk;
import com.google.cloud.compute.v1.DisksClient;
import com.google.cloud.compute.v1.Image;
import com.google.cloud.compute.v1.ImagesClient;
import com.google.cloud.compute.v1.InsertImageRequest;
import com.google.cloud.compute.v1.Instance;
import com.google.cloud.compute.v1.InstancesClient;
import com.google.cloud.compute.v1.Operation;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class CreateImage {

  public static void main(String[] args)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // TODO(developer): Replace these variables before running the sample.

    // Project ID or project number of the Cloud project you use.
    String project = "your-project-id";
    // Zone of the disk you copy from.
    String zone = "europe-central2-b";
    // Name of the source disk you copy from.
    String sourceDiskName = "source-disk-name";
    // Name of the image you want to create.
    String imageName = "your-image-name";
    // Storage location for the image. If the value is undefined,
    // function will store the image in the multi-region closest to your image's source location.
    String storageLocation = "eu";
    // Create the image even if the source disk is attached to a running instance.
    boolean forceCreate = false;

    createImage(project, zone, sourceDiskName, imageName, storageLocation, forceCreate);
  }

  // Creates a new disk image from the specified source disk.
  public static void createImage(String project, String zone, String sourceDiskName,
      String imageName, String storageLocation, boolean forceCreate)
      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 `client.close()` method on the client to safely
    // clean up any remaining background resources.
    try (ImagesClient imagesClient = ImagesClient.create();
        InstancesClient instancesClient = InstancesClient.create();
        DisksClient disksClient = DisksClient.create()) {

      Disk disk = disksClient.get(project, zone, sourceDiskName);

      // Getting instances where source disk is attached.
      for (String fullInstanceName : disk.getUsersList()) {
        Map<String, String> instanceInfo = parseInstanceName(fullInstanceName);
        Instance instance = instancesClient.get(instanceInfo.get("instanceProjectId"),
            instanceInfo.get("instanceZone"), instanceInfo.get("instanceName"));

        // Сheck whether the instances are stopped.
        if (!Arrays.asList("TERMINATED", "STOPPED").contains(instance.getStatus())
            && !forceCreate) {
          throw new IllegalStateException(
              String.format(
                  "Instance %s should be stopped. For Windows instances please stop the instance "
                      + "using GCESysprep command. For Linux instances just shut it down normally."
                      + " You can suppress this error and create an image of the disk by setting "
                      + "'forceCreate' parameter to true (not recommended). "
                      + "More information here: "
                      + "* https://cloud.google.com/compute/docs/instances/windows/creating-windows-os-image#api"
                      + "* https://cloud.google.com/compute/docs/images/create-delete-deprecate-private-images#prepare_instance_for_image",
                  instanceInfo.get("instanceName")));
        }
      }

      if (forceCreate) {
        System.out.println(
            "Warning: forceCreate option compromise the integrity of your image. "
                + "Stop the instance before you create the image if possible.");
      }

      // Create Image.
      Image image = Image.newBuilder()
          .setName(imageName)
          .setSourceDisk(String.format("/zones/%s/disks/%s", zone, sourceDiskName))
          .addStorageLocations(storageLocation.isEmpty() ? "" : storageLocation)
          .build();

      InsertImageRequest insertImageRequest = InsertImageRequest.newBuilder()
          .setProject(project)
          .setForceCreate(forceCreate)
          .setImageResource(image)
          .build();

      Operation response = imagesClient.insertAsync(insertImageRequest).get(5, TimeUnit.MINUTES);

      if (response.hasError()) {
        System.out.println("Image creation failed ! ! " + response);
        return;
      }

      System.out.println("Image created.");
    }
  }


  public static Map<String, String> parseInstanceName(String name) {
    String[] parsedName = name.split("/");
    int splitLength = parsedName.length;

    if (splitLength < 5) {
      throw new IllegalArgumentException(
          "Provide correct instance name in the following format: "
              + "https://www.googleapis.com/compute/v1/projects/PROJECT/zones/ZONE/instances/INSTANCE_NAME");
    }

    return new HashMap<>() {
      {
        put("instanceName", parsedName[splitLength - 1]);
        put("instanceZone", parsedName[splitLength - 3]);
        put("instanceProjectId", parsedName[splitLength - 5]);
      }
    };
  }

}

Pitão

Python

Antes de testar este exemplo, siga as instruções de configuração Python no guia de início rápido do Compute Engine usando bibliotecas de cliente . Para mais informações, consulte a documentação de referência da API Python do Compute Engine .

Para autenticar no Compute Engine, configure as credenciais padrão do aplicativo. Para obter mais informações, consulte Configurar autenticação para um ambiente de desenvolvimento local .

from __future__ import annotations

import sys
from typing import Any
import warnings

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


STOPPED_MACHINE_STATUS = (
    compute_v1.Instance.Status.TERMINATED.name,
    compute_v1.Instance.Status.STOPPED.name,
)


def create_image_from_disk(
    project_id: str,
    zone: str,
    source_disk_name: str,
    image_name: str,
    storage_location: str | None = None,
    force_create: bool = False,
) -> compute_v1.Image:
    """
    Creates a new disk image.

    Args:
        project_id: project ID or project number of the Cloud project you use.
        zone: zone of the disk you copy from.
        source_disk_name: name of the source disk you copy from.
        image_name: name of the image you want to create.
        storage_location: storage location for the image. If the value is undefined,
            function will store the image in the multi-region closest to your image's
            source location.
        force_create: create the image even if the source disk is attached to a
            running instance.

    Returns:
        An Image object.
    """
    image_client = compute_v1.ImagesClient()
    disk_client = compute_v1.DisksClient()
    instance_client = compute_v1.InstancesClient()

    # Get source disk
    disk = disk_client.get(project=project_id, zone=zone, disk=source_disk_name)

    for disk_user in disk.users:
        instance_name = disk_user.split("/")[-1]
        instance = instance_client.get(
            project=project_id, zone=zone, instance=instance_name
        )
        if instance.status in STOPPED_MACHINE_STATUS:
            continue
        if not force_create:
            raise RuntimeError(
                f"Instance {disk_user} should be stopped. For Windows instances please "
                f"stop the instance using `GCESysprep` command. For Linux instances just "
                f"shut it down normally. You can supress this error and create an image of"
                f"the disk by setting `force_create` parameter to true (not recommended). \n"
                f"More information here: \n"
                f" * https://cloud.google.com/compute/docs/instances/windows/creating-windows-os-image#api \n"
                f" * https://cloud.google.com/compute/docs/images/create-delete-deprecate-private-images#prepare_instance_for_image"
            )
        else:
            warnings.warn(
                f"Warning: The `force_create` option may compromise the integrity of your image. "
                f"Stop the {disk_user} instance before you create the image if possible."
            )

    # Create image
    image = compute_v1.Image()
    image.source_disk = disk.self_link
    image.name = image_name
    if storage_location:
        image.storage_locations = [storage_location]

    operation = image_client.insert(project=project_id, image_resource=image)

    wait_for_extended_operation(operation, "image creation from disk")

    return image_client.get(project=project_id, image=image_name)

DESCANSAR

Faça uma solicitação POST para o images().insert , uma URL no corpo da solicitação que aponta para o objeto de origem a partir do qual você deseja criar a imagem. Especifique URLs para seus recursos usando seu próprio ID de projeto e nomes de recursos.

Crie uma imagem de um disco permanente:

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/images

{
  "name": "IMAGE_NAME",
  "sourceDisk": "/zones/ZONE/disks/SOURCE_DISK",
  ("storageLocations": "LOCATION",)
  ("forceCreate": "TRUE")
}

Substitua o seguinte:

  • PROJECT_ID : o ID do projeto ao qual a imagem pertence.
  • IMAGE_NAME : um nome para a nova imagem que você deseja criar.
  • ZONE : a zona onde o disco de origem está localizado.
  • SOURCE_DISK : o disco a partir do qual você deseja criar a imagem.
  • LOCATION : Opcional: o local de armazenamento da sua imagem. Por exemplo, especifique us para armazenar a imagem na multirregião us ou us-central1 para armazená-la na região us-central1 . Se você não fizer uma seleção, o Compute Engine armazenará a imagem na multirregião mais próxima do local de origem da imagem.

O parâmetro opcional forceCreate permite criar a imagem a partir de uma VM em execução. Especifique TRUE somente se tiver certeza de que deseja criar a imagem a partir de uma VM em execução. A configuração padrão forceCreate é FALSE .

Crie uma imagem a partir de outra imagem:

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/images

{
  "name": "IMAGE_NAME",
  "sourceImage": "/global/images/SOURCE_IMAGE",
  ("storageLocations": "LOCATION")
}

Substitua o seguinte:

  • PROJECT_ID : o projeto ao qual a imagem pertence.
  • IMAGE_NAME : um nome para a nova imagem que você deseja criar.
  • SOURCE_IMAGE : a imagem a partir da qual você deseja criar a imagem.
  • LOCATION : Opcional: o local de armazenamento da sua imagem. Por exemplo, especifique us para armazenar a imagem na multirregião us ou us-central1 para armazená-la na região us-central1 . Se você não fizer uma seleção, o Compute Engine armazenará a imagem na multirregião mais próxima do local de origem da imagem.

Crie uma imagem a partir de um instantâneo:

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/images
{
  "name": "IMAGE_NAME",
  "sourceSnapshot": "(/SOURCE_PROJECT_ID)/global/snapshots/SOURCE_SNAPSHOT",
  ("storageLocations": "LOCATION")
}

Substitua o seguinte:

  • PROJECT_ID : o projeto ao qual a imagem pertence.
  • IMAGE_NAME : um nome para a nova imagem que você deseja criar.
  • SOURCE_PROJECT_ID : Opcional: o projeto no qual a captura instantânea está localizada. Você deve ter permissão para acessar o recurso de captura instantânea nesse projeto.
  • SOURCE_SNAPSHOT : o instantâneo a partir do qual você deseja criar a imagem.
  • LOCATION : Opcional: o local de armazenamento da sua imagem. Por exemplo, especifique us para armazenar a imagem na multirregião us ou us-central1 para armazená-la na região us-central1 . Se você não fizer uma seleção, o Compute Engine armazenará a imagem na multirregião mais próxima do local de origem da imagem.

Para obter mais informações sobre como adicionar imagens, consulte a referência de imagens .

Compartilhe a imagem

Depois de criar uma imagem personalizada, você pode compartilhá-la entre projetos . Se você permitir que usuários de outro projeto usem suas imagens personalizadas, eles poderão acessar essas imagens especificando o projeto de imagem na solicitação.

Habilitar recursos do sistema operacional convidado

Use recursos do sistema operacional (SO) convidado para configurar as seguintes opções de rede, segurança, armazenamento e SO em imagens personalizadas. Imagens personalizadas com esses recursos configurados são usadas como discos de inicialização.

gcloud

Use o comando gcloud compute images create com a sinalização --guest-os-features para criar uma nova imagem personalizada a partir de uma imagem personalizada existente.

gcloud compute images create IMAGE_NAME \
    --source-image=SOURCE_IMAGE \
    [--source-image-project=IMAGE_PROJECT] \
    --guest-os-features="FEATURES,..." \
    [--storage-location=LOCATION]

Substitua o seguinte:

  • IMAGE_NAME : o nome da nova imagem
  • SOURCE_IMAGE : uma imagem para basear a nova imagem
  • IMAGE_PROJECT : opcional: o projeto que contém a imagem de origem

    Use este parâmetro para copiar uma imagem de outro projeto.

  • FEATURES : tags de sistema operacional convidado para ativar recursos para VMs criadas a partir de imagens

    Para adicionar vários valores, use vírgulas para separar os valores. Defina um ou mais dos seguintes valores:

    • VIRTIO_SCSI_MULTIQUEUE . Use em dispositivos SSD locais como alternativa ao NVMe. Para obter mais informações sobre imagens que suportam SCSI, consulte Escolhendo uma interface.

      Para imagens do Linux, você pode ativar o SCSI multifilas em dispositivos SSD locais em imagens com versões de kernel 3.17 ou posteriores. Para imagens do Windows, você pode ativar o SCSI de várias filas em dispositivos SSD locais em imagens com o driver do Compute Engine para Windows versão 1.2 .

    • WINDOWS . Marque imagens de inicialização personalizadas do Windows Server como imagens do Windows.
    • MULTI_IP_SUBNET . Configure interfaces com uma máscara de rede diferente de /32 . Para obter mais informações sobre múltiplas interfaces de rede e como elas funcionam, consulte Visão geral e exemplos de múltiplas interfaces de rede .
    • UEFI_COMPATIBLE . Inicialize com firmware UEFI e os seguintes recursos de VM protegida :
    • GVNIC . Suporta larguras de banda de rede mais altas, de até 50 Gbps a velocidades de 100 Gbps . Para obter mais informações, consulte Usando o Google Virtual NIC .
    • IDPF . Suporta interfaces de rede Intel Infrastructure Data Path Function (IDPF).
    • SEV_CAPABLE ou SEV_SNP_CAPABLE . Use essas tags se quiser usar sua imagem em uma instância de VM confidencial com suporte para AMD Secure Encrypted Virtualization (SEV) ou AMD Secure Encrypted Virtualization-Secure Nested Paging (SEV-SNP). Para verificar se o seu kernel suporta AMD SEV ou AMD SEV-SNP, consulte Detalhes do kernel Linux .
    • SEV_LIVE_MIGRATABLE_V2 . Use esta tag se quiser usar sua imagem em uma instância de VM confidencial que oferece suporte à migração ao vivo no AMD SEV. Para verificar se o seu kernel suporta migração ao vivo, consulte Detalhes do kernel Linux .
    • TDX_CAPABLE . Use esta tag se quiser usar sua imagem em uma instância de VM confidencial com suporte para Intel Trust Domain Extensions (TDX). Para verificar se o seu kernel suporta Intel TDX, consulte Detalhes do kernel Linux .
    • SUSPEND_RESUME_COMPATIBLE . Suporte para suspensão e retomada em uma VM. Para obter mais informações, consulte Compatibilidade do sistema operacional .
  • LOCATION : Opcional: região ou multirregião na qual armazenar a imagem

    Por exemplo, especifique us para armazenar a imagem na multirregião us ou us-central1 para armazená-la na região us-central1 . Se você não fizer uma seleção, o Compute Engine armazenará a imagem na multirregião mais próxima do local de origem da imagem.

DESCANSAR

Use o método images().insert com o sinalizador guestOsFeatures para criar uma nova imagem personalizada a partir de uma imagem personalizada existente.


POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/images

{
 "name": "IMAGE_NAME",
 "sourceImage": "(projects/IMAGE_PROJECT)/global/images/SOURCE_IMAGE",
 ("storageLocations": "LOCATION",)
 "guestOsFeatures": [
  {
   "type": "FEATURES"
  }
 ]
}

Substitua o seguinte:

  • PROJECT_ID : o ID do projeto no qual será criada a nova imagem
  • IMAGE_NAME : um nome para a nova imagem
  • IMAGE_PROJECT : opcional: o projeto que contém a imagem de origem

    Use este parâmetro para copiar uma imagem de outro projeto.

  • SOURCE_IMAGE : a imagem na qual basear a nova imagem

  • LOCATION : Opcional: uma região ou multirregião na qual armazenar a imagem

    Por exemplo, especifique us para armazenar a imagem na multirregião us ou us-central1 para armazená-la na região us-central1 . Se você não fizer uma seleção, o Compute Engine armazenará a imagem na multirregião mais próxima do local de origem da imagem.

  • FEATURES : tags de sistema operacional convidado para ativar recursos para VMs criadas a partir de imagens

    Para adicionar vários valores, use vírgulas para separar os valores. Defina um ou mais dos seguintes valores:

    • VIRTIO_SCSI_MULTIQUEUE . Use em dispositivos SSD locais como alternativa ao NVMe. Para obter mais informações sobre imagens que suportam SCSI, consulte Escolhendo uma interface.

      Para imagens do Linux, você pode ativar o SCSI multifilas em dispositivos SSD locais em imagens com versões de kernel 3.17 ou posteriores. Para imagens do Windows, você pode ativar o SCSI de várias filas em dispositivos SSD locais em imagens com o driver do Compute Engine para Windows versão 1.2 .

    • WINDOWS . Marque imagens de inicialização personalizadas do Windows Server como imagens do Windows.
    • MULTI_IP_SUBNET . Configure interfaces com uma máscara de rede diferente de /32 . Para obter mais informações sobre múltiplas interfaces de rede e como elas funcionam, consulte Visão geral e exemplos de múltiplas interfaces de rede .
    • UEFI_COMPATIBLE . Inicialize com firmware UEFI e os seguintes recursos de VM protegida :
    • GVNIC . Suporta larguras de banda de rede mais altas, de até 50 Gbps a velocidades de 100 Gbps . Para obter mais informações, consulte Usando o Google Virtual NIC .
    • IDPF . Suporta interfaces de rede Intel Infrastructure Data Path Function (IDPF).
    • SEV_CAPABLE ou SEV_SNP_CAPABLE . Use essas tags se quiser usar sua imagem em uma instância de VM confidencial com suporte para AMD Secure Encrypted Virtualization (SEV) ou AMD Secure Encrypted Virtualization-Secure Nested Paging (SEV-SNP). Para verificar se o seu kernel suporta AMD SEV ou AMD SEV-SNP, consulte Detalhes do kernel Linux .
    • SEV_LIVE_MIGRATABLE_V2 . Use esta tag se quiser usar sua imagem em uma instância de VM confidencial que oferece suporte à migração ao vivo no AMD SEV. Para verificar se o seu kernel suporta migração ao vivo, consulte Detalhes do kernel Linux .
    • TDX_CAPABLE . Use esta tag se quiser usar sua imagem em uma instância de VM confidencial com suporte para Intel Trust Domain Extensions (TDX). Para verificar se o seu kernel suporta Intel TDX, consulte Detalhes do kernel Linux .
    • SUSPEND_RESUME_COMPATIBLE . Suporte para suspensão e retomada em uma VM. Para obter mais informações, consulte Compatibilidade do sistema operacional .

Evite informações confidenciais em variáveis ​​UEFI

Variáveis ​​de interface de firmware extensível unificada (UEFI) são variáveis ​​de pares de valores-chave usadas pelo firmware UEFI durante o tempo de inicialização para inicializar o sistema operacional de uma VM. Ao contrário das máquinas físicas, onde as variáveis ​​são armazenadas em um chip de hardware, o Compute Engine virtualiza o armazenamento dessas variáveis. Assim, em muitos sistemas operacionais, todos os aplicativos e usuários podem acessar essas variáveis ​​e acessar essas informações.

Por esse motivo, o Google recomenda enfaticamente que você não grave nem armazene informações confidenciais ou de identificação pessoal, como senhas ou chaves privadas, em variáveis ​​UEFI.

Considerações sobre imagens de braço

O Google oferece as séries de máquinas C4A e Tau T2A , que rodam em plataformas Arm CPU. Você pode iniciar uma VM com uma dessas séries de máquinas e depois usar essa VM de origem para criar uma imagem Arm. O processo para criar uma imagem Arm personalizada é idêntico à criação de uma imagem x86.

Para ajudar seus usuários a diferenciar entre imagens Arm e x86, as imagens Arm terão um campo architecture definido como ARM64 . Os valores possíveis para este campo são:

  • ARCHITECTURE_UNSPECIFIED
  • X86_64
  • ARM64

Os usuários de imagens podem então filtrar neste campo para encontrar imagens x86 ou baseadas em Arm.

O que vem a seguir