カスタム マシンタイプの VM を作成する


Compute Engine は、VM インスタンスの作成時に使用できる事前定義されたマシンタイプを提供しています。事前定義されたマシンタイプには、vCPU の数とメモリの容量がプリセットされており、セット価格で課金されます。

事前定義された VM がニーズに合わない場合は、カスタムの仮想ハードウェア設定を使用して VM インスタンスを作成できます。具体的には、カスタム マシンタイプを効果的に利用して、vCPU の数とメモリ容量をカスタマイズした VM インスタンスを作成できます。カスタム マシンタイプは、汎用マシン ファミリーで使用できます。カスタム VM を作成すると、E2、N2、N2D、または N1 マシン ファミリーからカスタム VM をデプロイします。

カスタム VM は、次のようなシナリオに適しています。

  • 事前定義された仮想マシンタイプに適していないワークロード。
  • 処理能力やメモリがさらに必要だが、次のレベルのマシンタイプで提供されるアップグレードをすべては必要としないワークロード。

始める前に

料金

Google は、VM が使用する vCPU の数とメモリの時間に基づいてカスタム VM の請求を行います。事前定義されたマシンタイプの課金方法とは異なります。詳細については、VM の料金をご覧ください。

カスタム VM には、他のインスタンスと同じ 1 分間の最低料金が発生しますが、カスタム マシンタイプの継続利用割引は計算方法が異なります。詳細については、カスタム VM の継続利用割引をご覧ください。

メモリの表記(GB または MB)

Google Cloud のツールとドキュメントでは、マシンタイプ メモリはギガバイト(GB)単位で計算されます。1 GB は 230 バイトです。この測定単位はギビバイト(GiB)とも呼ばれます。メモリを GB から MB に変換する場合、1 GB = 1,024 MB です。

API では、メモリは常に MB 単位で指定します。Google Cloud CLI を使用する場合は、VM の合計メモリを GB 単位または MB 単位で指定できます。ただし、gcloud ツールを使用する際にはメモリ値は整数と想定されているため、浮動小数点数値を指定することはできません。たとえば、5.75 GB を表現するには、5.75 GB を MB に変換します。この場合、5.75 GB は 5,888 MB と表現します。

カスタム マシンタイプの VM を作成する

VM インスタンスを作成する前に、このマシンタイプの作成に関するカスタム仕様を読んで理解しておいてください。

Console

  1. Google Cloud コンソールで、[インスタンスの作成] ページに移動します。

    [インスタンスの作成] に移動

  2. [ゾーン] リストで、この VM をホストするゾーンを選択します。[シリーズ] リストは、選択したゾーンで使用可能なマシンタイプ ファミリーのみが含まれるようにフィルタされます。

  3. [マシンの構成] セクションで、[汎用] を選択します。

    1. [シリーズ] リストで、N1 カスタム マシンタイプの場合は [第 1 世代] の [N1] をクリックし、第 2 世代のカスタム マシンタイプの場合は、[E2] または [N2]、[N2D] をクリックします。
    2. [マシンタイプ] で [カスタム] を選択します。
    3. VM インスタンスの vCPU の数とメモリ容量を指定するには、スライダーをドラッグするか、テキスト ボックスに値を入力します。vCPU の数とメモリを変更すると、コンソールに VM の見積もり価格が表示されます。
  4. VM の作成を続行します。

gcloud

カスタム マシンタイプの gcloud コマンドは、マシンタイプ ファミリーごとにわずかに異なります。

N1 マシンタイプの場合は、gcloud compute instances create コマンドを使用して次のいずれかのオプションを指定します。

  • --custom-cpu--custom-memory フラグ。
  • --machine-type=custom-[NUMBER_OF_CPUS]-[NUMBER_OF_MB] フラグ。

たとえば、次のコマンドは、4 個の vCPU と 5 GB の合計メモリを備えた N1 マシンタイプを実行するインスタンスを作成します。

gcloud compute instances create example-instance \
    --custom-cpu=4 --custom-memory=5

N2 マシンタイプの場合は、gcloud compute instances create コマンドを使用して次のいずれかのオプションを指定します。

  • --custom-cpu--custom-memory--custom-vm-type フラグ。
  • --machine-type=n2-custom-NUMBER_OF_CPUS-NUMBER_OF_MB フラグ。

--custom-memory フラグを使用する場合、メモリの合計量を GB または MB で指定します。プロパティは整数にする必要があるため、0.25 GB 単位のメモリを指定する場合は、代わりに値を MB に変換して指定します。

メモリの 2.5 GB などの増分値を指定するには、値を MB に変換して、その値に MB のサフィックスを付けて指定します。次の例では、N2 マシンタイプを実行するインスタンスを作成します。

gcloud compute instances create example-instance \
    --custom-cpu=6 --custom-memory=3072MB --custom-vm-type=n2

または、カスタム マシンタイプは次の形式を使用して、後から指定することもできます。

gcloud compute instances create example-instance \
    --machine-type n2-custom-NUMBER_OF_CPUS-NUMBER_OF_MB

以下を置き換えます。

  • NUMBER_OF_CPUS: 目的の CPU 数。
  • NUMBER_OF_MB: メモリ容量(MB)。

例:

gcloud compute instances create example-instance --machine-type=n2-custom-6-3072

N2D または E2 マシンタイプの場合は、gcloud compute instances create コマンドを使用して次のいずれかのオプションを指定します。

  • --custom-cpu--custom-memory--custom-vm-type フラグ。
  • --machine-type=n2d-custom-NUMBER_OF_CPUS-NUMBER_OF_MB フラグ。
  • --machine-type=e2-custom-NUMBER_OF_CPUS-NUMBER_OF_MB フラグ。

E2 共有コア カスタム マシンタイプの場合は、同じ gcloud compute instances create コマンドを使用し、共有コア マシンタイプ microsmall、または medium を指定します。

  • --machine-type=e2-custom-SHARED_CORE_MACHINE_SIZE-NUMBER_OF_MB フラグ。

例:

gcloud compute instances create example-instance \
    --machine-type=e2-custom-medium-NUMBER_OF_MB

--custom-memory フラグを使用する場合、メモリの合計量を GB または MB で指定します。プロパティは整数にする必要があります。0.25 GB 単位のメモリを指定する場合は、代わりに値を MB に変換して指定します。

メモリの 2.5 GB などの増分値を指定するには、値を MB に変換して、その値に MB のサフィックスを付けて指定します。次の例では、E2 マシンタイプを実行するインスタンスを作成します。

gcloud compute instances create example-instance \
    --custom-cpu=6 --custom-memory=3072MB --custom-vm-type=e2

または、次の形式を使用してカスタム マシンタイプを指定することもできます。

gcloud compute instances create example-instance \
    --machine-type=e2-custom-NUMBER_OF_CPUS-NUMBER_OF_MB

以下を置き換えます。

  • NUMBER_OF_CPUS: 目的の CPU 数。
  • NUMBER_OF_MB: メモリ容量(MB)。

例:

gcloud compute instances create example-instance --machine-type=e2-custom-6-3072

Terraform

Terraform コードを生成するには、Google Cloud コンソールの同等のコード コンポーネントを使用します。
  1. Google Cloud コンソールで [VM インスタンス] ページに移動します。

    [VM インスタンス] に移動

  2. [インスタンスを作成] をクリックします。
  3. 必要なパラメータを指定します。
  4. ページの上部または下部で [同等のコード] をクリックし、[Terraform] タブをクリックして Terraform コードを表示します。

API

API では、通常どおりインスタンス作成リクエストを作成しますが、machineType 値を指定する場合は次のいずれかの形式を使用します。NUMBER_OF_CPUS を CPU 数に、AMOUNT_OF_MEMORY_MB を必要なメモリ容量にそれぞれ置き換えます。メモリは MB 単位で指定します。

  • N1 マシンタイプの場合、次のように指定します。

    zones/ZONE/machineTypes/custom-NUMBER_OF_CPUS-AMOUNT_OF_MEMORY_MB
    
  • N2 マシンタイプの場合、次のように指定します。

    zones/ZONE/machineTypes/n2-custom-NUMBER_OF_CPUS-AMOUNT_OF_MEMORY_MB
    
  • N2D マシンタイプの場合:

    zones/ZONE/machineTypes/n2d-custom-NUMBER_OF_CPUS-AMOUNT_OF_MEMORY_MB
    
  • E2 マシンタイプの場合、次のように指定します。

    zones/ZONE/machineTypes/e2-custom-NUMBER_OF_CPUS-AMOUNT_OF_MEMORY_MB
    
  • E2 共有コア カスタム マシンタイプの場合は、次のように指定します。

    zones/ZONE/machineTypes/e2-custom-SHARED_CORE_MACHINE_SIZE-AMOUNT_OF_MEMORY_MB
    

    たとえば、次の URL は、4 個の vCPU と 5 GB(5,120 MB)のメモリのインスタンスを作成します。

    zone/us-central1-f/machineTypes/custom-4-5120

Go

このサンプルを試す前に、Compute Engine クイックスタート: クライアント ライブラリの使用に記載されている Go の設定手順を行います。 詳細については、Compute Engine Go API のリファレンス ドキュメントをご覧ください。

Compute Engine に対して認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証の設定をご覧ください。

import (
	"context"
	"fmt"
	"io"

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

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

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

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

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

		return false
	}

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

		return false
	}

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

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

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

	tl := typeLimitsMap[cpuSeries]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	return nil
}

Java

このサンプルを試す前に、Compute Engine クイックスタート: クライアント ライブラリの使用に記載されている Java の設定手順を行います。 詳細については、Compute Engine Java API のリファレンス ドキュメントをご覧ください。

Compute Engine に対して認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証の設定をご覧ください。