編輯運算執行個體的機器類型


如果虛擬機器 (VM) 執行個體未連接本機 SSD,且不屬於代管執行個體群組 (MIG),您可以在停止執行個體後變更機器類型

如果現有機器類型不適合在 VM 上執行的工作負載,請變更該 VM 的機器類型。例如,您可以在設定、開發及測試期間以較小的機器類型啟動 VM,並在準備好處理實際工作負載時,將 VM 變更為使用較大的機器類型。

您可以在下列情況下使用此程序:

  • 如要變更為同系列機器的類似機器類型,但 vCPU 數量或記憶體數量不同,例如:
    • 您可以將 n2-highcpu-4 變更為 n2-standard-4
    • 您可以將 c3d-standard-30 變更為 c3d-highmem-30
  • 如要變更機器類型,以便使用其他機器系列。這項功能僅支援第一和第二代機器系列,不包括 T2A 和 A2 機器系列。例如:
    • 您可以將 n2-standard-4 變更為 c2-standard-8
    • 您可以將 n1-highmem-4 變更為 n2d-standard-16

如果您想將使用第一或第二代機器系列 (N1、N2、M1 等) 的 VM 機器類型,改為第三代或更新機器系列 (M3、C3、N4 等) 的機器類型,則必須使用「將工作負載移至新的 Compute 執行個體」一文中所述的程序。

您可以變更機器類型,而不影響下列資源:

  • VM 的安全殼層金鑰
  • VM 設定,例如 VM 中繼資料
  • 已連結的 Persistent Disk 或 Hyperdisk 上的資料,包括已安裝的應用程式和應用程式資料

如要變更 MIG 中的 VM 機器類型,請參閱「在 MIG 中自動套用 VM 設定更新」。

事前準備

  • 瞭解如何停止 VM
  • 瞭解機器類型
  • 如果尚未設定,請先設定驗證機制。驗證是指驗證身分,以便存取 Google Cloud 服務和 API 的程序。如要在本機開發環境中執行程式碼或範例,您可以選取下列任一選項,向 Compute Engine 進行驗證:

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

    Console

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

    Java

    To use the Java samples on this page in a local development environment, install and initialize the gcloud CLI, and then set up Application Default Credentials with your user credentials.

    1. Install the Google Cloud CLI.
    2. If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.

    3. To initialize the gcloud CLI, run the following command:

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

      gcloud auth application-default login

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

      If an authentication error is returned, and you are using an external identity provider (IdP), confirm that you have signed in to the gcloud CLI with your federated identity.

    For more information, see Set up authentication for a local development environment.

    Python

    To use the Python samples on this page in a local development environment, install and initialize the gcloud CLI, and then set up Application Default Credentials with your user credentials.

    1. Install the Google Cloud CLI.
    2. If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.

    3. To initialize the gcloud CLI, run the following command:

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

      gcloud auth application-default login

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

      If an authentication error is returned, and you are using an external identity provider (IdP), confirm that you have signed in to the gcloud CLI with your federated identity.

    For more information, see Set up authentication for a local development environment.

    REST

    To use the REST API samples on this page in a local development environment, you use the credentials you provide to the gcloud CLI.

      After installing the Google Cloud CLI, initialize it by running the following command:

      gcloud init

      If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.

    For more information, see Authenticate for using REST in the Google Cloud authentication documentation.

必要的角色

如要取得變更 VM 機器類型所需的權限,請要求管理員為您授予專案的下列 IAM 角色:

如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和機構的存取權」。

這些預先定義的角色包含變更 VM 機型所需的權限。如要查看確切的必要權限,請展開「必要權限」部分:

所需權限

如要變更 VM 的機器類型,您必須具備下列權限:

  • compute.instances.setMachineType VM 上
  • compute.instances.start VM 上
  • compute.instances.stop VM 上

您或許還可透過自訂角色或其他預先定義的角色取得這些權限。

限制

帳單相關注意事項

每個機器類型都是以不同的費率計費,因此請務必瞭解變更機器類型對於計費方式的影響。舉例來說,e2-standard-2 機器類型的費用比 e2-micro 機器類型高。

變更機器類型可能也會影響該 VM 的續用折扣。系統會針對相同地區中的不同類別個別計算續用折扣。如果您變更機器類型,且新的機器類型屬於不同的類別,VM 的後續執行時間便會列入新類別的續用折扣。

舉例來說,假設您有一個已執行半個月的 n2-standard-2 機器類型 VM,然後您決定要將機器類型變更為 m1-ultramem-40。完成這項變更後,Compute Engine 就會開始將 VM 的執行時間,算到記憶體最佳化 vCPU 和記憶體類別的續用折扣中。

帳單上會列出您變更機器類型前已套用至 n2-standard-2 機器類型的續用折扣,以及 m1-ultramem-40 的個別續用折扣 (前提是您的 VM 在 m1-ultramem-40 上的執行時間至少達到當月剩餘時間的 25%)。

變更為規模較小的機器類型

如果您從具有較多資源的機器類型變更為資源較少的機器類型 (例如從 e2-standard-8 機器類型改為使用 e2-standard-2),可能會遭遇硬體資源問題或效能限制情形,這是因為規模較小的機器類型其功能不如規模較大的機器類型強大。請確認新的機器類型可支援目前在 VM 上執行的所有應用程式和服務;或者,您也可以更新您的服務和應用程式,確保這些項目能在規模較小的機器類型上正常運作。

變更機器類型前,請先查看調整大小建議。如要瞭解 Compute Engine 的大小建議,請參閱「為 VM 執行個體套用機器類型建議」。

最佳做法

以下提供一些最佳做法,協助您順利變更 VM 機器類型。

  • 使用快照定期備份永久磁碟資料。請考慮在變更機器類型前,為您的永久磁碟資料建立快照。如要確保新機器類型能夠支援現有 VM 上的資料,您可以先建立永久磁碟的快照,然後透過這份快照另外啟動一個採用新機器類型的 VM,藉此確認該 VM 是否能順利啟動。

  • 將其他磁碟新增至 /etc/fstab 檔案。如果 VM 連結了其他磁碟,請確認已將這些磁碟新增至 /etc/fstab 檔案,讓系統在 VM 重新啟動時自動掛接這些磁碟。

  • 變更機器類型前建立預留項目。為避免資源可用性相關錯誤,請在可用時為新機器類型建立 Compute Engine 預訂,以便在區域內預訂。預留資源可確保資源在您需要時可用。

如要建立預訂,請完成下列步驟:

  1. 建立保留項目 (或找出現有保留項目),並使用與所規劃 VM 相同的屬性。預留量的 VM 數量必須等於或大於您要變更的 VM 數量。如要防止其他 VM 使用這個預留項目,您可以選擇使用 specificReservationRequired 選項。

  2. 確認預定的 VM 可使用預留項目:

    1. 確認 VM 具有正確的預留配對
    2. 變更 VM 前,請先確認預留空間是否足夠

變更機器類型

您只能變更已停止執行的 VM 機器類型。只有在 VM 處於 TERMINATED 狀態時,系統才會將 VM 視為已停止。您無法變更執行中 VM 的機器類型。

如果您要將機器類型升級至最新一代,請先參閱「評估 VM 遷移選項」,再繼續操作。

主控台

  1. 前往 Google Cloud 控制台的「VM instances」(VM 執行個體) 頁面

    前往 VM 執行個體

  2. 在「Name」欄中,按一下要變更機器類型的 VM 名稱。

  3. 在「VM 執行個體詳細資料」頁面上,完成以下步驟:

    1. 如果 VM 正在執行,請在頁面頂端的選單中選取「Stop」,停止 VM。
    2. 如要編輯 VM,請按一下 「Edit」
    3. 在「Machine configuration」(機器設定) 區段中,選取您要使用的機器類型,或建立自訂機器類型

    4. 若要儲存變更,請按一下 [儲存]

    5. 重新啟動 VM。

gcloud

  1. 使用 gcloud compute instances stop 指令停止 VM:

    gcloud compute instances stop VM_NAME
    

    VM_NAME 替換為包含要變更的機器類型的 VM。

  2. 使用 gcloud compute instances set-machine-type 指令變更機器類型:

    gcloud compute instances set-machine-type VM_NAME \
        --machine-type NEW_MACHINE_TYPE
    

    NEW_MACHINE_TYPE 替換為 VM 的新機器類型。機器類型可以是下列任一類型:

  3. 使用 gcloud compute instances start 指令啟動 VM:

    gcloud compute instances start VM_NAME
    

    VM_NAME 替換為您變更的 VM 名稱。

Java

Java

在試用這個範例之前,請先按照 使用用戶端程式庫的 Compute Engine 快速入門中的操作說明設定 Java。詳情請參閱 Compute Engine Java API 參考資料說明文件

如要向 Compute Engine 進行驗證,請設定應用程式預設憑證。詳情請參閱「為本機開發環境設定驗證機制」。


import com.google.cloud.compute.v1.Instance;
import com.google.cloud.compute.v1.Instance.Status;
import com.google.cloud.compute.v1.InstancesClient;
import com.google.cloud.compute.v1.InstancesSetMachineTypeRequest;
import com.google.cloud.compute.v1.Operation;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class ChangeInstanceMachineType {

  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-project-id";
    // Name of the zone your instance belongs to.
    String zone = "zone-name";
    // Name of the VM you want to modify.
    String instanceName = "instance-name";
    // The new machine type you want to use for the VM.
    // For example: "e2-standard-8", "e2-custom-4-2048" or "m1-ultramem-40"
    // More about machine types: https://cloud.google.com/compute/docs/machine-resource
    String newMachineType = "e2-standard-8";
    changeMachineType(projectId, zone, instanceName, newMachineType);
  }

  // Changes the machine type of VM.
  // The VM needs to be in the 'TERMINATED' state for this operation to be successful.
  public static void changeMachineType(String projectId, String zone, String instanceName,
      String newMachineType)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests. After completing all of your requests, call
    // the `instancesClient.close()` method on the client to safely
    // clean up any remaining background resources.
    try (InstancesClient instancesClient = InstancesClient.create()) {

      Instance instance = instancesClient.get(projectId, zone, instanceName);
      if (!instance.getStatus().equals(Status.TERMINATED.name())) {
        throw new Error(String.format(
            "Only machines in TERMINATED state can have their machine type changed. "
                + "%s is in %s state.", instance.getName(), instance.getStatus()));
      }

      InstancesSetMachineTypeRequest machineTypeRequest =
          InstancesSetMachineTypeRequest.newBuilder()
              .setMachineType(String.format("projects/%s/zones/%s/machineTypes/%s",
                  projectId, zone, newMachineType))
              .build();

      Operation response = instancesClient
          .setMachineTypeAsync(projectId, zone, instanceName, machineTypeRequest)
          .get(3, TimeUnit.MINUTES);

      if (response.hasError()) {
        System.out.println("Machine type update failed! " + response);
        return;
      }
      System.out.println("Machine type update - operation status: " + response.getStatus());
    }
  }
}

Python

Python

在試用這個範例之前,請先按照 使用用戶端程式庫的 Compute Engine 快速入門中的操作說明設定 Python。詳情請參閱 Compute Engine Python API 參考資料說明文件

如要向 Compute Engine 進行驗證,請設定應用程式預設憑證。詳情請參閱「為本機開發環境設定驗證機制」。

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 change_machine_type(
    project_id: str, zone: str, instance_name: str, new_machine_type: str
) -> None:
    """
    Changes the machine type of VM. The VM needs to be in the 'TERMINATED' state for this operation to be successful.

    Args:
        project_id: project ID or project number of the Cloud project you want to use.
        zone: name of the zone your instance belongs to.
        instance_name: name of the VM you want to modify.
        new_machine_type: the new machine type you want to use for the VM.
            For example: `e2-standard-8`, `e2-custom-4-2048` or `m1-ultramem-40`
            More about machine types: https://cloud.google.com/compute/docs/machine-resource
    """
    client = compute_v1.InstancesClient()
    instance = client.get(project=project_id, zone=zone, instance=instance_name)

    if instance.status != compute_v1.Instance.Status.TERMINATED.name:
        raise RuntimeError(
            f"Only machines in TERMINATED state can have their machine type changed. "
            f"{instance.name} is in {instance.status}({instance.status_message}) state."
        )

    machine_type = compute_v1.InstancesSetMachineTypeRequest()
    machine_type.machine_type = (
        f"projects/{project_id}/zones/{zone}/machineTypes/{new_machine_type}"
    )
    operation = client.set_machine_type(
        project=project_id,
        zone=zone,
        instance=instance_name,
        instances_set_machine_type_request_resource=machine_type,
    )

    wait_for_extended_operation(operation, "changing machine type")

REST

  1. 使用 instances.stop 方法停止 VM:

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

    更改下列內容:

    • PROJECT_ID:專案 ID

    • ZONE:包含 VM 的可用區

    • VM_NAME:包含要變更機器類型的 VM

  2. 使用 instances.setMachineType 方法變更機器類型:

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

    在要求主體中提供更新的 machineType

    {
        machineType: "zones/MACHINE_TYPE_ZONE/machineTypes/NEW_MACHINE_TYPE"
    }
    

    更改下列內容:

    • MACHINE_TYPE_ZONE:包含機器類型的區域

    • NEW_MACHINE_TYPE:VM 的新機器類型

      機器類型可以是下列任一類型:

  3. 使用 instances.start 方法啟動 VM:

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

    更改下列內容:

    • PROJECT_ID:專案 ID
    • ZONE:包含 VM 的可用區
    • VM_NAME:您變更的 VM 名稱

後續步驟