יצירת תבניות של מופעים

במאמר הזה מוסבר איך ליצור ולנהל תבניות של מכונות וירטואליות. תבניות של מכונות מאפשרות לכם לציין את סוג המכונה, תמונת הדיסק לאתחול, הרשת ומאפיינים אחרים של מכונות וירטואליות (VM) שבהם אתם רוצים להשתמש כשאתם יוצרים מכונות וירטואליות.

אתם יכולים להשתמש בתבניות של מכונות וירטואליות כדי:

לפני שמתחילים

מגבלות

  • ‫VPC משותף בממשקים אחרים מלבד nic0 בתבניות של מכונות וירטואליות נתמך ב-CLI של gcloud וב-REST, אבל לא במסוףCloud de Confiance .
  • אי אפשר לעדכן תבנית קיימת של הגדרות מכונה וירטואלית או לשנות תבנית של הגדרות מכונה וירטואלית אחרי שהיא נוצרה. אם תבנית של הגדרות מכונה לא עדכנית, או שאתם צריכים לבצע שינויים בהגדרה, אתם יכולים ליצור תבנית חדשה של הגדרות מכונה.
  • אם רוצים לציין משפחת תמונות בתבנית של הגדרות מכונה, אי אפשר להשתמש במסוף Cloud de Confiance . במקום זאת, אפשר להשתמש ב-Google Cloud CLI או ב-REST.
  • אתם יכולים להשתמש בתבנית של הגדרות מכונה כדי ליצור מכונות וירטואליות עם דיסק אתחול Hyperdisk Balanced שנמצא במאגר אחסון, אם מאגר האחסון קיים באותו תחום (zone) שבו נוצרת המכונה הווירטואלית. אי אפשר להשתמש בתבניות גלובליות של מכונות כדי ליצור מכונות וירטואליות עם דיסקים שאינם דיסקים לאתחול שנמצאים במאגר אחסון.

יצירת תבנית של הגדרות מכונה

אפשר לציין בתבנית של הגדרות מכונה את רוב המאפיינים של מכונת ה-VM שאפשר לציין בבקשה ליצירת מכונת VM ספציפית, כולל מטא-נתונים של מכונת ה-VM, סקריפטים להפעלה, דיסקים קשיחים קבועים וחשבונות שירות. צריך לציין את סוג המכונה, דיסק האתחול והרשת.

יוצרים תבנית של הגדרות מכונה אזורית או גלובלית באמצעותCloud de Confiance console, Google Cloud CLI או API. כדי ליצור תבנית של הגדרות מכונה גלובלית, אפשר גם להשתמש ב-Terraform או בספריות הלקוח של Cloud.

המסוף

  1. נכנסים לדף Instance templates במסוף Cloud de Confiance .

    כניסה לדף Instance templates

    שאר השלבים יופיעו במסוף Cloud de Confiance .

  2. לוחצים על Create instance template.
  3. בוחרים את המיקום באופן הבא:
    1. אם רוצים להשתמש בתבנית של הגדרות המכונה בכמה אזורים, בוחרים באפשרות Global.
    2. אם רוצים לצמצם את התלות בין אזורים, בוחרים באפשרות אזורי.
  4. אם בחרתם באפשרות 'אזורי', בוחרים את האזור שבו רוצים ליצור את תבנית של הגדרות מכונה.
  5. בשדות הבאים, מאשרים את ערכי ברירת המחדל או משנים אותם לפי הצורך. ערכי ברירת המחדל משתנים בהתאם למשפחת המכונות שבוחרים.

    • בוחרים סוג מכונה.
    • כדי לעדכן את סוג דיסק האתחול או את התמונה, בקטע Boot disk לוחצים על Change.
    • כדי לעדכן את ההגדרות של ממשק הרשת או של כתובת ה-IP, לוחצים על אפשרויות מתקדמות, ואז על Networking, ואז על ממשק הרשת שרוצים לערוך.
  6. אופציונלי: אם בחרתם תמונה שתומכת במכונה וירטואלית מוגנת, משנים את ההגדרות של מכונה וירטואלית מוגנת ב-VM:

    1. לוחצים על אפשרויות מתקדמות ואז על הכרטיסייה אבטחה.
    2. כדי להשבית את האתחול המאובטח, מבטלים את הסימון בתיבה הפעלת אתחול מאובטח. האתחול המאובטח עוזר להגן על מופעי המכונות הווירטואליות מפני תוכנות זדוניות וערכות root ברמת האתחול והליבה. מידע נוסף זמין במאמר בנושא אתחול מאובטח.
    3. כדי להשבית את מודול הפלטפורמה הווירטואלית המהימנה (vTPM), מבטלים את הסימון בתיבה הפעלת vTPM. ה-vTPM מאפשר אתחול מדוד, שמאמת את התקינות של המכונה הווירטואלית לפני האתחול ובמהלכו. מידע נוסף זמין במאמר בנושא מודול פלטפורמה מהימנה וירטואלי (vTPM).

    4. אם רוצים להשבית את המעקב אחר תקינות, מבטלים את הסימון בתיבה הפעלה של מעקב אחר תקינות. ניטור התקינות מאפשר לכם לעקוב אחרי תקינות האתחול של מכונות וירטואליות מוגנות באמצעות Cloud Monitoring. מידע נוסף זמין במאמר מעקב אחר תקינות.

  7. אופציונלי: בקטע אפשרויות מתקדמות, לוחצים על הכרטיסיות כדי להתאים אישית את התבנית. לדוגמה, אפשר להוסיף עד 15 דיסקים משניים שלא מיועדים לאתחול.

  8. אופציונלי: לוחצים על Equivalent REST (מקבילת REST) כדי לראות את גוף בקשת ה-REST, שכולל את ייצוג ה-JSON של תבנית של הגדרות מכונה.

  9. לוחצים על יצירה כדי ליצור את התבנית.

gcloud

כדי ליצור תבנית של הגדרות מכונה אזורית או גלובלית, משתמשים בפקודה instance-templates create. כדי להגדיר את האזור של תבנית אזורית של הגדרות מכונה, צריך להשתמש בדגל --instance-template-region.

יוצרים תבנית אזורית של הגדרות מכונה באמצעות הפקודה הבאה.

gcloud compute instance-templates create INSTANCE_TEMPLATE_NAME \
    --instance-template-region=REGION

מחליפים את REGION באזור שבו רוצים ליצור את תבנית של הגדרות מכונה האזורית.

יוצרים תבנית גלובלית של הגדרות מכונה באמצעות הפקודה הבאה:

gcloud compute instance-templates create INSTANCE_TEMPLATE_NAME

אם לא מציינים הגדרות תבנית מפורשות, gcloud compute משתמש בערכי ברירת המחדל הבאים:

  • סוג המכונה: סוג המכונה – לדוגמה, n1-standard-1
  • תמונה: תמונת Debian העדכנית ביותר
  • דיסק אתחול: דיסק אתחול רגיל חדש שנקרא על שם המכונה הווירטואלית
  • רשת: רשת ה-VPC שמוגדרת כברירת מחדל
  • כתובת IP: כתובת IPv4 חיצונית זמנית
  • סוג ה-Stack: IPV4_ONLY

אפשר גם לספק את הגדרות התצורה האלה באופן מפורש. לדוגמה:

gcloud compute instance-templates create my-instance-template \
    --machine-type=e2-standard-4 \
    --image-family=debian-11 \
    --image-project=debian-cloud \
    --boot-disk-size=250GB

אפשר להוסיף עד 15 דיסקים משניים שאינם דיסקים לאתחול. מציינים את הדגל --create-disk לכל דיסק משני שיוצרים. כדי ליצור דיסקים משניים מתמונה ציבורית או מתמונה בהתאמה אישית, צריך לציין את המאפיינים image ו-image-project לכל דיסק בדגל --create-disk. כדי ליצור דיסק ריק, לא צריך לכלול את המאפיינים האלה. אפשר לכלול מאפיינים של הדיסק size ו-type.

gcloud compute instance-templates create INSTANCE_TEMPLATE_NAME \
    --machine-type=MACHINE_TYPE \
    --create-disk=image-family=DISK_IMAGE_FAMILY,image-project=DISK_IMAGE_PROJECT,size=SIZE_GB_DISK1 \
    --create-disk=device-name=DISK_NAME,type=DISK_TYPE,size=SIZE_GB_DISK2,replica-zones=^:^ZONE:REMOTE_ZONE,boot=false

מחליפים את מה שכתוב בשדות הבאים:

  • INSTANCE_TEMPLATE_NAME: השם של התבנית
  • MACHINE_TYPE: סוג המכונה של מכונות ה-VM
  • DISK_IMAGE_FAMILY: משפחת תמונות לשימוש כדיסק שאינו דיסק אתחול

    מידע נוסף על משפחות של תמונות זמין במאמר בנושא שיטות מומלצות לשימוש במשפחות של תמונות ב-Compute Engine.

    אפשר להשתמש בדגל --image=IMAGE כדי לציין גרסה ספציפית של תמונה.

    אם הדיסקים ריקים, אל תציינו את המאפיין image-family או image.

  • DISK_IMAGE_PROJECT: פרויקט התמונה שמכיל את התמונה

    אם הדיסקים ריקים, לא מציינים את המאפיין image-project. מידע נוסף על תמונות ציבוריות זמין במאמר תמונות ציבוריות.

  • SIZE_GB_DISK1 ו-SIZE_GB_DISK2: הגודל של כל דיסק משני

  • DISK_NAME: אופציונלי: שם הדיסק שמוצג למערכת ההפעלה של האורח אחרי יצירת המכונה הווירטואלית.

  • DISK_TYPE: אופציונלי: סוג הדיסק שרוצים ליצור. אם לא מציינים ערך, סוג הדיסק שמשמש כברירת מחדל תלוי בערך של הדגל --machine-type.

  • ZONE ו-REMOTE_ZONE: התחום שבו רוצים ליצור את הדיסק האזורי והתחום שאליו רוצים לשכפל אותו.

    בדיסקים אזוריים, אל תכללו את המאפיין replica-zones.

אם בחרתם תמונה שתומכת ב-מכונה וירטואלית מוגנת, אתם יכולים לשנות את ההגדרות של מכונה וירטואלית מוגנת של המכונה באמצעות אחד מהדגלים הבאים:

  • --no-shielded-secure-boot: השבתה של הפעלה מאובטחת

    האתחול המאובטח עוזר להגן על המכונות הווירטואליות מפני תוכנות זדוניות וערכות rootkit ברמת האתחול וברמת הליבה. מידע נוסף זמין במאמר בנושא אתחול מאובטח.

  • --no-shielded-vtpm: השבתה של מודול הפלטפורמה הווירטואלי המהימן (vTPM)

    ה-vTPM מאפשר אתחול מדוד, שמאמת את התקינות של המכונה הווירטואלית לפני האתחול ובמהלכו. מידע נוסף זמין במאמר בנושא מודול פלטפורמה מהימן וירטואלי (vTPM).

  • --no-shielded-integrity-monitoring: משבית את המעקב אחר תקינות

    בעזרת ניטור התקינות אתם יכולים לעקוב אחרי תקינות האתחול של מכונות וירטואליות מוגנות באמצעות Cloud Monitoring. מידע נוסף זמין במאמר בנושא מעקב אחר תקינות.

רשימה של כל פקודות המשנה והדגלים הזמינים מופיעה במאמרי העזרה בנושא instance-templates.

Terraform

כדי ליצור תבנית של הגדרות מכונה, משתמשים באחד מהמשאבים הבאים:

בדוגמה הבאה נוצרת תבנית של הגדרות מכונה גלובלית:

resource "google_compute_instance_template" "foobar" {
  name         = "my-instance-template"
  machine_type = "e2-standard-4"

  disk {
    source_image = "debian-cloud/debian-11"
    disk_size_gb = 250
  }

  network_interface {
    network = "default"

    # default access config, defining external IP configuration
    access_config {
      network_tier = "PREMIUM"
    }
  }

  # To avoid embedding secret keys or user credentials in the instances, Google recommends that you use custom service accounts with the following access scopes.
  service_account {
    scopes = [
      "https://www.googleapis.com/auth/cloud-platform"
    ]
  }
}

כדי ללמוד איך להחיל הגדרות ב-Terraform או להסיר אותן, ראו פקודות בסיסיות ב-Terraform.

המשך

import (
	"context"
	"fmt"
	"io"

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

// createTemplate creates a new instance template with the provided name and a specific instance configuration.
func createTemplate(w io.Writer, projectID, templateName string) error {
	// projectID := "your_project_id"
	// templateName := "your_template_name"

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

	req := &computepb.InsertInstanceTemplateRequest{
		Project: projectID,
		InstanceTemplateResource: &computepb.InstanceTemplate{
			Name: proto.String(templateName),
			Properties: &computepb.InstanceProperties{
				// The template describes the size and source image of the boot disk
				// to attach to the instance.
				Disks: []*computepb.AttachedDisk{
					{
						InitializeParams: &computepb.AttachedDiskInitializeParams{
							DiskSizeGb:  proto.Int64(250),
							SourceImage: proto.String("projects/debian-cloud/global/images/family/debian-11"),
						},
						AutoDelete: proto.Bool(true),
						Boot:       proto.Bool(true),
					},
				},
				MachineType: proto.String("e2-standard-4"),
				// The template connects the instance to the `default` network,
				// without specifying a subnetwork.
				NetworkInterfaces: []*computepb.NetworkInterface{
					{
						Name: proto.String("global/networks/default"),
						// The template lets the instance use an external IP address.
						AccessConfigs: []*computepb.AccessConfig{
							{
								Name:        proto.String("External NAT"),
								Type:        proto.String(computepb.AccessConfig_ONE_TO_ONE_NAT.String()),
								NetworkTier: proto.String(computepb.AccessConfig_PREMIUM.String()),
							},
						},
					},
				},
			},
		},
	}

	op, err := instanceTemplatesClient.Insert(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to create instance template: %w", err)
	}

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

	fmt.Fprintf(w, "Instance template created\n")

	return nil
}

Java

import com.google.cloud.compute.v1.AccessConfig;
import com.google.cloud.compute.v1.AccessConfig.NetworkTier;
import com.google.cloud.compute.v1.AttachedDisk;
import com.google.cloud.compute.v1.AttachedDiskInitializeParams;
import com.google.cloud.compute.v1.GlobalOperationsClient;
import com.google.cloud.compute.v1.InsertInstanceTemplateRequest;
import com.google.cloud.compute.v1.InstanceProperties;
import com.google.cloud.compute.v1.InstanceTemplate;
import com.google.cloud.compute.v1.InstanceTemplatesClient;
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 CreateInstanceTemplate {

  public static void main(String[] args)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // TODO(developer): Replace these variables before running the sample.
    // projectId: project ID or project number of the Cloud project you use.
    // templateName: name of the new template to create.
    String projectId = "your-project-id";
    String templateName = "template-name";
    createInstanceTemplate(projectId, templateName);
  }

  /*
    Create a new instance template with the provided name and a specific
    instance configuration.
   */
  public static void createInstanceTemplate(String projectId, String templateName)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    try (InstanceTemplatesClient instanceTemplatesClient = InstanceTemplatesClient.create()) {

      String machineType = "e2-standard-4";
      String sourceImage = "projects/debian-cloud/global/images/family/debian-11";

      // The template describes the size and source image of the boot disk
      // to attach to the instance.
      AttachedDisk attachedDisk = AttachedDisk.newBuilder()
          .setInitializeParams(AttachedDiskInitializeParams.newBuilder()
              .setSourceImage(sourceImage)
              .setDiskType("pd-balanced")
              .setDiskSizeGb(250).build())
          .setAutoDelete(true)
          .setBoot(true).build();

      // The template connects the instance to the `default` network,
      // without specifying a subnetwork.
      NetworkInterface networkInterface = NetworkInterface.newBuilder()
          .setName("global/networks/default")
          // The template lets the instance use an external IP address.
          .addAccessConfigs(AccessConfig.newBuilder()
              .setName("External NAT")
              .setType(AccessConfig.Type.ONE_TO_ONE_NAT.toString())
              .setNetworkTier(NetworkTier.PREMIUM.toString()).build()).build();

      InstanceProperties instanceProperties = InstanceProperties.newBuilder()
          .addDisks(attachedDisk)
          .setMachineType(machineType)
          .addNetworkInterfaces(networkInterface).build();

      InsertInstanceTemplateRequest insertInstanceTemplateRequest = InsertInstanceTemplateRequest
          .newBuilder()
          .setProject(projectId)
          .setInstanceTemplateResource(InstanceTemplate.newBuilder()
              .setName(templateName)
              .setProperties(instanceProperties).build()).build();

      // Create the Instance Template.
      Operation response = instanceTemplatesClient.insertAsync(insertInstanceTemplateRequest)
          .get(3, TimeUnit.MINUTES);

      if (response.hasError()) {
        System.out.println("Instance Template creation failed ! ! " + response);
        return;
      }
      System.out
          .printf("Instance Template Operation Status %s: %s", templateName, response.getStatus());
    }
  }

  public static void createInstanceTemplateWithDiskType(String projectId, String templateName)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    try (InstanceTemplatesClient instanceTemplatesClient = InstanceTemplatesClient.create();
        GlobalOperationsClient globalOperationsClient = GlobalOperationsClient.create()) {

      AttachedDisk disk = AttachedDisk.newBuilder()
          .setInitializeParams(AttachedDiskInitializeParams.newBuilder()
              .setDiskSizeGb(10)
              .setDiskType("pd-balanced")
              .setSourceImage("projects/debian-cloud/global/images/family/debian-11").build())
          .setAutoDelete(true)
          .setBoot(true)
          .setType(AttachedDisk.Type.PERSISTENT.toString()).build();

      InstanceTemplate instanceTemplate = InstanceTemplate.newBuilder()
          .setName(templateName)
          .setProperties(InstanceProperties.newBuilder()
              .setMachineType("n1-standard-1")
              .addDisks(disk)
              .addNetworkInterfaces(NetworkInterface.newBuilder()
                  .setName("global/networks/default").build()).build()).build();

      InsertInstanceTemplateRequest insertInstanceTemplateRequest = InsertInstanceTemplateRequest
          .newBuilder()
          .setProject(projectId)
          .setInstanceTemplateResource(instanceTemplate).build();

      Operation response = instanceTemplatesClient.insertAsync(insertInstanceTemplateRequest)
          .get(3, TimeUnit.MINUTES);

      if (response.hasError()) {
        System.out.println("Instance Template creation failed ! ! " + response);
        return;
      }
      System.out
          .printf("Instance Template Operation Status %s: %s", templateName, response.getStatus());
    }
  }
}

Node.js

/**
 * TODO(developer): Uncomment and replace these variables before running the sample.
 */
// const projectId = 'YOUR_PROJECT_ID';
// const templateName = 'your_template_name';

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

// Create a new instance template with the provided name and a specific instance configuration.
async function createTemplate() {
  const instanceTemplatesClient = new compute.InstanceTemplatesClient();

  const [response] = await instanceTemplatesClient.insert({
    project: projectId,
    instanceTemplateResource: {
      name: templateName,
      properties: {
        disks: [
          {
            // The template describes the size and source image of the boot disk
            // to attach to the instance.
            initializeParams: {
              diskSizeGb: '250',
              sourceImage:
                'projects/debian-cloud/global/images/family/debian-11',
            },
            autoDelete: true,
            boot: true,
          },
        ],
        machineType: 'e2-standard-4',
        // The template connects the instance to the `default` network,
        // without specifying a subnetwork.
        networkInterfaces: [
          {
            // Use the network interface provided in the networkName argument.
            name: 'global/networks/default',
            // The template lets the instance use an external IP address.
            accessConfigs: [
              {
                name: 'External NAT',
                type: 'ONE_TO_ONE_NAT',
                networkTier: 'PREMIUM',
              },
            ],
          },
        ],
      },
    },
  });
  let operation = response.latestResponse;
  const operationsClient = new compute.GlobalOperationsClient();

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

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

createTemplate();

Python

from __future__ import annotations

import sys
from typing import Any

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


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

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

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

    Returns:
        Whatever the operation.result() returns.

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

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

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

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

    return result


def create_template(project_id: str, template_name: str) -> compute_v1.InstanceTemplate:
    """
    Create a new instance template with the provided name and a specific
    instance configuration.

    Args:
        project_id: project ID or project number of the Cloud project you use.
        template_name: name of the new template to create.

    Returns:
        InstanceTemplate object that represents the new instance template.
    """
    # The template describes the size and source image of the boot disk
    # to attach to the instance.
    disk = compute_v1.AttachedDisk()
    initialize_params = compute_v1.AttachedDiskInitializeParams()
    initialize_params.source_image = (
        "projects/debian-cloud/global/images/family/debian-11"
    )
    initialize_params.disk_size_gb = 250
    disk.initialize_params = initialize_params
    disk.auto_delete = True
    disk.boot = True

    # The template connects the instance to the `default` network,
    # without specifying a subnetwork.
    network_interface = compute_v1.NetworkInterface()
    network_interface.name = "global/networks/default"

    # The template lets the instance use an external IP address.
    access_config = compute_v1.AccessConfig()
    access_config.name = "External NAT"
    access_config.type_ = "ONE_TO_ONE_NAT"
    access_config.network_tier = "PREMIUM"
    network_interface.access_configs = [access_config]

    template = compute_v1.InstanceTemplate()
    template.name = template_name
    template.properties.disks = [disk]
    template.properties.machine_type = "e2-standard-4"
    template.properties.network_interfaces = [network_interface]

    template_client = compute_v1.InstanceTemplatesClient()
    operation = template_client.insert(
        project=project_id, instance_template_resource=template
    )

    wait_for_extended_operation(operation, "instance template creation")

    return template_client.get(project=project_id, instance_template=template_name)

REST

כדי ליצור תבנית של הגדרות מכונה אזורית, שולחים בקשת POST אל ה-method‏ regionInstanceTemplates.insert באופן הבא:

POST https://compute.s3nsapis.fr/compute/v1/projects/PROJECT_ID/regions/REGION/instanceTemplates

כדי ליצור תבנית של הגדרות מכונה גלובלית, שולחים בקשת POST אל ה-method‏ instanceTemplates.insert:

POST https://compute.s3nsapis.fr/compute/v1/projects/PROJECT_ID/global/instanceTemplates

אפשר להוסיף עד 15 דיסקים משניים שאינם דיסקים לאתחול באמצעות המאפיין disks, עם שדה לכל דיסק נוסף. לכל דיסק נוסף, אפשר לבצע את הפעולות הבאות:

  • יוצרים דיסקים נוספים עם תמונה ציבורית או תמונה בהתאמה אישית.
  • כדי להוסיף דיסק ריק, מגדירים את הערך initializeParams בלי ערך sourceImage.

בגוף הבקשה, מציינים את מאפייני התבנית:

{
  "name": "INSTANCE_TEMPLATE_NAME",
  "properties": {
    "machineType": "MACHINE_TYPE",
    "networkInterfaces": [
      {
        "network": "global/networks/default",
        "accessConfigs":
        [
          {
            "name": "external-IP",
            "type": "ONE_TO_ONE_NAT"
          }
        ]
      }
    ],
    "disks":
    [
      {
        "type": "PERSISTENT",
        "boot": true,
        "mode": "READ_WRITE",
        "initializeParams":
        {
          "sourceImage": "projects/IMAGE_PROJECT/global/images/IMAGE"
        }
      },
      {
        "type": "PERSISTENT",
        "boot": false,
        "deviceName": "DISK_NAME"
      }
    ]
  }
}

מחליפים את מה שכתוב בשדות הבאים:

  • PROJECT_ID: מזהה הפרויקט
  • REGION: האזור שבו רוצים ליצור את התבנית האזורית של הגדרות המכונה
  • INSTANCE_TEMPLATE_NAME: השם של תבנית הגדרות המכונה
  • ZONE: האזור שבו נמצאות המכונות הווירטואליות
  • MACHINE_TYPE: סוג המכונה של מכונות ה-VM

  • IMAGE_PROJECT: פרויקט התמונה שמכיל את התמונה

    מידע נוסף על תמונות ציבוריות זמין במאמר תמונות ציבוריות.

  • IMAGE או IMAGE_FAMILY: מציינים אחת מהאפשרויות הבאות:
    • IMAGE: גרסה ספציפית של התמונה

      לדוגמה, "sourceImage": "projects/debian-cloud/global/images/debian-10-buster-v20200309"

    • IMAGE_FAMILY: משפחת תמונות

      כך נוצרת מכונת ה-VM מתמונת מערכת ההפעלה העדכנית ביותר שלא הוצאה משימוש. לדוגמה, אם מציינים "sourceImage": "projects/debian-cloud/global/images/family/debian-10",‏ Compute Engine יוצר מכונה וירטואלית מהגרסה האחרונה של תמונת מערכת ההפעלה במשפחת תמונות Debian 10.

      מידע נוסף על משפחות של תמונות זמין במאמר בנושא שיטות מומלצות לשימוש במשפחות של תמונות ב-Compute Engine.

  • DISK_NAME: אופציונלי: שם הדיסק שמוצג למערכת ההפעלה של האורח אחרי יצירת המכונה הווירטואלית.

  • PROJECT_NAME: הפרויקט שמשויך למכונה הווירטואלית

אפשר לציין אחת מהאפשרויות הבאות למאפיין disks:

  • מציינים initializeParams כדי ליצור דיסקי אתחול לכל מופע. אפשר ליצור דיסקים באמצעות תמונות ציבוריות או תמונות בהתאמה אישית (או משפחות תמונות) באמצעות המאפיין sourceImage, כמו בדוגמה הקודמת. כדי להוסיף דיסקים ריקים, לא מציינים sourceImage. אפשר גם להוסיף עד 15 דיסקים משניים שאינם דיסקים לאתחול באמצעות המאפיין initializeParams לכל דיסק נוסף.

  • מציינים source כדי לצרף דיסק אתחול קיים. אם מצרפים דיסק אתחול קיים, אפשר ליצור רק מכונה אחת מהתבנית.

אפשר גם לציין את המאפיינים diskSizeGb, diskType ו-labels עבור initializeParams, ואת המאפיין diskSizeGb עבור source.

אם בחרתם תמונה שתומכת ב-Shielded VM, אתם יכולים לשנות את ההגדרות של Shielded VM במכונה הווירטואלית באמצעות הפריטים הבוליאניים הבאים בגוף הבקשה:

  • enableSecureBoot: הפעלה או השבתה של הפעלה מאובטחת

    האתחול המאובטח עוזר להגן על המכונות הווירטואליות מפני תוכנות זדוניות וערכות rootkit ברמת האתחול וברמת הליבה. מידע נוסף זמין במאמר בנושא אתחול מאובטח.

  • enableVtpm: הפעלה או השבתה של מודול פלטפורמה וירטואלית מהימנה (vTPM)

    ה-vTPM מאפשר אתחול מדוד, שמאמת את התקינות של המכונה הווירטואלית לפני האתחול ובמהלכו. מידע נוסף זמין במאמר בנושא מודול פלטפורמה מהימן וירטואלי (vTPM).

  • enableIntegrityMonitoring: הפעלה או השבתה של מעקב אחר תקינות

    בעזרת ניטור התקינות אפשר לעקוב אחרי התקינות של האתחול בזמן הריצה של המכונות הווירטואליות המוגנות, ולאמת אותה באמצעות דוחות של Cloud Monitoring. מידע נוסף זמין במאמר בנושא מעקב אחר תקינות.

מידע נוסף על פרמטרים של בקשות זמין במאמר בנושא שיטת instanceTemplates.insert.

יצירת תבנית של הגדרות מכונה על סמך מכונה קיימת

אפשר להשתמש ב-REST או ב-CLI של gcloud כדי לשמור את ההגדרה של מכונה וירטואלית קיימת כתבנית של הגדרות מכונה. אפשר גם לשנות את האופן שבו מוגדרים דיסקי המקור בתבנית.

אם אתם צריכים לשנות מאפיינים אחרים, קודם יוצרים תבנית מכונה שמבוססת על מכונה קיימת, ואז יוצרים תבנית דומה עם שינויים נוספים.

gcloud

משתמשים בפקודה gcloud compute instance-templates create עם הדגלים --source-instance ו---source-instance-zone. אם רוצים ליצור תבנית של הגדרות מכונה אזורית, צריך להשתמש גם בדגל --instance-template-region כדי לציין את האזור של תבנית הגדרות המכונה.

כדי ליצור תבנית של הגדרות מכונה אזורית, משתמשים בפקודה הבאה:

 gcloud compute instance-templates create INSTANCE_TEMPLATE_NAME \
     --source-instance=SOURCE_INSTANCE \
     --source-instance-zone=SOURCE_INSTANCE_ZONE \
     --instance-template-region=REGION

כדי ליצור תבנית של הגדרות מכונה גלובלית, משתמשים בפקודה הבאה:

gcloud compute instance-templates create INSTANCE_TEMPLATE_NAME \
    --source-instance=SOURCE_INSTANCE \
    --source-instance-zone=SOURCE_INSTANCE_ZONE

כדי לשנות את האופן שבו מוגדרים הדיסקים של מופע המקור, מוסיפים סימון אחד או יותר של --configure-disk.

בדוגמה הבאה נוצרת תבנית מכונה גלובלית ממכונה קיימת, והדיסק של מכונת המקור מוחלף במפרטים שאתם מספקים.

  gcloud compute instance-templates create INSTANCE_TEMPLATE_NAME \
      --source-instance=SOURCE_INSTANCE \
      --source-instance-zone=SOURCE_INSTANCE_ZONE \
      --configure-disk= \
      device-name=SOURCE_DISK, \
      instantiate-from=INSTANTIATE_OPTIONS, \
      auto-delete=AUTO_DELETE

מחליפים את מה שכתוב בשדות הבאים:

  • INSTANCE_TEMPLATE_NAME הוא שם התבנית שרוצים ליצור.
  • SOURCE_INSTANCE הוא השם של המופע שרוצים להשתמש בו כמודל לתבנית החדשה.
  • SOURCE_INSTANCE_ZONE הוא התחום שמכיל את מופע המקור.
  • SOURCE_DISK הוא השם של דיסק של מופע מקור שרוצים לשנות בתבנית.
  • INSTANTIATE_OPTIONS מציין אם לכלול את הדיסק ואיזו תמונה להשתמש. הערכים התקינים תלויים בסוג הדיסק:

    • source-image או source-image-family (תקף רק לדיסקים של אתחול ולדיסקים אחרים של קריאה וכתיבה מתמשכים). מציינים את האפשרות הזו אם רוצים להשתמש באותה תמונת מקור או באותה משפחה של תמונות מקור ששימשה ליצירת הדיסק במופע ה-VM של המקור.
    • custom-image (תקף רק לאתחול ולדיסקים אחרים עם הרשאות קריאה וכתיבה מתמשכות). אם רוצים לשמור את האפליקציות וההגדרות ממכונות ה-VM של המקור בתבנית של הגדרות המכונה, אפשר ליצור תמונה בהתאמה אישית ואז לציין אותה כשיוצרים את התבנית. אם מציינים תמונה מותאמת אישית, צריך לספק את הנתיב או כתובת ה-URL שלה, כמו בדוגמה הבאה. אפשר גם לציין משפחת תמונות בפורמט הבא:

      --configure-disk=device-name=DATA_DISK_NAME,instantiate-from=custom-image, \
      custom-image=projects/PROJECT_ID/global/images/family/IMAGE_FAMILY_NAME
      
    • attach-read-only (תקף רק לדיסקים לקריאה בלבד).

    • blank (תקף רק לדיסקים לאחסון מתמיד שאינם דיסקים לאתחול ול-SSD מקומיים). אם מציינים את האפשרות הזו, כשמשתמשים בתבנית כדי ליצור מכונה וירטואלית חדשה, הדיסק נוצר ללא פורמט. כדי להשתמש בדיסק בהגדרה שניתנת להרחבה, צריך לעצב אותו ולטעון אותו בסקריפט לטעינה בזמן ההפעלה.

    • do-not-include (תקף רק לדיסקים מתמידים שאינם דיסקי אתחול ולדיסקים לקריאה בלבד).

  • AUTO_DELETE מציין אם הדיסק נמחק אוטומטית כשמוחקים את המכונה. הערכים התקפים הם: false,‏ no,‏ true ו-yes.

לדוגמה, הפקודה הבאה יוצרת תבנית של הגדרות מכונה על סמך my-source-instance, עם האפשרות להשתמש בתמונה המקורית מ-data-disk-a, אבל מגדירה את המחיקה האוטומטית ל-true ומחליפה את data-disk-b בתמונה בהתאמה אישית.

 gcloud compute instance-templates create my-instance-template  \
     --source-instance=my-source-instance \
     --configure-disk=device-name=data-disk-a,instantiate-from=source-image,auto-delete=true \
     --configure-disk=device-name=data-disk-b,instantiate-from=custom-image,custom-image=projects/cps-cloud/global/images/cos-89-16108-403-15

המשך

import (
	"context"
	"fmt"
	"io"

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

// createTemplateFromInstance creates a new instance template based on an existing instance.
// This new template specifies a different boot disk.
func createTemplateFromInstance(w io.Writer, projectID, instance, templateName string) error {
	// projectID := "your_project_id"
	// instance := "projects/project/zones/zone/instances/instance"
	// templateName := "your_template_name"

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

	req := &computepb.InsertInstanceTemplateRequest{
		Project: projectID,
		InstanceTemplateResource: &computepb.InstanceTemplate{
			Name:           proto.String(templateName),
			SourceInstance: proto.String(instance),
			SourceInstanceParams: &computepb.SourceInstanceParams{
				DiskConfigs: []*computepb.DiskInstantiationConfig{
					{
						// Device name must match the name of a disk attached to the instance
						// your template is based on.
						DeviceName: proto.String("disk-1"),
						// Replace the original boot disk image used in your instance with a Rocky Linux image.
						InstantiateFrom: proto.String(computepb.DiskInstantiationConfig_CUSTOM_IMAGE.String()),
						CustomImage:     proto.String("projects/rocky-linux-cloud/global/images/family/rocky-linux-8"),
						// Override the auto_delete setting.
						AutoDelete: proto.Bool(true),
					},
				},
			},
		},
	}

	op, err := instanceTemplatesClient.Insert(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to create instance template: %w", err)
	}

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

	fmt.Fprintf(w, "Instance template created\n")

	return nil
}

Java


import com.google.cloud.compute.v1.DiskInstantiationConfig;
import com.google.cloud.compute.v1.DiskInstantiationConfig.InstantiateFrom;
import com.google.cloud.compute.v1.GlobalOperationsClient;
import com.google.cloud.compute.v1.InsertInstanceTemplateRequest;
import com.google.cloud.compute.v1.InstanceTemplate;
import com.google.cloud.compute.v1.InstanceTemplatesClient;
import com.google.cloud.compute.v1.Operation;
import com.google.cloud.compute.v1.SourceInstanceParams;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class CreateTemplateFromInstance {

  public static void main(String[] args)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // TODO(developer): Replace these variables before running the sample.
    // projectId: project ID or project number of the Cloud project you use.
    // instance: the instance to base the new template on. This value uses the following format:
    // **NOTE**: "projects/{project}/zones/{zone}/instances/{instance_name}"
    // templateName: name of the new template to create.
    String projectId = "your-project-id";
    String templateName = "template-name";
    String instance = String.format("projects/%s/zones/%s/instances/%s", projectId, "zone",
        "instanceName");
    createTemplateFromInstance(projectId, templateName, instance);
  }

  // Create a new instance template based on an existing instance.
  // This new template specifies a different boot disk.
  public static void createTemplateFromInstance(String projectId, String templateName,
      String instance)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    try (InstanceTemplatesClient instanceTemplatesClient = InstanceTemplatesClient.create();
        GlobalOperationsClient globalOperationsClient = GlobalOperationsClient.create()) {

      SourceInstanceParams sourceInstanceParams = SourceInstanceParams.newBuilder()
          .addDiskConfigs(DiskInstantiationConfig.newBuilder()
              // Device name must match the name of a disk attached to the instance you are
              // basing your template on.
              .setDeviceName("disk-1")
              // Replace the original boot disk image used in your instance
              // with a Rocky Linux image.
              .setInstantiateFrom(InstantiateFrom.CUSTOM_IMAGE.toString())
              .setCustomImage(
                  String.format("projects/%s/global/images/family/%s", "rocky-linux-cloud",
                      "rocky-linux-8"))
              // Override the AutoDelete setting.
              .setAutoDelete(true).build())
          .build();

      InstanceTemplate instanceTemplate = InstanceTemplate.newBuilder()
          .setName(templateName)
          .setSourceInstance(instance)
          .setSourceInstanceParams(sourceInstanceParams)
          .build();

      InsertInstanceTemplateRequest insertInstanceTemplateRequest = InsertInstanceTemplateRequest
          .newBuilder()
          .setProject(projectId)
          .setInstanceTemplateResource(instanceTemplate)
          .build();

      Operation operation = instanceTemplatesClient.insertCallable()
          .futureCall(insertInstanceTemplateRequest).get(3, TimeUnit.MINUTES);

      Operation response = globalOperationsClient.wait(projectId, operation.getName());

      if (response.hasError()) {
        System.out.println("Instance Template creation failed ! ! " + response);
        return;
      }
      System.out.printf("Instance Template creation operation status %s: %s", templateName,
          response.getStatus());
    }
  }
}

Node.js

/**
 * TODO(developer): Uncomment and replace these variables before running the sample.
 */
// const projectId = 'YOUR_PROJECT_ID';
// const instance = 'projects/project/zones/zone/instances/instance';
// const templateName = 'your_template_name';

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

// Create a new instance template based on an existing instance.
// This new template specifies a different boot disk.
async function createTemplateFromInstance() {
  const instanceTemplatesClient = new compute.InstanceTemplatesClient();

  const [response] = await instanceTemplatesClient.insert({
    project: projectId,
    instanceTemplateResource: {
      name: templateName,
      sourceInstance: instance,
      sourceInstanceParams: {
        diskConfigs: [
          {
            // Device name must match the name of a disk attached to the instance
            // your template is based on.
            deviceName: 'disk-1',
            // Replace the original boot disk image used in your instance with a Rocky Linux image.
            instantiateFrom: 'CUSTOM_IMAGE',
            customImage:
              'projects/rocky-linux-cloud/global/images/family/rocky-linux-8',
            // Override the auto_delete setting.
            autoDelete: true,
          },
        ],
      },
    },
  });
  let operation = response.latestResponse;
  const operationsClient = new compute.GlobalOperationsClient();

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

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

createTemplateFromInstance();

Python

from __future__ import annotations

import sys
from typing import Any

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


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

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

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

    Returns:
        Whatever the operation.result() returns.

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

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

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

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

    return result


def create_template_from_instance(
    project_id: str, instance: str, template_name: str
) -> compute_v1.InstanceTemplate:
    """
    Create a new instance template based on an existing instance.
    This new template specifies a different boot disk.

    Args:
        project_id: project ID or project number of the Cloud project you use.
        instance: the instance to base the new template on. This value uses
            the following format: "projects/{project}/zones/{zone}/instances/{instance_name}"
        template_name: name of the new template to create.

    Returns:
        InstanceTemplate object that represents the new instance template.
    """
    disk = compute_v1.DiskInstantiationConfig()
    # Device name must match the name of a disk attached to the instance you are
    # basing your template on.
    disk.device_name = "disk-1"
    # Replace the original boot disk image used in your instance with a Rocky Linux image.
    disk.instantiate_from = "CUSTOM_IMAGE"
    disk.custom_image = "projects/rocky-linux-cloud/global/images/family/rocky-linux-8"
    # Override the auto_delete setting.
    disk.auto_delete = True

    template = compute_v1.InstanceTemplate()
    template.name = template_name
    template.source_instance = instance
    template.source_instance_params = compute_v1.SourceInstanceParams()
    template.source_instance_params.disk_configs = [disk]

    template_client = compute_v1.InstanceTemplatesClient()
    operation = template_client.insert(
        project=project_id, instance_template_resource=template
    )

    wait_for_extended_operation(operation, "instance template creation")

    return template_client.get(project=project_id, instance_template=template_name)

REST

כדי ליצור תבנית אזורית של הגדרות מכונה, משתמשים ב-‎regionInstanceTemplates.insert method. כדי ליצור תבנית גלובלית של הגדרות מכונה, משתמשים ב-‎instanceTemplates.insert method.

בבקשה צריך לציין את השדה sourceInstance. כדי לשנות את האופן שבו מוגדרים הדיסקים של מופע המקור, מוסיפים שדה diskConfigs אחד או יותר.

לדוגמה, אפשר לבצע את הקריאה הבאה כדי ליצור תבנית של הגדרות מכונה גלובלית ממכונה קיימת.

POST https://compute.s3nsapis.fr/compute/v1/projects/PROJECT_ID/global/instanceTemplates

{
  "name": "INSTANCE_TEMPLATE_NAME",
  "sourceInstance": "zones/SOURCE_INSTANCE_ZONE/instances/SOURCE_INSTANCE",
  "sourceInstanceParams": {
    "diskConfigs": [
      {
        "deviceName": "SOURCE_DISK",
        "instantiateFrom": "INSTANTIATE_OPTIONS",
        "autoDelete": false
      }
    ]
  }
}

מחליפים את מה שכתוב בשדות הבאים:

  • PROJECT_ID: מזהה הפרויקט
  • INSTANCE_TEMPLATE_NAME: השם של התבנית החדשה
  • SOURCE_INSTANCE_ZONE: האזור של מכונת המקור
  • SOURCE_INSTANCE: השם של מכונת המקור שתשמש כמודל לתבנית של הגדרות מכונה זו
  • SOURCE_DISK: השם של דיסק של מכונת מקור שרוצים לשנות בתבנית
  • INSTANTIATE_OPTIONS: מציין אם לכלול את הדיסק ואיזו תמונה להשתמש

    הערכים התקינים תלויים בסוג הדיסק:

    • source-image או source-image-family (תקף רק לדיסקים של אתחול ולדיסקים מתמידים אחרים עם הרשאות קריאה וכתיבה).
    • custom-image (תקף רק לאתחול ולדיסקים אחרים עם הרשאות קריאה וכתיבה מתמשכות). אם רוצים לשמור את האפליקציות וההגדרות ממכונות ה-VM של המקור בתבנית של הגדרות המכונה, אפשר ליצור תמונה בהתאמה אישית ואז לציין אותה כשיוצרים את התבנית. אם מציינים תמונה מותאמת אישית, צריך לספק את הנתיב או כתובת ה-URL שלה, כמו בדוגמה הבאה. אפשר גם לציין משפחת תמונות באמצעות הפורמט הבא:

        "diskConfigs": [
          {
            "deviceName": DATA_DISK_NAME,
            "instantiateFrom": custom-image,
            "customImage": "projects/PROJECT_ID/global/images/family/IMAGE_FAMILY_NAME"
          }
        ]
      
    • attach-read-only (תקף רק לדיסקים לקריאה בלבד).

    • blank (תקף רק לדיסקים לאחסון מתמיד שאינם דיסקי אתחול ול-SSD מקומיים). אם מציינים את האפשרות הזו, כשמשתמשים בתבנית כדי ליצור מכונה וירטואלית חדשה, הדיסק נוצר ללא פורמט. כדי להשתמש בדיסק בהגדרה שניתנת להרחבה, צריך לעצב אותו ולטעון אותו בסקריפט לטעינה בזמן ההפעלה.

    • do-not-include (תקף רק לדיסקים מתמידים שאינם דיסקי אתחול ולדיסקים לקריאה בלבד).

בדוגמה הבאה נוצרת תבנית של הגדרות מכונה חדשה על סמך my-source-instance. בתבנית של הגדרות מכונה, התמונה של data-disk-a מוחלפת בתמונה של projects/cos-cloud/global/images/cos-89-16108-403-15.

POST https://compute.s3nsapis.fr/compute/v1/projects/my_project/global/instanceTemplates

{
  "name": "my-instance-template",
  "sourceInstance": "zones/us-central1-a/instances/my-source-instance",
  "sourceInstanceParams":
  {
    "diskConfigs":
    [
      {
        "deviceName": "data-disk-a",
        "instantiateFrom": "custom-image",
        "customImage": "projects/cos-cloud/global/images/cos-89-16108-403-15"
      }
    ]
  }
}

בטבלה הבאה מפורטות האפשרויות להחלפת דיסקים שמוגדרות בתבנית.

סוג הדיסק אפשרויות
דיסק אתחול
  • [ברירת מחדל] שימוש באותה תמונת מקור או באותה משפחת תמונות ששימשו ליצירת דיסק האתחול במופע המקור.
  • אפשר להשתמש בכתובת ה-URL של כל תמונה (מותאמת אישית או ציבורית) כמו בדוגמה הקודמת, או לציין משפחת תמונות באמצעות הפורמט הבא:
  • projects/exampleproject/global/images/family/IMAGE_FAMILY_NAME

דיסקים אחרים של אחסון מתמיד עם הרשאות קריאה/כתיבה
  • [ברירת מחדל] שימוש באותה תמונת מקור או באותה משפחה של תמונות מקור ששימשו ליצירת הדיסק במופע המקור. הערה: אם בדיסק של מופע המקור אין מאפיין של תמונת מקור או משפחת תמונות מקור, הוא נכלל בתבנית כדיסק ריק.
  • אפשר להשתמש בכתובת ה-URL של כל תמונה (מותאמת אישית או ציבורית) כמו בדוגמה הקודמת, או לציין משפחת תמונות באמצעות הפורמט הבא:

    projects/exampleproject/global/images/family/IMAGE_FAMILY_NAME

  • במקום זאת, אפשר להשתמש בדיסק ריק בתבנית. כשמשתמשים בתבנית כדי ליצור מופע חדש, הדיסק הזה נוצר ללא פורמט. כדי להשתמש בדיסק בהגדרה שניתנת להרחבה, צריך לעצב אותו ולטעון אותו בסקריפט לטעינה בזמן ההפעלה.
  • אל תכללו את הדיסק.
דיסקים לקריאה בלבד
  • [Default] הדיסק ייכלל במצב קריאה-בלבד.
  • אל תכללו את הדיסק.
אחסון SSD מקומי
  • [Default] (ברירת מחדל) כולל SSD מקומי ריק. כשמשתמשים בתבנית כדי ליצור מופע חדש, הדיסק הזה נוצר ללא פורמט. כדי להשתמש בדיסק בהגדרה שניתנת להרחבה, צריך לעצב אותו ולטעון אותו בסקריפט לטעינה בזמן ההפעלה.

לכל דיסק, אפשר גם לשנות את מאפיין auto-delete כדי לציין אם הדיסק יימחק כשמוחקים את המופע המשויך אליו.

כברירת מחדל, אם לא מציינים אפשרויות לשינוי, הגדרת הדיסק בתבנית תואמת למופע המקור.

יצירת תבנית של הגדרות מכונה על סמך תבנית קיימת

אי אפשר לעדכן תבנית קיימת של הגדרות מכונה. אבל אם תבנית של הגדרות מכונה מתיישנת או אם צריך לבצע שינויים, אפשר ליצור עוד תבנית עם מאפיינים דומים באמצעות המסוף.

  1. עוברים לדף Instance templates.

    כניסה לדף Instance templates

  2. לוחצים על תבנית של הגדרות מכונה שרוצים להעתיק ולעדכן.

  3. לוחצים על יצירת תמונה דומה.

  4. מעדכנים את ההגדרה בתבנית החדשה.

  5. לוחצים על יצירה.

יצירת תבנית של הגדרות מכונה עבור מכונות וירטואליות עם GPU

כשיוצרים תבנית של הגדרות מכונה, אפשר להגדיר אותה ליצירת מכונות וירטואליות עם מעבדי GPU מצורפים. לשם כך, צריך לציין את הפרטים הבאים:

המסוף

כדי ליצור תבנית של הגדרות מכונה עבור מכונות וירטואליות עם GPU:

  1. נכנסים לדף Instance templates במסוף Cloud de Confiance .

    כניסה לדף Instance templates

  2. לוחצים על Create instance template.

  3. בשדה Name, מזינים שם לתבנית של הגדרות מכונה.

  4. בקטע מיקום בוחרים באחת מהאפשרויות הבאות:

    • כדי ליצור תבנית של הגדרות מכונה גלובלית, בוחרים באפשרות Global (ברירת מחדל).

    • כדי ליצור תבנית של הגדרות מכונה אזורית, בוחרים באפשרות Regional (אזורית) ואז בוחרים את האזור שבו רוצים ליצור את תבנית של הגדרות מכונה.

  5. בקטע Machine configuration מבצעים את הפעולות הבאות:

    1. לוחצים על הכרטיסייה GPUs.

    2. בתפריט סוג ה-GPU, בוחרים את סוג ה-GPU.

    3. בתפריט Number of GPUs (מספר יחידות ה-GPU), בוחרים את מספר יחידות ה-GPU.

    4. אופציונלי: אם דגם ה-GPU שלכם תומך בתחנות עבודה וירטואליות של NVIDIA RTX‏ (vWS) לעומסי עבודה של גרפיקה, ואתם מתכננים להריץ עומסי עבודה עתירי גרפיקה, בוחרים באפשרות הפעלת תחנת עבודה וירטואלית (NVIDIA GRID).

    5. בקטע Machine type, בוחרים סוג מכונה.

  6. אופציונלי: כדי לשנות את סוג דיסק האתחול או את התמונה שמוגדרים כברירת מחדל, בקטע Boot disk לוחצים על Change. אחר כך, פועלים לפי ההנחיות כדי לשנות את דיסק האתחול.

  7. לוחצים על יצירה.

gcloud

כדי ליצור תבנית של הגדרות מכונה עבור מכונות וירטואליות עם GPU, משתמשים בפקודה instance-templates create עם הדגל --maintenance-policy שמוגדר לערך TERMINATE.

לדוגמה, כדי ליצור תבנית של הגדרות מכונה גלובלית עבור מכונות וירטואליות עם GPU, משתמשים בפקודה הבאה:

gcloud compute instance-templates create INSTANCE_TEMPLATE_NAME \
    --image-project=IMAGE_PROJECT \
    --image-family=IMAGE_FAMILY \
    --machine-type=MACHINE_TYPE \
    --maintenance-policy=TERMINATE

מחליפים את מה שכתוב בשדות הבאים:

  • INSTANCE_TEMPLATE_NAME: השם של תבנית הגדרות המכונה.

  • IMAGE_PROJECT: פרויקט התמונה שמכיל את התמונה. לדוגמה, debian-cloud. מידע נוסף על פרויקטים של תמונות נתמכות זמין במאמר תמונות ציבוריות.

  • IMAGE_FAMILY או IMAGE: מציינים אחת מהאפשרויות הבאות:

    • IMAGE_FAMILY: משפחת תמונות. המאפיין הזה מציין את תמונת מערכת ההפעלה העדכנית ביותר שלא הוצאה משימוש. לדוגמה, אם מציינים debian-10, נעשה שימוש בגרסה האחרונה במשפחת תמונות Debian 10. מידע נוסף על שימוש במשפחות תמונות זמין במאמר בנושא שיטות מומלצות לשימוש במשפחות תמונות.

    • IMAGE: גרסה ספציפית של תמונת מערכת ההפעלה, לדוגמה debian-10-buster-v20200309. אם בוחרים לציין גרסה ספציפית של תמונת מערכת ההפעלה, צריך להחליף את הדגל --image-family בדגל --image.

  • MACHINE_TYPE: סוג המכונה של המכונות הווירטואליות. אם מציינים סוג מכונה N1, צריך לכלול את הדגל --accelerator כדי לציין את המספר והסוג של יחידות ה-GPU שיוצמדו למכונות הווירטואליות.

לדוגמה, נניח שרוצים ליצור תבנית של הגדרות מכונה גלובלית עבור מכונות וירטואליות עם GPU, שמציינת את המאפיינים הבאים:

  • מכונה עם קונפיגורציה מוגדרת (predefined) מסוג N1 עם 2 יחידות vCPU.

  • ‫GPU אחד של NVIDIA T4 לצירוף למכונות הווירטואליות.

  • ‫Debian כפרויקט התמונה.

  • ‫Debian 10 כמשפחת התמונות.

כדי ליצור את תבנית של הגדרות מכונה לדוגמה, משתמשים בפקודה הבאה:

gcloud compute instance-templates create instance-template-gpu \
    --accelerator=count=1,type=nvidia-tesla-t4 \
    --machine-type=n1-standard-2 \
    --image-family=debian-10 \
    --image-project=debian-cloud \
    --maintenance-policy=TERMINATE

Terraform

כדי ליצור תבנית של הגדרות מכונה, משתמשים באחד מהמשאבים הבאים:

בדוגמה הבאה נוצרת תבנית של הגדרות מכונה גלובלית שמציינת מכונה עם קונפיגורציה מוגדרת (predefined) מסוג N1 עם 2 vCPU ומעבד GPU אחד של NVIDIA T4 שמצורף:

resource "google_compute_instance_template" "default" {
  name         = "gpu-template"
  machine_type = "n1-standard-2"

  disk {
    source_image = "debian-cloud/debian-11"
  }

  network_interface {
    network = "default"
  }

  guest_accelerator {
    type  = "nvidia-tesla-t4"
    count = 1
  }

  scheduling {
    on_host_maintenance = "TERMINATE"
  }
}

כדי ללמוד איך להחיל הגדרות ב-Terraform או להסיר אותן, ראו פקודות בסיסיות ב-Terraform.

REST

כדי ליצור תבנית של הגדרות מכונה למכונות וירטואליות עם GPU, שולחים בקשת POST אל ה-method‏ instanceTemplates.insert. בגוף הבקשה, כוללים את השדה onHostMaintenance ומגדירים אותו לערך TERMINATE.

לדוגמה, כדי ליצור תבנית גלובלית של הגדרות מכונה עבור מכונות וירטואליות עם GPU, שולחים בקשה כפי שמוצג בהמשך:POST

POST https://compute.s3nsapis.fr/compute/v1/projects/PROJECT_ID/global/instanceTemplates

{
  "name": "INSTANCE_TEMPLATE_NAME",
  "properties": {
    "disks": [
      {
        "type": "PERSISTENT",
        "boot": true,
        "mode": "READ_WRITE",
        "initializeParams": {
          "sourceImage": "projects/IMAGE_PROJECT/global/images/IMAGE"
        }
      }
    ],
    "machineType": "MACHINE_TYPE",
    "networkInterfaces": [
      {
        "accessConfigs": [
          {
            "name": "external-IP",
            "type": "ONE_TO_ONE_NAT"
          }
        ],
        "network": "global/networks/default"
      }
    ],
    "scheduling": {
      "onHostMaintenance": "TERMINATE"
    }
  }
}

מחליפים את מה שכתוב בשדות הבאים:

  • PROJECT_ID: מזהה הפרויקט שבו רוצים ליצור את תבנית של הגדרות מכונה.

  • INSTANCE_TEMPLATE_NAME: השם של תבנית הגדרות המכונה.

  • IMAGE_PROJECT: פרויקט התמונה שמכיל את התמונה. לדוגמה, debian-cloud. מידע נוסף על פרויקטים של תמונות נתמכות זמין במאמר תמונות ציבוריות.

  • IMAGE או IMAGE_FAMILY: מציינים אחת מהאפשרויות הבאות:

    • IMAGE: גרסה ספציפית של תמונת מערכת ההפעלה, לדוגמה debian-10-buster-v20200309.

    • IMAGE_FAMILY: משפחת תמונות. המאפיין הזה מציין את תמונת מערכת ההפעלה העדכנית ביותר שלא הוצאה משימוש. לדוגמה, אם מציינים family/debian-10, נעשה שימוש בגרסה העדכנית ביותר במשפחת קובצי האימג' של Debian 10. מידע נוסף על שימוש במשפחות תמונות זמין במאמר בנושא שיטות מומלצות לשימוש במשפחות תמונות.

  • MACHINE_TYPE: סוג המכונה של המכונות הווירטואליות. אם מציינים סוג מכונה N1, צריך לכלול את השדה guestAccelerators כדי לציין את המספר והסוג של יחידות ה-GPU שרוצים לצרף למכונות הווירטואליות.

לדוגמה, נניח שרוצים ליצור תבנית של הגדרות מכונה גלובלית עבור מכונות וירטואליות עם GPU, שמציינת את המאפיינים הבאים:

  • מכונה עם קונפיגורציה מוגדרת (predefined) מסוג N1 עם 2 יחידות vCPU.

  • ‫GPU אחד של NVIDIA T4 לצירוף למכונות הווירטואליות.

  • ‫Debian כפרויקט התמונה.

  • ‫Debian 10 כמשפחת התמונות.

כדי ליצור את תבנית של הגדרות מכונה לדוגמה, שולחים בקשת POST באופן הבא:

POST https://compute.s3nsapis.fr/compute/v1/projects/example-project/global/instanceTemplates

{
  "name": "instance-template-gpu",
  "properties": {
    "disks": [
      {
        "type": "PERSISTENT",
        "boot": true,
        "mode": "READ_WRITE",
        "initializeParams": {
          "sourceImage": "projects/debian-cloud/global/images/family/debian-10"
        }
      }
    ],
    "guestAccelerators": [
      {
        "acceleratorType": "nvidia-tesla-t4",
        "acceleratorCount": 1
      }
    ],
    "machineType": "n1-standard-2",
    "networkInterfaces": [
      {
        "accessConfigs": [
          {
            "name": "external-IP",
            "type": "ONE_TO_ONE_NAT"
          }
        ],
        "network": "global/networks/default"
      }
    ],
    "scheduling": {
      "onHostMaintenance": "TERMINATE"
    }
  }
}

אפשרויות הגדרה נוספות ליצירת תבנית של הגדרות מכונה מפורטות במאמר יצירת תבנית של הגדרות מכונה.

יצירת תבנית של הגדרות מכונה עם קובץ אימג' של קונטיינר

אפשר לציין קובץ אימג' של קונטיינר בתבנית של הגדרות מכונה. כברירת מחדל, Compute Engine כולל בתבנית גם תמונה של מערכת הפעלה שמותאמת לקונטיינרים עם Docker מותקן. כשמשתמשים בתבנית כדי ליצור מופע חדש, מאגר התגים מופעל באופן אוטומטי כשהמופע מתחיל לפעול.

המסוף

  1. עוברים לדף Instance templates.

    כניסה לדף Instance templates

  2. לוחצים על Create instance template.

  3. בקטע Container (מאגר תגים), לוחצים על Deploy Container (פריסת מאגר תגים).

  4. בתיבת הדו-שיח Configure container (הגדרת קונטיינר), מציינים את Container image (קובץ אימג' של קונטיינר) שבו רוצים להשתמש.

    • אפשר לציין תמונה מ-Container Registry או מ-Artifact Registry. לדוגמה:
      • gcr.io/cloud-marketplace/google/nginx1:TAG, כאשר TAG הוא התג שמוגדר לגרסה ספציפית של קובץ אימג' של קונטיינר NGINX שזמינה ב-Google Cloud Marketplace.
      • us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0 בוחר תמונה לדוגמה hello-app שמאוחסנת ב-Artifact Registry.
    • אם משתמשים בקובץ אימג' של קונטיינר מ-Docker Hub, צריך תמיד לציין את השם המלא של קובץ האימג' של Docker. לדוגמה, כדי לפרוס קובץ אימג' של קונטיינר Apache, מציינים את שם קובץ האימג' הבא: docker.io/httpd:2.4.
  5. אפשר גם ללחוץ על אפשרויות מתקדמות של מאגרי תגים. מידע נוסף זמין במאמר בנושא הגדרת אפשרויות להפעלת הקונטיינר.

  6. לוחצים על יצירה.

gcloud

משתמשים בפקודה gcloud compute instance-templates create-with-container:

 gcloud compute instance-templates create-with-container INSTANCE_TEMPLATE_NAME \
     --container-image=CONTAINER_IMAGE

מחליפים את מה שכתוב בשדות הבאים:

  • INSTANCE_TEMPLATE_NAME: השם של התבנית שרוצים ליצור.
  • CONTAINER_IMAGE: השם המלא של תמונת מאגר התגים לשימוש.

לדוגמה, הפקודה הבאה יוצרת תבנית של הגדרות מכונה חדשה בשם nginx-vm. מכונה וירטואלית שנוצרה מהתבנית הזו מופעלת ומריצה את קובץ האימג' של הקונטיינר, gcr.io/cloud-marketplace/google/nginx1:TAG, כשהמכונה הווירטואלית מופעלת.

 gcloud compute instance-templates create-with-container nginx-vm \
     --container-image=gcr.io/cloud-marketplace/google/nginx1:TAG

מחליפים את TAG בתג שהוגדר לגרסה ספציפית של קובץ האימג' בקונטיינר NGINX שזמין ב-Google Cloud Marketplace.

אפשר גם להגדיר אפשרויות להרצת הקונטיינר.

יצירת תבנית של הגדרות מכונה שמציינת רשת משנה

gcloud

כדי ליצור תבנית של הגדרות מכונה אזורית או גלובלית, משתמשים בפקודה instance-templates create. משתמשים בדגל --subnet כדי למקם מופעים שנוצרו מהתבנית ברשת המשנה שבחרתם. הדגל --subnet מחייב את הדגל --region.

אם רוצים ליצור תבנית של הגדרות מכונה אזורית, צריך להשתמש בדגל --instance-template-region כדי להגדיר את האזור של התבנית. חשוב לוודא שאתם משתמשים ברשת משנה מאותו אזור שבו אתם רוצים ליצור את תבנית של הגדרות מכונה האזורית.

gcloud compute instance-templates create INSTANCE_TEMPLATE_NAME \
    --region=REGION \
    --subnet=SUBNET_NAME_OR_URL \
    --stack-type=STACK_TYPE \
    --instance-template-region=INSTANCE_TEMPLATE_REGION

מחליפים את מה שכתוב בשדות הבאים:

  • INSTANCE_TEMPLATE_NAME: השם של תבנית של הגדרות מכונה
  • REGION: האזור של תת-הרשת
  • SUBNET_NAME_OR_URL: שם תת-הרשת או כתובת ה-URL שלה

  • STACK_TYPE: אופציונלי: האם IPv6 מופעל בממשק הרשת שמוגדר כברירת מחדל. אפשר להשתמש בערכים הבאים: IPV4_ONLY, IPV4_IPV6 או IPV6_ONLY. אם לא מציינים את הדגל הזה, ערך ברירת המחדל הוא IPV4_ONLY.

  • INSTANCE_TEMPLATE_REGION: האזור שבו רוצים ליצור את תבנית של הגדרות מכונה. האזור הזה צריך להיות זהה לערך של REGION.

בדוגמה הבאה נוצרת תבנית בשם template-qa שיוצרת רק מופעים ברשת המשנה subnet-us-qa.

gcloud compute instance-templates create template-qa \
    --region=us-central1 \
    --subnet=subnet-us-qa

הפלט אמור להיראות כך:

Created [https://compute.s3nsapis.fr/compute/latest/projects/PROJECT_ID/global/instanceTemplates/template-qa].
NAME        MACHINE_TYPE        PREEMPTIBLE CREATION_TIMESTAMP
template-qa e2-standard-2       2019-12-23T20:34:00.791-07:00

המשך

import (
	"context"
	"fmt"
	"io"

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

// createTemplateWithSubnet creates an instance template that uses a provided subnet.
func createTemplateWithSubnet(w io.Writer, projectID, network, subnetwork, templateName string) error {
	// projectID := "your_project_id"
	// network := "projects/project/global/networks/network"
	// subnetwork := "projects/project/regions/region/subnetworks/subnetwork"
	// templateName := "your_template_name"

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

	req := &computepb.InsertInstanceTemplateRequest{
		Project: projectID,
		InstanceTemplateResource: &computepb.InstanceTemplate{
			Name: proto.String(templateName),
			Properties: &computepb.InstanceProperties{
				// The template describes the size and source image of the boot disk
				// to attach to the instance.
				Disks: []*computepb.AttachedDisk{
					{
						InitializeParams: &computepb.AttachedDiskInitializeParams{
							DiskSizeGb:  proto.Int64(250),
							SourceImage: proto.String("projects/debian-cloud/global/images/family/debian-11"),
						},
						AutoDelete: proto.Bool(true),
						Boot:       proto.Bool(true),
					},
				},
				MachineType: proto.String("e2-standard-4"),
				// The template connects the instance to the specified network and subnetwork.
				NetworkInterfaces: []*computepb.NetworkInterface{
					{
						Network:    proto.String(network),
						Subnetwork: proto.String(subnetwork),
					},
				},
			},
		},
	}

	op, err := instanceTemplatesClient.Insert(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to create instance template: %w", err)
	}

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

	fmt.Fprintf(w, "Instance template created\n")

	return nil
}

Java


import com.google.cloud.compute.v1.AttachedDisk;
import com.google.cloud.compute.v1.AttachedDiskInitializeParams;
import com.google.cloud.compute.v1.GlobalOperationsClient;
import com.google.cloud.compute.v1.InsertInstanceTemplateRequest;
import com.google.cloud.compute.v1.InstanceProperties;
import com.google.cloud.compute.v1.InstanceTemplate;
import com.google.cloud.compute.v1.InstanceTemplatesClient;
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 CreateTemplateWithSubnet {

  public static void main(String[] args)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    /*
    TODO(developer): Replace these variables before running the sample.
    projectId: project ID or project number of the Cloud project you use.
    network: the network to be used in the new template. This value uses
        the following format: "projects/{project}/global/networks/{network}"
    subnetwork: the subnetwork to be used in the new template. This value
        uses the following format: "projects/{project}/regions/{region}/subnetworks/{subnetwork}"
    templateName: name of the new template to create.
    */
    String projectId = "your-project-id";
    String network = String.format("projects/%s/global/networks/%s", projectId, "network");
    String subnetwork = String.format("projects/%s/regions/%s/subnetworks/%s", projectId, "region",
        "subnetwork");
    String templateName = "template-name";
    createTemplateWithSubnet(projectId, network, subnetwork, templateName);
  }

  // Create an instance template that uses a provided subnet.
  public static void createTemplateWithSubnet(String projectId, String network, String subnetwork,
      String templateName)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    try (InstanceTemplatesClient instanceTemplatesClient = InstanceTemplatesClient.create();
        GlobalOperationsClient globalOperationsClient = GlobalOperationsClient.create()) {

      AttachedDisk disk = AttachedDisk.newBuilder()
          .setInitializeParams(AttachedDiskInitializeParams.newBuilder()
              .setSourceImage(
                  String.format("projects/%s/global/images/family/%s", "debian-cloud", "debian-11"))
              .setDiskSizeGb(250).build())
          .setAutoDelete(true)
          .setBoot(true)
          .build();

      InstanceProperties instanceProperties = InstanceProperties.newBuilder()
          .addDisks(disk)
          .setMachineType("e2-standard-4")
          .addNetworkInterfaces(NetworkInterface.newBuilder()
              .setNetwork(network)
              .setSubnetwork(subnetwork).build())
          .build();

      InstanceTemplate instanceTemplate = InstanceTemplate.newBuilder()
          .setName(templateName)
          .setProperties(instanceProperties)
          .build();

      InsertInstanceTemplateRequest insertInstanceTemplateRequest = InsertInstanceTemplateRequest
          .newBuilder()
          .setProject(projectId)
          .setInstanceTemplateResource(instanceTemplate)
          .build();

      Operation operation = instanceTemplatesClient.insertCallable()
          .futureCall(insertInstanceTemplateRequest).get(3, TimeUnit.MINUTES);

      Operation response = globalOperationsClient.wait(projectId, operation.getName());

      if (response.hasError()) {
        System.out.println("Template creation from subnet failed ! ! " + response);
        return;
      }
      System.out.printf("Template creation from subnet operation status %s: %s", templateName,
          response.getStatus());
    }
  }
}

Node.js

/**
 * TODO(developer): Uncomment and replace these variables before running the sample.
 */
// const projectId = 'YOUR_PROJECT_ID';
// const network = 'projects/project/global/networks/network';
// const subnetwork = 'projects/project/regions/region/subnetworks/subnetwork';
// const templateName = 'your_template_name';

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

// Create an instance template that uses a provided subnet.
async function createTemplateWithSubnet() {
  const instanceTemplatesClient = new compute.InstanceTemplatesClient();

  const [response] = await instanceTemplatesClient.insert({
    project: projectId,
    instanceTemplateResource: {
      name: templateName,
      properties: {
        // The template describes the size and source image of the boot disk
        // to attach to the instance.
        disks: [
          {
            // The template describes the size and source image of the boot disk
            // to attach to the instance.
            initializeParams: {
              diskSizeGb: '250',
              sourceImage:
                'projects/debian-cloud/global/images/family/debian-11',
            },
            autoDelete: true,
            boot: true,
          },
        ],
        machineType: 'e2-standard-4',
        // The template connects the instance to the specified network and subnetwork.
        networkInterfaces: [
          {
            network,
            subnetwork,
          },
        ],
      },
    },
  });
  let operation = response.latestResponse;
  const operationsClient = new compute.GlobalOperationsClient();

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

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

createTemplateWithSubnet();

Python

from __future__ import annotations

import sys
from typing import Any

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


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

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

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

    Returns:
        Whatever the operation.result() returns.

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

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

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

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

    return result


def create_template_with_subnet(
    project_id: str, network: str, subnetwork: str, template_name: str
) -> compute_v1.InstanceTemplate:
    """
    Create an instance template that uses a provided subnet.

    Args:
        project_id: project ID or project number of the Cloud project you use.
        network: the network to be used in the new template. This value uses
            the following format: "projects/{project}/global/networks/{network}"
        subnetwork: the subnetwork to be used in the new template. This value
            uses the following format: "projects/{project}/regions/{region}/subnetworks/{subnetwork}"
        template_name: name of the new template to create.

    Returns:
        InstanceTemplate object that represents the new instance template.
    """
    # The template describes the size and source image of the book disk to
    # attach to the instance.
    disk = compute_v1.AttachedDisk()
    initialize_params = compute_v1.AttachedDiskInitializeParams()
    initialize_params.source_image = (
        "projects/debian-cloud/global/images/family/debian-11"
    )
    initialize_params.disk_size_gb = 250
    disk.initialize_params = initialize_params
    disk.auto_delete = True
    disk.boot = True

    template = compute_v1.InstanceTemplate()
    template.name = template_name
    template.properties = compute_v1.InstanceProperties()
    template.properties.disks = [disk]
    template.properties.machine_type = "e2-standard-4"

    # The template connects the instance to the specified network and subnetwork.
    network_interface = compute_v1.NetworkInterface()
    network_interface.network = network
    network_interface.subnetwork = subnetwork
    template.properties.network_interfaces = [network_interface]

    template_client = compute_v1.InstanceTemplatesClient()
    operation = template_client.insert(
        project=project_id, instance_template_resource=template
    )
    wait_for_extended_operation(operation, "instance template creation")

    return template_client.get(project=project_id, instance_template=template_name)

שימוש בתבנית הזו ליצירת מכונות של MIG (עם או בלי התאמה אוטומטית לעומס) יוצר באופן אוטומטי את המכונה באזור וברשת המשנה שצוינו. כך תוכלו לשלוט בתת-הרשת של מופעים חדשים שנוצרו לאיזון עומסים.

שימוש בתמונות מותאמות אישית או ציבוריות בתבניות של מופעים

אפשר להשתמש בתמונה מותאמת אישית או בתמונה ציבורית לתבניות של המופעים:

  • תמונות בהתאמה אישית. קבוצות MIG נועדו להוסיף ולהסיר מכונות לעיתים קרובות, ולכן כדאי ליצור אימג' בהתאמה אישית ולציין אותו בתבנית של הגדרות מכונה. אתם יכולים להכין את התמונה באמצעות האפליקציות וההגדרות שנדרשות למכונות הווירטואליות, כדי שלא תצטרכו להגדיר את הפריטים האלה באופן ידני במכונות וירטואליות נפרדות ב-MIG.

  • תמונות ציבוריות. אתם יכולים ליצור תבנית של הגדרות מכונה שמשתמשת בתמונה ציבורית ובסקריפט לטעינה בזמן ההפעלה כדי להכין את המכונה אחרי שהיא מתחילה לפעול.

תמונות בהתאמה אישית הן דטרמיניסטיות יותר ומתחילות מהר יותר ממכונות וירטואליות עם סקריפטים להפעלה. עם זאת, סקריפטים להפעלה הם גמישים יותר, ולכן הם עוזרים לכם לעדכן את האפליקציות וההגדרות במופעים.

אם אתם מנהלים תמונות באמצעות משפחות תמונות, אתם יכולים לציין את השם של משפחת התמונות המותאמת אישית או הציבורית בתבנית של המופע. מידע נוסף על משפחות של תמונות זמין במאמר שיטות מומלצות לשימוש במשפחות של תמונות ב-Compute Engine.

המאמרים הבאים