Spot-VMs erstellen und verwenden


Auf dieser Seite wird erläutert, wie Sie Spot-VMs erstellen und verwalten. Dazu gehört Folgendes:

  • Spot-VMs erstellen, starten und ermitteln
  • Vorzeitiges Beenden von Spot-VMs erkennen, verwalten und testen
  • Best Practices für Spot-VMs

Spot-VMs sind VM-Instanzen mit dem Spot-Bereitstellungsmodell. Spot-VMs sind im Vergleich zum Preis von Standard-VMs mit einem Rabatt von bis zu 60 bis 91% verfügbar. Die Compute Engine kann die Ressourcen jedoch jederzeit zurückfordern, indem Spot-VMs vorzeitig beendet werden. Spot-VMs werden nur für fehlertolerante Anwendungen empfohlen, die einem vorzeitigen Beenden von VMs standhalten. Prüfen Sie deshalb, ob Ihre Anwendung ein vorzeitiges Beenden verwalten kann, bevor Sie Spot-VMs erstellen.

Hinweise

  • Lesen Sie die Konzeptdokumentation zu Spot-VMs:
  • Richten Sie die Authentifizierung ein, falls Sie dies noch nicht getan haben. Bei der Authentifizierung wird Ihre Identität für den Zugriff auf Google Cloud-Dienste und APIs überprüft. Zur Ausführung von Code oder Beispielen aus einer lokalen Entwicklungsumgebung können Sie sich bei Compute Engine authentifizieren. Wählen Sie dazu eine der folgenden Optionen aus:

    Select the tab for how you plan to use the samples on this page:

    Console

    When you use the Google Cloud console to access Google Cloud services and APIs, you don't need to set up authentication.

    gcloud

    1. Install the Google Cloud CLI, then initialize it by running the following command:

      gcloud init
    2. Set a default region and zone.
    3. Terraform

      Wenn Sie die Terraform-Beispiele auf dieser Seite in einer lokalen Entwicklungsumgebung verwenden möchten, installieren und initialisieren Sie die gcloud CLI und richten dann die Standardanmeldedaten für Anwendungen mit Ihren Nutzeranmeldedaten ein.

      1. Install the Google Cloud CLI.
      2. To initialize the gcloud CLI, run the following command:

        gcloud init
      3. If you're using a local shell, then create local authentication credentials for your user account:

        gcloud auth application-default login

        You don't need to do this if you're using Cloud Shell.

      Weitere Informationen unter Set up authentication for a local development environment.

      REST

      Verwenden Sie die von der gcloud CLI bereitgestellten Anmeldedaten, um die REST API-Beispiele auf dieser Seite in einer lokalen Entwicklungsumgebung zu verwenden.

        Install the Google Cloud CLI, then initialize it by running the following command:

        gcloud init

      Weitere Informationen finden Sie unter Für die Verwendung von REST authentifizieren in der Dokumentation zur Google Cloud-Authentifizierung.

Spot-VM erstellen

Erstellen Sie eine Spot-VM mit der Google Cloud Console, der gcloud CLI oder der Compute Engine API. Eine Spot-VM ist eine beliebige VM, die für die Verwendung des Spot-Bereitstellungsmodells konfiguriert ist:

  • VM-Bereitstellungsmodell, das in der Google Cloud Console auf Spot gesetzt ist
  • --provisioning-model=SPOT in der gcloud CLI
  • "provisioningModel": "SPOT" in der Compute Engine API

Console

  1. Rufen Sie in der Google Cloud Console die Seite Instanz erstellen auf.

    Zur Seite „Instanz erstellen“

  2. Gehen Sie anschließend so vor:

    1. Wählen Sie im Abschnitt Verfügbarkeitsrichtlinien aus der Liste VM-Bereitstellungsmodell die Option Spot aus. Diese Einstellung deaktiviert die Optionen für den automatischen Neustart und die Hostwartung für die VM und die Option zur Beendigungsaktion.
    2. Optional: Wählen Sie in der Liste Beim Beenden der VM aus, was passiert, wenn Compute Engine die VM vorzeitig beendet:
      • Wählen Sie Beenden (Standardeinstellung) aus, um die VM während des vorzeitigen Beendens zu stoppen.
      • Wählen Sie Löschen aus, um die VM während des vorzeitigen Beendens zu löschen.
  3. Optional: Geben Sie andere VM-Optionen an. Weitere Informationen finden Sie unter VM-Instanz erstellen und starten.

  4. Klicken Sie zum Erstellen und Starten der VM auf Erstellen.

gcloud

Verwenden Sie zum Erstellen einer VM mit der gcloud CLI den Befehl gcloud compute instances create: Zum Erstellen von Spot-VMs müssen Sie das Flag --provisioning-model=SPOT angeben. Optional können Sie mit dem Flag --instance-termination-action auch eine Beendigungsaktion für Spot-VMs festlegen.

gcloud compute instances create VM_NAME \
    --provisioning-model=SPOT \
    --instance-termination-action=TERMINATION_ACTION

Dabei gilt:

  • VM_NAME ist der Name der neuen VM.
  • TERMINATION_ACTION: Optional: Geben Sie an, welche Aktion ausgeführt werden soll, wenn Compute Engine die VM vorzeitig beendet, entweder STOP (Standardverhalten) oder DELETE.

Weitere Informationen zu den Optionen, die Sie beim Erstellen einer VM angeben können, finden Sie unter VM-Instanz erstellen und starten. Verwenden Sie beispielsweise den folgenden Befehl, um Spot-VMs mit einem angegebenen Maschinentyp und Image zu erstellen:

gcloud compute instances create VM_NAME \
    --provisioning-model=SPOT \
    [--image=IMAGE | --image-family=IMAGE_FAMILY] \
    --image-project=IMAGE_PROJECT \
    --machine-type=MACHINE_TYPE \
    --instance-termination-action=TERMINATION_ACTION

Dabei gilt:

  • VM_NAME ist der Name der neuen VM.
  • IMAGE: Wählen Sie eine der folgenden Optionen aus:
    • IMAGE: Eine bestimmte Version eines öffentlichen Image oder der Image-Familie. Ein bestimmtes Image ist beispielsweise --image=debian-10-buster-v20200309.
    • Eine Image-Familie. Dadurch wird die VM aus dem neuesten nicht verworfenen Betriebssystem-Image erstellt. Wenn Sie beispielsweise --image-family=debian-10 angeben, legt Compute Engine eine VM aus der neuesten Version des Betriebssystem-Images in der Debian 10-Image-Familie an.
  • IMAGE_PROJECT ist das Projekt, das das Image enthält. Wenn Sie beispielsweise debian-10 als Image-Familie festlegen, geben Sie debian-cloud als Image-Projekt an.
  • MACHINE_TYPE ist der vordefinierte oder benutzerdefinierte Maschinentyp für die neue VM.
  • TERMINATION_ACTION: Optional: Geben Sie an, welche Aktion ausgeführt werden soll, wenn Compute Engine die VM vorzeitig beendet, entweder STOP (Standardverhalten) oder DELETE.

    Verwenden Sie zum Abrufen einer Liste der in einer Zone verfügbaren Maschinentypen den Befehl gcloud compute machine-types list mit dem Flag --zones.

Terraform

Mit einer Terraform-Ressource können Sie eine Spot-Instanz mit dem Planungsblock erstellen.


resource "google_compute_instance" "spot_vm_instance" {
  name         = "spot-instance-name"
  machine_type = "f1-micro"
  zone         = "us-central1-c"

  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-11"
    }
  }

  scheduling {
    preemptible                 = true
    automatic_restart           = false
    provisioning_model          = "SPOT"
    instance_termination_action = "STOP"
  }

  network_interface {
    # A default network is created for all GCP projects
    network = "default"
    access_config {
    }
  }
}

REST

Wenn Sie eine VM mit der Compute Engine API erstellen möchten, verwenden Sie die Methode instances.insert. Sie müssen dabei einen Maschinentyp und einen Namen für die VM angeben. Optional können Sie ein Image für das Bootlaufwerk festlegen.

Zum Erstellen von Spot-VMs müssen Sie das Feld "provisioningModel": spot angeben. Optional können Sie auch eine Beendigungsaktion für Spot-VMs angeben, indem Sie das Feld "instanceTerminationAction" einfügen.

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances
{
 "machineType": "zones/ZONE/machineTypes/MACHINE_TYPE",
 "name": "VM_NAME",
 "disks": [
   {
     "initializeParams": {
       "sourceImage": "projects/IMAGE_PROJECT/global/images/IMAGE"
     },
     "boot": true
   }
 ]
 "scheduling":
 {
     "provisioningModel": "SPOT",
     "instanceTerminationAction": "TERMINATION_ACTION"
 },
 ...
}

Dabei gilt:

  • PROJECT_ID ist die Projekt-ID des Projekts, in dem die VM erstellt werden soll.
  • ZONE ist die Zone, in der die VM erstellt werden soll. Diese Zone muss auch den Maschinentyp unterstützen, der für die neue VM verwendet werden soll.
  • MACHINE_TYPE ist der vordefinierte oder benutzerdefinierte Maschinentyp für die neue VM.
  • VM_NAME ist der Name der neuen VM.
  • IMAGE_PROJECT: Das Projekt, das das Image enthält. Wenn Sie beispielsweise family/debian-10 als Image-Familie festlegen, geben Sie debian-cloud als Image-Projekt an.
  • IMAGE: Wählen Sie eine der folgenden Optionen aus:
    • Eine bestimmte Version eines öffentlichen Images. Ein bestimmtes Image ist beispielsweise "sourceImage": "projects/debian-cloud/global/images/debian-10-buster-v20200309", wobei debian-cloud das IMAGE_PROJECT ist.
    • Eine Image-Familie. Dadurch wird die VM aus dem neuesten nicht verworfenen Betriebssystem-Image erstellt. Wenn Sie beispielsweise "sourceImage": "projects/debian-cloud/global/images/family/debian-10" angeben, wobei debian-cloud der IMAGE_PROJECT ist, erstellt Compute Engine eine VM aus der neuesten Version des Betriebssystem-Images in Debian. 10-Image-Familie.
  • TERMINATION_ACTION: Optional: Geben Sie an, welche Aktion ausgeführt werden soll, wenn Compute Engine die VM vorzeitig beendet, entweder STOP (Standardverhalten) oder DELETE.

Weitere Informationen zu den Optionen, die Sie beim Erstellen einer VM angeben können, finden Sie unter VM-Instanz erstellen und starten.

Go


import (
	"context"
	"fmt"
	"io"

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

// createSpotInstance creates a new Spot VM instance with Debian 10 operating system.
func createSpotInstance(w io.Writer, projectID, zone, instanceName string) error {
	// projectID := "your_project_id"
	// zone := "europe-central2-b"
	// instanceName := "your_instance_name"

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

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

	req := &computepb.GetFromFamilyImageRequest{
		Project: "debian-cloud",
		Family:  "debian-11",
	}

	image, err := imagesClient.GetFromFamily(ctx, req)
	if err != nil {
		return fmt.Errorf("getImageFromFamily: %w", err)
	}

	diskType := fmt.Sprintf("zones/%s/diskTypes/pd-standard", zone)
	disks := []*computepb.AttachedDisk{
		{
			AutoDelete: proto.Bool(true),
			Boot:       proto.Bool(true),
			InitializeParams: &computepb.AttachedDiskInitializeParams{
				DiskSizeGb:  proto.Int64(10),
				DiskType:    proto.String(diskType),
				SourceImage: proto.String(image.GetSelfLink()),
			},
			Type: proto.String(computepb.AttachedDisk_PERSISTENT.String()),
		},
	}

	req2 := &computepb.InsertInstanceRequest{
		Project: projectID,
		Zone:    zone,
		InstanceResource: &computepb.Instance{
			Name:        proto.String(instanceName),
			Disks:       disks,
			MachineType: proto.String(fmt.Sprintf("zones/%s/machineTypes/%s", zone, "n1-standard-1")),
			NetworkInterfaces: []*computepb.NetworkInterface{
				{
					Name: proto.String("global/networks/default"),
				},
			},
			Scheduling: &computepb.Scheduling{
				ProvisioningModel: proto.String(computepb.Scheduling_SPOT.String()),
			},
		},
	}
	op, err := instancesClient.Insert(ctx, req2)
	if err != nil {
		return fmt.Errorf("insert: %w", err)
	}

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

	instance, err := instancesClient.Get(ctx, &computepb.GetInstanceRequest{
		Project:  projectID,
		Zone:     zone,
		Instance: instanceName,
	})

	if err != nil {
		return fmt.Errorf("createInstance: %w", err)
	}

	fmt.Fprintf(w, "Instance created: %v\n", instance)
	return nil
}

Java


import com.google.cloud.compute.v1.AccessConfig;
import com.google.cloud.compute.v1.AccessConfig.Type;
import com.google.cloud.compute.v1.Address.NetworkTier;
import com.google.cloud.compute.v1.AttachedDisk;
import com.google.cloud.compute.v1.AttachedDiskInitializeParams;
import com.google.cloud.compute.v1.ImagesClient;
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.Scheduling;
import com.google.cloud.compute.v1.Scheduling.ProvisioningModel;
import java.io.IOException;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class CreateSpotVm {
  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 Google Cloud project you want to use.
    String projectId = "your-project-id";
    // Name of the virtual machine to check.
    String instanceName = "your-instance-name";
    // Name of the zone you want to use. For example: "us-west3-b"
    String zone = "your-zone";

    createSpotInstance(projectId, instanceName, zone);
  }

  // Create a new Spot VM instance with Debian 11 operating system.
  public static Instance createSpotInstance(String projectId, String instanceName, String zone)
          throws IOException, ExecutionException, InterruptedException, TimeoutException {
    String image;
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests.
    try (ImagesClient imagesClient = ImagesClient.create()) {
      image = imagesClient.getFromFamily("debian-cloud", "debian-11").getSelfLink();
    }
    AttachedDisk attachedDisk = buildAttachedDisk(image, zone);
    String machineTypes = String.format("zones/%s/machineTypes/%s", zone, "n1-standard-1");

    // Send an instance creation request to the Compute Engine API and wait for it to complete.
    Instance instance =
            createInstance(projectId, zone, instanceName, attachedDisk, true, machineTypes, false);

    System.out.printf("Spot instance '%s' has been created successfully", instance.getName());

    return 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"
  // external_access: boolean flag indicating if the instance should have an external IPv4
  //     address assigned.
  // spot: boolean value indicating if the new instance should be a Spot VM or not.
  private static Instance createInstance(String projectId, String zone, String instanceName,
                                         AttachedDisk disk, boolean isSpot, String machineType,
                                         boolean externalAccess)
          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.
    try (InstancesClient client = InstancesClient.create()) {
      Instance instanceResource =
              buildInstanceResource(instanceName, disk, machineType, externalAccess, isSpot);

      InsertInstanceRequest build = InsertInstanceRequest.newBuilder()
              .setProject(projectId)
              .setRequestId(UUID.randomUUID().toString())
              .setZone(zone)
              .setInstanceResource(instanceResource)
              .build();
      client.insertCallable().futureCall(build).get(60, TimeUnit.SECONDS);

      return client.get(projectId, zone, instanceName);
    }
  }

  private static Instance buildInstanceResource(String instanceName, AttachedDisk disk,
                                                String machineType, boolean externalAccess,
                                                boolean isSpot) {
    NetworkInterface networkInterface =
            networkInterface(externalAccess);
    Instance.Builder builder = Instance.newBuilder()
            .setName(instanceName)
            .addDisks(disk)
            .setMachineType(machineType)
            .addNetworkInterfaces(networkInterface);

    if (isSpot) {
      // Set the Spot VM setting
      Scheduling.Builder scheduling = builder.getScheduling()
              .toBuilder()
              .setProvisioningModel(ProvisioningModel.SPOT.name())
              .setInstanceTerminationAction("STOP");
      builder.setScheduling(scheduling);
    }

    return builder.build();
  }

  private static NetworkInterface networkInterface(boolean externalAccess) {
    NetworkInterface.Builder build = NetworkInterface.newBuilder()
            .setNetwork("global/networks/default");

    if (externalAccess) {
      AccessConfig.Builder accessConfig = AccessConfig.newBuilder()
              .setType(Type.ONE_TO_ONE_NAT.name())
              .setName("External NAT")
              .setNetworkTier(NetworkTier.PREMIUM.name());
      build.addAccessConfigs(accessConfig.build());
    }

    return build.build();
  }

  private static AttachedDisk buildAttachedDisk(String sourceImage, String zone) {
    AttachedDiskInitializeParams initializeParams = AttachedDiskInitializeParams.newBuilder()
            .setSourceImage(sourceImage)
            .setDiskSizeGb(10)
            .setDiskType(String.format("zones/%s/diskTypes/pd-standard", zone))
            .build();
    return AttachedDisk.newBuilder()
            .setInitializeParams(initializeParams)
            // 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();
  }
}

Python

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_spot_instance(
    project_id: str, zone: str, instance_name: str
) -> compute_v1.Instance:
    """
    Create a new Spot VM instance with Debian 10 operating system.

    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.

    Returns:
        Instance object.
    """
    newest_debian = get_image_from_family(project="debian-cloud", family="debian-11")
    disk_type = f"zones/{zone}/diskTypes/pd-standard"
    disks = [disk_from_image(disk_type, 10, True, newest_debian.self_link)]
    instance = create_instance(project_id, zone, instance_name, disks, spot=True)
    return instance

Um mehrere Spot-VMs mit denselben Attributen zu erstellen, können Sie eine Instanzvorlage erstellen und die Vorlage, zur Erstellung einer verwalteten Instanzgruppe (MIG) verwenden. Weitere Informationen finden Sie unter Best Practices.

Spot-VMs starten

Wie andere VMs starten Spot-VMs bei der Erstellung. Ebenso können Sie, wenn Spot-VMs beendet werden, die VMs neu starten und zum Status RUNNING zurückkehren. Sie können vorzeitig beendete Spot-VMs beliebig oft stoppen und neu starten, solange Kapazität vorhanden ist. Weitere Informationen finden Sie unter Lebenszyklus von VM-Instanzen.

Wenn Compute Engine eine oder mehrere Spot-VMs in einer verwalteten Instanzgruppe (Managed Instance Group, MIG) oder einem Google Kubernetes Engine-Cluster (GKE) beendet, startet die Gruppe die VMs neu, sobald die Ressourcen wieder verfügbar sind.

Bereitstellungsmodell und Beendigungsaktion einer VM identifizieren

Ermitteln Sie anhand des Bereitstellungsmodells einer VM, ob es sich um eine Standard-VM, Spot-VM oder präemptive VM handelt. Für eine Spot-VM können Sie auch die Beendigungsaktion identifizieren. Sie können das Bereitstellungsmodell und die Beendigungsaktion einer VM über die Google Cloud Console, die gcloud CLI oder die Compute Engine API identifizieren.

Console

  1. Rufen Sie die Seite VM-Instanzen auf.

    Zur Seite "VM-Instanzen"

  2. Klicken Sie auf den Namen der VM, die Sie ändern möchten. Die Seite VM-Instanzdetails wird geöffnet.

  3. Wechseln Sie unten auf der Seite zum Abschnitt Verwaltung. Aktivieren Sie im Unterbereich Verfügbarkeitsrichtlinien die folgenden Optionen:

    • Wenn das VM-Bereitstellungsmodell auf Spot gesetzt ist, ist die VM eine Spot-VM.
      • Bei VM gibt Beendigung an, welche Aktion ausgeführt werden soll, wenn Compute Engine die VM vorzeitig beendet: entweder beenden oder löschen.
    • Wenn das VM-Bereitstellungsmodell auf Standard oder gesetzt ist, gilt Folgendes:
      • Wenn die Option Abrufbarkeit auf Ein festgelegt ist, ist die VM eine VM auf Abruf.
      • Andernfalls ist die VM eine Standard-VM.

gcloud

Verwenden Sie zum Beschreiben einer VM mit der gcloud CLI den Befehl gcloud compute instances describe:

gcloud compute instances describe VM_NAME

Dabei ist VM_NAME der Name der VM, die Sie prüfen möchten.

Prüfen Sie in der Ausgabe das Feld scheduling, um die VM zu identifizieren:

  • Wenn die Ausgabe das Feld provisioningModel enthält, das auf SPOT festgelegt ist, ist die VM eine Spot-VM, ähnlich wie im Folgenden.

    ...
    scheduling:
    ...
    provisioningModel: SPOT
    instanceTerminationAction: TERMINATION_ACTION
    ...
    

    Dabei gibt TERMINATION_ACTION an, welche Aktion ausgeführt werden soll, wenn Compute Engine die VM vorzeitig beendet – entweder Stoppen (STOP) oder Löschen (DELETE). Wenn das Feld instanceTerminationAction fehlt, ist der Standardwert STOP.

  • Wenn dagegen die Ausgabe das Feld provisioningModel enthält, das auf standard gesetzt ist, oder wenn das Feld provisioningModel nicht in der Ausgabe angegeben ist:

    • Wenn die Ausgabe das Feld preemptible enthält, das auf true gesetzt ist, ist die VM eine VM auf Abruf.
    • Andernfalls ist die VM eine Standard-VM.

REST

Zum Beschreiben einer VM aus der Compute Engine API verwenden Sie die Methode instances.get:

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

Dabei gilt:

  • PROJECT_ID ist die Projekt-ID des Projekts mit der VM.
  • ZONE ist die Zone, in der sich die VM befindet.
  • VM_NAME ist der Name der VM, die Sie prüfen möchten.

Prüfen Sie in der Ausgabe das Feld scheduling, um die VM zu identifizieren:

  • Wenn die Ausgabe das Feld provisioningModel enthält, das auf SPOT festgelegt ist, ist die VM eine Spot-VM, ähnlich wie im Folgenden.

    {
      ...
      "scheduling":
      {
         ...
         "provisioningModel": "SPOT",
         "instanceTerminationAction": "TERMINATION_ACTION"
         ...
      },
      ...
    }
    

    Dabei gibt TERMINATION_ACTION an, welche Aktion ausgeführt werden soll, wenn Compute Engine die VM vorzeitig beendet – entweder Stoppen (STOP) oder Löschen (DELETE). Wenn das Feld instanceTerminationAction fehlt, ist der Standardwert STOP.

  • Wenn dagegen die Ausgabe das Feld provisioningModel enthält, das auf standard gesetzt ist, oder wenn das Feld provisioningModel nicht in der Ausgabe angegeben ist:

    • Wenn die Ausgabe das Feld preemptible enthält, das auf true gesetzt ist, ist die VM eine VM auf Abruf.
    • Andernfalls ist die VM eine Standard-VM.

Go


import (
	"context"
	"fmt"
	"io"

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

// isSpotVM checks if a given instance is a Spot VM or not.
func isSpotVM(w io.Writer, projectID, zone, instanceName string) (bool, error) {
	// projectID := "your_project_id"
	// zone := "europe-central2-b"
	// instanceName := "your_instance_name"
	ctx := context.Background()
	client, err := compute.NewInstancesRESTClient(ctx)
	if err != nil {
		return false, fmt.Errorf("NewInstancesRESTClient: %w", err)
	}
	defer client.Close()

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

	instance, err := client.Get(ctx, req)
	if err != nil {
		return false, fmt.Errorf("GetInstance: %w", err)
	}

	isSpot := instance.GetScheduling().GetProvisioningModel() == computepb.Scheduling_SPOT.String()

	var isSpotMessage string
	if !isSpot {
		isSpotMessage = " not"
	}
	fmt.Fprintf(w, "Instance %s is%s spot\n", instanceName, isSpotMessage)

	return instance.GetScheduling().GetProvisioningModel() == computepb.Scheduling_SPOT.String(), nil
}

Java


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

public class CheckIsSpotVm {
  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 Google Cloud project you want to use.
    String projectId = "your-project-id";
    // Name of the virtual machine to check.
    String instanceName = "your-route-name";
    // Name of the zone you want to use. For example: "us-west3-b"
    String zone = "your-zone";

    boolean isSpotVm = isSpotVm(projectId, instanceName, zone);
    System.out.printf("Is %s spot VM instance - %s", instanceName, isSpotVm);
  }

  // Check if a given instance is Spot VM or not.
  public static boolean isSpotVm(String projectId, String instanceName, String zone)
          throws IOException {
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests.
    try (InstancesClient client = InstancesClient.create()) {
      Instance instance = client.get(projectId, zone, instanceName);

      return instance.getScheduling().getProvisioningModel()
              .equals(Scheduling.ProvisioningModel.SPOT.name());
    }
  }
}

Python

from google.cloud import compute_v1


def is_spot_vm(project_id: str, zone: str, instance_name: str) -> bool:
    """
    Check if a given instance is Spot VM or not.
    Args:
        project_id: project ID or project number of the Cloud project you want to use.
        zone: name of the zone you want to use. For example: "us-west3-b"
        instance_name: name of the virtual machine to check.
    Returns:
        The Spot VM status of the instance.
    """
    instance_client = compute_v1.InstancesClient()
    instance = instance_client.get(
        project=project_id, zone=zone, instance=instance_name
    )
    return (
        instance.scheduling.provisioning_model
        == compute_v1.Scheduling.ProvisioningModel.SPOT.name
    )

Vorzeitiges Beenden mit einem Shutdown-Skript verwalten

Wenn Compute Engine eine Spot-VM vorzeitig beendet, können Sie ein Shutdown-Script verwenden, mit dem Bereinigungsaktionen ausgeführt werden, bevor die VM vorzeitig beendet wird. Sie können z. B. einen laufenden Prozess ordnungsgemäß beenden und eine Checkpoint-Datei in Cloud Storage kopieren. Die maximale Dauer der Abschaltung ist beim vorzeitigen Beenden kürzer als bei einer vom Nutzer initiierten Abschaltung. Weitere Informationen zur Abschaltungsdauer bei vorzeitigem Beenden finden Sie in der Konzeptdokumentation für Spot-VMs unter Vorgang des vorzeitigen Beendens.

Das folgende Beispiel zeigt ein Shutdown-Skript, das Sie laufenden Spot-VMs hinzufügen oder beim Erstellen neuer Spot-VMs hinzufügen können. Dieses Script wird ausgeführt, wenn die VM mit dem Herunterfahren beginnt, bevor mit dem normalen kill-Befehl des Betriebssystems alle restlichen Prozesse beendet werden. Nachdem das gewünschte Programm ordnungsgemäß beendet wurde, lädt das Skript parallel eine Prüfpunktdatei in einen Cloud Storage-Bucket hoch.

#!/bin/bash

MY_PROGRAM="PROGRAM_NAME" # For example, "apache2" or "nginx"
MY_USER="LOCAL_USER"
CHECKPOINT="/home/$MY_USER/checkpoint.out"
BUCKET_NAME="BUCKET_NAME" # For example, "my-checkpoint-files" (without gs://)

echo "Shutting down!  Seeing if ${MY_PROGRAM} is running."

# Find the newest copy of $MY_PROGRAM
PID="$(pgrep -n "$MY_PROGRAM")"

if [[ "$?" -ne 0 ]]; then
  echo "${MY_PROGRAM} not running, shutting down immediately."
  exit 0
fi

echo "Sending SIGINT to $PID"
kill -2 "$PID"

# Portable waitpid equivalent
while kill -0 "$PID"; do
   sleep 1
done

echo "$PID is done, copying ${CHECKPOINT} to gs://${BUCKET_NAME} as ${MY_USER}"

su "${MY_USER}" -c "gcloud storage cp $CHECKPOINT gs://${BUCKET_NAME}/"

echo "Done uploading, shutting down."

Das Skript setzt Folgendes aus:

  • Die VM wurde mindestens mit Lese-/Schreibzugriff auf Cloud Storage erstellt. Eine Anleitung zum Erstellen einer VM mit den entsprechenden Bereichen finden Sie in der Dokumentation zur Authentifizierung.

  • Sie haben einen Cloud Storage-Bucket und die Berechtigung zum Schreiben in diesen Bucket.

Um dieses Skript einer VM hinzuzufügen, konfigurieren Sie es so, dass es mit einer Anwendung auf der VM funktioniert, und fügen es den VM-Metadaten hinzu.

  1. Kopieren Sie das Shutdown-Skript oder laden Sie es herunter:

    • Kopieren Sie das vorherige Shutdown-Skript und ersetzen Sie darin Folgendes:

      • PROGRAM_NAME ist der Name des Prozesses oder Programms, das Sie herunterfahren möchten. Beispiel: apache2 oder nginx
      • LOCAL_USER ist der Nutzername, mit dem Sie in der virtuellen Maschine angemeldet sind.
      • BUCKET_NAME ist der Name des Cloud Storage-Buckets, in dem die Prüfpunktdatei des Programms gespeichert werden soll. Der Bucket-Name beginnt in diesem Fall nicht mit gs://.
    • Laden Sie das Shutdown-Skript auf Ihre lokale Workstation herunter und ersetzen Sie in der Datei die folgenden Variablen:

      • [PROGRAM_NAME] ist der Name des Prozesses oder Programms, das Sie herunterfahren möchten. Beispiel: apache2 oder nginx
      • [LOCAL_USER] ist der Nutzername, mit dem Sie in der virtuellen Maschine angemeldet sind.
      • [BUCKET_NAME] ist der Name des Cloud Storage-Buckets, in dem die Prüfpunktdatei des Programms gespeichert werden soll. Der Bucket-Name beginnt in diesem Fall nicht mit gs://.
  2. Fügen Sie das Shutdown-Skript einer neuen VM oder einer vorhandenen VM hinzu.

Vorzeitiges Beenden von Spot-VMs erkennen

Bestimmen Sie mit der Google Cloud Console, der gcloud CLI oder der Compute Engine API, ob Spot-VMs von Compute Engine vorzeitig beendet wurden.

Console

Im Systemaktivitätsprotokoll können Sie prüfen, ob eine VM vorzeitig beendet wurde.

  1. Öffnen Sie in der Google Cloud Console die Seite Logs.

    Zu den Logs

  2. Wählen Sie Ihr Projekt aus und klicken Sie auf Weiter.

  3. Fügen Sie compute.instances.preempted zum Feld Nach Label oder Textsuche filtern hinzu.

  4. Optional können Sie auch einen VM-Namen eingeben, wenn Sie Vorgänge der vorzeitigen Beendigung für eine bestimmte VM prüfen möchten.

  5. Drücken Sie die Eingabetaste, um die angegebenen Filter anzuwenden. Die Google Cloud Console aktualisiert die Liste der Logs so, dass nur die Vorgänge angezeigt werden, bei denen eine VM vorzeitig beendet wurde.

  6. Wählen Sie einen Vorgang aus der Liste aus, um Details zur VM zu sehen, die vorzeitig beendet wurde.

gcloud

Verwenden Sie den Befehl gcloud compute operations list mit einem Filterparameter, um eine Liste vorzeitig beendeter Ereignisse in Ihrem Projekt zu erhalten.

gcloud compute operations list \
    --filter="operationType=compute.instances.preempted"

Optional können Sie die Ergebnisse durch zusätzliche Filterparameter anpassen. Mit dem folgenden Befehl können Sie beispielsweise Ereignisse der vorzeitigen Beendigung nur für Instanzen innerhalb einer verwalteten Instanzgruppe aufrufen:

gcloud compute operations list \
    --filter="operationType=compute.instances.preempted AND targetLink:instances/BASE_INSTANCE_NAME"

Dabei ist BASE_INSTANCE_NAME der Basisname, der als Präfix für die Namen aller VMs in dieser verwalteten Instanzgruppe verwendet wird.

Die entsprechende Ausgabe sieht etwa so aus:

NAME                  TYPE                         TARGET                                        HTTP_STATUS STATUS TIMESTAMP
systemevent-xxxxxxxx  compute.instances.preempted  us-central1-f/instances/example-instance-xxx  200         DONE   2015-04-02T12:12:10.881-07:00

Der Vorgangstyp compute.instances.preempted zeigt an, dass die VM vorzeitig beendet wurde. Mit dem Befehl gcloud compute operations describe erhalten Sie weitere Informationen zu einem bestimmten Vorgang zur vorzeitigen Beendigung.

gcloud compute operations describe SYSTEM_EVENT \
    --zone=ZONE

Ersetzen Sie Folgendes:

  • SYSTEM_EVENT: das Systemereignis aus der Ausgabe des Befehls gcloud compute operations list, z. B. systemevent-xxxxxxxx.
  • ZONE: Die Zone des Systemereignisses, z. B. us-central1-f.

Die Ausgabe sieht in etwa so aus:

...
operationType: compute.instances.preempted
progress: 100
selfLink: https://compute.googleapis.com/compute/v1/projects/my-project/zones/us-central1-f/operations/systemevent-xxxxxxxx
startTime: '2015-04-02T12:12:10.881-07:00'
status: DONE
statusMessage: Instance was preempted.
...

REST

Mit der Methode zoneOperations.get können Sie eine Liste der letzten Systemvorgänge für ein bestimmtes Projekt und eine bestimmte Zone abrufen.

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

Dabei gilt:

Wenn Sie die Antworten optional so eingrenzen möchten, dass nur Vorgänge zur vorzeitigen Beendigung angezeigt werden, können Sie Ihrer API-Anfrage einen Filter hinzufügen:

operationType="compute.instances.preempted"

Alternativ können Sie zum Abrufen von Vorgängen zur vorzeitigen Beendigung für eine bestimmte VM den Parameter targetLink zum Filter hinzufügen:

operationType="compute.instances.preempted" AND
targetLink="https://www.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME

Ersetzen Sie Folgendes: + PROJECT_ID: die Projekt-ID. + ZONE: die Zone. + VM_NAME: der Name einer bestimmten VM in dieser Zone und in diesem Projekt.

Die Antwort enthält eine Liste der letzten Vorgänge. Vorzeitiges Beenden sieht beispielsweise so aus:

{
  "kind": "compute#operation",
  "id": "15041793718812375371",
  "name": "systemevent-xxxxxxxx",
  "zone": "https://www.googleapis.com/compute/v1/projects/my-project/zones/us-central1-f",
  "operationType": "compute.instances.preempted",
  "targetLink": "https://www.googleapis.com/compute/v1/projects/my-project/zones/us-central1-f/instances/example-instance",
  "targetId": "12820389800990687210",
  "status": "DONE",
  "statusMessage": "Instance was preempted.",
  ...
}

Alternativ können Sie feststellen, ob eine VM innerhalb der VM selbst vorzeitig beendet wurde. Das ist nützlich, wenn Sie das Herunterfahren aufgrund einer vorzeitigen Compute Engine-Beendigung anders verarbeiten möchten als ein normales Herunterfahren in einem Shutdown-Skript. Dazu prüfen Sie einfach den Metadatenserver auf den Wert preempted in den Standardmetadaten der VM.

Verwenden Sie beispielsweise curl in der VM, um den Wert für preempted abzurufen:

curl "http://metadata.google.internal/computeMetadata/v1/instance/preempted" -H "Metadata-Flavor: Google"
TRUE

Wenn dieser Wert TRUE ist, wurde die VM von Compute Engine vorzeitig beendet, andernfalls lautet er FALSE.

Wenn Sie dies außerhalb eines Shutdown-Skripts verwenden möchten, können Sie ?wait_for_change=true an die URL anhängen. Dadurch wird eine hängende HTTP-GET-Anfrage ausgeführt, die nur zurückgegeben wird, wenn sich die Metadaten geändert haben und die VM vorzeitig beendet wurde.

curl "http://metadata.google.internal/computeMetadata/v1/instance/preempted?wait_for_change=true" -H "Metadata-Flavor: Google"
TRUE

Einstellungen für das vorzeitige Beenden testen

Sie können simulierte Wartungsereignisse für Ihre VMs ausführen, um eine vorzeitige Beendigung zu erzwingen. Mit diesem Feature können Sie testen, wie Spot-VMs von Ihren Anwendungen verarbeitet werden. Unter Hostwartungsereignis simulieren erfahren Sie, wie Sie Wartungsereignisse in Ihren Instanzen testen.

Anstatt ein Wartungsereignis zu simulieren, können Sie auch eine vorzeitige Beendigung der VM simulieren, indem Sie die VM-Instanz beenden. So lassen sich Kontingentlimits vermeiden.

Best Practices

Im Folgenden finden Sie einige Best Practices, mit denen Sie Spot-VMs optimal nutzen können.

  • Instanzvorlagen verwenden. Anstatt Spot-VMs einzeln zu erstellen, können Sie mit Instanzvorlagen mehrere Spot-VMs mit denselben Attributen erstellen. Instanzvorlagen sind für die Verwendung von MIGs erforderlich. Alternativ können Sie mehrere Spot-VMs mit der Bulk-Instanz-API erstellen.

  • Mit MIGs Spot-VMs regional verteilen und automatisch neu erstellen. Verwenden Sie MIGs, um Arbeitslasten auf Spot-VMs flexibler und stabiler zu gestalten. Verwenden Sie beispielsweise regionale MIGs, um VMs auf mehrere Zonen zu verteilen. Dadurch werden Fehler bei der Ressourcenverfügbarkeit minimiert. Außerdem können Sie Spot-VMs mithilfe der automatischen Reparatur automatisch neu erstellen, nachdem sie vorzeitig beendet wurden.

  • Kleinere Maschinentypen auswählen. Ressourcen für Spot-VMs stammen aus überschüssiger Kapazität und Sicherungskapazität von Google Cloud. Die Kapazität für Spot-VMs ist häufig für kleinere Maschinentypen leichter zu erhalten, also für Maschinentypen mit weniger Ressourcen wie vCPUs und Arbeitsspeicher. Wenn Sie einen kleineren benutzerdefinierten Maschinentyp auswählen, finden Sie möglicherweise mehr Kapazität für Spot-VMs. Für kleinere vordefinierte Maschinentypen ist die Kapazität jedoch wahrscheinlicher. Im Vergleich zu der Kapazität für den vordefinierten Maschinentyp n2-standard-32 ist die Kapazität für den benutzerdefinierten Maschinentyp n2-custom-24-96 wahrscheinlicher, aber die Kapazität für den vordefinierten Maschinentyp n2-standard-16 ist noch wahrscheinlicher.

  • Führen Sie große Cluster von Spot-VMs außerhalb der Spitzenzeiten aus. Die Auslastung der Google Cloud-Rechenzentren variiert je nach Standort und Tageszeit, ist aber im Allgemeinen nachts und am Wochenende am niedrigsten. Somit eignen sich Nächte und Wochenenden am besten zur Ausführung großer Cluster von Spot-VMs.

  • Anwendungen tolerant gegenüber Fehlern und vorzeitigem Beenden gestalten. Man sollte immer darauf vorbereitet sein, dass Änderungen bei den vorzeitigen Beendigungsmustern zu unterschiedlichen Zeiten auftreten. Wenn beispielsweise eine Zone teilweise ausfällt, könnte eine große Anzahl von Spot-VMs vorzeitig beendet werden, um Platz für Standard-VMs zu schaffen, die im Rahmen der Wiederherstellung verschoben werden müssen. In diesem kleinen Zeitfenster würde die vorzeitige Beendigungsrate ganz anders als an jedem anderen Tag aussehen. Wenn die Anwendung davon ausgeht, dass vorzeitige Beendigungen immer in kleinen Gruppen erfolgen, sind Sie möglicherweise nicht auf einen derartigen Fall vorbereitet.

  • Erstellen von Spot-VMs wiederholen, die vorzeitig beendet wurden. Wenn die Spot-VMs vorzeitig beendet wurden, versuchen Sie ein- oder zweimal, neue Spot-VMs zu erstellen, bevor Sie auf Standard-VMs zurückgreifen. Je nach Anforderungen können Sie Standard-VMs und Spot-VMs in Ihren Clustern kombinieren, um eine Fortsetzung der Arbeit mit einer angemessenen Geschwindigkeit sicherzustellen.

  • Shutdown-Skripts verwenden. Verwalten Sie Hinweise zu Shutdown und vorzeitiger Beendigung mit einem Shutdown-Skript, das den Fortschritt eines Jobs speichern kann. Dann kann der Job nach einer Unterbrechung an jener Stelle wiederaufgenommen werden, an der er unterbrochen wurde, und muss nicht vollständig neu erstellt werden.

Nächste Schritte