Compute Engine menawarkan jenis mesin yang telah ditetapkan yang dapat Anda gunakan saat membuat instance VM. Jenis mesin yang telah ditetapkan memiliki jumlah vCPU dan memori yang telah diatur, serta dikenai tagihan dengan harga tetap. Jika VM yang telah ditetapkan tidak memenuhi kebutuhan, Anda dapat membuat instance VM dengan setelan hardware virtual kustom. Secara khusus, Anda dapat membuat instance VM dengan jumlah vCPU kustom dan jumlah memori, yang secara efektif menggunakan jenis mesin kustom. Jenis mesin kustom tersedia di kelompok mesin tujuan umum untuk seri mesin N dan E saja. Jenis mesin kustom tidak tersedia untuk seri mesin C dan Tau. Anda dapat membuat VM kustom pada jenis mesin N4, N2, N2D, E2, atau N1.
VM kustom ideal dalam skenario berikut:
- Workload yang tidak sesuai untuk jenis VM yang telah ditetapkan.
- Workload yang memerlukan daya pemrosesan atau memori lebih besar, tetapi tidak butuh semua upgrade yang disediakan oleh jenis mesin tingkat berikutnya.
Sebelum memulai
Peran yang diperlukan
Untuk mendapatkan izin yang diperlukan untuk membuat VM dengan jenis mesin kustom,
minta administrator untuk memberi Anda peran IAM
Compute Instance Admin (v1) (roles/compute.instanceAdmin.v1
) di project.
Untuk mengetahui informasi selengkapnya tentang cara memberikan peran, lihat Mengelola akses.
Peran yang telah ditetapkan ini berisi izin yang diperlukan untuk membuat VM dengan jenis mesin kustom. Untuk melihat izin yang benar-benar diperlukan, perluas bagian Izin yang diperlukan:
Izin yang diperlukan
Izin berikut diperlukan untuk membuat VM dengan jenis mesin kustom:
-
Untuk menambahkan memori yang diperluas ke VM yang ada:
compute.instances.setMachineType
di VM
-
Untuk membuat VM dengan jenis mesin kustom:
compute.instances.create
pada project - Untuk menggunakan image kustom guna membuat VM:
compute.images.useReadOnly
pada image - Untuk menggunakan snapshot guna membuat VM:
compute.snapshots.useReadOnly
di snapshot - Untuk menggunakan template instance untuk membuat VM:
compute.instanceTemplates.useReadOnly
pada template instance - Untuk menetapkan jaringan lama ke VM:
compute.networks.use
di project - Untuk menentukan alamat IP statis untuk VM:
compute.addresses.use
di project - Untuk menetapkan alamat IP eksternal ke VM saat menggunakan jaringan lama:
compute.networks.useExternalIp
di project - Untuk menentukan subnet VM:
compute.subnetworks.use
di project atau subnet yang dipilih - Untuk menetapkan alamat IP eksternal ke VM saat menggunakan jaringan VPC:
compute.subnetworks.useExternalIp
di project atau di subnet yang dipilih - Untuk menetapkan metadata instance VM untuk VM:
compute.instances.setMetadata
di project - Untuk menetapkan tag untuk VM:
compute.instances.setTags
di VM - Untuk menetapkan label VM:
compute.instances.setLabels
di VM - Untuk menetapkan akun layanan agar VM dapat menggunakan:
compute.instances.setServiceAccount
di VM - Untuk membuat disk baru bagi VM:
compute.disks.create
di project - Untuk memasang disk yang ada dalam mode hanya baca atau baca-tulis:
compute.disks.use
di disk - Untuk memasang disk yang ada dalam mode hanya baca:
compute.disks.useReadOnly
pada disk
Anda mung juga bisa mendapatkan
izin ini
dengan peran khusus atau
peran bawaanlainnya.
Batasan
- Jika VM Anda memiliki disk SSD Lokal, Anda tidak dapat mengubah konfigurasi vCPU dan memori.
- Memori tambahan hanya tersedia pada jenis mesin kustom. Jenis mesin yang telah ditetapkan tidak didukung.
- Ada jumlah memori maksimum yang dapat Anda tambahkan ke setiap jenis mesin.
- Anda harus menentukan memori dalam kelipatan 256 MB.
- Memori tambahan tidak memenuhi syarat untuk mendapatkan diskon abonemen.
- Jenis mesin N4 dan N2D hanya tersedia di
region dan zona tertentu.
Harga jenis mesin kustom
Google mengenakan biaya untuk VM kustom berdasarkan jumlah vCPU dan jam memori yang digunakan VM. Hal ini berbeda dengan model penagihan untuk jenis mesin yang telah ditetapkan. Harga on-demand untuk jenis mesin kustom mencakup premi sebesar 5% dibandingkan harga on demand untuk jenis mesin yang telah ditetapkan.
Saat menggunakan jenis mesin kustom, semua memori hingga dan termasuk jumlah default per vCPU dikenakan biaya dengan harga jenis mesin kustom kelompok mesin.
Jenis mesin kustom E2 dan jenis mesin kustom dengan inti bersama
E2 memiliki skema harga yang sama.
Jika Anda menggunakan komitmen resource N4 untuk menjalankan jenis mesin kustom, Compute Engine mengenakan biaya premi sebesar 5% di atas harga komitmen.
Compute Engine menagih premi ini untuk bagian dan durasi komitmen yang digunakan untuk menjalankan VM jenis mesin kustom ini.
Lihat Harga instance VM untuk mengetahui informasi berdasarkan seri mesin.
Sama seperti semua instance lainnya, biaya minimum 1 menit juga berlaku pada VM kustom, tetapi diskon untuk penggunaan berkelanjutan untuk jenis mesin kustom dihitung dengan cara berbeda. Untuk mengetahui informasi selengkapnya, lihat diskon untuk penggunaan berkelanjutan untuk VM kustom.
Harga memori tambahan
Untuk memori di atas nilai default, Compute Engine mengenakan biaya untuk memori tambahan berdasarkan harga memori kustom tambahan kelompok mesin. Harga
memori tambahan berbeda dengan harga
memori di bawah nilai minimum default.
Harga memori tambahan dapat berbeda-beda di setiap region. Instance yang berjalan dengan memori tambahan dikenai biaya minimum 1 menit yang sama seperti semua instance lainnya. Memori yang lebih besar juga memenuhi syarat untuk diskon untuk penggunaan berkelanjutan.
Menambahkan memori tambahan ke jenis mesin
Bergantung pada seri mesin, setiap jenis mesin memiliki jumlah memori tertentu secara default. Untuk beberapa workload, memori ini mungkin tidak cukup. Dengan biaya tambahan, Anda bisa mendapatkan memori lebih besar per vCPU di luar batas default. Ini disebut sebagai {i>extended memory<i}.
Dengan memori yang diperluas, Anda dapat menentukan jumlah memori untuk jenis mesin kustom tanpa batasan per vCPU. Daripada menggunakan ukuran memori default berdasarkan jumlah vCPU yang ditentukan, Anda dapat menentukan jumlah memori yang diperluas, hingga batas seri mesin.
Seri mesin |
Batas vCPU |
Batas memori |
N4 |
80 |
640 GB |
N2 |
128 |
640 GB |
N2D |
224 |
768 GB |
E2 |
32 |
128 GB |
N1 |
96 |
624 GB |
Jika Anda memerlukan lebih banyak memori, gunakan salah satu
jenis mesin yang dioptimalkan untuk memori,
yang memungkinkan Anda membuat VM dengan total memori hingga 12 TB per VM.
Menentukan apakah Anda memerlukan memori tambahan
Workload tertentu memerlukan memori per vCPU yang lebih besar daripada jumlah default-nya agar dapat memberikan hasil yang optimal. Workload yang didasarkan pada database analisis berperforma tinggi dalam memori, termasuk database relasional dan NoSQL seperti MS SQL Server, MongoDB, dan MemcacheD/Redis, termasuk dalam kategori ini. Pemberian lisensi berbasis vCPU untuk sistem operasi dan stack software juga membuat pemilihan konfigurasi memori VM yang optimal jadi lebih menantang pada jenis mesin yang telah ditetapkan. Dengan memori tambahan, Anda dapat menambahkan memori sebanyak yang dibutuhkan VM untuk mendapatkan rasio harga-performa terbaik.
Ekspresikan memori dalam GB atau MB
Untuk alat dan dokumentasi Google Cloud, memori jenis mesin dihitung dalam gigabyte (GB), di mana 1 GB sama dengan 230 byte. Unit pengukuran ini juga disebut sebagai gibibyte (GiB).
Saat mengonversi memori dari GB ke MB, 1 GB = 1024 MB.
Di API, Anda harus selalu memasukkan memori dalam megabyte. Jika menggunakan Google Cloud CLI, Anda dapat menyediakan total memori untuk VM dalam gigabyte atau megabyte. Namun, gcloud CLI mengharapkan nilai memori berupa bilangan bulat, sehingga Anda tidak dapat memberikan nilai float. Misalnya, untuk menyatakan 5,75 GB, konversi 5,75 GB menjadi MB. Dalam hal ini, 5,75 GB sama dengan 5888 MB.
Membuat VM dengan jenis mesin kustom
Sebelum membuat instance VM kustom, pastikan Anda membaca
spesifikasi kustom untuk membuat jenis mesin ini.
Konsol
Di konsol Google Cloud, buka halaman Create an instance.
Buka Buat instance
Pilih Region dan Zone tempat Anda ingin menghosting VM.
Di bagian Machine configuration, pilih General-purpose.
- Dalam daftar Series, pilih seri mesin untuk membuat mesin
kustom; N4, N2, N2D, E2, dan N1 menawarkan jenis mesin kustom.
- Di bagian Machine type, pilih Custom.
- Untuk menentukan jumlah vCPU dan memori bagi instance VM, tarik penggeser atau masukkan nilai di kotak teks. Konsol akan menampilkan perkiraan biaya untuk VM saat Anda mengubah jumlah vCPU dan memori.
Lanjutkan untuk membuat VM.
gcloud
Buat mesin kustom menggunakan perintah gcloud compute instances create
dengan opsi --machine-type
.
gcloud compute instances create INSTANCE_NAME \
--machine-type=MACHINE_TYPE-NUMBER_OF_VCPUS-AMOUNT_OF_MEMORY_MB
Ganti kode berikut:
- INSTANCE_NAME: nama instance
- MACHINE_TYPE: jenis mesin, seperti N2
- NUMBER_OF_VCPUS: jumlah vCPU
- AMOUNT_OF_MEMORY_MB: jumlah memori dalam MB atau GB
Berikut ini contoh penggunaan jenis mesin N2 dengan 48 vCPU dan memori 310 GB di zona us-central1-a
:
gcloud compute instances create example-instance \
--zone=us-central1-a --machine-type=n2-custom-48-317440
Atau, Anda dapat menentukan jenis mesin kustom menggunakan opsi
kustom: --custom-cpu
, --custom-memory
, --custom-vm-type
,
dan --custom-extensions
. Untuk mengonfigurasi memori tambahan, yang memungkinkan Anda menentukan jumlah memori yang lebih tinggi daripada rasio memori maksimum terhadap vCPU, naikkan nilai AMOUNT_OF_MEMORY_MB
dan tambahkan -ext
ke nama jenis mesin.
gcloud compute instances create INSTANCE_NAME \
--custom-cpu=NUMBER_OF_VCPUS \
--custom-memory=NUMBER_OF_MB \
--custom-vm-type=MACHINE_TYPE \
--custom-extension
Ganti kode berikut:
- INSTANCE_NAME: nama instance
- NUMBER_OF_VCPUS: jumlah vCPU
- NUMBER_OF_MB: jumlah memori dalam MB atau GB
- MACHINE_TYPE: jenis mesin, seperti N2
Contoh berikut adalah jenis mesin kustom N2 dengan 48 vCPU dan memori 310 GB yang menggunakan opsi Google Cloud CLI.
gcloud compute instances create example-instance \
--custom-cpu=48 --custom-memory=317440 --custom-extension --custom-vm-type=n2
Saat menggunakan opsi --custom-memory
, tentukan total jumlah memori dalam GB atau MB. Properti ini harus berupa bilangan bulat, jadi jika Anda ingin menentukan kelipatan 0,25 GB untuk memori, konversi nilai tersebut menjadi MB.
Untuk jenis mesin kustom dengan inti bersama E2, gunakan perintah gcloud compute instances create
yang sama dan sertakan ukuran mesin dengan inti bersama: micro
, small
, atau medium
.
vCPU dan memori terbatas.
gcloud compute instances create INSTANCE_NAME\
--machine-type=MACHINE_TYPE-AMOUNT_OF_MEMORY_MB
Ganti kode berikut:
- INSTANCE_NAME: nama instance
- MACHINE_TYPE: E2 kecil
- AMOUNT_OF_MEMORY_MB: jumlah memori dalam MB atau GB
Contoh berikut adalah jenis mesin kustom kecil dengan inti bersama E2 dengan vCPU 0,5 vCPU dan memori 2,25 GB.
gcloud compute instances create example-instance \
--machine-type=e2-custom-small-2304
Untuk membuat kode Terraform, Anda dapat menggunakan komponen Equivalent code di Konsol Google Cloud.
- Di Konsol Google Cloud, buka halaman Instance VM.
Buka Instance VM
- Klik Create instance.
- Tentukan parameter yang Anda inginkan.
- Di bagian atas atau bawah halaman, klik Kode yang setara, lalu klik
tab Terraform untuk melihat kode Terraform.
Go
Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Go di panduan memulai Compute Engine menggunakan library klien.
Untuk informasi selengkapnya, lihat
dokumentasi referensi API
Go Compute Engine.
Untuk melakukan autentikasi ke Compute Engine, siapkan Kredensial Default Aplikasi.
Untuk mengetahui informasi selengkapnya, baca
Menyiapkan autentikasi untuk lingkungan pengembangan lokal.
import (
"context"
"fmt"
"io"
compute "cloud.google.com/go/compute/apiv1"
computepb "cloud.google.com/go/compute/apiv1/computepb"
"google.golang.org/protobuf/proto"
)
func customMachineTypeURI(zone, cpuSeries string, coreCount, memory int) (string, error) {
const (
n1 = "custom"
n2 = "n2-custom"
n2d = "n2d-custom"
e2 = "e2-custom"
e2Micro = "e2-custom-micro"
e2Small = "e2-custom-small"
e2Medium = "e2-custom-medium"
)
type typeLimit struct {
allowedCores []int
minMemPerCore int
maxMemPerCore int
allowExtraMemory bool
extraMemoryLimit int
}
makeRange := func(start, end, step int) []int {
if step <= 0 || end < start {
return []int{}
}
s := make([]int, 0, 1+(end-start)/step)
for start <= end {
s = append(s, start)
start += step
}
return s
}
containsString := func(s []string, str string) bool {
for _, v := range s {
if v == str {
return true
}
}
return false
}
containsInt := func(nums []int, n int) bool {
for _, v := range nums {
if v == n {
return true
}
}
return false
}
var (
cpuSeriesE2Limit = typeLimit{
allowedCores: makeRange(2, 33, 2),
minMemPerCore: 512,
maxMemPerCore: 8192,
}
cpuSeriesE2MicroLimit = typeLimit{minMemPerCore: 1024, maxMemPerCore: 2048}
cpuSeriesE2SmallLimit = typeLimit{minMemPerCore: 2048, maxMemPerCore: 4096}
cpuSeriesE2MeidumLimit = typeLimit{minMemPerCore: 4096, maxMemPerCore: 8192}
cpuSeriesN2Limit = typeLimit{
allowedCores: append(makeRange(2, 33, 2), makeRange(36, 129, 4)...),
minMemPerCore: 512, maxMemPerCore: 8192,
allowExtraMemory: true,
extraMemoryLimit: 624 << 10,
}
cpuSeriesN2DLimit = typeLimit{
allowedCores: []int{2, 4, 8, 16, 32, 48, 64, 80, 96},
minMemPerCore: 512, maxMemPerCore: 8192,
allowExtraMemory: true,
extraMemoryLimit: 768 << 10,
}
cpuSeriesN1Limit = typeLimit{
allowedCores: append([]int{1}, makeRange(2, 97, 2)...),
minMemPerCore: 922,
maxMemPerCore: 6656,
allowExtraMemory: true,
extraMemoryLimit: 624 << 10,
}
)
typeLimitsMap := map[string]typeLimit{
n1: cpuSeriesN1Limit,
n2: cpuSeriesN2Limit,
n2d: cpuSeriesN2DLimit,
e2: cpuSeriesE2Limit,
e2Micro: cpuSeriesE2MicroLimit,
e2Small: cpuSeriesE2SmallLimit,
e2Medium: cpuSeriesE2MeidumLimit,
}
if !containsString([]string{e2, n1, n2, n2d}, cpuSeries) {
return "", fmt.Errorf("incorrect cpu type: %v", cpuSeries)
}
tl := typeLimitsMap[cpuSeries]
// Check whether the requested parameters are allowed.
// Find more information about limitations of custom machine types at:
// https://cloud.google.com/compute/docs/general-purpose-machines#custom_machine_types
// Check the number of cores
if len(tl.allowedCores) > 0 && !containsInt(tl.allowedCores, coreCount) {
return "", fmt.Errorf(
"invalid number of cores requested. Allowed number of cores for %v is: %v",
cpuSeries,
tl.allowedCores,
)
}
// Memory must be a multiple of 256 MB
if memory%256 != 0 {
return "", fmt.Errorf("requested memory must be a multiple of 256 MB")
}
// Check if the requested memory isn't too little
if memory < coreCount*tl.minMemPerCore {
return "", fmt.Errorf(
"requested memory is too low. Minimal memory for %v is %v MB per core",
cpuSeries,
tl.minMemPerCore,
)
}
// Check if the requested memory isn't too much
if memory > coreCount*tl.maxMemPerCore && !tl.allowExtraMemory {
return "", fmt.Errorf(
"requested memory is too large.. Maximum memory allowed for %v is %v MB per core",
cpuSeries,
tl.maxMemPerCore,
)
}
if memory > tl.extraMemoryLimit && tl.allowExtraMemory {
return "", fmt.Errorf(
"requested memory is too large.. Maximum memory allowed for %v is %v MB",
cpuSeries,
tl.extraMemoryLimit,
)
}
// Return the custom machine type in form of a string acceptable by Compute Engine API.
if containsString([]string{e2Small, e2Micro, e2Medium}, cpuSeries) {
return fmt.Sprintf("zones/%v/machineTypes/%v-%v", zone, cpuSeries, memory), nil
}
if memory > coreCount*tl.maxMemPerCore {
return fmt.Sprintf(
"zones/%v/machineTypes/%v-%v-%v-ext",
zone,
cpuSeries,
coreCount,
memory,
), nil
}
return fmt.Sprintf("zones/%v/machineTypes/%v-%v-%v", zone, cpuSeries, coreCount, memory), nil
}
// createInstanceWithCustomMachineTypeWithHelper creates a new VM instance with a custom machine type.
func createInstanceWithCustomMachineTypeWithHelper(
w io.Writer,
projectID, zone, instanceName, cpuSeries string,
coreCount, memory int,
) error {
// projectID := "your_project_id"
// zone := "europe-central2-b"
// instanceName := "your_instance_name"
// cpuSeries := "e2-custom-micro" // the type of CPU you want to use"
// coreCount := 2 // number of CPU cores you want to use.
// memory := 256 // the amount of memory for the VM instance, in megabytes.
machineType, err := customMachineTypeURI(zone, cpuSeries, coreCount, memory)
if err != nil {
return fmt.Errorf("unable to create custom machine type string: %w", err)
}
ctx := context.Background()
instancesClient, err := compute.NewInstancesRESTClient(ctx)
if err != nil {
return fmt.Errorf("NewInstancesRESTClient: %w", err)
}
defer instancesClient.Close()
req := &computepb.InsertInstanceRequest{
Project: projectID,
Zone: zone,
InstanceResource: &computepb.Instance{
Name: proto.String(instanceName),
Disks: []*computepb.AttachedDisk{
{
InitializeParams: &computepb.AttachedDiskInitializeParams{
DiskSizeGb: proto.Int64(10),
SourceImage: proto.String(
"projects/debian-cloud/global/images/family/debian-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
Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Java di panduan memulai Compute Engine menggunakan library klien.
Untuk informasi selengkapnya, lihat
dokumentasi referensi API
Java Compute Engine.
Untuk melakukan autentikasi ke Compute Engine, siapkan Kredensial Default Aplikasi.
Untuk mengetahui informasi selengkapnya, baca
Menyiapkan autentikasi untuk lingkungan pengembangan lokal.
import com.google.cloud.compute.v1.AttachedDisk;
import com.google.cloud.compute.v1.AttachedDiskInitializeParams;
import com.google.cloud.compute.v1.InsertInstanceRequest;
import com.google.cloud.compute.v1.Instance;
import com.google.cloud.compute.v1.InstancesClient;
import com.google.cloud.compute.v1.NetworkInterface;
import com.google.cloud.compute.v1.Operation;
import com.google.common.collect.ImmutableMap;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.stream.IntStream;
public class CreateWithHelper {
// This class defines the configurable parameters for a custom VM.
static final class TypeLimits {
int[] allowedCores;
int minMemPerCore;
int maxMemPerCore;
int extraMemoryLimit;
boolean allowExtraMemory;
TypeLimits(int[] allowedCores, int minMemPerCore, int maxMemPerCore, boolean allowExtraMemory,
int extraMemoryLimit) {
this.allowedCores = allowedCores;
this.minMemPerCore = minMemPerCore;
this.maxMemPerCore = maxMemPerCore;
this.allowExtraMemory = allowExtraMemory;
this.extraMemoryLimit = extraMemoryLimit;
}
}
public enum CpuSeries {
N1("custom"),
N2("n2-custom"),
N2D("n2d-custom"),
E2("e2-custom"),
E2_MICRO("e2-custom-micro"),
E2_SMALL("e2-custom-small"),
E2_MEDIUM("e2-custom-medium");
private static final Map<String, CpuSeries> ENUM_MAP;
static {
ENUM_MAP = init();
}
// Build an immutable map of String name to enum pairs.
public static Map<String, CpuSeries> init() {
Map<String, CpuSeries> map = new ConcurrentHashMap<>();
for (CpuSeries instance : CpuSeries.values()) {
map.put(instance.getCpuSeries(), instance);
}
return Collections.unmodifiableMap(map);
}
private final String cpuSeries;
CpuSeries(String cpuSeries) {
this.cpuSeries = cpuSeries;
}
public static CpuSeries get(String name) {
return ENUM_MAP.get(name);
}
public String getCpuSeries() {
return this.cpuSeries;
}
}
// This enum correlates a machine type with its limits.
// The limits for various CPU types are described in:
// https://cloud.google.com/compute/docs/general-purpose-machines
enum Limits {
CPUSeries_E2(new TypeLimits(getNumsInRangeWithStep(2, 33, 2), 512, 8192, false, 0)),
CPUSeries_E2MICRO(new TypeLimits(new int[]{}, 1024, 2048, false, 0)),
CPUSeries_E2SMALL(new TypeLimits(new int[]{}, 2048, 4096, false, 0)),
CPUSeries_E2MEDIUM(new TypeLimits(new int[]{}, 4096, 8192, false, 0)),
CPUSeries_N2(
new TypeLimits(concat(getNumsInRangeWithStep(2, 33, 2), getNumsInRangeWithStep(36, 129, 4)),
512, 8192, true, gbToMb(624))),
CPUSeries_N2D(
new TypeLimits(new int[]{2, 4, 8, 16, 32, 48, 64, 80, 96}, 512, 8192, true, gbToMb(768))),
CPUSeries_N1(
new TypeLimits(concat(new int[]{1}, getNumsInRangeWithStep(2, 97, 2)), 922, 6656, true,
gbToMb(624)));
private final TypeLimits typeLimits;
Limits(TypeLimits typeLimits) {
this.typeLimits = typeLimits;
}
public TypeLimits getTypeLimits() {
return typeLimits;
}
}
static ImmutableMap<String, Limits> typeLimitsMap = ImmutableMap.<String, Limits>builder()
.put("N1", Limits.CPUSeries_N1)
.put("N2", Limits.CPUSeries_N2)
.put("N2D", Limits.CPUSeries_N2D)
.put("E2", Limits.CPUSeries_E2)
.put("E2_MICRO", Limits.CPUSeries_E2MICRO)
.put("E2_SMALL", Limits.CPUSeries_E2SMALL)
.put("E2_MEDIUM", Limits.CPUSeries_E2SMALL)
.build();
// Returns the array of integers within the given range, incremented by the specified step.
// start (inclusive): starting number of the range
// stop (inclusive): ending number of the range
// step : increment value
static int[] getNumsInRangeWithStep(int start, int stop, int step) {
return IntStream.range(start, stop).filter(x -> (x - start) % step == 0).toArray();
}
static int gbToMb(int value) {
return value << 10;
}
static int[] concat(int[] a, int[] b) {
int[] result = new int[a.length + b.length];
System.arraycopy(a, 0, result, 0, a.length);
System.arraycopy(b, 0, result, a.length, b.length);
return result;
}
public static void main(String[] args)
throws IOException, ExecutionException, InterruptedException, TimeoutException {
// TODO(developer): Replace these variables before running the sample.
// Project ID or project number of the Cloud project you want to use.
String projectId = "your-google-cloud-project-id";
// Name of the zone to create the instance in. For example: "us-west3-b".
String zone = "google-cloud-zone";
// Name of the new virtual machine (VM) instance.
String instanceName = "instance-name";
String cpuSeries = "N1";
// Number of CPU cores you want to use.
int coreCount = 2;
// The amount of memory for the VM instance, in megabytes.
int memory = 256;
createInstanceWithCustomMachineTypeWithHelper(
projectId, zone, instanceName, cpuSeries, coreCount, memory);
}
// Create a VM instance with a custom machine type.
public static void createInstanceWithCustomMachineTypeWithHelper(
String project, String zone, String instanceName, String cpuSeries, int coreCount, int memory)
throws IOException, ExecutionException, InterruptedException, TimeoutException {
// Construct the URI string identifying the machine type.
String machineTypeUri = customMachineTypeUri(zone, cpuSeries, coreCount, memory);
// Initialize client that will be used to send requests. This client only needs to be created
// once, and can be reused for multiple requests. After completing all of your requests, call
// the `instancesClient.close()` method on the client to safely
// clean up any remaining background resources.
try (InstancesClient instancesClient = InstancesClient.create()) {
AttachedDisk attachedDisk = AttachedDisk.newBuilder()
.setInitializeParams(
// Describe the size and source image of the boot disk to attach to the instance.
// The list of public images available in Compute Engine can be found here:
// https://cloud.google.com/compute/docs/images#list_of_public_images_available_on
AttachedDiskInitializeParams.newBuilder()
.setSourceImage(
String.format("projects/%s/global/images/family/%s", "debian-cloud",
"debian-11"))
.setDiskSizeGb(10)
.build()
)
// Remember to set auto_delete to True if you want the disk to be deleted when you delete
// your VM instance.
.setAutoDelete(true)
.setBoot(true)
.build();
// Create the Instance object with the relevant information.
Instance instance = Instance.newBuilder()
.setName(instanceName)
.addDisks(attachedDisk)
.setMachineType(machineTypeUri)
.addNetworkInterfaces(
NetworkInterface.newBuilder().setName("global/networks/default").build())
.build();
// Create the insert instance request object.
InsertInstanceRequest insertInstanceRequest = InsertInstanceRequest.newBuilder()
.setProject(project)
.setZone(zone)
.setInstanceResource(instance)
.build();
// Invoke the API with the request object and wait for the operation to complete.
Operation response = instancesClient.insertAsync(insertInstanceRequest)
.get(3, TimeUnit.MINUTES);
// Check for errors.
if (response.hasError()) {
throw new Error("Instance creation failed!!" + response);
}
System.out.printf("Instance created : %s", instanceName);
System.out.println("Operation Status: " + response.getStatus());
}
}
public static String customMachineTypeUri(String zone, String cpuSeries, int coreCount,
int memory) {
if (!Arrays.asList(CpuSeries.E2.cpuSeries, CpuSeries.N1.cpuSeries, CpuSeries.N2.cpuSeries,
CpuSeries.N2D.cpuSeries).contains(cpuSeries)) {
throw new Error(String.format("Incorrect cpu type: %s", cpuSeries));
}
TypeLimits typeLimit = Objects.requireNonNull(
typeLimitsMap.get(CpuSeries.get(cpuSeries).name())).typeLimits;
// Perform the following checks to verify if the requested parameters are allowed.
// Find more information about limitations of custom machine types at:
// https://cloud.google.com/compute/docs/general-purpose-machines#custom_machine_types
// 1. Check the number of cores and if the coreCount is present in allowedCores.
if (typeLimit.allowedCores.length > 0 && Arrays.stream(typeLimit.allowedCores)
.noneMatch(x -> x == coreCount)) {
throw new Error(String.format(
"Invalid number of cores requested. "
+ "Number of cores requested for CPU %s should be one of: %s",
cpuSeries,
Arrays.toString(typeLimit.allowedCores)));
}
// 2. Memory must be a multiple of 256 MB
if (memory % 256 != 0) {
throw new Error("Requested memory must be a multiple of 256 MB");
}
// 3. Check if the requested memory isn't too little
if (memory < coreCount * typeLimit.minMemPerCore) {
throw new Error(
String.format("Requested memory is too low. Minimum memory for %s is %s MB per core",
cpuSeries, typeLimit.minMemPerCore));
}
// 4. Check if the requested memory isn't too much
if (memory > coreCount * typeLimit.maxMemPerCore && !typeLimit.allowExtraMemory) {
throw new Error(String.format(
"Requested memory is too large.. Maximum memory allowed for %s is %s MB per core",
cpuSeries, typeLimit.extraMemoryLimit));
}
// 5. Check if the requested memory isn't too large
if (memory > typeLimit.extraMemoryLimit && typeLimit.allowExtraMemory) {
throw new Error(
String.format("Requested memory is too large.. Maximum memory allowed for %s is %s MB",
cpuSeries, typeLimit.extraMemoryLimit));
}
// Check if the CPU Series is E2 and return the custom machine type in the form of a string
// acceptable by Compute Engine API.
if (Arrays.asList(CpuSeries.E2_SMALL.cpuSeries, CpuSeries.E2_MICRO.cpuSeries,
CpuSeries.E2_MEDIUM.cpuSeries).contains(cpuSeries)) {
return String.format("zones/%s/machineTypes/%s-%s", zone, cpuSeries, memory);
}
// Check if extended memory was requested and return the extended custom machine type
// in the form of a string acceptable by Compute Engine API.
if (memory > coreCount * typeLimit.maxMemPerCore) {
return String.format("zones/%s/machineTypes/%s-%s-%s-ext", zone, cpuSeries, coreCount,
memory);
}
// Return the custom machine type in the form of a standard string
// acceptable by Compute Engine API.
return String.format("zones/%s/machineTypes/%s-%s-%s", zone, cpuSeries, coreCount, memory);
}
}
Node.js
Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Node.js di panduan memulai Compute Engine menggunakan library klien.
Untuk informasi selengkapnya, lihat
dokumentasi referensi API
Node.js Compute Engine.
Untuk melakukan autentikasi ke Compute Engine, siapkan Kredensial Default Aplikasi.
Untuk mengetahui informasi selengkapnya, baca
Menyiapkan autentikasi untuk lingkungan pengembangan lokal.
/**
* TODO(developer): Uncomment and replace these variables before running the sample.
*/
// const projectId = 'YOUR_PROJECT_ID';
// const zone = 'europe-central2-b';
// const instanceName = 'YOUR_INSTANCE_NAME';
// const cpuSeries = 'N1';
// const coreCount = 2
// const memory = 256
const compute = require('@google-cloud/compute');
function range(from, to, step) {
return [...Array(Math.floor((to - from) / step) + 1)].map(
(_, i) => from + i * step
);
}
class CustomMachineType {
constructor(zone, cpuSeries, coreCount, memory) {
this.zone = zone;
this.cpuSeries = cpuSeries;
this.coreCount = coreCount;
this.memory = memory;
this.N1 = 'custom';
this.N2 = 'n2-custom';
this.N2D = 'n2d-custom';
this.E2 = 'e2-custom';
this.E2Micro = 'e2-custom-micro';
this.E2Small = 'e2-custom-small';
this.E2Medium = 'e2-custom-medium';
this.CpuSeriesE2Limit = {
allowedCores: range(2, 33, 2),
minMemPerCore: 512,
maxMemPerCore: 8192,
allowExtraMemory: false,
extraMemoryLimit: 0,
};
this.CpuSeriesE2MicroLimit = {
allowedCores: [],
minMemPerCore: 1024,
maxMemPerCore: 2048,
allowExtraMemory: false,
extraMemoryLimit: 0,
};
this.CpuSeriesE2SmallLimit = {
allowedCores: [],
minMemPerCore: 2048,
maxMemPerCore: 4096,
allowExtraMemory: false,
extraMemoryLimit: 0,
};
this.CpuSeriesE2MediumLimit = {
allowedCores: [],
minMemPerCore: 4096,
maxMemPerCore: 8192,
allowExtraMemory: false,
extraMemoryLimit: 0,
};
this.CpuSeriesN2Limit = {
allowedCores: [...range(2, 33, 2), ...range(36, 129, 4)],
minMemPerCore: 512,
maxMemPerCore: 8192,
allowExtraMemory: true,
extraMemoryLimit: 624 << 10,
};
this.CpuSeriesN2DLimit = {
allowedCores: [2, 4, 8, 16, 32, 48, 64, 80, 96],
minMemPerCore: 512,
maxMemPerCore: 8192,
allowExtraMemory: true,
extraMemoryLimit: 768 << 10,
};
this.CpuSeriesN1Limit = {
allowedCores: [1, range(2, 97, 2)],
minMemPerCore: 922,
maxMemPerCore: 6656,
allowExtraMemory: true,
extraMemoryLimit: 624 << 10,
};
this.TYPE_LIMITS = {
[this.N1]: this.CpuSeriesN1Limit,
[this.N2]: this.CpuSeriesN2Limit,
[this.N2D]: this.CpuSeriesN2DLimit,
[this.E2]: this.CpuSeriesE2Limit,
[this.E2Micro]: this.CpuSeriesE2MicroLimit,
[this.E2Small]: this.CpuSeriesE2SmallLimit,
[this.E2Medium]: this.CpuSeriesE2MediumLimit,
};
if (![this.E2, this.N1, this.N2, this.N2D].includes(cpuSeries)) {
throw new Error(`Incorrect CPU type: ${this.cpuSeries}`);
}
this.typeLimit = this.TYPE_LIMITS[this.cpuSeries];
// Check whether the requested parameters are allowed.
// Find more information about limitations of custom machine types at:
// https://cloud.google.com/compute/docs/general-purpose-machines#custom_machine_types
// Check the number of cores
if (
this.typeLimit.allowedCores.length > 0 &&
!this.typeLimit.allowedCores.includes(coreCount)
) {
throw new Error(
`Invalid number of cores requested. Allowed number of cores for ${this.cpuSeries} is: ${this.typeLimit.allowedCores}`
);
}
// Memory must be a multiple of 256 MB
if (this.memory % 256 !== 0) {
throw new Error('Requested memory must be a multiple of 256 MB');
}
// Check if the requested memory isn't too little
if (this.memory < this.coreCount * this.typeLimit.minMemPerCore) {
throw new Error(
`Requested memory is too low. Minimal memory for ${this.cpuSeries} is ${this.typeLimit.minMemPerCore} MB per core`
);
}
// Check if the requested memory isn't too much
if (
this.memory > this.coreCount * this.typeLimit.maxMemPerCore &&
!this.typeLimit.allowExtraMemory
) {
throw new Error(
`Requested memory is too large.. Maximum memory allowed for ${this.cpuSeries} is ${this.typeLimit.maxMemPerCore} MB per core`
);
}
if (
this.memory > this.typeLimit.extraMemoryLimit &&
this.typeLimit.allowExtraMemory
) {
throw new Error(
`Requested memory is too large.. Maximum memory allowed for ${this.cpuSeries} is ${this.typeLimit.extraMemoryLimit} MB`
);
}
}
// Returns the custom machine type in form of a string acceptable by Compute Engine API.
getMachineTypeURI() {
if (
[this.E2Small, this.E2Micro, this.E2Medium].includes(this.cpuSeries)
) {
return `zones/${this.zone}/machineTypes/${this.cpuSeries}-${this.memory}`;
}
if (this.memory > this.coreCount * this.typeLimit.maxMemPerCore) {
return `zones/${this.zone}/machineTypes/${this.cpuSeries}-${this.coreCount}-${this.memory}-ext`;
}
return `zones/${zone}/machineTypes/${this.cpuSeries}-${this.coreCount}-${this.memory}`;
}
}
async function createInstanceWithCustomMachineTypeWithHelper() {
const instancesClient = new compute.InstancesClient();
const machineType = new CustomMachineType(
zone,
cpuSeries,
coreCount,
memory
).getMachineTypeURI();
const [response] = await instancesClient.insert({
instanceResource: {
name: instanceName,
disks: [
{
initializeParams: {
diskSizeGb: '64',
sourceImage:
'projects/debian-cloud/global/images/family/debian-11/',
},
autoDelete: true,
boot: true,
},
],
machineType,
networkInterfaces: [
{
name: 'global/networks/default',
},
],
},
project: projectId,
zone,
});
let operation = response.latestResponse;
const operationsClient = new compute.ZoneOperationsClient();
// Wait for the create operation to complete.
while (operation.status !== 'DONE') {
[operation] = await operationsClient.wait({
operation: operation.name,
project: projectId,
zone: operation.zone.split('/').pop(),
});
}
console.log('Instance created.');
}
createInstanceWithCustomMachineTypeWithHelper();
Python
Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Python di panduan memulai Compute Engine menggunakan library klien.
Untuk informasi selengkapnya, lihat
dokumentasi referensi API
Python Compute Engine.
Untuk melakukan autentikasi ke Compute Engine, siapkan Kredensial Default Aplikasi.
Untuk mengetahui informasi selengkapnya, baca
Menyiapkan autentikasi untuk lingkungan pengembangan lokal.
from __future__ import annotations
from collections import namedtuple
from enum import Enum
from enum import unique
import re
import sys
from typing import Any
import warnings
from google.api_core.extended_operation import ExtendedOperation
from google.cloud import compute_v1
def gb_to_mb(value: int) -> int:
return value << 10
class CustomMachineType:
"""
Allows to create custom machine types to be used with the VM instances.
"""
@unique
class CPUSeries(Enum):
N1 = "custom"
N2 = "n2-custom"
N2D = "n2d-custom"
E2 = "e2-custom"
E2_MICRO = "e2-custom-micro"
E2_SMALL = "e2-custom-small"
E2_MEDIUM = "e2-custom-medium"
TypeLimits = namedtuple(
"TypeLimits",
[
"allowed_cores",
"min_mem_per_core",
"max_mem_per_core",
"allow_extra_memory",
"extra_memory_limit",
],
)
# The limits for various CPU types are described on:
# https://cloud.google.com/compute/docs/general-purpose-machines
LIMITS = {
CPUSeries.E2: TypeLimits(frozenset(range(2, 33, 2)), 512, 8192, False, 0),
CPUSeries.E2_MICRO: TypeLimits(frozenset(), 1024, 2048, False, 0),
CPUSeries.E2_SMALL: TypeLimits(frozenset(), 2048, 4096, False, 0),
CPUSeries.E2_MEDIUM: TypeLimits(frozenset(), 4096, 8192, False, 0),
CPUSeries.N2: TypeLimits(
frozenset(range(2, 33, 2)).union(set(range(36, 129, 4))),
512,
8192,
True,
gb_to_mb(624),
),
CPUSeries.N2D: TypeLimits(
frozenset({2, 4, 8, 16, 32, 48, 64, 80, 96}), 512, 8192, True, gb_to_mb(768)
),
CPUSeries.N1: TypeLimits(
frozenset({1}.union(range(2, 97, 2))), 922, 6656, True, gb_to_mb(624)
),
}
def __init__(
self, zone: str, cpu_series: CPUSeries, memory_mb: int, core_count: int = 0
):
self.zone = zone
self.cpu_series = cpu_series
self.limits = self.LIMITS[self.cpu_series]
# Shared machine types (e2-small, e2-medium and e2-micro) always have
# 2 vCPUs: https://cloud.google.com/compute/docs/general-purpose-machines#e2_limitations
self.core_count = 2 if self.is_shared() else core_count
self.memory_mb = memory_mb
self._checked = False
self._check_parameters()
self.extra_memory_used = self._check_extra_memory()
def is_shared(self):
return self.cpu_series in (
CustomMachineType.CPUSeries.E2_SMALL,
CustomMachineType.CPUSeries.E2_MICRO,
CustomMachineType.CPUSeries.E2_MEDIUM,
)
def _check_extra_memory(self) -> bool:
if self._checked:
return self.memory_mb > self.core_count * self.limits.max_mem_per_core
else:
raise RuntimeError(
"You need to call _check_parameters() before calling _check_extra_memory()"
)
def _check_parameters(self):
"""
Check whether the requested parameters are allowed. Find more information about limitations of custom machine
types at: https://cloud.google.com/compute/docs/general-purpose-machines#custom_machine_types
"""
# Check the number of cores
if (
self.limits.allowed_cores
and self.core_count not in self.limits.allowed_cores
):
raise RuntimeError(
f"Invalid number of cores requested. Allowed number of cores for {self.cpu_series.name} is: {sorted(self.limits.allowed_cores)}"
)
# Memory must be a multiple of 256 MB
if self.memory_mb % 256 != 0:
raise RuntimeError("Requested memory must be a multiple of 256 MB.")
# Check if the requested memory isn't too little
if self.memory_mb < self.core_count * self.limits.min_mem_per_core:
raise RuntimeError(
f"Requested memory is too low. Minimal memory for {self.cpu_series.name} is {self.limits.min_mem_per_core} MB per core."
)
# Check if the requested memory isn't too much
if self.memory_mb > self.core_count * self.limits.max_mem_per_core:
if self.limits.allow_extra_memory:
if self.memory_mb > self.limits.extra_memory_limit:
raise RuntimeError(
f"Requested memory is too large.. Maximum memory allowed for {self.cpu_series.name} is {self.limits.extra_memory_limit} MB."
)
else:
raise RuntimeError(
f"Requested memory is too large.. Maximum memory allowed for {self.cpu_series.name} is {self.limits.max_mem_per_core} MB per core."
)
self._checked = True
def __str__(self) -> str:
"""
Return the custom machine type in form of a string acceptable by Compute Engine API.
"""
if self.cpu_series in {
self.CPUSeries.E2_SMALL,
self.CPUSeries.E2_MICRO,
self.CPUSeries.E2_MEDIUM,
}:
return f"zones/{self.zone}/machineTypes/{self.cpu_series.value}-{self.memory_mb}"
if self.extra_memory_used:
return f"zones/{self.zone}/machineTypes/{self.cpu_series.value}-{self.core_count}-{self.memory_mb}-ext"
return f"zones/{self.zone}/machineTypes/{self.cpu_series.value}-{self.core_count}-{self.memory_mb}"
def short_type_str(self) -> str:
"""
Return machine type in a format without the zone. For example, n2-custom-0-10240.
This format is used to create instance templates.
"""
return str(self).rsplit("/", maxsplit=1)[1]
@classmethod
def from_str(cls, machine_type: str):
"""
Construct a new object from a string. The string needs to be a valid custom machine type like:
- https://www.googleapis.com/compute/v1/projects/diregapic-mestiv/zones/us-central1-b/machineTypes/e2-custom-4-8192
- zones/us-central1-b/machineTypes/e2-custom-4-8192
- e2-custom-4-8192 (in this case, the zone parameter will not be set)
"""
zone = None
if machine_type.startswith("http"):
machine_type = machine_type[machine_type.find("zones/") :]
if machine_type.startswith("zones/"):
_, zone, _, machine_type = machine_type.split("/")
extra_mem = machine_type.endswith("-ext")
if machine_type.startswith("custom"):
cpu = cls.CPUSeries.N1
_, cores, memory = machine_type.rsplit("-", maxsplit=2)
else:
if extra_mem:
cpu_series, _, cores, memory, _ = machine_type.split("-")
else:
cpu_series, _, cores, memory = machine_type.split("-")
if cpu_series == "n2":
cpu = cls.CPUSeries.N2
elif cpu_series == "n2d":
cpu = cls.CPUSeries.N2D
elif cpu_series == "e2":
cpu = cls.CPUSeries.E2
if cores == "micro":
cpu = cls.CPUSeries.E2_MICRO
cores = 2
elif cores == "small":
cpu = cls.CPUSeries.E2_SMALL
cores = 2
elif cores == "medium":
cpu = cls.CPUSeries.E2_MEDIUM
cores = 2
else:
raise RuntimeError("Unknown CPU series.")
cores = int(cores)
memory = int(memory)
return cls(zone, cpu, memory, cores)
def get_image_from_family(project: str, family: str) -> compute_v1.Image:
"""
Retrieve the newest image that is part of a given family in a project.
Args:
project: project ID or project number of the Cloud project you want to get image from.
family: name of the image family you want to get image from.
Returns:
An Image object.
"""
image_client = compute_v1.ImagesClient()
# List of public operating system (OS) images: https://cloud.google.com/compute/docs/images/os-details
newest_image = image_client.get_from_family(project=project, family=family)
return newest_image
def disk_from_image(
disk_type: str,
disk_size_gb: int,
boot: bool,
source_image: str,
auto_delete: bool = True,
) -> compute_v1.AttachedDisk:
"""
Create an AttachedDisk object to be used in VM instance creation. Uses an image as the
source for the new disk.
Args:
disk_type: the type of disk you want to create. This value uses the following format:
"zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".
For example: "zones/us-west3-b/diskTypes/pd-ssd"
disk_size_gb: size of the new disk in gigabytes
boot: boolean flag indicating whether this disk should be used as a boot disk of an instance
source_image: source image to use when creating this disk. You must have read access to this disk. This can be one
of the publicly available images or an image from one of your projects.
This value uses the following format: "projects/{project_name}/global/images/{image_name}"
auto_delete: boolean flag indicating whether this disk should be deleted with the VM that uses it
Returns:
AttachedDisk object configured to be created using the specified image.
"""
boot_disk = compute_v1.AttachedDisk()
initialize_params = compute_v1.AttachedDiskInitializeParams()
initialize_params.source_image = source_image
initialize_params.disk_size_gb = disk_size_gb
initialize_params.disk_type = disk_type
boot_disk.initialize_params = initialize_params
# Remember to set auto_delete to True if you want the disk to be deleted when you delete
# your VM instance.
boot_disk.auto_delete = auto_delete
boot_disk.boot = boot
return boot_disk
def wait_for_extended_operation(
operation: ExtendedOperation, verbose_name: str = "operation", timeout: int = 300
) -> Any:
"""
Waits for the extended (long-running) operation to complete.
If the operation is successful, it will return its result.
If the operation ends with an error, an exception will be raised.
If there were any warnings during the execution of the operation
they will be printed to sys.stderr.
Args:
operation: a long-running operation you want to wait on.
verbose_name: (optional) a more verbose name of the operation,
used only during error and warning reporting.
timeout: how long (in seconds) to wait for operation to finish.
If None, wait indefinitely.
Returns:
Whatever the operation.result() returns.
Raises:
This method will raise the exception received from `operation.exception()`
or RuntimeError if there is no exception set, but there is an `error_code`
set for the `operation`.
In case of an operation taking longer than `timeout` seconds to complete,
a `concurrent.futures.TimeoutError` will be raised.
"""
result = operation.result(timeout=timeout)
if operation.error_code:
print(
f"Error during {verbose_name}: [Code: {operation.error_code}]: {operation.error_message}",
file=sys.stderr,
flush=True,
)
print(f"Operation ID: {operation.name}", file=sys.stderr, flush=True)
raise operation.exception() or RuntimeError(operation.error_message)
if operation.warnings:
print(f"Warnings during {verbose_name}:\n", file=sys.stderr, flush=True)
for warning in operation.warnings:
print(f" - {warning.code}: {warning.message}", file=sys.stderr, flush=True)
return result
def create_instance(
project_id: str,
zone: str,
instance_name: str,
disks: list[compute_v1.AttachedDisk],
machine_type: str = "n1-standard-1",
network_link: str = "global/networks/default",
subnetwork_link: str = None,
internal_ip: str = None,
external_access: bool = False,
external_ipv4: str = None,
accelerators: list[compute_v1.AcceleratorConfig] = None,
preemptible: bool = False,
spot: bool = False,
instance_termination_action: str = "STOP",
custom_hostname: str = None,
delete_protection: bool = False,
) -> compute_v1.Instance:
"""
Send an instance creation request to the Compute Engine API and wait for it to complete.
Args:
project_id: project ID or project number of the Cloud project you want to use.
zone: name of the zone to create the instance in. For example: "us-west3-b"
instance_name: name of the new virtual machine (VM) instance.
disks: a list of compute_v1.AttachedDisk objects describing the disks
you want to attach to your new instance.
machine_type: machine type of the VM being created. This value uses the
following format: "zones/{zone}/machineTypes/{type_name}".
For example: "zones/europe-west3-c/machineTypes/f1-micro"
network_link: name of the network you want the new instance to use.
For example: "global/networks/default" represents the network
named "default", which is created automatically for each project.
subnetwork_link: name of the subnetwork you want the new instance to use.
This value uses the following format:
"regions/{region}/subnetworks/{subnetwork_name}"
internal_ip: internal IP address you want to assign to the new instance.
By default, a free address from the pool of available internal IP addresses of
used subnet will be used.
external_access: boolean flag indicating if the instance should have an external IPv4
address assigned.
external_ipv4: external IPv4 address to be assigned to this instance. If you specify
an external IP address, it must live in the same region as the zone of the instance.
This setting requires `external_access` to be set to True to work.
accelerators: a list of AcceleratorConfig objects describing the accelerators that will
be attached to the new instance.
preemptible: boolean value indicating if the new instance should be preemptible
or not. Preemptible VMs have been deprecated and you should now use Spot VMs.
spot: boolean value indicating if the new instance should be a Spot VM or not.
instance_termination_action: What action should be taken once a Spot VM is terminated.
Possible values: "STOP", "DELETE"
custom_hostname: Custom hostname of the new VM instance.
Custom hostnames must conform to RFC 1035 requirements for valid hostnames.
delete_protection: boolean value indicating if the new virtual machine should be
protected against deletion or not.
Returns:
Instance object.
"""
instance_client = compute_v1.InstancesClient()
# Use the network interface provided in the network_link argument.
network_interface = compute_v1.NetworkInterface()
network_interface.network = network_link
if subnetwork_link:
network_interface.subnetwork = subnetwork_link
if internal_ip:
network_interface.network_i_p = internal_ip
if external_access:
access = compute_v1.AccessConfig()
access.type_ = compute_v1.AccessConfig.Type.ONE_TO_ONE_NAT.name
access.name = "External NAT"
access.network_tier = access.NetworkTier.PREMIUM.name
if external_ipv4:
access.nat_i_p = external_ipv4
network_interface.access_configs = [access]
# Collect information into the Instance object.
instance = compute_v1.Instance()
instance.network_interfaces = [network_interface]
instance.name = instance_name
instance.disks = disks
if re.match(r"^zones/[a-z\d\-]+/machineTypes/[a-z\d\-]+$", machine_type):
instance.machine_type = machine_type
else:
instance.machine_type = f"zones/{zone}/machineTypes/{machine_type}"
instance.scheduling = compute_v1.Scheduling()
if accelerators:
instance.guest_accelerators = accelerators
instance.scheduling.on_host_maintenance = (
compute_v1.Scheduling.OnHostMaintenance.TERMINATE.name
)
if preemptible:
# Set the preemptible setting
warnings.warn(
"Preemptible VMs are being replaced by Spot VMs.", DeprecationWarning
)
instance.scheduling = compute_v1.Scheduling()
instance.scheduling.preemptible = True
if spot:
# Set the Spot VM setting
instance.scheduling.provisioning_model = (
compute_v1.Scheduling.ProvisioningModel.SPOT.name
)
instance.scheduling.instance_termination_action = instance_termination_action
if custom_hostname is not None:
# Set the custom hostname for the instance
instance.hostname = custom_hostname
if delete_protection:
# Set the delete protection bit
instance.deletion_protection = True
# Prepare the request to insert an instance.
request = compute_v1.InsertInstanceRequest()
request.zone = zone
request.project = project_id
request.instance_resource = instance
# Wait for the create operation to complete.
print(f"Creating the {instance_name} instance in {zone}...")
operation = instance_client.insert(request=request)
wait_for_extended_operation(operation, "instance creation")
print(f"Instance {instance_name} created.")
return instance_client.get(project=project_id, zone=zone, instance=instance_name)
def create_custom_instance(
project_id: str,
zone: str,
instance_name: str,
cpu_series: CustomMachineType.CPUSeries,
core_count: int,
memory: int,
) -> compute_v1.Instance:
"""
Create a new VM instance with a custom machine type.
Args:
project_id: project ID or project number of the Cloud project you want to use.
zone: name of the zone to create the instance in. For example: "us-west3-b"
instance_name: name of the new virtual machine (VM) instance.
cpu_series: the type of CPU you want to use. Select one value from the CustomMachineType.CPUSeries enum.
For example: CustomMachineType.CPUSeries.N2
core_count: number of CPU cores you want to use.
memory: the amount of memory for the VM instance, in megabytes.
Return:
Instance object.
"""
assert cpu_series in (
CustomMachineType.CPUSeries.E2,
CustomMachineType.CPUSeries.N1,
CustomMachineType.CPUSeries.N2,
CustomMachineType.CPUSeries.N2D,
)
custom_type = CustomMachineType(zone, cpu_series, memory, core_count)
newest_debian = get_image_from_family(project="debian-cloud", family="debian-10")
disk_type = f"zones/{zone}/diskTypes/pd-standard"
disks = [disk_from_image(disk_type, 10, True, newest_debian.self_link)]
return create_instance(project_id, zone, instance_name, disks, str(custom_type))
REST
Dengan menggunakan metode instances.insert
,
buat permintaan pembuatan instance dan tentukan
nilai machineType
kustom.
Sediakan memori dalam MB.
- Untuk seri mesin N1, mulailah dengan kustom.
- Untuk core bersama E2, NUMBER_OF_CPU adalah
micro
, small
, atau medium
.
- Untuk mengaktifkan memori tambahan, sertakan
-ext
di akhir jenis mesin.
POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances
Contoh isi permintaan
{
"name": "exampleinstance",
"machineType": "zones/us-central1-a/machineTypes/n2-custom-16-107520",
"disks": [
{
"boot": true,
"diskSizeGb": 10,
"initializeParams": {
"sourceImage": "projects/debian-cloud/global/images/family/debian-11"
}
}
],
"networkInterfaces": [
{
"network": "global/networks/default"
}
]
}
```
Anda juga dapat membuat preemptible instance dan grup instance dengan jenis mesin kustom.
Menambahkan memori tambahan selama pembuatan instance
Untuk membuat instance VM dengan memori yang diperluas, lakukan hal berikut:
Konsol
Di konsol Google Cloud, buka halaman Create an instance.
Buka halaman Create an instance
Dalam daftar Zone, pilih zona tempat Anda ingin menghosting VM ini. Daftar Series difilter agar hanya menyertakan kelompok jenis mesin yang tersedia di zona yang dipilih.
Di bagian Machine configuration, pilih General-purpose.
- Dalam daftar Series, pilih N4, N2, N2D, E2, atau
N1 untuk membuat jenis mesin kustom.
- Untuk menentukan jumlah vCPU, tarik penggeser Cores atau masukkan nilai dalam kolom. Untuk core bersama E2, centang kotak.
- Untuk menambahkan memori tambahan, pilih Perpanjang memori. Untuk menentukan
jumlah memori untuk jenis mesin, tarik penggeser Memory atau
masukkan nilai ke kolom. Konsol akan menampilkan perkiraan biaya untuk VM saat Anda mengedit jumlah vCPU dan memori.
Lanjutkan pembuatan VM.
gcloud
Buat mesin kustom menggunakan perintah gcloud compute instances create
dengan opsi --machine-type
.
gcloud compute instances create INSTANCE_NAME\
--machine-type=MACHINE_TYPE-NUMBER_OF_VCPUS-AMOUNT_OF_MEMORY_MB
Ganti kode berikut:
- INSTANCE_NAME: nama instance
- MACHINE_TYPE: jenis mesin, seperti N2
- NUMBER_OF_VCPUS: jumlah vCPU
- AMOUNT_OF_MEMORY_MB: jumlah memori dalam MB atau GB
Berikut ini contoh penggunaan jenis mesin N2 dengan 48 vCPU dan memori 310 GB di zona us-central1-a
:
gcloud compute instances create example-instance \
--zone=us-central1-a --machine-type=n2-custom-48-317440
Untuk jenis mesin dengan inti bersama E2 kustom, gunakan opsi --machine-type
,
dan tunjukkan jenis mesin: micro
, small
, atau medium
, lalu masukkan
jumlah memori dalam bentuk MB atau GB.
Python
Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Python di panduan memulai Compute Engine menggunakan library klien.
Untuk informasi selengkapnya, lihat
dokumentasi referensi API
Python Compute Engine.
Untuk melakukan autentikasi ke Compute Engine, siapkan Kredensial Default Aplikasi.
Untuk mengetahui informasi selengkapnya, baca
Menyiapkan autentikasi untuk lingkungan pengembangan lokal.
from __future__ import annotations
import re
import sys
from typing import Any
import warnings
from google.api_core.extended_operation import ExtendedOperation
from google.cloud import compute_v1
def get_image_from_family(project: str, family: str) -> compute_v1.Image:
"""
Retrieve the newest image that is part of a given family in a project.
Args:
project: project ID or project number of the Cloud project you want to get image from.
family: name of the image family you want to get image from.
Returns:
An Image object.
"""
image_client = compute_v1.ImagesClient()
# List of public operating system (OS) images: https://cloud.google.com/compute/docs/images/os-details
newest_image = image_client.get_from_family(project=project, family=family)
return newest_image
def disk_from_image(
disk_type: str,
disk_size_gb: int,
boot: bool,
source_image: str,
auto_delete: bool = True,
) -> compute_v1.AttachedDisk:
"""
Create an AttachedDisk object to be used in VM instance creation. Uses an image as the
source for the new disk.
Args:
disk_type: the type of disk you want to create. This value uses the following format:
"zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".
For example: "zones/us-west3-b/diskTypes/pd-ssd"
disk_size_gb: size of the new disk in gigabytes
boot: boolean flag indicating whether this disk should be used as a boot disk of an instance
source_image: source image to use when creating this disk. You must have read access to this disk. This can be one
of the publicly available images or an image from one of your projects.
This value uses the following format: "projects/{project_name}/global/images/{image_name}"
auto_delete: boolean flag indicating whether this disk should be deleted with the VM that uses it
Returns:
AttachedDisk object configured to be created using the specified image.
"""
boot_disk = compute_v1.AttachedDisk()
initialize_params = compute_v1.AttachedDiskInitializeParams()
initialize_params.source_image = source_image
initialize_params.disk_size_gb = disk_size_gb
initialize_params.disk_type = disk_type
boot_disk.initialize_params = initialize_params
# Remember to set auto_delete to True if you want the disk to be deleted when you delete
# your VM instance.
boot_disk.auto_delete = auto_delete
boot_disk.boot = boot
return boot_disk
def wait_for_extended_operation(
operation: ExtendedOperation, verbose_name: str = "operation", timeout: int = 300
) -> Any:
"""
Waits for the extended (long-running) operation to complete.
If the operation is successful, it will return its result.
If the operation ends with an error, an exception will be raised.
If there were any warnings during the execution of the operation
they will be printed to sys.stderr.
Args:
operation: a long-running operation you want to wait on.
verbose_name: (optional) a more verbose name of the operation,
used only during error and warning reporting.
timeout: how long (in seconds) to wait for operation to finish.
If None, wait indefinitely.
Returns:
Whatever the operation.result() returns.
Raises:
This method will raise the exception received from `operation.exception()`
or RuntimeError if there is no exception set, but there is an `error_code`
set for the `operation`.
In case of an operation taking longer than `timeout` seconds to complete,
a `concurrent.futures.TimeoutError` will be raised.
"""
result = operation.result(timeout=timeout)
if operation.error_code:
print(
f"Error during {verbose_name}: [Code: {operation.error_code}]: {operation.error_message}",
file=sys.stderr,
flush=True,
)
print(f"Operation ID: {operation.name}", file=sys.stderr, flush=True)
raise operation.exception() or RuntimeError(operation.error_message)
if operation.warnings:
print(f"Warnings during {verbose_name}:\n", file=sys.stderr, flush=True)
for warning in operation.warnings:
print(f" - {warning.code}: {warning.message}", file=sys.stderr, flush=True)
return result
def create_instance(
project_id: str,
zone: str,
instance_name: str,
disks: list[compute_v1.AttachedDisk],
machine_type: str = "n1-standard-1",
network_link: str = "global/networks/default",
subnetwork_link: str = None,
internal_ip: str = None,
external_access: bool = False,
external_ipv4: str = None,
accelerators: list[compute_v1.AcceleratorConfig] = None,
preemptible: bool = False,
spot: bool = False,
instance_termination_action: str = "STOP",
custom_hostname: str = None,
delete_protection: bool = False,
) -> compute_v1.Instance:
"""
Send an instance creation request to the Compute Engine API and wait for it to complete.
Args:
project_id: project ID or project number of the Cloud project you want to use.
zone: name of the zone to create the instance in. For example: "us-west3-b"
instance_name: name of the new virtual machine (VM) instance.
disks: a list of compute_v1.AttachedDisk objects describing the disks
you want to attach to your new instance.
machine_type: machine type of the VM being created. This value uses the
following format: "zones/{zone}/machineTypes/{type_name}".
For example: "zones/europe-west3-c/machineTypes/f1-micro"
network_link: name of the network you want the new instance to use.
For example: "global/networks/default" represents the network
named "default", which is created automatically for each project.
subnetwork_link: name of the subnetwork you want the new instance to use.
This value uses the following format:
"regions/{region}/subnetworks/{subnetwork_name}"
internal_ip: internal IP address you want to assign to the new instance.
By default, a free address from the pool of available internal IP addresses of
used subnet will be used.
external_access: boolean flag indicating if the instance should have an external IPv4
address assigned.
external_ipv4: external IPv4 address to be assigned to this instance. If you specify
an external IP address, it must live in the same region as the zone of the instance.
This setting requires `external_access` to be set to True to work.
accelerators: a list of AcceleratorConfig objects describing the accelerators that will
be attached to the new instance.
preemptible: boolean value indicating if the new instance should be preemptible
or not. Preemptible VMs have been deprecated and you should now use Spot VMs.
spot: boolean value indicating if the new instance should be a Spot VM or not.
instance_termination_action: What action should be taken once a Spot VM is terminated.
Possible values: "STOP", "DELETE"
custom_hostname: Custom hostname of the new VM instance.
Custom hostnames must conform to RFC 1035 requirements for valid hostnames.
delete_protection: boolean value indicating if the new virtual machine should be
protected against deletion or not.
Returns:
Instance object.
"""
instance_client = compute_v1.InstancesClient()
# Use the network interface provided in the network_link argument.
network_interface = compute_v1.NetworkInterface()
network_interface.network = network_link
if subnetwork_link:
network_interface.subnetwork = subnetwork_link
if internal_ip:
network_interface.network_i_p = internal_ip
if external_access:
access = compute_v1.AccessConfig()
access.type_ = compute_v1.AccessConfig.Type.ONE_TO_ONE_NAT.name
access.name = "External NAT"
access.network_tier = access.NetworkTier.PREMIUM.name
if external_ipv4:
access.nat_i_p = external_ipv4
network_interface.access_configs = [access]
# Collect information into the Instance object.
instance = compute_v1.Instance()
instance.network_interfaces = [network_interface]
instance.name = instance_name
instance.disks = disks
if re.match(r"^zones/[a-z\d\-]+/machineTypes/[a-z\d\-]+$", machine_type):
instance.machine_type = machine_type
else:
instance.machine_type = f"zones/{zone}/machineTypes/{machine_type}"
instance.scheduling = compute_v1.Scheduling()
if accelerators:
instance.guest_accelerators = accelerators
instance.scheduling.on_host_maintenance = (
compute_v1.Scheduling.OnHostMaintenance.TERMINATE.name
)
if preemptible:
# Set the preemptible setting
warnings.warn(
"Preemptible VMs are being replaced by Spot VMs.", DeprecationWarning
)
instance.scheduling = compute_v1.Scheduling()
instance.scheduling.preemptible = True
if spot:
# Set the Spot VM setting
instance.scheduling.provisioning_model = (
compute_v1.Scheduling.ProvisioningModel.SPOT.name
)
instance.scheduling.instance_termination_action = instance_termination_action
if custom_hostname is not None:
# Set the custom hostname for the instance
instance.hostname = custom_hostname
if delete_protection:
# Set the delete protection bit
instance.deletion_protection = True
# Prepare the request to insert an instance.
request = compute_v1.InsertInstanceRequest()
request.zone = zone
request.project = project_id
request.instance_resource = instance
# Wait for the create operation to complete.
print(f"Creating the {instance_name} instance in {zone}...")
operation = instance_client.insert(request=request)
wait_for_extended_operation(operation, "instance creation")
print(f"Instance {instance_name} created.")
return instance_client.get(project=project_id, zone=zone, instance=instance_name)
def create_custom_instances_extra_mem(
project_id: str, zone: str, instance_name: str, core_count: int, memory: int
) -> list[compute_v1.Instance]:
"""
Create 3 new VM instances with extra memory without using a CustomMachineType helper class.
Args:
project_id: project ID or project number of the Cloud project you want to use.
zone: name of the zone to create the instance in. For example: "us-west3-b"
instance_name: name of the new virtual machine (VM) instance.
core_count: number of CPU cores you want to use.
memory: the amount of memory for the VM instance, in megabytes.
Returns:
List of Instance objects.
"""
newest_debian = get_image_from_family(project="debian-cloud", family="debian-10")
disk_type = f"zones/{zone}/diskTypes/pd-standard"
disks = [disk_from_image(disk_type, 10, True, newest_debian.self_link)]
# The core_count and memory values are not validated anywhere and can be rejected by the API.
instances = [
create_instance(
project_id,
zone,
f"{instance_name}_n1_extra_mem",
disks,
f"zones/{zone}/machineTypes/custom-{core_count}-{memory}-ext",
),
create_instance(
project_id,
zone,
f"{instance_name}_n2_extra_mem",
disks,
f"zones/{zone}/machineTypes/n2-custom-{core_count}-{memory}-ext",
),
create_instance(
project_id,
zone,
f"{instance_name}_n2d_extra_mem",
disks,
f"zones/{zone}/machineTypes/n2d-custom-{core_count}-{memory}-ext",
),
]
return instances
REST
Dengan metode instances.insert
, buat permintaan pembuatan instance seperti yang Anda lakukan untuk membuat instance dengan memori kustom. Menyertakan -ext
, yang menunjukkan memori tambahan, saat
menentukan nilai machineType
:
- Untuk semua jenis mesin kustom, tambahkan
-ext
untuk menambah memori hingga
batas seperti yang dijelaskan oleh kelompok mesin tertentu tersebut.
- Dengan core bersama E2, tentukan
micro
, small
, atau medium
.
zones/ZONE/machineTypes//MACHINE_TYPE-NUMBER_OF_CPUS-AMOUNT_OF_MEMORY-ext
Ganti kode berikut:
- ZONE: Lokasi perangkat
- MACHINE_TYPE: Jenis mesin, seperti N2 atau E2 kecil
- NUMBER_OF_CPUS: jumlah vCPU
- AMOUNT_OF_MEMORY_MB: jumlah memori dalam MB
Misalnya, contoh berikut menentukan jenis mesin N2 dengan 2 vCPU dan memori 20 GB. Perhatikan bahwa Anda harus mengonversi memori ke MB:
zones/ZONE/machineTypes/n2-custom-2-20480-ext
Menambahkan memori tambahan ke instance VM yang ada
Untuk menambahkan lebih banyak memori ke instance yang ada, Anda harus
menghentikan instance terlebih dahulu.
Setelah instance berhenti, selesaikan langkah-langkah berikut untuk menambahkan lebih banyak memori ke VM.
Konsol
Di konsol Google Cloud, buka halaman Instance VM.
Buka halaman VM instances
Pilih VM yang dihentikan yang ingin Anda ubah dari daftar VM.
Klik Edit di bagian atas halaman.
Di Machine configuration, pilih General-purpose.
Di bagian Machine type, pilih Custom.
Pilih jumlah vCPU yang Anda inginkan.
Untuk menambahkan memori tambahan, pilih Extend memory, lalu tentukan jumlah memori yang Anda inginkan.
Simpan perubahan.
Go
Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Go di panduan memulai Compute Engine menggunakan library klien.
Untuk informasi selengkapnya, lihat
dokumentasi referensi API
Go Compute Engine.
Untuk melakukan autentikasi ke Compute Engine, siapkan Kredensial Default Aplikasi.
Untuk mengetahui informasi selengkapnya, baca
Menyiapkan autentikasi untuk lingkungan pengembangan lokal.
import (
"context"
"fmt"
"io"
"strings"
compute "cloud.google.com/go/compute/apiv1"
computepb "cloud.google.com/go/compute/apiv1/computepb"
"google.golang.org/protobuf/proto"
)
// modifyInstanceWithExtendedMemory sends an instance creation request
// to the Compute Engine API and waits for it to complete.
func modifyInstanceWithExtendedMemory(
w io.Writer,
projectID, zone, instanceName string,
newMemory int,
) error {
// projectID := "your_project_id"
// zone := "europe-central2-b"
// instanceName := "your_instance_name"
// newMemory := 256 // the amount of memory for the VM instance, in megabytes.
ctx := context.Background()
instancesClient, err := compute.NewInstancesRESTClient(ctx)
if err != nil {
return fmt.Errorf("NewInstancesRESTClient: %w", err)
}
defer instancesClient.Close()
reqInstance := &computepb.GetInstanceRequest{
Project: projectID,
Zone: zone,
Instance: instanceName,
}
instance, err := instancesClient.Get(ctx, reqInstance)
if err != nil {
return fmt.Errorf("unable to get instance: %w", err)
}
containsString := func(s []string, str string) bool {
for _, v := range s {
if v == str {
return true
}
}
return false
}
if !(strings.Contains(instance.GetMachineType(), "machineTypes/n1-") ||
strings.Contains(instance.GetMachineType(), "machineTypes/n2-") ||
strings.Contains(instance.GetMachineType(), "machineTypes/n2d-")) {
return fmt.Errorf("extra memory is available only for N1, N2 and N2D CPUs")
}
// Make sure that the machine is turned off
if !containsString([]string{"TERMINATED", "STOPPED"}, instance.GetStatus()) {
reqStop := &computepb.StopInstanceRequest{
Project: projectID,
Zone: zone,
Instance: instanceName,
}
op, err := instancesClient.Stop(ctx, reqStop)
if err != nil {
return fmt.Errorf("unable to stop instance: %w", err)
}
if err = op.Wait(ctx); err != nil {
return fmt.Errorf("unable to wait for the operation: %w", err)
}
}
// Modify the machine definition, remember that extended memory
// is available only for N1, N2 and N2D CPUs
machineType := instance.GetMachineType()
start := machineType[:strings.LastIndex(machineType, "-")]
updateReq := &computepb.SetMachineTypeInstanceRequest{
Project: projectID,
Zone: zone,
Instance: instanceName,
InstancesSetMachineTypeRequestResource: &computepb.InstancesSetMachineTypeRequest{
MachineType: proto.String(fmt.Sprintf("%s-%v-ext", start, newMemory)),
},
}
op, err := instancesClient.SetMachineType(ctx, updateReq)
if err != nil {
return fmt.Errorf("unable to update instance: %w", err)
}
if err = op.Wait(ctx); err != nil {
return fmt.Errorf("unable to wait for the operation: %w", err)
}
fmt.Fprintf(w, "Instance updated\n")
return nil
}
Python
Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Python di panduan memulai Compute Engine menggunakan library klien.
Untuk informasi selengkapnya, lihat
dokumentasi referensi API
Python Compute Engine.
Untuk melakukan autentikasi ke Compute Engine, siapkan Kredensial Default Aplikasi.
Untuk mengetahui informasi selengkapnya, baca
Menyiapkan autentikasi untuk lingkungan pengembangan lokal.
from __future__ import annotations
import sys
import time
from typing import Any
from google.api_core.extended_operation import ExtendedOperation
from google.cloud import compute_v1
def wait_for_extended_operation(
operation: ExtendedOperation, verbose_name: str = "operation", timeout: int = 300
) -> Any:
"""
Waits for the extended (long-running) operation to complete.
If the operation is successful, it will return its result.
If the operation ends with an error, an exception will be raised.
If there were any warnings during the execution of the operation
they will be printed to sys.stderr.
Args:
operation: a long-running operation you want to wait on.
verbose_name: (optional) a more verbose name of the operation,
used only during error and warning reporting.
timeout: how long (in seconds) to wait for operation to finish.
If None, wait indefinitely.
Returns:
Whatever the operation.result() returns.
Raises:
This method will raise the exception received from `operation.exception()`
or RuntimeError if there is no exception set, but there is an `error_code`
set for the `operation`.
In case of an operation taking longer than `timeout` seconds to complete,
a `concurrent.futures.TimeoutError` will be raised.
"""
result = operation.result(timeout=timeout)
if operation.error_code:
print(
f"Error during {verbose_name}: [Code: {operation.error_code}]: {operation.error_message}",
file=sys.stderr,
flush=True,
)
print(f"Operation ID: {operation.name}", file=sys.stderr, flush=True)
raise operation.exception() or RuntimeError(operation.error_message)
if operation.warnings:
print(f"Warnings during {verbose_name}:\n", file=sys.stderr, flush=True)
for warning in operation.warnings:
print(f" - {warning.code}: {warning.message}", file=sys.stderr, flush=True)
return result
def add_extended_memory_to_instance(
project_id: str, zone: str, instance_name: str, new_memory: int
):
"""
Modify an existing VM to use extended memory.
Args:
project_id: project ID or project number of the Cloud project you want to use.
zone: name of the zone to create the instance in. For example: "us-west3-b"
instance_name: name of the new virtual machine (VM) instance.
new_memory: the amount of memory for the VM instance, in megabytes.
Returns:
Instance object.
"""
instance_client = compute_v1.InstancesClient()
instance = instance_client.get(
project=project_id, zone=zone, instance=instance_name
)
if not (
"n1-" in instance.machine_type
or "n2-" in instance.machine_type
or "n2d-" in instance.machine_type
):
raise RuntimeError("Extra memory is available only for N1, N2 and N2D CPUs.")
# Make sure that the machine is turned off
if instance.status not in (
instance.Status.TERMINATED.name,
instance.Status.STOPPED.name,
):
operation = instance_client.stop(
project=project_id, zone=zone, instance=instance_name
)
wait_for_extended_operation(operation, "instance stopping")
start = time.time()
while instance.status not in (
instance.Status.TERMINATED.name,
instance.Status.STOPPED.name,
):
# Waiting for the instance to be turned off.
instance = instance_client.get(
project=project_id, zone=zone, instance=instance_name
)
time.sleep(2)
if time.time() - start >= 300: # 5 minutes
raise TimeoutError()
# Modify the machine definition, remember that extended memory is available only for N1, N2 and N2D CPUs
start, end = instance.machine_type.rsplit("-", maxsplit=1)
instance.machine_type = start + f"-{new_memory}-ext"
# TODO: If you prefer to use the CustomMachineType helper class, uncomment this code and comment the 2 lines above
# Using CustomMachineType helper
# cmt = CustomMachineType.from_str(instance.machine_type)
# cmt.memory_mb = new_memory
# cmt.extra_memory_used = True
# instance.machine_type = str(cmt)
operation = instance_client.update(
project=project_id,
zone=zone,
instance=instance_name,
instance_resource=instance,
)
wait_for_extended_operation(operation, "instance update")
return instance_client.get(project=project_id, zone=zone, instance=instance_name)
REST
Gunakan metode instances.stop
,
lalu gunakan
metode instances.setMachineType
untuk mengedit resource jenis mesin.
Setelah Anda menghentikan instance, edit opsi machineTypes
dengan perubahan Anda.
{
"name": "INSTANCE_NAME",
"machineType": "zones/ZONE/machineTypes/MACHINE_TYPE",
...
}
Ganti kode berikut:
+ INSTANCE_NAME: The name of the VM
+ ZONE: The zone where your VMs reside
+ MACHINE_TYPE: The name of the VM
Langkah selanjutnya