מחיקת מכונה של Compute Engine

במאמר הזה נסביר איך למחוק באופן סופי מכונה של Compute Engine.

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

השלכות החיוב על מכונות שנמחקו

אחרי שמוחקים מכונה, מפסיקים לצבור חיובים על המכונה ועל המשאבים שמצורפים אליה, חוץ מהמקרים הבאים:

  • אם מוחקים מכונה שמתארחת בשרת לדייר יחיד, עדיין מחויבים על השרת לדייר יחיד.

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

    • אתם מוחקים את הבקשה, או ש-Compute Engine מוחק אותה בפעולה אוטומטית.

    • אתם מקטינים את מספר המכונות השמורות בהזמנה.

  • אם יש לכם הנחה תמורת התחייבות לשימוש, אתם ממשיכים לשלם על המשאבים שהתחייבתם להשתמש בהם, גם אם אתם לא משתמשים בהם.

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

למידע נוסף, ראו תמחור של מכונות וירטואליות.

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

שמירת המשאבים המצורפים

אם רוצים לשמור משאב שמצורף למכונה לפני שמוחקים אותה, אפשר לבצע אחת או יותר מהפעולות הבאות:

התפקידים הנדרשים

כדי לקבל את ההרשאות שנדרשות למחיקת מכונה, צריך לבקש מהאדמין להקצות לכם ב-IAM את התפקיד אדמין מכונות של Compute ‏ (v1) (roles/compute.instanceAdmin.v1) בפרויקט. כדי לקרוא הסבר על מתן תפקידים, ראו איך מנהלים את הגישה ברמת הפרויקט, התיקייה והארגון.

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

ההרשאות הנדרשות

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

  • ‫compute.instances.delete במכונה
  • כדי לאלץ מחיקה של דיסק מצורף: ‫compute.disks.delete בדיסק

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

מחיקת מכונות Compute

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

  • ‫Delete disks: אתם יכולים למחוק את דיסקי האתחול, את הדיסקים שהם לא דיסקי אתחול או את כל הדיסקים שמחוברים למכונות שלכם. אם הגדרתם את הדיסקים כך שיישמרו לאחר המחיקה, תוכלו לשנות את ההגדרה הזו ולאלץ את המחיקה שלהם.

    איך מוחקים מכונות וכל המשאבים שמצורפים אליהן

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

    להוראות, קראו את המאמר מחיקת מכונות Compute תוך שמירה על הדיסקים.

מחיקת מכונות וכל המשאבים שמצורפים אליהן

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

  • מחיקה כפויה של דיסקים: אם הגדרתם דיסק מצורף לשמירה כש-Compute Engine מוחק מכונה, אתם יכולים לשנות את ההגדרה הזו ולאלץ את המחיקה באמצעות Google Cloud CLI.

  • דילוג על כיבוי מבוקר או סיום שלו: אם הפעלתם כיבוי מבוקר במכונה, אתם יכולים למחוק את המכונה בלי לבצע כיבוי מבוקר או לסיים כיבוי מבוקר שמתבצע באמצעות מסוףGoogle Cloud , ה-CLI של gcloud או API בארכיטקטורת REST.

  • מחיקה של כמה מכונות: אם רוצים למחוק כמה מכונות בו-זמנית, משתמשים במסוף Google Cloud או ב-CLI של gcloud (אם המכונות נמצאות באותו אזור).

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

המסוף

  1. נכנסים לדף VM instances במסוף Google Cloud .

    כניסה לדף VM instances

  2. בוחרים את המופעים שרוצים למחוק.

  3. לוחצים על מחיקה. אם האפשרות Delete לא מופיעה, לוחצים על More actions ובוחרים באפשרות Delete.

  4. בתיבת הדו-שיח שמופיעה:

    1. אופציונלי: כדי למחוק את המכונות בלי כיבוי מבוקר, או כדי לסיים כיבוי מבוקר שמתבצע, בוחרים בתיבת הסימון Skip graceful shutdown (if applicable).

    2. כדי לאשר, לוחצים על מחיקה.

gcloud

כדי למחוק מכונה אחת או יותר באותו אזור, משתמשים בפקודה gcloud compute instances delete:

gcloud compute instances delete INSTANCE_NAMES \
    --zone=ZONE

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

  • ‫INSTANCE_NAMES: רשימה של שמות המכונות שרוצים למחוק, מופרדים ברווחים. לדוגמה, מציינים את הערך instance-01 instance-02 instance-03.

  • ‫ZONE: האזור שבו נמצאות המכונות.

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

  • כדי לאלץ מחיקה של הדיסקים שמחוברים למכונה אחת או יותר, צריך לכלול את הדגל --delete-disks:

    gcloud compute instances delete INSTANCE_NAMES \
        --delete-disks=DELETE_DISK_TYPE \
        --zone=ZONE
    

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

    • כדי למחוק אחסון מתמיד של אתחול ואחסון מתמיד שאינו של אתחול: all

    • כדי למחוק רק את האחסון המתמיד של האתחול: boot

    • כדי למחוק רק אחסון מתמיד שאינו לאתחול: data

  • כדי לדלג על כיבוי מבוקר שמתבצע או לסיים אותו, צריך לכלול את הדגל --no-graceful-shutdown:

    gcloud compute instances delete INSTANCE_NAMES \
        --no-graceful-shutdown \
        --zone=ZONE
    

C#‎


using Google.Cloud.Compute.V1;
using System.Threading.Tasks;

public class DeleteInstanceAsyncSample
{
    public async Task DeleteInstanceAsync(
        // TODO(developer): Set your own default values for these parameters or pass different values when calling this method.
        string projectId = "your-project-id",
        string zone = "us-central1-a",
        string machineName = "test-machine")
    {

        // Initialize client that will be used to send requests. This client only needs to be created
        // once, and can be reused for multiple requests.
        InstancesClient client = await InstancesClient.CreateAsync();

        // Make the request to delete a VM instance.
        var instanceDeletion = await client.DeleteAsync(projectId, zone, machineName);

        // Wait for the operation to complete using client-side polling.
        await instanceDeletion.PollUntilCompletedAsync();
    }
}

Go

import (
	"context"
	"fmt"
	"io"

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

// deleteInstance sends a delete request to the Compute Engine API and waits for it to complete.
func deleteInstance(w io.Writer, projectID, zone, instanceName string) error {
	// projectID := "your_project_id"
	// zone := "europe-central2-b"
	// instanceName := "your_instance_name"
	ctx := context.Background()
	instancesClient, err := compute.NewInstancesRESTClient(ctx)
	if err != nil {
		return fmt.Errorf("NewInstancesRESTClient: %w", err)
	}
	defer instancesClient.Close()

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

	op, err := instancesClient.Delete(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to delete 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 deleted\n")

	return nil
}

Java


import com.google.api.gax.longrunning.OperationFuture;
import com.google.cloud.compute.v1.DeleteInstanceRequest;
import com.google.cloud.compute.v1.InstancesClient;
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 DeleteInstance {

  public static void main(String[] args)
      throws IOException, InterruptedException, ExecutionException, TimeoutException {
    // TODO(developer): Replace these variables before running the sample.
    String project = "your-project-id";
    String zone = "zone-name";
    String instanceName = "instance-name";
    deleteInstance(project, zone, instanceName);
  }

  // Delete the instance specified by `instanceName`
  // if it's present in the given project and zone.
  public static void deleteInstance(String project, String zone, String instanceName)
      throws IOException, InterruptedException, ExecutionException, 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()) {

      System.out.printf("Deleting instance: %s ", instanceName);

      // Describe which instance is to be deleted.
      DeleteInstanceRequest deleteInstanceRequest = DeleteInstanceRequest.newBuilder()
          .setProject(project)
          .setZone(zone)
          .setInstance(instanceName).build();

      OperationFuture<Operation, Operation> operation = instancesClient.deleteAsync(
          deleteInstanceRequest);
      // Wait for the operation to complete.
      Operation response = operation.get(3, TimeUnit.MINUTES);

      if (response.hasError()) {
        System.out.println("Instance deletion failed ! ! " + response);
        return;
      }
      System.out.println("Operation Status: " + response.getStatus());
    }
  }
}

Node.js

/**
 * TODO(developer): Uncomment these variables before running the sample.
 */
// const projectId = 'YOUR_PROJECT_ID';
// const zone = 'europe-central2-b'
// const instanceName = 'YOUR_INSTANCE_NAME';

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

// Delete the instance specified by `instanceName` if it's present in the given project and zone.
async function deleteInstance() {
  const instancesClient = new compute.InstancesClient();

  console.log(`Deleting ${instanceName} from ${zone}...`);

  const [response] = await instancesClient.delete({
    project: projectId,
    zone,
    instance: instanceName,
  });
  let operation = response.latestResponse;
  const operationsClient = new compute.ZoneOperationsClient();

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

  console.log('Instance deleted.');
}

deleteInstance();

PHP

use Google\Cloud\Compute\V1\Client\InstancesClient;
use Google\Cloud\Compute\V1\DeleteInstanceRequest;

/**
 * Delete an instance.
 *
 * @param string $projectId Your Google Cloud project ID.
 * @param string $zone Zone where the instance you want to delete is (like "us-central1-a").
 * @param string $instanceName Unique name for the Compute instance to delete.
 *
 * @throws \Google\ApiCore\ApiException if the remote call fails.
 * @throws \Google\ApiCore\ValidationException if local error occurs before remote call.
 */
function delete_instance(
    string $projectId,
    string $zone,
    string $instanceName
) {
    // Delete the Compute Engine instance using InstancesClient.
    $instancesClient = new InstancesClient();
    $request = (new DeleteInstanceRequest())
        ->setInstance($instanceName)
        ->setProject($projectId)
        ->setZone($zone);
    $operation = $instancesClient->delete($request);

    // Wait for the operation to complete.
    $operation->pollUntilComplete();
    if ($operation->operationSucceeded()) {
        printf('Deleted instance %s' . PHP_EOL, $instanceName);
    } else {
        $error = $operation->getError();
        printf('Failed to delete instance: %s' . PHP_EOL, $error?->getMessage());
    }
}

Python

from __future__ import annotations

import sys
from typing import Any

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


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

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

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

    Returns:
        Whatever the operation.result() returns.

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

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

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

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

    return result


def delete_instance(project_id: str, zone: str, machine_name: str) -> None:
    """
    Send an instance deletion 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 you want to use. For example: “us-west3-b”
        machine_name: name of the machine you want to delete.
    """
    instance_client = compcompute_v1tInstancesClient    print(f"Deleting {machine_name} from {zone}...")
    operation = instinstance_client.delete      project=project_id, zone=zone, instance=machine_name
    )
    wait_for_extended_operation(operation, "instance deletion")
    print(f"Instance {machine_name} deleted.")

Ruby


require "google/cloud/compute/v1"

# Sends an instance deletion request to the Compute Engine API and waits for it to complete.
#
# @param [String] project project ID or project number of the Cloud project you want to use.
# @param [String] zone name of the zone you want to use. For example: "us-west3-b"
# @param [String] instance_name name of the instance you want to delete.
def delete_instance project:, zone:, instance_name:
  # Initialize client that will be used to send requests. This client only needs to be created
  # once, and can be reused for multiple requests.
  client = ::Google::Cloud::Compute::V1::Instances::Rest::Client.new

  puts "Deleting #{instance_name} from #{zone}..."
  begin
    # Make the request to delete a VM instance.
    operation = client.delete project: project, zone: zone, instance: instance_name
    # Wait for the delete operation to complete.
    operation = wait_until_done operation: operation

    compute_operation = operation.operation
    if operation.error?
      warn "Error during deletion:", compute_operation.error.errors.map { |e| "#{e.code}: #{e.message}" }
    else
      warn "Warning during deletion:", compute_operation.warnings unless compute_operation.warnings.empty?
      puts "Instance #{instance_name} deleted."
    end
  rescue ::Google::Cloud::Error => e
    warn "Exception during deletion:", e
  end
end

REST

כדי למחוק מכונה, שולחים בקשת DELETE אל ה-method‏ instances delete:

DELETE https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_NAME

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

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

  • ‫ZONE: האזור שבו נמצאת המכונה.

  • ‫INSTANCE_NAME: השם של המכונה הווירטואלית.

אם רוצים לדלג על כיבוי מבוקר שמתבצע או לסיים אותו, צריך לכלול את פרמטר השאילתה noGracefulShutdown שמוגדר ל-true בכתובת ה-URL של הבקשה:

DELETE https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME?noGracefulShutdown=true

מחיקת מכונות ושמירת דיסקים

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

כדי למחוק מכונה אחת או יותר באותו אזור בלי למחוק את הדיסקים שמחוברים אליהן, משתמשים בפקודה gcloud compute instances delete עם הדגל --keep-disks:

gcloud compute instances delete INSTANCE_NAMES \
    --keep-disks=KEEP_DISK_TYPE \
    --zone=ZONE

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

  • ‫INSTANCE_NAMES: רשימה של שמות המכונות שרוצים למחוק, מופרדים ברווחים. לדוגמה, מציינים את הערך instance-01 instance-02 instance-03.

  • ‫KEEP_DISK_TYPE: סוגי הדיסקים שרוצים לשמור. מציינים את אחד מהערכים הבאים:

    • כדי לשמור על אחסון מתמיד מצורף, עם או בלי יכולת אתחול: all

    • כדי לשמור רק את האחסון המתמיד של הטעינה המצורפת: boot

    • כדי לשמור רק על אחסון מתמיד מצורף שאינו לאתחול: data

  • ‫ZONE: האזור שבו נמצאות המכונות.

אם הפעלתם כיבוי מבוקר במכונה אחת או יותר, אתם יכולים לחסוך בעלויות על ידי מחיקת המכונות בלי לבצע כיבוי מבוקר, או על ידי סיום ידני של כיבוי מבוקר שמתבצע. כדי לעשות את זה, מוסיפים לפקודה את הדגל --no-graceful-shutdown:

gcloud compute instances delete VM_NAMES \
    --keep-disks=KEEP_DISK_TYPE \
    --no-graceful-shutdown \
    --zone=ZONE

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