部署带有区域永久性磁盘的可恢复冷应用服务器

本文档适用于架构师以及在运营和管理团队工作的人员。本文档介绍了您可以在 Google Cloud 中用于自己的部署的示例模式。

在此模式中,您可以将区域永久性磁盘代管式实例组搭配使用,以便为网络服务器实现冷故障切换模式。

在本教程中,您将创建一个代管式实例组,它使用存储数据的区域永久性磁盘运行单个虚拟机。外部 HTTP(S) 负载均衡会将用户定向到在代管式实例组中运行的虚拟机,如下图所示:

外部 HTTP(S) 负载均衡会将用户定向到在代管式实例组中运行的单个虚拟机,并且区域永久性磁盘会挂接到该虚拟机。

如果存在实例故障,则代管式实例组会尝试在同一可用区重新创建虚拟机。如果故障发生在可用区级别,则 Cloud Monitoring 或类似服务可通知您存在问题,并且您将在另一个工作可用区中另外手动创建一个代管式实例组。在任一故障转移场景中,平台都会将地区永久性磁盘挂接到实例组中的新虚拟机。

在本文档中,您可以使用虚拟机或负载均衡器的外部 IP 地址查看网络服务器上的基本页面。如果您没有注册域名且没有任何 DNS 更改,则可通过此方法测试冷故障切换模式。在生产环境中,请创建并配置 Cloud DNS 可用区和记录,以解析为分配给负载均衡器的外部 IP 地址。

此场景可在运行多个虚拟机的同时保持一定级别的数据保护,从而平衡费用差异。当您运行区域永久性磁盘以在一个地区的两个区域之间持续复制数据时,您的费用会更高,但当可用区级发生故障时,您可以最大限度地降低数据丢失的风险。如需降低存储费用,请考虑改为使用永久性磁盘快照部署可恢复的冷应用

下表简要介绍了使用区域永久性磁盘或永久性磁盘快照的可恢复冷方法在数据保护方案之间的一些差异。如需了解详情,请参阅使用永久性磁盘的高可用性选项

区域永久性磁盘 永久性磁盘快照
数据丢失 - 恢复点目标 (RPO) 单个故障(例如在可用区或网络中断中连续中断)为零。 自上次截取快照以来的所有数据(通常为一小时或更长时间)。

数据丢失的可能性取决于您控制快照截取频率的快照时间表。
目标恢复时间 (RTO) 新虚拟机的部署时间,以及重新挂接区域永久性磁盘的秒数。 新虚拟机的部署时间,以及根据最新快照创建新永久性磁盘的时间。

磁盘的创建时间取决于快照的大小,并且可能需要几分钟或几小时。
费用 由于区域永久性磁盘不断复制到另一个地区,因此存储费用会翻倍。 您只需为使用的快照空间付费。
如需了解详情,请参阅磁盘和映像价格

目标

  • 创建代管式实例组以运行具有区域永久性磁盘的虚拟机。
  • 创建实例模板和启动脚本。
  • 创建和配置外部 HTTP(S) 负载均衡。
  • 使用替换代管式实例组测试网络服务器冷故障切换。

费用

本教程使用 Google Cloud 的以下收费组件:

您可使用价格计算器根据您的预计使用量来估算费用。 Google Cloud 新用户可能有资格申请免费试用

准备工作

  1. 登录您的 Google Cloud 帐号。如果您是 Google Cloud 新手,请创建一个帐号来评估我们的产品在实际场景中的表现。新客户还可获享 $300 赠金,用于运行、测试和部署工作负载。
  2. 在 Google Cloud Console 的项目选择器页面上,选择或创建一个 Google Cloud 项目。

    转到“项目选择器”

  3. 确保您的 Cloud 项目已启用结算功能。 了解如何确认您的项目是否已启用结算功能

  4. 启用 Compute Engine API。

    启用 API

  5. 安装并初始化 Cloud SDK
  6. 您可以在 Cloud Console 中运行 gcloud 命令行工具,无需安装 Cloud SDK。如需在 Cloud Console 中运行 gcloud 工具,请使用 Cloud Shell。

准备环境

在本部分中,您将为资源名称和位置定义一些变量。在您部署资源时,gcloud 命令行工具命令会使用这些变量。

在本教程中,除非另有说明,否则您在 Cloud Shell 或本地开发环境中输入所有命令。

  1. 请将 PROJECT_ID 替换为您自己的项目 ID。如果需要,请为资源提供自己的名称后缀,例如 app

    指定区域(例如 us-central1),指定区域内的两个可用区(例如 us-central1-aus-central1-f)。这些可用区定义区域永久性磁盘和初始代管式实例组组的部署位置,以及您可以根据需要手动故障转移到的位置。

    PROJECT_ID=PROJECT_ID
    NAME_SUFFIX=app
    REGION=us-central1
    ZONE1=us-central1-a
    ZONE2=us-central1-f
    

创建 VPC 和子网

如需为虚拟机提供网络访问权限,请创建 Virtual Private Cloud (VPC) 和子网。由于代管式实例组可在单个区域内的多个地区工作,因此只创建一个子网。 如需详细了解自定义子网模式的优势来管理环境中使用的 IP 地址范围,请参阅使用自定义模式 VPC 网络

  1. 使用自定义子网模式创建 VPC:

    gcloud compute networks create network-$NAME_SUFFIX \
        --subnet-mode=custom
    

    如果您看到 Cloud Shell 提示符,请授权第一个请求以进行 API 调用。

  2. 在新 VPC 中创建一个子网。定义您自己的地址范围使其适合您的网络范围,例如 10.1.0.0/20

    gcloud compute networks subnets create subnet-$NAME_SUFFIX-$REGION \
        --network=network-$NAME_SUFFIX \
        --range=10.1.0.0/20 \
        --region=$REGION
    

创建防火墙规则

  1. 创建防火墙规则,以允许针对负载均衡器和代管式实例组的网络流量和健康检查:

    gcloud compute firewall-rules create allow-http-$NAME_SUFFIX \
        --network=network-$NAME_SUFFIX \
        --direction=INGRESS \
        --priority=1000 \
        --action=ALLOW \
        --rules=tcp:80 \
        --source-ranges=0.0.0.0/0 \
        --target-tags=http-server
    
    gcloud compute firewall-rules create allow-health-check-$NAME_SUFFIX \
        --network=network-$NAME_SUFFIX \
        --action=allow \
        --direction=ingress \
        --source-ranges=130.211.0.0/22,35.191.0.0/16 \
        --target-tags=allow-health-check \
        --rules=tcp:80
    

    HTTP 规则允许发送到任何应用 http-server 标记的虚拟机的流量,并允许来自任何使用 0.0.0.0/0 范围的来源的流量。对于健康检查规则,Google Cloud 的默认范围需设置为允许平台正确检查资源的运行状况。

  2. 如需允许基本虚拟机映像对 SSH 流量进行初始配置,请使用 --source-range 参数将防火墙规则范围限定到您的环境。您可能需要与网络团队合作,以确定您的组织使用的来源范围。

    IP_ADDRESS_SCOPE 替换为您自己的 IP 地址范围:

    gcloud compute firewall-rules create allow-ssh-$NAME_SUFFIX \
        --network=network-$NAME_SUFFIX \
        --direction=INGRESS \
        --priority=1000 \
        --action=ALLOW \
        --rules=tcp:22 \
        --source-ranges=IP_ADDRESS_SCOPE
    
  3. 创建防火墙规则后,请验证是否添加了这三条规则:

    gcloud compute firewall-rules list \
        --project=$PROJECT_ID \
        --filter="NETWORK=network-$NAME_SUFFIX"
    

    以下示例输出显示了已正确创建三个规则:

    NAME                    NETWORK      DIRECTION  PRIORITY  ALLOW
    allow-health-check-app  network-app  INGRESS    1000      tcp:80
    allow-http-app          network-app  INGRESS    1000      tcp:80
    allow-ssh-app           network-app  INGRESS    1000      tcp:22
    

创建区域永久性磁盘和虚拟机

区域永久性磁盘可在同一区域中的两个可用区之间连续复制数据。然后,在与区域永久性磁盘相同的两个可用区中运行的代管式实例组可以将磁盘挂接到虚拟机。

  1. 创建一个 10 GiB 的 SSD。了解您的存储空间需求以及预配空间的相关费用,而不是消耗空间的相关费用。如需了解详情,请参阅永久性磁盘价格

    gcloud compute disks create disk-$NAME_SUFFIX \
        --region $REGION \
        --replica-zones $ZONE1,$ZONE2 \
        --size=10 \
        --type=pd-ssd
    
  2. 创建挂接了地区永久性磁盘的基本虚拟机:

    gcloud compute instances create vm-base-$NAME_SUFFIX \
        --zone=$ZONE1 \
        --machine-type=n1-standard-1 \
        --subnet=subnet-$NAME_SUFFIX-$REGION \
        --tags=http-server \
        --image=debian-10-buster-v20210721 \
        --image-project=debian-cloud \
        --boot-disk-size=10GB \
        --boot-disk-type=pd-balanced \
        --boot-disk-device-name=vm-base-$NAME_SUFFIX \
        --disk=mode=rw,name=disk-$NAME_SUFFIX,device-name=disk-$NAME_SUFFIX,scope=regional
    

    您可以使用本文档开头定义的参数来命名虚拟机并连接到正确的子网。名称还会从启动磁盘的数据参数和数据磁盘的参数进行分配。

  3. 如需安装和配置简单网站,请首先使用 SSH 连接到基本虚拟机:

    gcloud compute ssh vm-base-$NAME_SUFFIX --zone=$ZONE1
    
  4. 在与虚拟机的 SSH 会话中,创建一个脚本以在您选择的编辑器中配置虚拟机。以下示例使用 Nano 作为编辑器:

    nano configure-vm.sh
    

    将以下配置脚本粘贴到此文件中。更新 NAME_SUFFIX 变量以匹配本文档开头设置的值,例如 app

    #!/bin/bash
    
    NAME_SUFFIX=app
    
    # Create directory for the basic website files
    sudo mkdir -p /var/www/example.com
    sudo chmod a+w /var/www/example.com
    sudo chown -R www-data: /var/www/example.com
    
    # Find the disk name, then format and mount it
    DISK_NAME="google-disk-$NAME_SUFFIX"
    DISK_PATH="$(find /dev/disk/by-id -name "${DISK_NAME}" | xargs -I '{}' readlink -f '{}')"
    
    sudo mkfs.ext4 -m 0 -E lazy_itable_init=0,lazy_journal_init=0,discard $DISK_PATH
    sudo mount -o discard,defaults $DISK_PATH /var/www/example.com
    
    # Install Apache
    sudo apt-get update && sudo apt-get -y install apache2
    
    # Write out a basic HTML file to the mounted persistent disk
    sudo tee -a /var/www/example.com/index.html >/dev/null <<'EOF'
    <!doctype html>
    <html lang=en>
    <head>
    <meta charset=utf-8>
        <title>HA / DR example</title>
    </head>
    <body>
        <p>Welcome to a test web server with regional persistent disks!</p>
    </body>
    </html>
    EOF
    
    # Write out an Apache configuration file
    sudo tee -a /etc/apache2/sites-available/example.com.conf >/dev/null <<'EOF'
    <VirtualHost *:80>
            ServerName www.example.com
    
            ServerAdmin webmaster@localhost
            DocumentRoot /var/www/example.com
    
            ErrorLog ${APACHE_LOG_DIR}/error.log
            CustomLog ${APACHE_LOG_DIR}/access.log combined
    </VirtualHost>
    EOF
    
    # Enable the Apache configuration file and reload service
    sudo a2dissite 000-default
    sudo a2ensite example.com.conf
    sudo systemctl reload apache2
    
  5. 写出该文件并退出编辑器。例如,在 Nano 中,您可以使用 Ctrl-O 写出该文件,然后使用 Ctrl-X 退出。

  6. 将配置脚本设为可执行,然后运行它:

    chmod +x configure-vm.sh
    ./configure-vm.sh
    
  7. 退出与虚拟机的 SSH 会话:

    exit
    
  8. 获取虚拟机的 IP 地址,并使用 curl 查看基本网页:

    curl $(gcloud compute instances describe vm-base-$NAME_SUFFIX \
        --zone $ZONE1 \
        --format="value(networkInterfaces.accessConfigs.[0].natIP)")
    

    系统会返回基本网站,如以下示例输出所示:

    <!doctype html>
    <html lang=en>
    <head>
    <meta charset=utf-8>
        <title>HA / DR example</title>
    </head>
    <body>
        <p>Welcome to a test web server with regional persistent disks!</p>
    </body>
    </html>
    

    此步骤确认 Apache 已正确配置,并且已从挂接的区域永久性磁盘加载页面。在下面的部分中,您将使用此基本虚拟机创建映像,并使用启动脚本配置实例模板。

创建虚拟机映像和实例模板

若要创建无需额外配置即可自动部署的相同虚拟机,请使用自定义虚拟机映像。此映像会捕获操作系统和 Apache 配置。在后续步骤中,在代管式实例组中创建的每个虚拟机都会使用此映像。

  1. 您必须先停止虚拟机,然后才能创建映像:

    gcloud compute instances stop vm-base-$NAME_SUFFIX --zone=$ZONE1
    
  2. 创建上一部分中配置的基本虚拟机的映像:

    gcloud compute images create image-$NAME_SUFFIX \
        --source-disk=vm-base-$NAME_SUFFIX \
        --source-disk-zone=$ZONE1 \
        --storage-location=$REGION
    
  3. 创建一个实例模板,以定义每个虚拟机的配置:

    gcloud compute instance-templates create template-$NAME_SUFFIX \
        --machine-type=n1-standard-1 \
        --subnet=projects/$PROJECT_ID/regions/$REGION/subnetworks/subnet-$NAME_SUFFIX-$REGION \
        --tags=http-server \
        --image=image-$NAME_SUFFIX \
        --region=$REGION \
        --metadata=^,@^startup-script=\!\#\ /bin/bash$'\n'echo\ UUID=\`blkid\ -s\ UUID\ -o\ value\ /dev/sdb\`\ /var/www/example.com\ ext4\ discard,defaults,nofail\ 0\ 2\ \|\ tee\ -a\ /etc/fstab$'\n'mount\ -a
    

    上一步中创建的映像定义为每个虚拟机的来源,并且还定义了装载区域永久性磁盘的启动脚本。

创建托管实例组

代管式实例组会运行这些虚拟机。代管式实例组在定义的可用区中运行,并监控虚拟机的运行状况。如果发生实例故障,并且虚拟机停止运行,则代管式实例组会尝试在同一可用区重新创建另一个虚拟机,并挂接区域永久性磁盘。如果故障发生在可用区级别,则您必须手动执行冷故障切换,并在其他可用区中另外创建一个代管式实例组。相同的自定义映像和实例模板会自动以相同的方式配置虚拟机。

  1. 创建一个运行状况检查以监控代管式实例组中的虚拟机。此运行状况检查可确保虚拟机在端口 80 上响应。对于您自己的应用,监控相应端口以检查虚拟机运行状况。

    gcloud compute health-checks create http http-basic-check-$NAME_SUFFIX --port 80
    
  2. 创建一个使用上一步中创建的实例模板的代管式实例组,该实例组最初没有虚拟机。

    gcloud compute instance-groups managed create instance-group-$NAME_SUFFIX-$ZONE1 \
        --base-instance-name=instance-vm-$NAME_SUFFIX \
        --template=template-$NAME_SUFFIX \
        --size=0 \
        --zone=$ZONE1 \
        --health-check=http-basic-check-$NAME_SUFFIX
    
  3. 在该代管式实例组中创建一个虚拟机,并挂接区域永久性磁盘。如果此虚拟机发生故障,则代管式实例组会尝试在同一可用区中重新创建此磁盘,然后重新挂接永久性磁盘。

    gcloud compute instance-groups managed create-instance instance-group-$NAME_SUFFIX-$ZONE1 \
        --instance instance-vm-$NAME_SUFFIX \
        --zone=$ZONE1\
        --stateful-disk device-name=disk-$NAME_SUFFIX,source=projects/$PROJECT_ID/regions/$REGION/disks/disk-$NAME_SUFFIX
    

对于这种冷可恢复的应用场景,请勿创建自动扩缩规则来增加代管式实例组中运行的虚拟机的数量。

创建和配置负载平衡器

为了让用户能够访问您的网站,您需要允许流量流向代管式实例组中运行的虚拟机。如果代管式实例组中有可用区故障,您还需要将流量自动重定向到新虚拟机。

在下面的部分中,您将创建外部负载均衡器和后端服务,以获取端口 80 上的 HTTP 流量,使用在前面步骤中创建的健康检查,并将外部 IP 地址映射到后端服务。

如需了解详情,请参阅如何设置简单的外部 HTTP 负载均衡器

  1. 为您的应用创建和配置负载平衡器:

    # Configure port rules for HTTP port 80
    gcloud compute instance-groups set-named-ports \
        instance-group-$NAME_SUFFIX-$ZONE1 \
        --named-ports http:80 \
        --zone $ZONE1
    
    # Create a backend service and add the managed instance group to it
    gcloud compute backend-services create \
        web-backend-service-$NAME_SUFFIX \
        --protocol=HTTP \
        --port-name=http \
        --health-checks=http-basic-check-$NAME_SUFFIX \
        --global
    
    gcloud compute backend-services add-backend \
        web-backend-service-$NAME_SUFFIX \
        --instance-group=instance-group-$NAME_SUFFIX-$ZONE1 \
        --instance-group-zone=$ZONE1 \
        --global
    
    # Create a URL map for the backend service
    gcloud compute url-maps create web-map-http-$NAME_SUFFIX \
        --default-service web-backend-service-$NAME_SUFFIX
    
    # Configure forwarding for the HTTP traffic
    gcloud compute target-http-proxies create \
        http-lb-proxy-$NAME_SUFFIX \
        --url-map web-map-http-$NAME_SUFFIX
    
    gcloud compute forwarding-rules create \
        http-content-rule-$NAME_SUFFIX \
        --global \
        --target-http-proxy=http-lb-proxy-$NAME_SUFFIX \
        --ports=80
    
  2. 获取 Web 流量的转发规则的 IP 地址:

    IP_ADDRESS=$(gcloud compute forwarding-rules describe http-content-rule-$NAME_SUFFIX \
        --global \
        --format="value(IPAddress)")
    
  3. 使用 curl 或打开网络浏览器,以使用上一步中的负载均衡器的 IP 地址查看网站:

    curl $IP_ADDRESS
    

    负载均衡器完成部署并将流量正确定向到您的后端需要几分钟时间。如果负载均衡器仍在部署,则会返回 HTTP 404 或 502 错误。如需要,请等待几分钟,再尝试访问网站。

    系统会返回基本网站,如以下示例输出所示:

    <!doctype html>
    
    <html lang=en>
    <head>
    <meta charset=utf-8>
        <title>HA / DR example</title>
    </head>
    <body>
        <p>Welcome to a test web server with regional persistent disks!</p>
    </body>
    </html>
    

模拟可用区故障和恢复

让我们先查看资源部署,然后再在可用区级别模拟故障。所有资源均已创建用于支持环境,如下图所示:

外部 HTTP(S) 负载均衡会将用户定向到在代管式实例组中运行的单个虚拟机,并且区域永久性磁盘会挂接到该虚拟机。

  • 一个在代管式实例组中运行的虚拟机,其中挂接了一个区域永久性磁盘,用于存储基本网站。
  • 启动脚本会应用于实例模板,因此在代管式实例组中创建的任何虚拟机都会装载区域永久性磁盘。
  • 运行状况检查会监控代管式实例组内虚拟机的状态。
  • 外部 HTTP(S) 负载均衡会将用户定向到在托管实例组中运行的虚拟机。
  • 如果虚拟机发生故障,则代管式实例组会尝试在同一可用区重新创建虚拟机。如果故障发生在可用区级别,您必须在另一个工作可用区手动创建替换代管实例组。

在生产环境中,您可能会在出现问题时使用 Cloud Monitoring 或其他监控解决方案收到提醒。此提醒会提示您人工了解故障的范围,然后再在另一个有效可用区中手动创建替换托管实例组。另一种方法是使用监控解决方案自动响应代管式实例组发生的服务中断。

当您或监控解决方案确定最合适的操作是故障切换时,请创建一个替换代管式实例组。在本文档中,您将手动创建此替换资源。

  1. 如需模拟可用区级别的故障,请删除负载均衡器后端和代管式实例组:

    gcloud compute backend-services remove-backend \
        web-backend-service-$NAME_SUFFIX \
        --instance-group=instance-group-$NAME_SUFFIX-$ZONE1 \
        --instance-group-zone=$ZONE1 \
        --global
    
    gcloud compute instance-groups managed delete instance-group-$NAME_SUFFIX-$ZONE1 \
          --zone=$ZONE1
    

    出现提示时,确认删除代管式实例组的请求。

    在生产环境中,您的监控系统会生成提醒,立即提示冷故障切换操作。

  2. 使用 curl 或网络浏览器再次访问负载均衡器的 IP 地址:

    curl $IP_ADDRESS --max-time 5
    

    curl 请求失败,因为负载均衡器没有运行状况良好的目标。

  3. 如需模拟冷故障切换,请在其他可用区创建一个代管式实例组:

    gcloud compute instance-groups managed create instance-group-$NAME_SUFFIX-$ZONE2 \
        --base-instance-name=instance-vm-$NAME_SUFFIX \
        --template=template-$NAME_SUFFIX \
        --size=0 \
        --zone=$ZONE2 \
        --health-check=http-basic-check-$NAME_SUFFIX
    
    gcloud compute instance-groups managed create-instance instance-group-$NAME_SUFFIX-$ZONE2 \
        --instance instance-vm-$NAME_SUFFIX \
        --zone=$ZONE2 \
        --stateful-disk device-name=disk-$NAME_SUFFIX,source=projects/$PROJECT_ID/regions/$REGION/disks/disk-$NAME_SUFFIX
    

    虚拟机映像、实例模板和区域永久性磁盘会保留应用实例的所有配置。

  4. 更新负载均衡器以添加新的代管式实例组和虚拟机:

    gcloud compute instance-groups set-named-ports \
        instance-group-$NAME_SUFFIX-$ZONE2 \
        --named-ports http:80 \
        --zone $ZONE2
    
    gcloud compute backend-services add-backend \
        web-backend-service-$NAME_SUFFIX \
        --instance-group=instance-group-$NAME_SUFFIX-$ZONE2 \
        --instance-group-zone=$ZONE2 \
        --global
    
  5. 再次使用 curl 或网络浏览器访问负载均衡器的 IP 地址,该负载均衡器会将流量定向到代管式实例组中运行的虚拟机:

    curl $IP_ADDRESS
    

    虚拟机完成部署并挂接地区永久性磁盘需要几分钟的时间。如需要,请等待几分钟,再尝试访问网站。

    以下示例响应显示了在虚拟机上正常运行的网页:

    <!doctype html>
    <html lang=en>
    <head>
    <meta charset=utf-8>
        <title>HA / DR example</title>
    </head>
    <body>
        <p>Welcome to a test web server with regional persistent disks!</p>
    </body>
    </html>
    

清除数据

为避免因本教程中使用的资源导致您的 Google Cloud 帐号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。

要删除本文档中创建的各资源,请完成以下步骤。

  1. 删除负载平衡器配置:

    gcloud compute forwarding-rules delete \
        http-content-rule-$NAME_SUFFIX --global --quiet
    
    gcloud compute target-http-proxies delete \
        http-lb-proxy-$NAME_SUFFIX --quiet
    
    gcloud compute url-maps delete web-map-http-$NAME_SUFFIX --quiet
    
    gcloud compute backend-services delete \
        web-backend-service-$NAME_SUFFIX --global --quiet
    
  2. 删除代管式实例组和运行状况检查:

    gcloud compute instance-groups managed delete instance-group-$NAME_SUFFIX-$ZONE2 \
        --zone=$ZONE2 --quiet
    
    gcloud compute health-checks delete http-basic-check-$NAME_SUFFIX --quiet
    
  3. 删除实例模板、映像、基本虚拟机和永久性磁盘:

    gcloud compute instance-templates delete template-$NAME_SUFFIX --quiet
    
    gcloud compute images delete image-$NAME_SUFFIX --quiet
    
    gcloud compute instances delete vm-base-$NAME_SUFFIX --zone=$ZONE1 --quiet
    
    gcloud compute disks delete disk-$NAME_SUFFIX --region=$REGION --quiet
    
  4. 删除防火墙规则:

    gcloud compute firewall-rules delete allow-health-check-$NAME_SUFFIX --quiet
    
    gcloud compute firewall-rules delete allow-ssh-$NAME_SUFFIX --quiet
    
    gcloud compute firewall-rules delete allow-http-$NAME_SUFFIX --quiet
    
  5. 删除静态外部 IP 地址、子网和 VPC:

    gcloud compute networks subnets delete \
        subnet-$NAME_SUFFIX-$REGION --region=$REGION --quiet
    
    gcloud compute networks delete network-$NAME_SUFFIX --quiet
    

后续步骤