将 Cloud DNS 与 Compute Engine 和 Cloud Storage 搭配使用来部署可热恢复的 Web 服务器

Last reviewed 2021-06-28 UTC

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

在此架构中,Cloud DNS 会将流量定向到传送内容的代管式实例组中的 Compute Engine 实例。在服务中断时,您需要更新 Cloud DNS 区域并故障切换到 Cloud Storage 中的静态网站。

如需部署此解决方案,您需要一个由您控制并希望用于本文档的注册域名。

在生产部署中,您的网站在代管式实例组虚拟机 (VM) 上包含的文件和附加应用代码可能比本文档中显示的要多。然后,Cloud Storage 会托管一个较受限的静态版本,该版本提供最少的功能。在暖故障切换场景中,直到代管式实例组恢复并可以传送流量以实现完整的网站体验前,用户只能看到此受限网站。

架构

在本架构中,您将部署资源以创建环境,如下图所示:

Cloud DNS 将用户定向到外部负载均衡器后面的代管式实例组,并显示完整的网站体验。

如果需要进行故障切换,请更新 Cloud DNS 配置以将流量定向到 Cloud Storage,如下图所示:

Cloud DNS 现在将用户定向到 Cloud Storage 中托管的静态网站,并显示较受限的体验。

这种暖故障切换模式会平衡在其他区域运行另一个代管式实例组的费用,该区域仅在主区域发生故障时使用。使用 Cloud Storage 的静态网站的费用低于运行另一个代管式实例组的费用,但在更新托管选项之间的 Cloud DNS 时,会出现短暂的延迟。Cloud Storage 中的受限网站体验优于完全不可用的网站和糟糕的客户体验。

如需了解使用外部应用负载均衡器而不是 Cloud DNS 来控制故障切换的替代方法,请参阅使用 Compute Engine 和 Cloud Storage 部署可热恢复的 Web 服务器。如果您没有或不想使用 Cloud DNS,则此模式非常有用。

如需在 Google Cloud 中运行可靠的应用,我们建议您设计应用基础架构以处理服务中断。根据您的应用和业务需求,您可能需要冷故障切换、暖故障切换或热故障切换模式。如需详细了解如何为自己的应用确定最佳方法,请参阅灾难恢复规划指南

本文档使用的是基本 Apache Web 服务器,但基础架构部署的相同方法适用于您需要创建的其他应用环境。

目标

  • 使用自定义虚拟机映像创建区域级代管式实例组。
  • 创建 Cloud Storage 存储分区。
  • 创建和配置 Cloud DNS 区域。
  • 使用更新后的 Cloud DNS 记录测试 Web 服务器暖故障切换。
  • 使用更新后的 Cloud DNS 记录测试恢复和故障恢复。

费用

在本文档中,您将使用 Google Cloud 的以下收费组件:

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

须知事项

您的组织定义的安全限制条件可能会导致您无法完成以下步骤。如需了解相关问题排查信息,请参阅在受限的 Google Cloud 环境中开发应用

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

    转到“项目选择器”

  3. 确保您的 Google Cloud 项目已启用结算功能

  4. 启用 Compute Engine API。

    启用 API

  5. 安装 Google Cloud CLI。
  6. 如需初始化 gcloud CLI,请运行以下命令:

    gcloud init
  7. 在 Google Cloud Console 中的项目选择器页面上,选择或创建一个 Google Cloud 项目

    转到“项目选择器”

  8. 确保您的 Google Cloud 项目已启用结算功能

  9. 启用 Compute Engine API。

    启用 API

  10. 安装 Google Cloud CLI。
  11. 如需初始化 gcloud CLI,请运行以下命令:

    gcloud init
  12. 您可以在 Google Cloud 控制台中运行 Google Cloud CLI,而无需安装 Google Cloud CLI。如需在 Google Cloud 控制台中运行 gcloud CLI,请使用 Cloud Shell。

准备环境

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

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

  1. 请将 PROJECT_ID 替换为您自己的项目 ID。如果需要,您可以为资源提供自己的名称后缀,以帮助搜索和识别这些资源,例如 app

    指定两个区域(如 us-west1us-west2),以及其中一个区域中的可用区(如 us-west1-a)。此可用区定义用于创建初始基础虚拟机的位置,该虚拟机用于为代管式实例组创建映像。

    最后,设置用于静态网站的网域,例如 example.com

    PROJECT_ID=PROJECT_ID
    NAME_SUFFIX=app
    REGION1=us-west1
    REGION2=us-west2
    ZONE=us-west1-a
    DOMAIN=example.com
    

创建 VPC 和子网

如需提供对虚拟机的网络访问权限,请创建 Virtual Private Cloud (VPC) 和子网。您需要两个区域中的代管式实例组时,可以在每个区域中创建一个子网。如需详细了解自定义子网模式的优势来管理环境中使用的 IP 地址范围,请参阅使用自定义模式 VPC 网络

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

    gcloud compute networks create network-$NAME_SUFFIX --subnet-mode=custom
    
  2. 现在,在新 VPC 中创建两个子网,每个区域一个。自行定义适合您的网络范围的地址范围(例如 10.1.0.0/2010.2.0.0/20):

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

创建防火墙规则

如需在 VPC 中正确处理网络流量,您可以使用防火墙规则

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

    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
    

创建和配置基本虚拟机映像

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

在虚拟机上,在永久性磁盘上创建基本的 index.html 文件并将其装载到 /var/www/example.com。位于 /etc/apache2/sites-available/example.com.conf 的 Apache 配置文件从已装载的永久性磁盘位置提供网页内容。

下图展示了由永久性磁盘上存储的 Apache 提供的基本 HTML 页面。

该虚拟机在永久性磁盘上存储基本的 HTML 页面,以及从装载的磁盘位置加载的 Apache 配置文件

您可以按照以下步骤构建此环境。

  1. 创建挂接了永久性磁盘的基本虚拟机:

    gcloud compute instances create vm-base-$NAME_SUFFIX \
        --zone=$ZONE \
        --machine-type=n1-standard-1 \
        --subnet=subnet-$NAME_SUFFIX-$REGION1 \
        --tags=http-server \
        --image=debian-10-buster-v20210420 \
        --image-project=debian-cloud \
        --boot-disk-size=10GB \
        --boot-disk-type=pd-balanced \
        --boot-disk-device-name=vm-base-$NAME_SUFFIX \
        --create-disk=type=pd-ssd,name=disk-base-$NAME_SUFFIX,size=10GB,device-name=disk-base-$NAME_SUFFIX
    

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

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

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

    nano configure-vm.sh
    

    将以下配置脚本粘贴到该文件中:

    #!/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-base-$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 Compute Engine website with warm failover to Cloud Storage!</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
    

    更新 NAME_SUFFIX 变量以匹配本文档开头设置的值,例如 app

  4. 写出该文件并退出编辑器。例如,在 Nano 中,您可以使用 Ctrl-O 写出该文件,然后使用 Ctrl-X 退出。

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

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

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

    curl $(gcloud compute instances describe vm-base-$NAME_SUFFIX \
        --zone $ZONE \
        --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 Compute Engine website with warm failover to Cloud Storage!</p>
    </body>
    </html>
    

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

部署 Compute Engine 资源

暖故障切换模式使用代管式实例组运行虚拟机。代管式实例组在两个区域中运行,每组均监控虚拟机的运行状况。如果发生服务中断并且其中一个虚拟机发生故障,则代管式实例组会重新创建该虚拟机。此配置会创建高可用性应用,即使没有暖故障切换到 Cloud Storage 中的静态网站也是如此。

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

    gcloud compute instances stop vm-base-$NAME_SUFFIX --zone=$ZONE
    
  2. 运行下面一组命令来创建虚拟机映像、实例模板和代管式实例组:

    # Create the base VM images
    gcloud compute images create image-$NAME_SUFFIX \
        --source-disk=vm-base-$NAME_SUFFIX \
        --source-disk-zone=$ZONE
    
    gcloud compute images create image-disk-$NAME_SUFFIX \
        --source-disk=disk-base-$NAME_SUFFIX \
        --source-disk-zone=$ZONE
    
    # Create instance templates
    gcloud compute instance-templates create template-$NAME_SUFFIX-$REGION1 \
        --machine-type=n1-standard-1 \
        --subnet=projects/$PROJECT_ID/regions/$REGION1/subnetworks/subnet-$NAME_SUFFIX-$REGION1 \
        --region=$REGION1 \
        --tags=http-server \
        --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 \
        --image=image-$NAME_SUFFIX \
        --create-disk=image=image-disk-$NAME_SUFFIX,auto-delete=yes
    
    gcloud compute instance-templates create template-$NAME_SUFFIX-$REGION2 \
        --machine-type=n1-standard-1 \
        --subnet=projects/$PROJECT_ID/regions/$REGION2/subnetworks/subnet-$NAME_SUFFIX-$REGION2 \
        --region=$REGION2 \
        --tags=http-server \
        --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 \
        --image=image-$NAME_SUFFIX \
        --create-disk=image=image-disk-$NAME_SUFFIX,auto-delete=yes
    
    # Create a health check for VM instances
    gcloud compute health-checks create http http-basic-check-$NAME_SUFFIX \
        --port 80
    
    # Create the managed instance groups
    gcloud compute instance-groups managed create instance-group-$NAME_SUFFIX-$REGION1 \
        --template=template-$NAME_SUFFIX-$REGION1 \
        --size=2 \
        --region=$REGION1 \
        --health-check=http-basic-check-$NAME_SUFFIX
    
    gcloud compute instance-groups managed create instance-group-$NAME_SUFFIX-$REGION2 \
        --template=template-$NAME_SUFFIX-$REGION2 \
        --size=2 \
        --region=$REGION2 \
        --health-check=http-basic-check-$NAME_SUFFIX
    

创建和配置负载均衡器

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

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

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

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

    # Configure port rules for HTTP port 80
    gcloud compute instance-groups set-named-ports \
        instance-group-$NAME_SUFFIX-$REGION1 \
        --named-ports http:80 \
        --region $REGION1
    
    gcloud compute instance-groups set-named-ports \
        instance-group-$NAME_SUFFIX-$REGION2 \
        --named-ports http:80 \
        --region $REGION2
    
    # Create a backend service and add the managed instance groups 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-$REGION1 \
        --instance-group-region=$REGION1 \
        --global
    
    gcloud compute backend-services add-backend \
        web-backend-service-$NAME_SUFFIX \
        --instance-group=instance-group-$NAME_SUFFIX-$REGION2 \
        --instance-group-region=$REGION2 \
        --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 错误。如需要,请等待几分钟,再尝试访问网站。

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

    <!doctype html>
    
    <html lang=en>
    <head>
    <meta charset=utf-8>
        <title>HA / DR example</title>
    </head>
    <body>
        <p>Welcome to a Compute Engine website with warm failover to Cloud Storage!</p>
    </body>
    </html>
    

创建和配置存储桶

Cloud Storage 用于保存静态网站文件。在此基本示例中,您将创建一个文本与虚拟机上的文本略有不同的文件。

在生产部署中,您的网站在代管式实例组虚拟机上包含的文件和附加应用代码可能比本文档中显示的要多。然后,托管在 Cloud Storage 中的静态版本通常是一个较受限的版本,该版本提供最少的功能。在暖故障切换场景中,直到代管式实例组恢复并可以传送流量以实现完整的网站体验前,系统只会显示 Cloud Storage 中的此受限版本。

  1. 验证您要用于 Cloud Storage 存储桶的网域

  2. 创建一个 Cloud Storage 存储桶,以匹配您拥有且要使用的网域名称:

    gsutil mb gs://static-web.$DOMAIN
    

    使用本文档开头定义的 DOMAIN 变量,例如 example.com。此示例将静态文件存储在 static-web.example.com 中。

  3. 创建您在下一步中复制到 Cloud Storage 存储桶的本地文件:

    cat <<EOF > index.html
    <!doctype html>
    <html lang=en>
    <head>
    <meta charset=utf-8>
        <title>HA / DR example</title>
    </head>
    <body>
        <p>Welcome to a test static web server with warm failover from Cloud Storage!</p>
    </body>
    </html>
    EOF
    
  4. 将基本 HTML 文件上传到 Cloud Storage 存储桶:

    gsutil cp index.html gs://static-web.$DOMAIN
    
  5. 如需允许用户查看静态 Web 内容,请对 Cloud Storage 存储桶设置适当的权限:

    gsutil iam ch allUsers:objectViewer gs://static-web.$DOMAIN
    
  6. 配置 Cloud Storage 存储桶以传送 index.html 文件作为默认网页:

    gsutil web set -m index.html gs://static-web.$DOMAIN
    

创建 DNS 区域和记录

如需在代管式实例组发生服务中断时允许流量定向到 Cloud Storage 上的暖静态网站,请创建 Cloud DNS 区域。在正常情况下,此 DNS 区域会通过外部负载均衡器将流量定向到前面部分中创建的代管式实例组。

  1. 创建 Cloud DNS 区域:

    gcloud dns managed-zones create zone-$NAME_SUFFIX \
        --dns-name=$DOMAIN \
        --description="DNS zone for warm site failover"
    

    使用本文档开头定义的 DOMAIN 变量,例如 example.com

  2. 获取 Cloud DNS 区域的详细信息:

    gcloud dns managed-zones describe zone-$NAME_SUFFIX
    

    以下示例输出展示了相应区域的 nameServers,例如 ns-cloud-b1.googledomains.com

    [...]
    kind: dns#managedZone
    name: zone-app
    nameServers:
    - ns-cloud-b1.googledomains.com.
    - ns-cloud-b2.googledomains.com.
    - ns-cloud-b3.googledomains.com.
    - ns-cloud-b4.googledomains.com.
    
  3. Cloud DNS 必须对您的网域具有权威性。通过您指向 Cloud DNS 区域的域名注册商创建域名服务器 (NS) 记录。使用上一步中返回的域名服务器地址。

    如需了解详情并查看使用 Google Domains 的示例,请参阅如何更新域名服务器

  4. 在 Cloud DNS 区域中,使用上一部分中获取的负载均衡器 IP 地址为 www 添加记录:

    gcloud dns record-sets transaction start \
        --zone=zone-$NAME_SUFFIX
    
    gcloud dns record-sets transaction add $IP_ADDRESS \
        --name=www.$DOMAIN \
        --ttl=300 \
        --type=A \
        --zone=zone-$NAME_SUFFIX
    

    此记录会通过负载均衡器将用户对网站的请求定向到代管式实例组。将 TTL 设置为 300 秒会缩短已缓存的 DNS 记录针对用户存在的时长。

  5. 创建供静态网站的 Cloud Storage 存储桶使用的记录:

    gcloud dns record-sets transaction add c.storage.googleapis.com. \
        --name=static-web.$DOMAIN \
        --ttl=300 \
        --type=CNAME \
        --zone=zone-$NAME_SUFFIX
    

    此示例使用 static-web 作为子网域。再次保留 c.storage.googleapis.com.,将 TTL 设置为 300 秒会缩短已缓存的 DNS 记录针对用户存在的时长。

  6. 最后,将添加的 DNS 记录提交到相应区域:

    gcloud dns record-sets transaction execute \
        --zone=zone-$NAME_SUFFIX
    

验证并测试 DNS 区域和记录

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

Cloud DNS 将用户定向到外部负载均衡器后面的代管式实例组,并显示完整的网站体验。

  • Cloud DNS 区域记录将用户定向到负载均衡器,以便在代管式实例组虚拟机之间分布。
  • Cloud Storage 存储桶配置为在代管式实例组发生服务中断时托管静态网页。
  • Cloud DNS 区域配置为使用 Cloud Storage 中的静态网站,但目前无法解析对存储桶的请求。

如需查看 DNS 记录并测试解析,您必须根据 Cloud DNS 服务器解析地址。在生产部署中,请确保测试并验证地址是否正确解析,然后更新您自己的 DNS 服务器以适当地进行解析。本文档并未详细介绍更新您自己的 DNS 服务器的步骤,只介绍了如何验证在正常和故障切换条件下流量是否正确流动。

  1. 再次获取 Cloud DNS 区域的详细信息:

    gcloud dns managed-zones describe zone-$NAME_SUFFIX
    

    以下示例输出展示了相应区域的 nameServers,例如 ns-cloud-b1.googledomains.com

    [...]
    kind: dns#managedZone
    name: zone-app
    nameServers:
    - ns-cloud-b1.googledomains.com.
    - ns-cloud-b2.googledomains.com.
    - ns-cloud-b3.googledomains.com.
    - ns-cloud-b4.googledomains.com.
    
  2. 如需根据一个域名服务器解析 Cloud DNS 区域的 www 记录,请使用 dig 命令:

    dig @ns-cloud-b1.googledomains.com www.$DOMAIN
    

    此示例使用从上一个 describe 命令返回的 ns-cloud-b1.googledomains.com 域名服务器地址。提供上一命令的输出中显示的您自己的域名服务器地址

    以下示例输出显示记录解析为负载均衡器的 IP 地址。如果您使用此域名服务器访问地址(例如将 curl--resolve 参数用于 Cloud DNS 域名服务器),则系统将从负载均衡器后面的一个代管式实例组显示默认页面。

    ; <<>> DiG 9.11.5-P4-5.1+deb10u3-Debian <<>> @ns-cloud-b1.googledomains.com www.example.com
    ; (1 server found)
    
    [...]
    
    ;; QUESTION SECTION:
    ;www.example.com.           IN      A
    
    ;; ANSWER SECTION:
    www.example.com.    300     IN      A       35.227.253.90
    
  3. 再次使用 dig 命令验证 Cloud Storage 中静态网站的 DNS 记录:

    dig @ns-cloud-b1.googledomains.com static-web.$DOMAIN
    

    以下示例输出显示记录解析为 Cloud Storage,以便从存储桶传送静态内容:

    ; <<>> DiG 9.11.5-P4-5.1+deb10u3-Debian <<>> @ns-cloud-b1.googledomains.com static-web.example.com
    ; (1 server found)
    
    [...]
    
    ;; QUESTION SECTION:
    ;static-web.example.com.    IN      A
    
    ;; ANSWER SECTION:
    static-web.example.com. 300 IN      CNAME   c.storage.googleapis.com.
    

故障切换到 Cloud Storage 存储桶

在生产环境中,如果代管式实例组出现问题,您可以使用 Cloud Monitoring 或其他监控解决方案接收提醒。在更新 Cloud DNS 记录以将流量重定向到 Cloud Storage 托管的静态网站之前,此提醒会提示相关人员了解故障的范围。另一种方法是使用监控解决方案自动响应代管式实例组发生的服务中断。

故障切换时,Cloud DNS 会将流量解析为 Cloud Storage 托管的静态网站,如下图所示:

Cloud DNS 现在将用户定向到 Cloud Storage 中托管的静态网站,并显示较受限的体验。

当您或监控解决方案确定最合适的操作是更新 Cloud DNS 记录以将流量定向到 Cloud Storage 时,请更新现有 DNS A 记录。在本文档中,您将手动更新 Cloud DNS 记录以将流量重定向到 Cloud Storage 托管的静态网站。

  1. 如需对 Cloud DNS 记录进行故障切换,请移除解析为负载均衡器的现有 A 记录:

    gcloud dns record-sets transaction start \
        --zone=zone-$NAME_SUFFIX
    
    gcloud dns record-sets transaction remove $IP_ADDRESS \
        --name=www.$DOMAIN \
        --ttl=300 \
        --type=A \
        --zone=zone-$NAME_SUFFIX
    
  2. www 创建 CNAME 记录,指向 Cloud Storage 托管的内容:

    gcloud dns record-sets transaction add static-web.$DOMAIN \
        --name=www.$DOMAIN. \
        --ttl=30 \
        --type=CNAME \
        --zone=zone-$NAME_SUFFIX
    
  3. 将更新提交到 Cloud DNS 区域:

    gcloud dns record-sets transaction execute \
        --zone=zone-$NAME_SUFFIX
    
  4. 使用 dig 命令确认 www 记录现在是否解析为 Cloud Storage 静态网站的地址:

    dig @ns-cloud-b1.googledomains.com www.$DOMAIN
    

    以下示例输出显示 www.example.com 记录解析为 Cloud Storage 静态网站的 CNAME 记录。访问 www.example.com 的请求会重定向到 Cloud Storage 存储桶,该存储桶显示静态网站:

    ; <<>> DiG 9.11.5-P4-5.1+deb10u3-Debian <<>> @ns-cloud-b1.googledomains.com www.example.com
    ; (1 server found)
    
    [...]
    
    ;; QUESTION SECTION:
    ;www.example.com.           IN      A
    
    ;; ANSWER SECTION:
    www.example.com.    30      IN      CNAME   static-web.example.com.
    static-web.example.com. 300 IN      CNAME   c.storage.googleapis.com.
    

故障恢复至代管式实例组

代管式实例组存在的问题解决后,您可以通过再次更新 Cloud DNS 记录,故障恢复至从负载均衡的代管式实例组传送内容。同样,相关人员可使用 Cloud Monitoring 数据分析来了解代管式实例组的运行状况。或者,您可以使用自动化功能来响应代管式实例组的恢复运行状况。在本文档中,您将手动更新 Cloud DNS 记录。

故障恢复时,Cloud DNS 会再次将流量解析为代管式实例组,如下图所示:

Cloud DNS 再次将用户定向到外部负载均衡器后面的代管式实例组,并显示完整的网站体验。

  1. 移除将流量重定向到 Cloud Storage 托管的内容的 www CNAME 记录:

    gcloud dns record-sets transaction start \
        --zone=zone-$NAME_SUFFIX
    
    gcloud dns record-sets transaction remove static-web.$DOMAIN \
        --name=www.$DOMAIN \
        --ttl=30 \
        --type=CNAME \
        --zone=zone-$NAME_SUFFIX
    
  2. 添加 A 记录,以再次指向代管式实例组前面的负载均衡器:

    gcloud dns record-sets transaction add $IP_ADDRESS \
        --name=www.$DOMAIN \
        --ttl=300 \
        --type=A \
        --zone=zone-$NAME_SUFFIX
    
  3. 将更新提交到 Cloud DNS 区域:

    gcloud dns record-sets transaction execute \
        --zone=zone-$NAME_SUFFIX
    
  4. 再次使用 dig 命令确认 www 记录是否再次解析为代管式实例组前面的负载均衡器的地址:

    dig @ns-cloud-b1.googledomains.com www.$DOMAIN
    

    以下示例输出显示该记录解析为负载均衡器的 IP 地址,并且流量将从某个代管式实例组中传送。

    ; <<>> DiG 9.11.5-P4-5.1+deb10u3-Debian <<>> @ns-cloud-b1.googledomains.com www.example.com
    ; (1 server found)
    
    [...]
    
    ;; QUESTION SECTION:
    ;www.example.com.           IN      A
    
    ;; ANSWER SECTION:
    www.example.com.    300     IN      A       35.227.253.90
    

清除数据

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

如需删除本文档中创建的各个资源,请完成以下步骤:

  1. 删除 DNS 区域和记录:

    touch empty-file
    gcloud dns record-sets import -z zone-$NAME_SUFFIX \
        --delete-all-existing \
        empty-file
    rm empty-file
    
    gcloud dns managed-zones delete zone-$NAME_SUFFIX
    
  2. 删除 Cloud Storage 存储分区:

    gsutil rm -r gs://static-web.$DOMAIN
    
  3. 删除负载均衡器配置:

    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
    
  4. 删除代管式实例组和健康检查:

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

    gcloud compute instance-templates delete \
        template-$NAME_SUFFIX-$REGION1 --quiet
    
    gcloud compute instance-templates delete \
        template-$NAME_SUFFIX-$REGION2 --quiet
    
    gcloud compute images delete image-$NAME_SUFFIX --quiet
    
    gcloud compute images delete image-disk-$NAME_SUFFIX --quiet
    
    gcloud compute instances delete vm-base-$NAME_SUFFIX \
        --zone=$ZONE --quiet
    
  6. 删除防火墙规则。

    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
    
  7. 删除子网和 VPC。

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

后续步骤