Cree una VM con un tipo de máquina personalizado


Compute Engine ofrece tipos de máquinas predefinidas que puedes usar cuando creas una instancia de VM. Un tipo de máquina predefinido tiene una cantidad preestablecida de vCPU y una cantidad de memoria, y se cobra a un precio fijo. Si las máquinas virtuales predefinidas no satisfacen sus necesidades, puede crear una instancia de máquina virtual con configuraciones de hardware virtualizadas personalizadas. Específicamente, puede crear una instancia de VM con una cantidad personalizada de vCPU y una cantidad de memoria, utilizando efectivamente un tipo de máquina personalizada. Hay tipos de máquinas personalizados disponibles para lo siguiente:

Las máquinas virtuales personalizadas son ideales en los siguientes escenarios:

  • Cargas de trabajo que no son adecuadas para los tipos de VM predefinidos.
  • Cargas de trabajo que requieren más potencia de procesamiento o más memoria pero que no necesitan todas las actualizaciones que proporciona el tipo de máquina del siguiente nivel.
  • Cargas de trabajo que tienen costos de licencia de software por CPU. Personalice la cantidad de vCPU para evitar costos de licencia por potencia de procesamiento no utilizada o para igualar el número de licencias de software disponibles.

Antes de comenzar

Roles requeridos

Para obtener los permisos que necesita para crear una máquina virtual con un tipo de máquina personalizado, solicite a su administrador que le otorgue la función de IAM Compute Instance Admin (v1) ( roles/compute.instanceAdmin.v1 ) en el proyecto. Para obtener más información sobre cómo otorgar roles, consulte Administrar el acceso a proyectos, carpetas y organizaciones .

Esta función predefinida contiene los permisos necesarios para crear una VM con un tipo de máquina personalizado. Para ver los permisos exactos que se requieren, expanda la sección Permisos requeridos :

Permisos requeridos

Se requieren los siguientes permisos para crear una VM con un tipo de máquina personalizado:

  • Para agregar memoria extendida a una VM existente: compute.instances.setMachineType en la VM
  • Para crear una VM con un tipo de máquina personalizado:
    • compute.instances.create en el proyecto.
    • Para usar una imagen personalizada para crear la VM: compute.images.useReadOnly en la imagen
    • Para usar una instantánea para crear la VM: compute.snapshots.useReadOnly en la instantánea
    • Para usar una plantilla de instancia para crear la VM: compute.instanceTemplates.useReadOnly en la plantilla de instancia
    • Para asignar una red heredada a la VM: compute.networks.use en el proyecto
    • Para especificar una dirección IP estática para la VM: compute.addresses.use en el proyecto
    • Para asignar una dirección IP externa a la VM cuando se usa una red heredada: compute.networks.useExternalIp en el proyecto
    • Para especificar una subred para la VM: compute.subnetworks.use en el proyecto o en la subred elegida
    • Para asignar una dirección IP externa a la VM cuando se usa una red VPC: compute.subnetworks.useExternalIp en el proyecto o en la subred elegida
    • Para configurar metadatos de instancia de VM para la VM: compute.instances.setMetadata en el proyecto
    • Para configurar etiquetas para la VM: compute.instances.setTags en la VM
    • Para configurar etiquetas para la VM: compute.instances.setLabels en la VM
    • Para configurar una cuenta de servicio para que la use la VM: compute.instances.setServiceAccount en la VM
    • Para crear un nuevo disco para la VM: compute.disks.create en el proyecto
    • Para conectar un disco existente en modo de solo lectura o lectura-escritura: compute.disks.use en el disco
    • Para conectar un disco existente en modo de solo lectura: compute.disks.useReadOnly en el disco

Es posible que también pueda obtener estos permisos con roles personalizados u otros roles predefinidos .

Limitaciones

  • Si su máquina virtual tiene discos SSD locales, no puede cambiar la configuración de la memoria y la vCPU.
  • La memoria extendida está disponible en los tipos de máquinas personalizadas N4, N2, N2D y N1. Los tipos de máquinas predefinidos, así como los tipos de máquinas personalizadas G2 y E2, no admiten memoria extendida.
  • Hay una cantidad máxima de memoria que puede agregar a cada tipo de máquina.
  • Debe especificar la memoria en incrementos de 256 MB.
  • La memoria extendida no califica para descuentos por uso comprometido (CUD) basados ​​en recursos .

Precios de tipos de máquinas personalizados

Google cobra por las máquinas virtuales personalizadas según la cantidad de vCPU y horas de memoria que utiliza la máquina virtual. Esto es diferente de cómo se cobran los tipos de máquinas predefinidas. Los precios bajo demanda para tipos de máquinas personalizados incluyen una prima del 5 % sobre los precios bajo demanda para tipos de máquinas predefinidos.

  • Cuando se utiliza un tipo de máquina personalizado, cualquier memoria hasta la cantidad predeterminada por vCPU inclusive se cobra al precio del tipo de máquina personalizada de la familia de máquinas. Los tipos de máquinas personalizadas E2 y de núcleo compartido E2 comparten el mismo esquema de precios.

  • Si utiliza sus compromisos para ejecutar tipos de máquinas personalizados, Compute Engine cobra una prima del 5 % sobre los precios del compromiso. Compute Engine cobra esta prima por la parte y la duración de su compromiso de ejecutar estas máquinas virtuales de tipo de máquina personalizadas.

Consulte los precios de las instancias de VM para obtener información por serie de máquinas.

Las VM personalizadas están sujetas al mismo cargo mínimo de 1 minuto que cualquier otra instancia, pero los descuentos por uso sostenido para tipos de máquinas personalizadas se calculan de manera diferente. Para obtener más información, consulte descuentos por uso sostenido para máquinas virtuales personalizadas.

Precio de la memoria extendida

Para la memoria superior a la predeterminada, Compute Engine cobra por la memoria extendida según el precio de la memoria personalizada extendida de la familia de máquinas. El precio de la memoria extendida es diferente del precio de la memoria por debajo del umbral predeterminado.

Los precios de la memoria extendida varían según la región. Las instancias que se ejecutan con memoria extendida están sujetas al mismo cargo mínimo de 1 minuto que cualquier otra instancia. La memoria extendida también califica para descuentos por uso sostenido .

Agregar memoria extendida a un tipo de máquina

Dependiendo de la serie de máquinas, cada tipo de máquina tiene una cantidad específica de memoria de forma predeterminada. Para algunas cargas de trabajo, es posible que esta memoria no sea suficiente. Por un costo adicional, puede obtener más memoria por vCPU más allá del límite predeterminado. Esto se conoce como memoria extendida.

Con la memoria extendida, puede especificar una cantidad de memoria para el tipo de máquina personalizada sin limitación por vCPU. En lugar de utilizar el tamaño de memoria predeterminado según la cantidad de vCPU especificadas, puede especificar una cantidad de memoria extendida, hasta el límite de la serie de máquinas.

Serie de máquinas límite de vCPU Límite de memoria
N4 80 640GB
N2 80 864GB
N2D 96 768GB
N1 96 624GB

Si necesita más memoria, utilice uno de los tipos de máquinas con memoria optimizada .

Determina si necesitas memoria extendida

Ciertas cargas de trabajo necesitan más que la cantidad predeterminada de memoria por vCPU para ofrecer resultados óptimos. Las cargas de trabajo que se basan en bases de datos de análisis de alto rendimiento en memoria, incluidas bases de datos relacionales y NoSQL como MS SQL Server, MongoDB y MemcacheD/Redis, se encuentran en esta categoría. Las licencias de sistemas operativos y pilas de software basadas en vCPU también hacen que la selección de una configuración óptima de memoria de VM sea más desafiante con tipos de máquinas predefinidas. Al utilizar memoria extendida, puede agregar tanta memoria como sus máquinas virtuales necesiten para obtener la mejor relación precio-rendimiento.

Memoria Express en GB o MB

Para Google Cloud herramientas y documentación, la memoria del tipo de máquina se calcula en gigabytes (GB), donde 1 GB son 2 30 bytes. Esta unidad de medida también se conoce como gibibyte (GiB) . Al convertir memoria de GB a MB, 1 GB = 1024 MB.

En la API, siempre debes proporcionar memoria en megabytes. Si usa la CLI de Google Cloud, puede proporcionar la memoria total para una VM en gigabytes o megabytes. Sin embargo, la CLI de gcloud espera que el valor de la memoria sea un número entero, por lo que no puedes proporcionar un valor flotante. Por ejemplo, para expresar 5,75 GB, convierta 5,75 GB en MB. En este caso, 5,75 GB son 5888 MB.

Cree una VM con un tipo de máquina personalizado

Antes de crear una instancia de VM personalizada, asegúrese de leer las especificaciones personalizadas para crear este tipo de máquina.

Consola

  1. En el Google Cloud consola, vaya a la página Crear una instancia .

    Ir a Crear una instancia

  2. En el panel de configuración de la máquina , haga lo siguiente:

    1. Seleccione la Región y Zona donde desea alojar la instancia.
    2. Seleccione Propósito general o GPU .
      1. En la lista Serie , seleccione una serie de máquinas.
        • Para Uso general , elija N4, N2, N2D, E2 o N1.
        • Para GPU , elija G2.
      2. En la sección Tipo de máquina , seleccione Personalizado .
      3. Para especificar la cantidad de vCPU y la cantidad de memoria para la instancia, arrastre los controles deslizantes o ingrese los valores en los cuadros de texto. La consola muestra un costo estimado para la instancia a medida que cambia la cantidad de vCPU y memoria.
  3. Opcional: especifique otras opciones de configuración. Para obtener más información, consulte Opciones de configuración durante la creación de instancias .

  4. Para crear e iniciar la instancia, haga clic en Crear .

nube de gcloud

Cree un tipo de máquina personalizada mediante el comando gcloud compute instances create con la opción --machine-type .

  gcloud compute instances create INSTANCE_NAME \
    --machine-type=MACHINE_TYPE-custom-NUMBER_OF_VCPUS-AMOUNT_OF_MEMORY_MB

Reemplace lo siguiente:

  • INSTANCE_NAME : nombre de la instancia
  • MACHINE_TYPE : tipo de máquina, como N2
  • NUMBER_OF_VCPUS : número de vCPU
  • AMOUNT_OF_MEMORY_MB : cantidad de memoria en MB o GB

    Para crear una máquina virtual G2 con 4 vCPU y 19 GB de memoria en la zona us-central1-a , ejecute el siguiente comando:

    gcloud compute instances create example-instance \
       --zone=us-central1-a --machine-type=g2-custom-4-19456
    

    Para las máquinas virtuales G2, la memoria debe ser múltiplo de 1024 MB y estar dentro del rango de memoria admitido . Para obtener más información sobre la creación de máquinas virtuales G2, consulte Crear una máquina virtual que tenga GPU conectadas .

A continuación se muestra un ejemplo que utiliza un tipo de máquina N2 con 48 vCPU y 310 GB de memoria en la zona us-central1-a :

gcloud compute instances create example-instance \
  --zone=us-central1-a --machine-type=n2-custom-48-317440

Para las series de máquinas compatibles, como N2, puede configurar la memoria extendida, lo que le permite especificar una cantidad de memoria mayor que la relación máxima de memoria a vCPU. Para configurar la memoria extendida, aumente el valor de AMOUNT_OF_MEMORY_MB y agregue -ext al nombre del tipo de máquina, por ejemplo --machine-type=n2-custom-48-720000-ext .

Como alternativa, puede especificar un tipo de máquina personalizada utilizando las opciones personalizadas: --custom-cpu , --custom-memory , --custom-vm-type y --custom-extensions .

  gcloud compute instances create INSTANCE_NAME \
        --custom-cpu=NUMBER_OF_VCPUS \
        --custom-memory=NUMBER_OF_MB \
        --custom-vm-type=MACHINE_TYPE \
        --custom-extension

Reemplace lo siguiente:

  • INSTANCE_NAME : nombre de la instancia
  • NUMBER_OF_VCPUS : número de vCPU
  • NUMBER_OF_MB : cantidad de memoria en MB o GB
  • MACHINE_TYPE : tipo de máquina, como N2

El siguiente ejemplo es un tipo de máquina personalizada N2 con 48 vCPU y 310 GB de memoria que utiliza las opciones de la CLI de Google Cloud.

  gcloud compute instances create example-instance \
    --custom-cpu=48 --custom-memory=317440 --custom-extension --custom-vm-type=n2

Cuando utilice la opción --custom-memory , especifique la cantidad total de memoria en GB o en MB. El valor de la propiedad debe ser un número entero, por lo que si desea especificar incrementos de 0,25 GB para la memoria, utilice el valor 250 MB.

Para los tipos de máquinas personalizadas de núcleo compartido E2, use el mismo comando gcloud compute instances create e incluya el tamaño de la máquina de núcleo compartido: micro , small o medium . La vCPU y la memoria son limitadas.

  gcloud compute instances create INSTANCE_NAME\
    --machine-type=MACHINE_TYPE-AMOUNT_OF_MEMORY_MB

Reemplace lo siguiente:

  • INSTANCE_NAME : nombre de la instancia
  • MACHINE_TYPE : E2 pequeño
  • AMOUNT_OF_MEMORY_MB : cantidad de memoria en MB o GB

El siguiente ejemplo es un tipo de máquina personalizada pequeña de núcleo compartido E2 con 0,5 vCPU y 2,25 GB de memoria.

  gcloud compute instances create example-instance \
    --machine-type=e2-custom-small-2304

Terraformar

Para generar el código Terraform, puede utilizar el componente Código equivalente en el Google Cloud consola.
  1. En el Google Cloud consola, vaya a la página de instancias de VM .

    Ir a instancias de VM

  2. Haga clic en Crear instancia .
  3. Especifique los parámetros que desee.
  4. En la parte superior o inferior de la página, haga clic en Código equivalente y luego haga clic en la pestaña Terraform para ver el código de Terraform.

Ir

Antes de probar este ejemplo, sigue las instrucciones de configuración Go en el inicio rápido de Compute Engine usando bibliotecas cliente . Para obtener más información, consulta la documentación de referencia de la API Go de Compute Engine .

Para autenticarse en Compute Engine, configure las credenciales predeterminadas de la aplicación. Para obtener más información, consulte Configurar la autenticación para un entorno de desarrollo local .

import (
	"context"
	"fmt"
	"io"

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

func customMachineTypeURI(zone, cpuSeries string, coreCount, memory int) (string, error) {
	const (
		n1       = "custom"
		n2       = "n2-custom"
		n2d      = "n2d-custom"
		e2       = "e2-custom"
		e2Micro  = "e2-custom-micro"
		e2Small  = "e2-custom-small"
		e2Medium = "e2-custom-medium"
	)

	type typeLimit struct {
		allowedCores     []int
		minMemPerCore    int
		maxMemPerCore    int
		allowExtraMemory bool
		extraMemoryLimit int
	}

	makeRange := func(start, end, step int) []int {
		if step <= 0 || end < start {
			return []int{}
		}
		s := make([]int, 0, 1+(end-start)/step)
		for start <= end {
			s = append(s, start)
			start += step
		}
		return s
	}

	containsString := func(s []string, str string) bool {
		for _, v := range s {
			if v == str {
				return true
			}
		}

		return false
	}

	containsInt := func(nums []int, n int) bool {
		for _, v := range nums {
			if v == n {
				return true
			}
		}

		return false
	}

	var (
		cpuSeriesE2Limit = typeLimit{
			allowedCores:  makeRange(2, 33, 2),
			minMemPerCore: 512,
			maxMemPerCore: 8192,
		}
		cpuSeriesE2MicroLimit  = typeLimit{minMemPerCore: 1024, maxMemPerCore: 2048}
		cpuSeriesE2SmallLimit  = typeLimit{minMemPerCore: 2048, maxMemPerCore: 4096}
		cpuSeriesE2MeidumLimit = typeLimit{minMemPerCore: 4096, maxMemPerCore: 8192}
		cpuSeriesN2Limit       = typeLimit{
			allowedCores:  append(makeRange(2, 33, 2), makeRange(36, 129, 4)...),
			minMemPerCore: 512, maxMemPerCore: 8192,
			allowExtraMemory: true,
			extraMemoryLimit: 624 << 10,
		}
		cpuSeriesN2DLimit = typeLimit{
			allowedCores:  []int{2, 4, 8, 16, 32, 48, 64, 80, 96},
			minMemPerCore: 512, maxMemPerCore: 8192,
			allowExtraMemory: true,
			extraMemoryLimit: 768 << 10,
		}
		cpuSeriesN1Limit = typeLimit{
			allowedCores:     append([]int{1}, makeRange(2, 97, 2)...),
			minMemPerCore:    922,
			maxMemPerCore:    6656,
			allowExtraMemory: true,
			extraMemoryLimit: 624 << 10,
		}
	)

	typeLimitsMap := map[string]typeLimit{
		n1:       cpuSeriesN1Limit,
		n2:       cpuSeriesN2Limit,
		n2d:      cpuSeriesN2DLimit,
		e2:       cpuSeriesE2Limit,
		e2Micro:  cpuSeriesE2MicroLimit,
		e2Small:  cpuSeriesE2SmallLimit,
		e2Medium: cpuSeriesE2MeidumLimit,
	}

	if !containsString([]string{e2, n1, n2, n2d}, cpuSeries) {
		return "", fmt.Errorf("incorrect cpu type: %v", cpuSeries)
	}

	tl := typeLimitsMap[cpuSeries]

	// Check whether the requested parameters are allowed.
	// Find more information about limitations of custom machine types at:
	// https://cloud.google.com/compute/docs/general-purpose-machines#custom_machine_types

	// Check the number of cores
	if len(tl.allowedCores) > 0 && !containsInt(tl.allowedCores, coreCount) {
		return "", fmt.Errorf(
			"invalid number of cores requested. Allowed number of cores for %v is: %v",
			cpuSeries,
			tl.allowedCores,
		)
	}

	// Memory must be a multiple of 256 MB
	if memory%256 != 0 {
		return "", fmt.Errorf("requested memory must be a multiple of 256 MB")
	}

	// Check if the requested memory isn't too little
	if memory < coreCount*tl.minMemPerCore {
		return "", fmt.Errorf(
			"requested memory is too low. Minimal memory for %v is %v MB per core",
			cpuSeries,
			tl.minMemPerCore,
		)
	}

	// Check if the requested memory isn't too much
	if memory > coreCount*tl.maxMemPerCore && !tl.allowExtraMemory {
		return "", fmt.Errorf(
			"requested memory is too large.. Maximum memory allowed for %v is %v MB per core",
			cpuSeries,
			tl.maxMemPerCore,
		)
	}
	if memory > tl.extraMemoryLimit && tl.allowExtraMemory {
		return "", fmt.Errorf(
			"requested memory is too large.. Maximum memory allowed for %v is %v MB",
			cpuSeries,
			tl.extraMemoryLimit,
		)
	}

	// Return the custom machine type in form of a string acceptable by Compute Engine API.
	if containsString([]string{e2Small, e2Micro, e2Medium}, cpuSeries) {
		return fmt.Sprintf("zones/%v/machineTypes/%v-%v", zone, cpuSeries, memory), nil
	}

	if memory > coreCount*tl.maxMemPerCore {
		return fmt.Sprintf(
			"zones/%v/machineTypes/%v-%v-%v-ext",
			zone,
			cpuSeries,
			coreCount,
			memory,
		), nil
	}

	return fmt.Sprintf("zones/%v/machineTypes/%v-%v-%v", zone, cpuSeries, coreCount, memory), nil
}

// createInstanceWithCustomMachineTypeWithHelper creates a new VM instance with a custom machine type.
func createInstanceWithCustomMachineTypeWithHelper(
	w io.Writer,
	projectID, zone, instanceName, cpuSeries string,
	coreCount, memory int,
) error {
	// projectID := "your_project_id"
	// zone := "europe-central2-b"
	// instanceName := "your_instance_name"
	// cpuSeries := "e2-custom-micro" // the type of CPU you want to use"
	// coreCount := 2 // number of CPU cores you want to use.
	// memory := 256 // the amount of memory for the VM instance, in megabytes.

	machineType, err := customMachineTypeURI(zone, cpuSeries, coreCount, memory)
	if err != nil {
		return fmt.Errorf("unable to create custom machine type string: %w", err)
	}

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

	req := &computepb.InsertInstanceRequest{
		Project: projectID,
		Zone:    zone,
		InstanceResource: &computepb.Instance{
			Name: proto.String(instanceName),
			Disks: []*computepb.AttachedDisk{
				{
					InitializeParams: &computepb.AttachedDiskInitializeParams{
						DiskSizeGb: proto.Int64(10),
						SourceImage: proto.String(
							"projects/debian-cloud/global/images/family/debian-12",
						),
					},
					AutoDelete: proto.Bool(true),
					Boot:       proto.Bool(true),
				},
			},
			MachineType: proto.String(machineType),
			NetworkInterfaces: []*computepb.NetworkInterface{
				{
					Name: proto.String("global/networks/default"),
				},
			},
		},
	}

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

	return nil
}

Java

Antes de probar este ejemplo, sigue las instrucciones de configuración Java en el inicio rápido de Compute Engine usando bibliotecas cliente . Para obtener más información, consulta la documentación de referencia de la API Java de Compute Engine .

Para autenticarse en Compute Engine, configure las credenciales predeterminadas de la aplicación. Para obtener más información, consulte Configurar la autenticación para un entorno de desarrollo local .


import com.google.cloud.compute.v1.AttachedDisk;
import com.google.cloud.compute.v1.AttachedDiskInitializeParams;
import com.google.cloud.compute.v1.InsertInstanceRequest;
import com.google.cloud.compute.v1.Instance;
import com.google.cloud.compute.v1.InstancesClient;
import com.google.cloud.compute.v1.NetworkInterface;
import com.google.cloud.compute.v1.Operation;
import com.google.common.collect.ImmutableMap;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.stream.IntStream;

public class CreateWithHelper {

  // This class defines the configurable parameters for a custom VM.
  static final class TypeLimits {

    int[] allowedCores;
    int minMemPerCore;
    int maxMemPerCore;
    int extraMemoryLimit;
    boolean allowExtraMemory;

    TypeLimits(int[] allowedCores, int minMemPerCore, int maxMemPerCore, boolean allowExtraMemory,
        int extraMemoryLimit) {
      this.allowedCores = allowedCores;
      this.minMemPerCore = minMemPerCore;
      this.maxMemPerCore = maxMemPerCore;
      this.allowExtraMemory = allowExtraMemory;
      this.extraMemoryLimit = extraMemoryLimit;
    }
  }

  public enum CpuSeries {
    N1("custom"),
    N2("n2-custom"),
    N2D("n2d-custom"),
    E2("e2-custom"),
    E2_MICRO("e2-custom-micro"),
    E2_SMALL("e2-custom-small"),
    E2_MEDIUM("e2-custom-medium");

    private static final Map<String, CpuSeries> ENUM_MAP;

    static {
      ENUM_MAP = init();
    }

    // Build an immutable map of String name to enum pairs.
    public static Map<String, CpuSeries> init() {
      Map<String, CpuSeries> map = new ConcurrentHashMap<>();
      for (CpuSeries instance : CpuSeries.values()) {
        map.put(instance.getCpuSeries(), instance);
      }
      return Collections.unmodifiableMap(map);
    }

    private final String cpuSeries;

    CpuSeries(String cpuSeries) {
      this.cpuSeries = cpuSeries;
    }

    public static CpuSeries get(String name) {
      return ENUM_MAP.get(name);
    }

    public String getCpuSeries() {
      return this.cpuSeries;
    }
  }

  // This enum correlates a machine type with its limits.
  // The limits for various CPU types are described in:
  // https://cloud.google.com/compute/docs/general-purpose-machines
  enum Limits {
    CPUSeries_E2(new TypeLimits(getNumsInRangeWithStep(2, 33, 2), 512, 8192, false, 0)),
    CPUSeries_E2MICRO(new TypeLimits(new int[]{}, 1024, 2048, false, 0)),
    CPUSeries_E2SMALL(new TypeLimits(new int[]{}, 2048, 4096, false, 0)),
    CPUSeries_E2MEDIUM(new TypeLimits(new int[]{}, 4096, 8192, false, 0)),
    CPUSeries_N2(
        new TypeLimits(concat(getNumsInRangeWithStep(2, 33, 2), getNumsInRangeWithStep(36, 129, 4)),
            512, 8192, true, gbToMb(624))),
    CPUSeries_N2D(
        new TypeLimits(new int[]{2, 4, 8, 16, 32, 48, 64, 80, 96}, 512, 8192, true, gbToMb(768))),
    CPUSeries_N1(
        new TypeLimits(concat(new int[]{1}, getNumsInRangeWithStep(2, 97, 2)), 922, 6656, true,
            gbToMb(624)));

    private final TypeLimits typeLimits;

    Limits(TypeLimits typeLimits) {
      this.typeLimits = typeLimits;
    }

    public TypeLimits getTypeLimits() {
      return typeLimits;
    }
  }

  static ImmutableMap<String, Limits> typeLimitsMap = ImmutableMap.<String, Limits>builder()
      .put("N1", Limits.CPUSeries_N1)
      .put("N2", Limits.CPUSeries_N2)
      .put("N2D", Limits.CPUSeries_N2D)
      .put("E2", Limits.CPUSeries_E2)
      .put("E2_MICRO", Limits.CPUSeries_E2MICRO)
      .put("E2_SMALL", Limits.CPUSeries_E2SMALL)
      .put("E2_MEDIUM", Limits.CPUSeries_E2SMALL)
      .build();

  // Returns the array of integers within the given range, incremented by the specified step.
  // start (inclusive): starting number of the range
  // stop (inclusive): ending number of the range
  // step : increment value
  static int[] getNumsInRangeWithStep(int start, int stop, int step) {
    return IntStream.range(start, stop).filter(x -> (x - start) % step == 0).toArray();
  }

  static int gbToMb(int value) {
    return value << 10;
  }

  static int[] concat(int[] a, int[] b) {
    int[] result = new int[a.length + b.length];
    System.arraycopy(a, 0, result, 0, a.length);
    System.arraycopy(b, 0, result, a.length, b.length);
    return result;
  }

  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-google-cloud-project-id";
    // Name of the zone to create the instance in. For example: "us-west3-b".
    String zone = "google-cloud-zone";
    // Name of the new virtual machine (VM) instance.
    String instanceName = "instance-name";
    String cpuSeries = "N1";
    // Number of CPU cores you want to use.
    int coreCount = 2;
    // The amount of memory for the VM instance, in megabytes.
    int memory = 256;

    createInstanceWithCustomMachineTypeWithHelper(
        projectId, zone, instanceName, cpuSeries, coreCount, memory);
  }

  // Create a VM instance with a custom machine type.
  public static void createInstanceWithCustomMachineTypeWithHelper(
      String project, String zone, String instanceName, String cpuSeries, int coreCount, int memory)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // Construct the URI string identifying the machine type.
    String machineTypeUri = customMachineTypeUri(zone, cpuSeries, coreCount, memory);

    // 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()) {

      AttachedDisk attachedDisk = AttachedDisk.newBuilder()
          .setInitializeParams(
              // Describe the size and source image of the boot disk to attach to the instance.
              // The list of public images available in Compute Engine can be found here:
              // https://cloud.google.com/compute/docs/images#list_of_public_images_available_on
              AttachedDiskInitializeParams.newBuilder()
                  .setSourceImage(
                      String.format("projects/%s/global/images/family/%s", "debian-cloud",
                          "debian-11"))
                  .setDiskSizeGb(10)
                  .build()
          )
          // Remember to set auto_delete to True if you want the disk to be deleted when you delete
          // your VM instance.
          .setAutoDelete(true)
          .setBoot(true)
          .build();

      // Create the Instance object with the relevant information.
      Instance instance = Instance.newBuilder()
          .setName(instanceName)
          .addDisks(attachedDisk)
          .setMachineType(machineTypeUri)
          .addNetworkInterfaces(
              NetworkInterface.newBuilder().setName("global/networks/default").build())
          .build();

      // Create the insert instance request object.
      InsertInstanceRequest insertInstanceRequest = InsertInstanceRequest.newBuilder()
          .setProject(project)
          .setZone(zone)
          .setInstanceResource(instance)
          .build();

      // Invoke the API with the request object and wait for the operation to complete.
      Operation response = instancesClient.insertAsync(insertInstanceRequest)
          .get(3, TimeUnit.MINUTES);

      // Check for errors.
      if (response.hasError()) {
        throw new Error("Instance creation failed!!" + response);
      }
      System.out.printf("Instance created : %s", instanceName);
      System.out.println("Operation Status: " + response.getStatus());
    }
  }

  public static String customMachineTypeUri(String zone, String cpuSeries, int coreCount,
      int memory) {

    if (!Arrays.asList(CpuSeries.E2.cpuSeries, CpuSeries.N1.cpuSeries, CpuSeries.N2.cpuSeries,
        CpuSeries.N2D.cpuSeries).contains(cpuSeries)) {
      throw new Error(String.format("Incorrect cpu type: %s", cpuSeries));
    }

    TypeLimits typeLimit = Objects.requireNonNull(
        typeLimitsMap.get(CpuSeries.get(cpuSeries).name())).typeLimits;

    // Perform the following checks to verify if the requested parameters are allowed.
    // Find more information about limitations of custom machine types at:
    // https://cloud.google.com/compute/docs/general-purpose-machines#custom_machine_types

    // 1. Check the number of cores and if the coreCount is present in allowedCores.
    if (typeLimit.allowedCores.length > 0 && Arrays.stream(typeLimit.allowedCores)
        .noneMatch(x -> x == coreCount)) {
      throw new Error(String.format(
          "Invalid number of cores requested. "
              + "Number of cores requested for CPU %s should be one of: %s",
          cpuSeries,
          Arrays.toString(typeLimit.allowedCores)));
    }

    // 2. Memory must be a multiple of 256 MB
    if (memory % 256 != 0) {
      throw new Error("Requested memory must be a multiple of 256 MB");
    }

    // 3. Check if the requested memory isn't too little
    if (memory < coreCount * typeLimit.minMemPerCore) {
      throw new Error(
          String.format("Requested memory is too low. Minimum memory for %s is %s MB per core",
              cpuSeries, typeLimit.minMemPerCore));
    }

    // 4. Check if the requested memory isn't too much
    if (memory > coreCount * typeLimit.maxMemPerCore && !typeLimit.allowExtraMemory) {
      throw new Error(String.format(
          "Requested memory is too large.. Maximum memory allowed for %s is %s MB per core",
          cpuSeries, typeLimit.extraMemoryLimit));
    }

    // 5. Check if the requested memory isn't too large
    if (memory > typeLimit.extraMemoryLimit && typeLimit.allowExtraMemory) {
      throw new Error(
          String.format("Requested memory is too large.. Maximum memory allowed for %s is %s MB",
              cpuSeries, typeLimit.extraMemoryLimit));
    }

    // Check if the CPU Series is E2 and return the custom machine type in the form of a string
    // acceptable by Compute Engine API.
    if (Arrays.asList(CpuSeries.E2_SMALL.cpuSeries, CpuSeries.E2_MICRO.cpuSeries,
        CpuSeries.E2_MEDIUM.cpuSeries).contains(cpuSeries)) {
      return String.format("zones/%s/machineTypes/%s-%s", zone, cpuSeries, memory);
    }

    // Check if extended memory was requested and return the extended custom machine type
    // in the form of a string acceptable by Compute Engine API.
    if (memory > coreCount * typeLimit.maxMemPerCore) {
      return String.format("zones/%s/machineTypes/%s-%s-%s-ext", zone, cpuSeries, coreCount,
          memory);
    }

    // Return the custom machine type in the form of a standard string
    // acceptable by Compute Engine API.
    return String.format("zones/%s/machineTypes/%s-%s-%s", zone, cpuSeries, coreCount, memory);
  }
}

Nodo.js

Antes de probar este ejemplo, sigue las instrucciones de configuración de Node.js en el inicio rápido de Compute Engine usando bibliotecas cliente . Para obtener más información, consulta la documentación de referencia de la API de Compute Engine Node.js

Para autenticarse en Compute Engine, configure las credenciales predeterminadas de la aplicación. Para obtener más información, consulte Configurar la autenticación para un entorno de desarrollo 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 cpuSeries = 'N1';
// const coreCount = 2
// const memory = 256

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

function range(from, to, step) {
  return [...Array(Math.floor((to - from) / step) + 1)].map(
    (_, i) => from + i * step
  );
}

class CustomMachineType {
  constructor(zone, cpuSeries, coreCount, memory) {
    this.zone = zone;
    this.cpuSeries = cpuSeries;
    this.coreCount = coreCount;
    this.memory = memory;

    this.N1 = 'custom';
    this.N2 = 'n2-custom';
    this.N2D = 'n2d-custom';
    this.E2 = 'e2-custom';
    this.E2Micro = 'e2-custom-micro';
    this.E2Small = 'e2-custom-small';
    this.E2Medium = 'e2-custom-medium';

    this.CpuSeriesE2Limit = {
      allowedCores: range(2, 33, 2),
      minMemPerCore: 512,
      maxMemPerCore: 8192,
      allowExtraMemory: false,
      extraMemoryLimit: 0,
    };

    this.CpuSeriesE2MicroLimit = {
      allowedCores: [],
      minMemPerCore: 1024,
      maxMemPerCore: 2048,
      allowExtraMemory: false,
      extraMemoryLimit: 0,
    };

    this.CpuSeriesE2SmallLimit = {
      allowedCores: [],
      minMemPerCore: 2048,
      maxMemPerCore: 4096,
      allowExtraMemory: false,
      extraMemoryLimit: 0,
    };

    this.CpuSeriesE2MediumLimit = {
      allowedCores: [],
      minMemPerCore: 4096,
      maxMemPerCore: 8192,
      allowExtraMemory: false,
      extraMemoryLimit: 0,
    };

    this.CpuSeriesN2Limit = {
      allowedCores: [...range(2, 33, 2), ...range(36, 129, 4)],
      minMemPerCore: 512,
      maxMemPerCore: 8192,
      allowExtraMemory: true,
      extraMemoryLimit: 624 << 10,
    };

    this.CpuSeriesN2DLimit = {
      allowedCores: [2, 4, 8, 16, 32, 48, 64, 80, 96],
      minMemPerCore: 512,
      maxMemPerCore: 8192,
      allowExtraMemory: true,
      extraMemoryLimit: 768 << 10,
    };

    this.CpuSeriesN1Limit = {
      allowedCores: [1, range(2, 97, 2)],
      minMemPerCore: 922,
      maxMemPerCore: 6656,
      allowExtraMemory: true,
      extraMemoryLimit: 624 << 10,
    };

    this.TYPE_LIMITS = {
      [this.N1]: this.CpuSeriesN1Limit,
      [this.N2]: this.CpuSeriesN2Limit,
      [this.N2D]: this.CpuSeriesN2DLimit,
      [this.E2]: this.CpuSeriesE2Limit,
      [this.E2Micro]: this.CpuSeriesE2MicroLimit,
      [this.E2Small]: this.CpuSeriesE2SmallLimit,
      [this.E2Medium]: this.CpuSeriesE2MediumLimit,
    };

    if (![this.E2, this.N1, this.N2, this.N2D].includes(cpuSeries)) {
      throw new Error(`Incorrect CPU type: ${this.cpuSeries}`);
    }

    this.typeLimit = this.TYPE_LIMITS[this.cpuSeries];

    // Check whether the requested parameters are allowed.
    // Find more information about limitations of custom machine types at:
    // https://cloud.google.com/compute/docs/general-purpose-machines#custom_machine_types

    // Check the number of cores
    if (
      this.typeLimit.allowedCores.length > 0 &&
      !this.typeLimit.allowedCores.includes(coreCount)
    ) {
      throw new Error(
        `Invalid number of cores requested. Allowed number of cores for ${this.cpuSeries} is: ${this.typeLimit.allowedCores}`
      );
    }

    // Memory must be a multiple of 256 MB
    if (this.memory % 256 !== 0) {
      throw new Error('Requested memory must be a multiple of 256 MB');
    }

    // Check if the requested memory isn't too little
    if (this.memory < this.coreCount * this.typeLimit.minMemPerCore) {
      throw new Error(
        `Requested memory is too low. Minimal memory for ${this.cpuSeries} is ${this.typeLimit.minMemPerCore} MB per core`
      );
    }

    // Check if the requested memory isn't too much
    if (
      this.memory > this.coreCount * this.typeLimit.maxMemPerCore &&
      !this.typeLimit.allowExtraMemory
    ) {
      throw new Error(
        `Requested memory is too large.. Maximum memory allowed for ${this.cpuSeries} is ${this.typeLimit.maxMemPerCore} MB per core`
      );
    }

    if (
      this.memory > this.typeLimit.extraMemoryLimit &&
      this.typeLimit.allowExtraMemory
    ) {
      throw new Error(
        `Requested memory is too large.. Maximum memory allowed for ${this.cpuSeries} is ${this.typeLimit.extraMemoryLimit} MB`
      );
    }
  }

  // Returns the custom machine type in form of a string acceptable by Compute Engine API.
  getMachineTypeURI() {
    if (
      [this.E2Small, this.E2Micro, this.E2Medium].includes(this.cpuSeries)
    ) {
      return `zones/${this.zone}/machineTypes/${this.cpuSeries}-${this.memory}`;
    }

    if (this.memory > this.coreCount * this.typeLimit.maxMemPerCore) {
      return `zones/${this.zone}/machineTypes/${this.cpuSeries}-${this.coreCount}-${this.memory}-ext`;
    }

    return `zones/${zone}/machineTypes/${this.cpuSeries}-${this.coreCount}-${this.memory}`;
  }
}

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

  const machineType = new CustomMachineType(
    zone,
    cpuSeries,
    coreCount,
    memory
  ).getMachineTypeURI();

  const [response] = await instancesClient.insert({
    instanceResource: {
      name: instanceName,
      disks: [
        {
          initializeParams: {
            diskSizeGb: '64',
            sourceImage:
              'projects/debian-cloud/global/images/family/debian-11/',
          },
          autoDelete: true,
          boot: true,
        },
      ],
      machineType,
      networkInterfaces: [
        {
          name: 'global/networks/default',
        },
      ],
    },
    project: projectId,
    zone,
  });
  let operation = response.latestResponse;
  const operationsClient = new compute.ZoneOperationsClient();

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

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

createInstanceWithCustomMachineTypeWithHelper();

Pitón

Antes de probar este ejemplo, sigue las instrucciones de configuración Python en el inicio rápido de Compute Engine usando bibliotecas cliente . Para obtener más información, consulta la documentación de referencia de la API Python de Compute Engine .

Para autenticarse en Compute Engine, configure las credenciales predeterminadas de la aplicación. Para obtener más información, consulte Configurar la autenticación para un entorno de desarrollo local .

from __future__ import annotations

from collections import namedtuple
from enum import Enum
from enum import unique
import re
import sys
from typing import Any
import warnings

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


def gb_to_mb(value: int) -> int:
    return value << 10


class CustomMachineType:
    """
    Allows to create custom machine types to be used with the VM instances.
    """

    @unique
    class CPUSeries(Enum):
        N1 = "custom"
        N2 = "n2-custom"
        N2D = "n2d-custom"
        E2 = "e2-custom"
        E2_MICRO = "e2-custom-micro"
        E2_SMALL = "e2-custom-small"
        E2_MEDIUM = "e2-custom-medium"

    TypeLimits = namedtuple(
        "TypeLimits",
        [
            "allowed_cores",
            "min_mem_per_core",
            "max_mem_per_core",
            "allow_extra_memory",
            "extra_memory_limit",
        ],
    )

    # The limits for various CPU types are described on:
    # https://cloud.google.com/compute/docs/general-purpose-machines
    LIMITS = {
        CPUSeries.E2: TypeLimits(frozenset(range(2, 33, 2)), 512, 8192, False, 0),
        CPUSeries.E2_MICRO: TypeLimits(frozenset(), 1024, 2048, False, 0),
        CPUSeries.E2_SMALL: TypeLimits(frozenset(), 2048, 4096, False, 0),
        CPUSeries.E2_MEDIUM: TypeLimits(frozenset(), 4096, 8192, False, 0),
        CPUSeries.N2: TypeLimits(
            frozenset(range(2, 33, 2)).union(set(range(36, 129, 4))),
            512,
            8192,
            True,
            gb_to_mb(624),
        ),
        CPUSeries.N2D: TypeLimits(
            frozenset({2, 4, 8, 16, 32, 48, 64, 80, 96}), 512, 8192, True, gb_to_mb(768)
        ),
        CPUSeries.N1: TypeLimits(
            frozenset({1}.union(range(2, 97, 2))), 922, 6656, True, gb_to_mb(624)
        ),
    }

    def __init__(
        self, zone: str, cpu_series: CPUSeries, memory_mb: int, core_count: int = 0
    ):
        self.zone = zone
        self.cpu_series = cpu_series
        self.limits = self.LIMITS[self.cpu_series]
        # Shared machine types (e2-small, e2-medium and e2-micro) always have
        # 2 vCPUs: https://cloud.google.com/compute/docs/general-purpose-machines#e2_limitations
        self.core_count = 2 if self.is_shared() else core_count
        self.memory_mb = memory_mb
        self._checked = False
        self._check_parameters()
        self.extra_memory_used = self._check_extra_memory()

    def is_shared(self):
        return self.cpu_series in (
            CustomMachineType.CPUSeries.E2_SMALL,
            CustomMachineType.CPUSeries.E2_MICRO,
            CustomMachineType.CPUSeries.E2_MEDIUM,
        )

    def _check_extra_memory(self) -> bool:
        if self._checked:
            return self.memory_mb > self.core_count * self.limits.max_mem_per_core
        else:
            raise RuntimeError(
                "You need to call _check_parameters() before calling _check_extra_memory()"
            )

    def _check_parameters(self):
        """
        Check whether the requested parameters are allowed. Find more information about limitations of custom machine
        types at: https://cloud.google.com/compute/docs/general-purpose-machines#custom_machine_types
        """
        # Check the number of cores
        if (
            self.limits.allowed_cores
            and self.core_count not in self.limits.allowed_cores
        ):
            raise RuntimeError(
                f"Invalid number of cores requested. Allowed number of cores for {self.cpu_series.name} is: {sorted(self.limits.allowed_cores)}"
            )

        # Memory must be a multiple of 256 MB
        if self.memory_mb % 256 != 0:
            raise RuntimeError("Requested memory must be a multiple of 256 MB.")

        # Check if the requested memory isn't too little
        if self.memory_mb < self.core_count * self.limits.min_mem_per_core:
            raise RuntimeError(
                f"Requested memory is too low. Minimal memory for {self.cpu_series.name} is {self.limits.min_mem_per_core} MB per core."
            )

        # Check if the requested memory isn't too much
        if self.memory_mb > self.core_count * self.limits.max_mem_per_core:
            if self.limits.allow_extra_memory:
                if self.memory_mb > self.limits.extra_memory_limit:
                    raise RuntimeError(
                        f"Requested memory is too large.. Maximum memory allowed for {self.cpu_series.name} is {self.limits.extra_memory_limit} MB."
                    )
            else:
                raise RuntimeError(
                    f"Requested memory is too large.. Maximum memory allowed for {self.cpu_series.name} is {self.limits.max_mem_per_core} MB per core."
                )

        self._checked = True

    def __str__(self) -> str:
        """
        Return the custom machine type in form of a string acceptable by Compute Engine API.
        """
        if self.cpu_series in {
            self.CPUSeries.E2_SMALL,
            self.CPUSeries.E2_MICRO,
            self.CPUSeries.E2_MEDIUM,
        }:
            return f"zones/{self.zone}/machineTypes/{self.cpu_series.value}-{self.memory_mb}"

        if self.extra_memory_used:
            return f"zones/{self.zone}/machineTypes/{self.cpu_series.value}-{self.core_count}-{self.memory_mb}-ext"

        return f"zones/{self.zone}/machineTypes/{self.cpu_series.value}-{self.core_count}-{self.memory_mb}"

    def short_type_str(self) -> str:
        """
        Return machine type in a format without the zone. For example, n2-custom-0-10240.
        This format is used to create instance templates.
        """
        return str(self).rsplit("/", maxsplit=1)[1]

    @classmethod
    def from_str(cls, machine_type: str):
        """
        Construct a new object from a string. The string needs to be a valid custom machine type like:
         - https://www.googleapis.com/compute/v1/projects/diregapic-mestiv/zones/us-central1-b/machineTypes/e2-custom-4-8192
         - zones/us-central1-b/machineTypes/e2-custom-4-8192
         - e2-custom-4-8192 (in this case, the zone parameter will not be set)
        """
        zone = None
        if machine_type.startswith("http"):
            machine_type = machine_type[machine_type.find("zones/") :]

        if machine_type.startswith("zones/"):
            _, zone, _, machine_type = machine_type.split("/")

        extra_mem = machine_type.endswith("-ext")

        if machine_type.startswith("custom"):
            cpu = cls.CPUSeries.N1
            _, cores, memory = machine_type.rsplit("-", maxsplit=2)
        else:
            if extra_mem:
                cpu_series, _, cores, memory, _ = machine_type.split("-")
            else:
                cpu_series, _, cores, memory = machine_type.split("-")
            if cpu_series == "n2":
                cpu = cls.CPUSeries.N2
            elif cpu_series == "n2d":
                cpu = cls.CPUSeries.N2D
            elif cpu_series == "e2":
                cpu = cls.CPUSeries.E2
                if cores == "micro":
                    cpu = cls.CPUSeries.E2_MICRO
                    cores = 2
                elif cores == "small":
                    cpu = cls.CPUSeries.E2_SMALL
                    cores = 2
                elif cores == "medium":
                    cpu = cls.CPUSeries.E2_MEDIUM
                    cores = 2
            else:
                raise RuntimeError("Unknown CPU series.")

        cores = int(cores)
        memory = int(memory)

        return cls(zone, cpu, memory, cores)


def get_image_from_family(project: str, family: str) -> compute_v1.Image:
    """
    Retrieve the newest image that is part of a given family in a project.

    Args:
        project: project ID or project number of the Cloud project you want to get image from.
        family: name of the image family you want to get image from.

    Returns:
        An Image object.
    """
    image_client = compute_v1.ImagesClient()
    # List of public operating system (OS) images: https://cloud.google.com/compute/docs/images/os-details
    newest_image = image_client.get_from_family(project=project, family=family)
    return newest_image


def disk_from_image(
    disk_type: str,
    disk_size_gb: int,
    boot: bool,
    source_image: str,
    auto_delete: bool = True,
) -> compute_v1.AttachedDisk:
    """
    Create an AttachedDisk object to be used in VM instance creation. Uses an image as the
    source for the new disk.

    Args:
         disk_type: the type of disk you want to create. This value uses the following format:
            "zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".
            For example: "zones/us-west3-b/diskTypes/pd-ssd"
        disk_size_gb: size of the new disk in gigabytes
        boot: boolean flag indicating whether this disk should be used as a boot disk of an instance
        source_image: source image to use when creating this disk. You must have read access to this disk. This can be one
            of the publicly available images or an image from one of your projects.
            This value uses the following format: "projects/{project_name}/global/images/{image_name}"
        auto_delete: boolean flag indicating whether this disk should be deleted with the VM that uses it

    Returns:
        AttachedDisk object configured to be created using the specified image.
    """
    boot_disk = compute_v1.AttachedDisk()
    initialize_params = compute_v1.AttachedDiskInitializeParams()
    initialize_params.source_image = source_image
    initialize_params.disk_size_gb = disk_size_gb
    initialize_params.disk_type = disk_type
    boot_disk.initialize_params = initialize_params
    # Remember to set auto_delete to True if you want the disk to be deleted when you delete
    # your VM instance.
    boot_disk.auto_delete = auto_delete
    boot_disk.boot = boot
    return boot_disk


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 create_instance(
    project_id: str,
    zone: str,
    instance_name: str,
    disks: list[compute_v1.AttachedDisk],
    machine_type: str = "n1-standard-1",
    network_link: str = "global/networks/default",
    subnetwork_link: str = None,
    internal_ip: str = None,
    external_access: bool = False,
    external_ipv4: str = None,
    accelerators: list[compute_v1.AcceleratorConfig] = None,
    preemptible: bool = False,
    spot: bool = False,
    instance_termination_action: str = "STOP",
    custom_hostname: str = None,
    delete_protection: bool = False,
) -> compute_v1.Instance:
    """
    Send an instance creation request to the Compute Engine API and wait for it to complete.

    Args:
        project_id: project ID or project number of the Cloud project you want to use.
        zone: name of the zone to create the instance in. For example: "us-west3-b"
        instance_name: name of the new virtual machine (VM) instance.
        disks: a list of compute_v1.AttachedDisk objects describing the disks
            you want to attach to your new instance.
        machine_type: machine type of the VM being created. This value uses the
            following format: "zones/{zone}/machineTypes/{type_name}".
            For example: "zones/europe-west3-c/machineTypes/f1-micro"
        network_link: name of the network you want the new instance to use.
            For example: "global/networks/default" represents the network
            named "default", which is created automatically for each project.
        subnetwork_link: name of the subnetwork you want the new instance to use.
            This value uses the following format:
            "regions/{region}/subnetworks/{subnetwork_name}"
        internal_ip: internal IP address you want to assign to the new instance.
            By default, a free address from the pool of available internal IP addresses of
            used subnet will be used.
        external_access: boolean flag indicating if the instance should have an external IPv4
            address assigned.
        external_ipv4: external IPv4 address to be assigned to this instance. If you specify
            an external IP address, it must live in the same region as the zone of the instance.
            This setting requires `external_access` to be set to True to work.
        accelerators: a list of AcceleratorConfig objects describing the accelerators that will
            be attached to the new instance.
        preemptible: boolean value indicating if the new instance should be preemptible
            or not. Preemptible VMs have been deprecated and you should now use Spot VMs.
        spot: boolean value indicating if the new instance should be a Spot VM or not.
        instance_termination_action: What action should be taken once a Spot VM is terminated.
            Possible values: "STOP", "DELETE"
        custom_hostname: Custom hostname of the new VM instance.
            Custom hostnames must conform to RFC 1035 requirements for valid hostnames.
        delete_protection: boolean value indicating if the new virtual machine should be
            protected against deletion or not.
    Returns:
        Instance object.
    """
    instance_client = compute_v1.InstancesClient()

    # Use the network interface provided in the network_link argument.
    network_interface = compute_v1.NetworkInterface()
    network_interface.network = network_link
    if subnetwork_link:
        network_interface.subnetwork = subnetwork_link

    if internal_ip:
        network_interface.network_i_p = internal_ip

    if external_access:
        access = compute_v1.AccessConfig()
        access.type_ = compute_v1.AccessConfig.Type.ONE_TO_ONE_NAT.name
        access.name = "External NAT"
        access.network_tier = access.NetworkTier.PREMIUM.name
        if external_ipv4:
            access.nat_i_p = external_ipv4
        network_interface.access_configs = [access]

    # Collect information into the Instance object.
    instance = compute_v1.Instance()
    instance.network_interfaces = [network_interface]
    instance.name = instance_name
    instance.disks = disks
    if re.match(r"^zones/[a-z\d\-]+/machineTypes/[a-z\d\-]+$", machine_type):
        instance.machine_type = machine_type
    else:
        instance.machine_type = f"zones/{zone}/machineTypes/{machine_type}"

    instance.scheduling = compute_v1.Scheduling()
    if accelerators:
        instance.guest_accelerators = accelerators
        instance.scheduling.on_host_maintenance = (
            compute_v1.Scheduling.OnHostMaintenance.TERMINATE.name
        )

    if preemptible:
        # Set the preemptible setting
        warnings.warn(
            "Preemptible VMs are being replaced by Spot VMs.", DeprecationWarning
        )
        instance.scheduling = compute_v1.Scheduling()
        instance.scheduling.preemptible = True

    if spot:
        # Set the Spot VM setting
        instance.scheduling.provisioning_model = (
            compute_v1.Scheduling.ProvisioningModel.SPOT.name
        )
        instance.scheduling.instance_termination_action = instance_termination_action

    if custom_hostname is not None:
        # Set the custom hostname for the instance
        instance.hostname = custom_hostname

    if delete_protection:
        # Set the delete protection bit
        instance.deletion_protection = True

    # Prepare the request to insert an instance.
    request = compute_v1.InsertInstanceRequest()
    request.zone = zone
    request.project = project_id
    request.instance_resource = instance

    # Wait for the create operation to complete.
    print(f"Creating the {instance_name} instance in {zone}...")

    operation = instance_client.insert(request=request)

    wait_for_extended_operation(operation, "instance creation")

    print(f"Instance {instance_name} created.")
    return instance_client.get(project=project_id, zone=zone, instance=instance_name)


def create_custom_instance(
    project_id: str,
    zone: str,
    instance_name: str,
    cpu_series: CustomMachineType.CPUSeries,
    core_count: int,
    memory: int,
) -> compute_v1.Instance:
    """
    Create a new VM instance with a custom machine type.

    Args:
        project_id: project ID or project number of the Cloud project you want to use.
        zone: name of the zone to create the instance in. For example: "us-west3-b"
        instance_name: name of the new virtual machine (VM) instance.
        cpu_series: the type of CPU you want to use. Select one value from the CustomMachineType.CPUSeries enum.
            For example: CustomMachineType.CPUSeries.N2
        core_count: number of CPU cores you want to use.
        memory: the amount of memory for the VM instance, in megabytes.

    Return:
        Instance object.
    """
    assert cpu_series in (
        CustomMachineType.CPUSeries.E2,
        CustomMachineType.CPUSeries.N1,
        CustomMachineType.CPUSeries.N2,
        CustomMachineType.CPUSeries.N2D,
    )
    custom_type = CustomMachineType(zone, cpu_series, memory, core_count)

    newest_debian = get_image_from_family(project="debian-cloud", family="debian-12")
    disk_type = f"zones/{zone}/diskTypes/pd-standard"
    disks = [disk_from_image(disk_type, 10, True, newest_debian.self_link)]

    return create_instance(project_id, zone, instance_name, disks, str(custom_type))

DESCANSAR

Utilizando el método instances.insert , cree una solicitud de creación de instancia y especifique los valores personalizados machineType . Proporcione la memoria en MB .

  • Para la serie de máquinas N1, comience con la personalizada.
  • Para el núcleo compartido E2, el NUMBER_OF_CPU es micro , small o medium .
  • Para habilitar la memoria extendida, incluya -ext al final del tipo de máquina.

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

Cuerpo de solicitud de ejemplo

      {
    "name": "exampleinstance",
    "machineType": "zones/us-central1-a/machineTypes/n2-custom-16-107520",
    "disks": [
      {
        "boot": true,
        "diskSizeGb": 10,
        "initializeParams": {
          "sourceImage": "projects/debian-cloud/global/images/family/debian-11"
        }
      }
    ],
    "networkInterfaces": [
      {
        "network": "global/networks/default"
      }
    ]
  }
```

De manera similar, puede crear instancias interrumpibles y grupos de instancias con tipos de máquinas personalizados.

Agregar memoria extendida durante la creación de la instancia

Para crear una instancia de VM con memoria extendida, haga lo siguiente:

Consola

  1. En el Google Cloud consola, vaya a la página Crear una instancia .

    Ir a Crear una instancia

  2. En el panel de configuración de la máquina , haga lo siguiente:

    1. En la lista Zona , seleccione la zona donde desea alojar esta VM. La lista de Series se filtra para incluir solo las familias de tipos de máquinas disponibles en la zona seleccionada.
    2. Seleccione De uso general .
      1. En la lista Serie , seleccione N4 , N2 , N2D , N1 para crear un tipo de máquina personalizado.
      2. Para especificar la cantidad de vCPU, arrastre el control deslizante Núcleos o ingrese el valor en el campo.
      3. Para agregar memoria extendida, seleccione Ampliar memoria . Para especificar la cantidad de memoria para el tipo de máquina, arrastre el control deslizante Memoria o ingrese el valor en el campo. La consola muestra un costo estimado para la VM a medida que edita la cantidad de vCPU y memoria.
  3. Opcional: especifique otras opciones de configuración. Para obtener más información, consulte Opciones de configuración durante la creación de instancias .

  4. Para crear e iniciar la VM, haga clic en Crear .

nube de gcloud

Cree una máquina personalizada mediante el comando gcloud compute instances create con la opción --machine-type .

  gcloud compute instances create  INSTANCE_NAME\
    --machine-type=MACHINE_TYPE-custom-NUMBER_OF_VCPUS-AMOUNT_OF_MEMORY_MB

Reemplace lo siguiente:

  • INSTANCE_NAME : nombre de la instancia
  • MACHINE_TYPE : tipo de máquina, como N2
  • NUMBER_OF_VCPUS : número de vCPU
  • AMOUNT_OF_MEMORY_MB : cantidad de memoria en MB o GB

A continuación se muestra un ejemplo que utiliza un tipo de máquina N2 con 48 vCPU y 310 GB de memoria en la zona us-central1-a :

  gcloud compute instances create example-instance \
    --zone=us-central1-a --machine-type=n2-custom-48-317440

Ir

Antes de probar este ejemplo, sigue las instrucciones de configuración Go en el inicio rápido de Compute Engine usando bibliotecas cliente . Para obtener más información, consulta la documentación de referencia de la API Go de Compute Engine .

Para autenticarse en Compute Engine, configure las credenciales predeterminadas de la aplicación. Para obtener más información, consulte Configurar la autenticación para un entorno de desarrollo local .

import (
	"context"
	"fmt"
	"io"

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

// createInstanceWithExtraMemWithoutHelper сreates new VM instances with extra memory
// without using a CustomMachineType struct.
func createInstanceWithExtraMemWithoutHelper(
	w io.Writer,
	projectID, zone, instanceName, cpuSeries string,
	coreCount, memory int,
) error {
	// projectID := "your_project_id"
	// zone := "europe-central2-b"
	// instanceName := "your_instance_name"
	// cpuSeries := "N1"
	// coreCount := 2 // number of CPU cores you want to use.
	// memory := 256 // the amount of memory for the VM instance, in megabytes.

	// The coreCount and memory values are not validated anywhere and can be rejected by the API.

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

	mt := fmt.Sprintf("zones/%s/machineTypes/%v-%v-%v-ext", zone, cpuSeries, coreCount, memory)
	inst := &computepb.Instance{
		Name: proto.String(instanceName),
		Disks: []*computepb.AttachedDisk{
			{
				InitializeParams: &computepb.AttachedDiskInitializeParams{
					DiskSizeGb: proto.Int64(10),
					SourceImage: proto.String(
						"projects/debian-cloud/global/images/family/debian-12",
					),
				},
				AutoDelete: proto.Bool(true),
				Boot:       proto.Bool(true),
			},
		},
		MachineType: proto.String(mt),
		NetworkInterfaces: []*computepb.NetworkInterface{
			{
				Name: proto.String("global/networks/default"),
			},
		},
	}

	req := &computepb.InsertInstanceRequest{
		Project:          projectID,
		Zone:             zone,
		InstanceResource: inst,
	}

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

	return nil
}

Java

Antes de probar este ejemplo, sigue las instrucciones de configuración Java en el inicio rápido de Compute Engine usando bibliotecas cliente . Para obtener más información, consulta la documentación de referencia de la API Java de Compute Engine .

Para autenticarse en Compute Engine, configure las credenciales predeterminadas de la aplicación. Para obtener más información, consulte Configurar la autenticación para un entorno de desarrollo local .


import com.google.cloud.compute.v1.AttachedDisk;
import com.google.cloud.compute.v1.AttachedDiskInitializeParams;
import com.google.cloud.compute.v1.InsertInstanceRequest;
import com.google.cloud.compute.v1.Instance;
import com.google.cloud.compute.v1.InstancesClient;
import com.google.cloud.compute.v1.NetworkInterface;
import com.google.cloud.compute.v1.Operation;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class ExtraMemoryWithoutHelper {

  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-google-cloud-project-id";
    // Name of the zone to create the instance in. For example: "us-west3-b".
    String zone = "google-cloud-zone";
    // Name of the new virtual machine (VM) instance.
    String instanceName = "instance-name";
    String cpuSeries = "N1";
    // Number of CPU cores you want to use.
    int coreCount = 2;
    // The amount of memory for the VM instance, in megabytes.
    int memory = 256;

    createInstanceWithExtraMemoryWithoutHelper(projectId, zone, instanceName, cpuSeries, coreCount,
        memory);
  }

  // Create VM instances with extra memory without using a CustomMachineType class and
  // return the created Instance.
  public static void createInstanceWithExtraMemoryWithoutHelper(
      String project, String zone, String instanceName, String cpuSeries, int coreCount, int memory)
      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()) {

      // The coreCount and memory values are not validated anywhere and can be rejected by the API.
      String machineType = String.format("zones/%s/machineTypes/%s-%s-%s-ext", zone, cpuSeries,
          coreCount, memory);

      AttachedDisk attachedDisk = AttachedDisk.newBuilder()
          .setInitializeParams(
              // Describe the size and source image of the boot disk to attach to the instance.
              // The list of public images available in Compute Engine can be found here:
              // https://cloud.google.com/compute/docs/images#list_of_public_images_available_on
              AttachedDiskInitializeParams.newBuilder()
                  .setSourceImage(
                      String.format("projects/%s/global/images/family/%s", "debian-cloud",
                          "debian-11"))
                  .setDiskSizeGb(10)
                  .build()
          )
          // Remember to set auto_delete to True if you want the disk to be deleted when you delete
          // your VM instance.
          .setAutoDelete(true)
          .setBoot(true)
          .build();

      // Create the Instance object with the relevant information.
      Instance instance = Instance.newBuilder()
          .setName(instanceName)
          .addDisks(attachedDisk)
          .setMachineType(machineType)
          .addNetworkInterfaces(
              NetworkInterface.newBuilder().setName("global/networks/default").build())
          .build();

      // Create the insert instance request object.
      InsertInstanceRequest insertInstanceRequest = InsertInstanceRequest.newBuilder()
          .setProject(project)
          .setZone(zone)
          .setInstanceResource(instance)
          .build();

      // Invoke the API with the request object and wait for the operation to complete.
      Operation response = instancesClient.insertAsync(insertInstanceRequest)
          .get(3, TimeUnit.MINUTES);

      // Check for errors.
      if (response.hasError()) {
        System.out.println("Instance creation failed!!" + response);
        return;
      }
      System.out.printf("Instance created : %s", instanceName);
      System.out.println("Operation Status: " + response.getStatus());
    }
  }
}

Nodo.js

Antes de probar este ejemplo, sigue las instrucciones de configuración de Node.js en el inicio rápido de Compute Engine usando bibliotecas cliente . Para obtener más información, consulta la documentación de referencia de la API de Compute Engine Node.js

Para autenticarse en Compute Engine, configure las credenciales predeterminadas de la aplicación. Para obtener más información, consulte Configurar la autenticación para un entorno de desarrollo 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 cpuSeries = 'N1';
// const coreCount = 2
// const memory = 256

// The coreCount and memory values are not validated anywhere and can be rejected by the API.

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

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

  const machineType = `zones/${zone}/machineTypes/${cpuSeries}-${coreCount}-${memory}-ext`;

  const [response] = await instancesClient.insert({
    instanceResource: {
      name: instanceName,
      disks: [
        {
          initializeParams: {
            diskSizeGb: '64',
            sourceImage:
              'projects/debian-cloud/global/images/family/debian-11/',
          },
          autoDelete: true,
          boot: true,
        },
      ],
      machineType,
      networkInterfaces: [
        {
          name: 'global/networks/default',
        },
      ],
    },
    project: projectId,
    zone,
  });
  let operation = response.latestResponse;
  const operationsClient = new compute.ZoneOperationsClient();

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

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

createInstanceWithExtraMemWithoutHelper();

Pitón

Antes de probar este ejemplo, sigue las instrucciones de configuración Python en el inicio rápido de Compute Engine usando bibliotecas cliente . Para obtener más información, consulta la documentación de referencia de la API Python de Compute Engine .

Para autenticarse en Compute Engine, configure las credenciales predeterminadas de la aplicación. Para obtener más información, consulte Configurar la autenticación para un entorno de desarrollo local .

from __future__ import annotations

import re
import sys
from typing import Any
import warnings

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


def get_image_from_family(project: str, family: str) -> compute_v1.Image:
    """
    Retrieve the newest image that is part of a given family in a project.

    Args:
        project: project ID or project number of the Cloud project you want to get image from.
        family: name of the image family you want to get image from.

    Returns:
        An Image object.
    """
    image_client = compute_v1.ImagesClient()
    # List of public operating system (OS) images: https://cloud.google.com/compute/docs/images/os-details
    newest_image = image_client.get_from_family(project=project, family=family)
    return newest_image


def disk_from_image(
    disk_type: str,
    disk_size_gb: int,
    boot: bool,
    source_image: str,
    auto_delete: bool = True,
) -> compute_v1.AttachedDisk:
    """
    Create an AttachedDisk object to be used in VM instance creation. Uses an image as the
    source for the new disk.

    Args:
         disk_type: the type of disk you want to create. This value uses the following format:
            "zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".
            For example: "zones/us-west3-b/diskTypes/pd-ssd"
        disk_size_gb: size of the new disk in gigabytes
        boot: boolean flag indicating whether this disk should be used as a boot disk of an instance
        source_image: source image to use when creating this disk. You must have read access to this disk. This can be one
            of the publicly available images or an image from one of your projects.
            This value uses the following format: "projects/{project_name}/global/images/{image_name}"
        auto_delete: boolean flag indicating whether this disk should be deleted with the VM that uses it

    Returns:
        AttachedDisk object configured to be created using the specified image.
    """
    boot_disk = compute_v1.AttachedDisk()
    initialize_params = compute_v1.AttachedDiskInitializeParams()
    initialize_params.source_image = source_image
    initialize_params.disk_size_gb = disk_size_gb
    initialize_params.disk_type = disk_type
    boot_disk.initialize_params = initialize_params
    # Remember to set auto_delete to True if you want the disk to be deleted when you delete
    # your VM instance.
    boot_disk.auto_delete = auto_delete
    boot_disk.boot = boot
    return boot_disk


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 create_instance(
    project_id: str,
    zone: str,
    instance_name: str,
    disks: list[compute_v1.AttachedDisk],
    machine_type: str = "n1-standard-1",
    network_link: str = "global/networks/default",
    subnetwork_link: str = None,
    internal_ip: str = None,
    external_access: bool = False,
    external_ipv4: str = None,
    accelerators: list[compute_v1.AcceleratorConfig] = None,
    preemptible: bool = False,
    spot: bool = False,
    instance_termination_action: str = "STOP",
    custom_hostname: str = None,
    delete_protection: bool = False,
) -> compute_v1.Instance:
    """
    Send an instance creation request to the Compute Engine API and wait for it to complete.

    Args:
        project_id: project ID or project number of the Cloud project you want to use.
        zone: name of the zone to create the instance in. For example: "us-west3-b"
        instance_name: name of the new virtual machine (VM) instance.
        disks: a list of compute_v1.AttachedDisk objects describing the disks
            you want to attach to your new instance.
        machine_type: machine type of the VM being created. This value uses the
            following format: "zones/{zone}/machineTypes/{type_name}".
            For example: "zones/europe-west3-c/machineTypes/f1-micro"
        network_link: name of the network you want the new instance to use.
            For example: "global/networks/default" represents the network
            named "default", which is created automatically for each project.
        subnetwork_link: name of the subnetwork you want the new instance to use.
            This value uses the following format:
            "regions/{region}/subnetworks/{subnetwork_name}"
        internal_ip: internal IP address you want to assign to the new instance.
            By default, a free address from the pool of available internal IP addresses of
            used subnet will be used.
        external_access: boolean flag indicating if the instance should have an external IPv4
            address assigned.
        external_ipv4: external IPv4 address to be assigned to this instance. If you specify
            an external IP address, it must live in the same region as the zone of the instance.
            This setting requires `external_access` to be set to True to work.
        accelerators: a list of AcceleratorConfig objects describing the accelerators that will
            be attached to the new instance.
        preemptible: boolean value indicating if the new instance should be preemptible
            or not. Preemptible VMs have been deprecated and you should now use Spot VMs.
        spot: boolean value indicating if the new instance should be a Spot VM or not.
        instance_termination_action: What action should be taken once a Spot VM is terminated.
            Possible values: "STOP", "DELETE"
        custom_hostname: Custom hostname of the new VM instance.
            Custom hostnames must conform to RFC 1035 requirements for valid hostnames.
        delete_protection: boolean value indicating if the new virtual machine should be
            protected against deletion or not.
    Returns:
        Instance object.
    """
    instance_client = compute_v1.InstancesClient()

    # Use the network interface provided in the network_link argument.
    network_interface = compute_v1.NetworkInterface()
    network_interface.network = network_link
    if subnetwork_link:
        network_interface.subnetwork = subnetwork_link

    if internal_ip:
        network_interface.network_i_p = internal_ip

    if external_access:
        access = compute_v1.AccessConfig()
        access.type_ = compute_v1.AccessConfig.Type.ONE_TO_ONE_NAT.name
        access.name = "External NAT"
        access.network_tier = access.NetworkTier.PREMIUM.name
        if external_ipv4:
            access.nat_i_p = external_ipv4
        network_interface.access_configs = [access]

    # Collect information into the Instance object.
    instance = compute_v1.Instance()
    instance.network_interfaces = [network_interface]
    instance.name = instance_name
    instance.disks = disks
    if re.match(r"^zones/[a-z\d\-]+/machineTypes/[a-z\d\-]+$", machine_type):
        instance.machine_type = machine_type
    else:
        instance.machine_type = f"zones/{zone}/machineTypes/{machine_type}"

    instance.scheduling = compute_v1.Scheduling()
    if accelerators:
        instance.guest_accelerators = accelerators
        instance.scheduling.on_host_maintenance = (
            compute_v1.Scheduling.OnHostMaintenance.TERMINATE.name
        )

    if preemptible:
        # Set the preemptible setting
        warnings.warn(
            "Preemptible VMs are being replaced by Spot VMs.", DeprecationWarning
        )
        instance.scheduling = compute_v1.Scheduling()
        instance.scheduling.preemptible = True

    if spot:
        # Set the Spot VM setting
        instance.scheduling.provisioning_model = (
            compute_v1.Scheduling.ProvisioningModel.SPOT.name
        )
        instance.scheduling.instance_termination_action = instance_termination_action

    if custom_hostname is not None:
        # Set the custom hostname for the instance
        instance.hostname = custom_hostname

    if delete_protection:
        # Set the delete protection bit
        instance.deletion_protection = True

    # Prepare the request to insert an instance.
    request = compute_v1.InsertInstanceRequest()
    request.zone = zone
    request.project = project_id
    request.instance_resource = instance

    # Wait for the create operation to complete.
    print(f"Creating the {instance_name} instance in {zone}...")

    operation = instance_client.insert(request=request)

    wait_for_extended_operation(operation, "instance creation")

    print(f"Instance {instance_name} created.")
    return instance_client.get(project=project_id, zone=zone, instance=instance_name)


def create_custom_instances_extra_mem(
    project_id: str, zone: str, instance_name: str, core_count: int, memory: int
) -> list[compute_v1.Instance]:
    """
    Create 3 new VM instances with extra memory without using a CustomMachineType helper class.

    Args:
        project_id: project ID or project number of the Cloud project you want to use.
        zone: name of the zone to create the instance in. For example: "us-west3-b"
        instance_name: name of the new virtual machine (VM) instance.
        core_count: number of CPU cores you want to use.
        memory: the amount of memory for the VM instance, in megabytes.

    Returns:
        List of Instance objects.
    """
    newest_debian = get_image_from_family(project="debian-cloud", family="debian-12")
    disk_type = f"zones/{zone}/diskTypes/pd-standard"
    disks = [disk_from_image(disk_type, 10, True, newest_debian.self_link)]
    # The core_count and memory values are not validated anywhere and can be rejected by the API.
    instances = [
        create_instance(
            project_id,
            zone,
            f"{instance_name}_n1_extra_mem",
            disks,
            f"zones/{zone}/machineTypes/custom-{core_count}-{memory}-ext",
        ),
        create_instance(
            project_id,
            zone,
            f"{instance_name}_n2_extra_mem",
            disks,
            f"zones/{zone}/machineTypes/n2-custom-{core_count}-{memory}-ext",
        ),
        create_instance(
            project_id,
            zone,
            f"{instance_name}_n2d_extra_mem",
            disks,
            f"zones/{zone}/machineTypes/n2d-custom-{core_count}-{memory}-ext",
        ),
    ]
    return instances

DESCANSAR

Utilizando el método instances.insert , cree su solicitud de creación de instancia como lo haría para crear una instancia con memoria personalizada. Incluya -ext , que indica memoria extendida, al especificar los valores machineType :

  • Para todos los tipos de máquinas personalizadas, agregue -ext para ampliar la memoria hasta el límite descrito por esa familia de máquinas en particular.
        zones/ZONE/machineTypes//MACHINE_TYPE-NUMBER_OF_CPUS-AMOUNT_OF_MEMORY-ext

Reemplace lo siguiente:

  • ZONE : Ubicación de la máquina
  • MACHINE_TYPE : tipo de máquina, como N2 o E2 pequeña
  • NUMBER_OF_CPUS : cantidad de vCPU
  • AMOUNT_OF_MEMORY_MB : cantidad de memoria en MB

Por ejemplo, lo siguiente especifica un tipo de máquina N2 con 2 vCPU y 20 GB de memoria; tenga en cuenta que debe convertir la memoria a MB:

zones/ZONE/machineTypes/n2-custom-2-20480-ext

Agregar memoria extendida a una instancia de VM existente

Para agregar más memoria a una instancia existente que utiliza un tipo de máquina personalizada, primero debe detener la instancia . Después de que la instancia se detenga, complete los siguientes pasos para agregar más memoria a la VM.

Consola

  1. En el Google Cloud consola, vaya a la página de instancias de VM .

    Ir a instancias de VM

  2. Elija la VM detenida que desea modificar de la lista de VM.

  3. Haga clic en Editar en la parte superior de la página.

  4. En Configuración de la máquina , seleccione Propósito general .

  5. En la sección Tipo de máquina , seleccione Personalizado .

  6. Seleccione la cantidad de vCPU que desee.

  7. Para agregar memoria extendida, seleccione Ampliar memoria y luego especifique la cantidad de memoria que desea.

  8. Guarde sus cambios.

nube de gcloud

Usa el comando gcloud compute instances stop para detener la VM. Luego use el comando gcloud compute instances set-machine-type con las opciones --custom-memory y --custom-extensions para editar los recursos de la máquina.

Guarde los cambios y reinicie la VM.

Ir

Antes de probar este ejemplo, sigue las instrucciones de configuración Go en el inicio rápido de Compute Engine usando bibliotecas cliente . Para obtener más información, consulta la documentación de referencia de la API Go de Compute Engine .

Para autenticarse en Compute Engine, configure las credenciales predeterminadas de la aplicación. Para obtener más información, consulte Configurar la autenticación para un entorno de desarrollo local .

import (
	"context"
	"fmt"
	"io"
	"strings"

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

// modifyInstanceWithExtendedMemory sends an instance creation request
// to the Compute Engine API and waits for it to complete.
func modifyInstanceWithExtendedMemory(
	w io.Writer,
	projectID, zone, instanceName string,
	newMemory int,
) error {
	// projectID := "your_project_id"
	// zone := "europe-central2-b"
	// instanceName := "your_instance_name"
	// newMemory := 256 // the amount of memory for the VM instance, in megabytes.

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

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

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

	containsString := func(s []string, str string) bool {
		for _, v := range s {
			if v == str {
				return true
			}
		}

		return false
	}

	if !(strings.Contains(instance.GetMachineType(), "machineTypes/n1-") ||
		strings.Contains(instance.GetMachineType(), "machineTypes/n2-") ||
		strings.Contains(instance.GetMachineType(), "machineTypes/n2d-")) {
		return fmt.Errorf("extra memory is available only for N1, N2 and N2D CPUs")
	}

	// Make sure that the machine is turned off
	if !containsString([]string{"TERMINATED", "STOPPED"}, instance.GetStatus()) {
		reqStop := &computepb.StopInstanceRequest{
			Project:  projectID,
			Zone:     zone,
			Instance: instanceName,
		}

		op, err := instancesClient.Stop(ctx, reqStop)
		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)
		}
	}

	// Modify the machine definition, remember that extended memory
	// is available only for N1, N2 and N2D CPUs
	machineType := instance.GetMachineType()
	start := machineType[:strings.LastIndex(machineType, "-")]

	updateReq := &computepb.SetMachineTypeInstanceRequest{
		Project:  projectID,
		Zone:     zone,
		Instance: instanceName,
		InstancesSetMachineTypeRequestResource: &computepb.InstancesSetMachineTypeRequest{
			MachineType: proto.String(fmt.Sprintf("%s-%v-ext", start, newMemory)),
		},
	}
	op, err := instancesClient.SetMachineType(ctx, updateReq)
	if err != nil {
		return fmt.Errorf("unable to update 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 updated\n")

	return nil

}

Java

Antes de probar este ejemplo, sigue las instrucciones de configuración Java en el inicio rápido de Compute Engine usando bibliotecas cliente . Para obtener más información, consulta la documentación de referencia de la API Java de Compute Engine .

Para autenticarse en Compute Engine, configure las credenciales predeterminadas de la aplicación. Para obtener más información, consulte Configurar la autenticación para un entorno de desarrollo local .


import com.google.api.gax.longrunning.OperationFuture;
import com.google.cloud.compute.v1.GetInstanceRequest;
import com.google.cloud.compute.v1.Instance;
import com.google.cloud.compute.v1.Instance.Status;
import com.google.cloud.compute.v1.InstancesClient;
import com.google.cloud.compute.v1.InstancesSetMachineTypeRequest;
import com.google.cloud.compute.v1.Operation;
import com.google.cloud.compute.v1.SetMachineTypeInstanceRequest;
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 UpdateMemory {

  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-google-cloud-project-id";
    // Name of the zone to create the instance in. For example: "us-west3-b".
    String zone = "google-cloud-zone";
    // Name of the new virtual machine (VM) instance.
    String instanceName = "instance-name";
    // The amount of memory for the VM instance, in megabytes.
    int newMemory = 256;

    modifyInstanceWithExtendedMemory(projectId, zone, instanceName, newMemory);
  }

  // Modify an existing VM to use extended memory and return the modified Instance.
  public static void modifyInstanceWithExtendedMemory(
      String project, String zone, String instanceName, int newMemory)
      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 get instance request object.
      GetInstanceRequest getInstanceRequest = GetInstanceRequest.newBuilder()
          .setProject(project)
          .setZone(zone)
          .setInstance(instanceName)
          .build();

      Instance instance = instancesClient.get(getInstanceRequest);

      // Check the machine type.
      if (!(instance.getMachineType().contains("machineTypes/n1-")
          || instance.getMachineType().contains("machineTypes/n2-")
          || instance.getMachineType().contains("machineTypes/n2d-"))) {
        System.out.println("extra memory is available only for N1, N2 and N2D CPUs");
        return;
      }

      // Make sure that the machine is turned off.
      if (!(instance.getStatus().equals(Status.TERMINATED.toString())
          || instance.getStatus().equals(Status.STOPPED.toString()))) {

        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.hasError()) {
          System.out.printf("Unable to stop instance %s", response.getError());
          return;
        }
      }

      // Modify the machine definition. Note that extended memory
      // is available only for N1, N2 and N2D CPUs.
      String machineType = instance.getMachineType();
      String start = machineType.substring(0, machineType.lastIndexOf("-"));

      // Create the machine type instance request object.
      SetMachineTypeInstanceRequest setMachineTypeInstanceRequest =
          SetMachineTypeInstanceRequest.newBuilder()
              .setProject(project)
              .setZone(zone)
              .setInstance(instanceName)
              .setInstancesSetMachineTypeRequestResource(InstancesSetMachineTypeRequest.newBuilder()
                  .setMachineType(String.format("%s-%d-ext", start, newMemory))
                  .build())
              .build();

      // Invoke the API with the request object and wait for the operation to complete.
      Operation response = instancesClient.setMachineTypeAsync(setMachineTypeInstanceRequest)
          .get(3, TimeUnit.MINUTES);

      // Check for errors.
      if (response.hasError()) {
        System.out.printf("Unable to update instance %s", response.getError());
        return;
      }
      System.out.println("Instance updated!");
    }
  }
}

Nodo.js

Antes de probar este ejemplo, sigue las instrucciones de configuración de Node.js en el inicio rápido de Compute Engine usando bibliotecas cliente . Para obtener más información, consulta la documentación de referencia de la API de Compute Engine Node.js

Para autenticarse en Compute Engine, configure las credenciales predeterminadas de la aplicación. Para obtener más información, consulte Configurar la autenticación para un entorno de desarrollo 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 newMemory = 256;

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

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

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

  if (
    !['machineTypes/n1-', 'machineTypes/n2-', 'machineTypes/n2d-'].some(
      type => instance.machineType.includes(type)
    )
  ) {
    throw new Error('extra memory is available only for N1, N2 and N2D CPUs');
  }

  // Make sure that the machine is turned off
  if (!['TERMINATED', 'STOPPED'].some(status => instance.status === status)) {
    const [response] = await instancesClient.stop({
      project: projectId,
      zone,
      instance: instanceName,
    });

    let operation = response.latestResponse;
    const operationsClient = new compute.ZoneOperationsClient();

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

  // Modify the machine definition, remember that extended memory
  // is available only for N1, N2 and N2D CPUs

  const start = instance.machineType.substring(
    0,
    instance.machineType.lastIndexOf('-')
  );

  const [response] = await instancesClient.setMachineType({
    project: projectId,
    zone,
    instance: instanceName,
    instancesSetMachineTypeRequestResource: {
      machineType: `${start}-${newMemory}-ext`,
    },
  });
  let operation = response.latestResponse;
  const operationsClient = new compute.ZoneOperationsClient();

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

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

modifyInstanceWithExtendedMemory();

Pitón

Antes de probar este ejemplo, sigue las instrucciones de configuración Python en el inicio rápido de Compute Engine usando bibliotecas cliente . Para obtener más información, consulta la documentación de referencia de la API Python de Compute Engine .

Para autenticarse en Compute Engine, configure las credenciales predeterminadas de la aplicación. Para obtener más información, consulte Configurar la autenticación para un entorno de desarrollo local .

from __future__ import annotations

import sys
import time
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 add_extended_memory_to_instance(
    project_id: str, zone: str, instance_name: str, new_memory: int
):
    """
    Modify an existing VM to use extended memory.

    Args:
        project_id: project ID or project number of the Cloud project you want to use.
        zone: name of the zone to create the instance in. For example: "us-west3-b"
        instance_name: name of the new virtual machine (VM) instance.
        new_memory: the amount of memory for the VM instance, in megabytes.

    Returns:
        Instance object.
    """
    instance_client = compute_v1.InstancesClient()
    instance = instance_client.get(
        project=project_id, zone=zone, instance=instance_name
    )

    if not (
        "n1-" in instance.machine_type
        or "n2-" in instance.machine_type
        or "n2d-" in instance.machine_type
    ):
        raise RuntimeError("Extra memory is available only for N1, N2 and N2D CPUs.")

    # Make sure that the machine is turned off
    if instance.status not in (
        instance.Status.TERMINATED.name,
        instance.Status.STOPPED.name,
    ):
        operation = instance_client.stop(
            project=project_id, zone=zone, instance=instance_name
        )
        wait_for_extended_operation(operation, "instance stopping")
        start = time.time()
        while instance.status not in (
            instance.Status.TERMINATED.name,
            instance.Status.STOPPED.name,
        ):
            # Waiting for the instance to be turned off.
            instance = instance_client.get(
                project=project_id, zone=zone, instance=instance_name
            )
            time.sleep(2)
            if time.time() - start >= 300:  # 5 minutes
                raise TimeoutError()

    # Modify the machine definition, remember that extended memory is available only for N1, N2 and N2D CPUs
    start, end = instance.machine_type.rsplit("-", maxsplit=1)
    instance.machine_type = start + f"-{new_memory}-ext"
    # TODO: If you prefer to use the CustomMachineType helper class, uncomment this code and comment the 2 lines above
    # Using CustomMachineType helper
    # cmt = CustomMachineType.from_str(instance.machine_type)
    # cmt.memory_mb = new_memory
    # cmt.extra_memory_used = True
    # instance.machine_type = str(cmt)
    operation = instance_client.update(
        project=project_id,
        zone=zone,
        instance=instance_name,
        instance_resource=instance,
    )
    wait_for_extended_operation(operation, "instance update")

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

DESCANSAR

Utilice el método instances.stop y luego utilice el método instances.setMachineType para editar los recursos del tipo de máquina.

Una vez que detenga la instancia, edite la opción machineTypes con sus cambios.

{

"nombre": " INSTANCE_NAME ", "machineType": "zonas/ ZONE /machineTypes/ MACHINE_TYPE ",

... }

Reemplace lo siguiente:

+ INSTANCE_NAME: The name of the VM
+ ZONE: The zone where your VMs reside
+ MACHINE_TYPE: The name of the VM

¿Qué sigue?