使用GCE和GCS部署可热恢复的Web服务器
温馨提示:这篇文章已超过578天没有更新,请注意相关的内容是否还可用!
负载均衡器将流量定向到为内容提供服务的托管实例组中的 Compute Engine 实例。如果发生服务中断,您需要更新外部 HTTP 负载平衡配置并将故障转移到 Cloud Storage 中的静态站点。在生产部署中,您的网站在托管实例组虚拟机 上包含的文件和附加应用程序代码可能比本文档中显示的更多。使用 Cloud Storage 的静态网站比运行另一组托管实例的成本更低,但在托管选项之间更新负载均衡器配置时会有短暂的延迟。Cloud Storage 中有限的网站体验比网站不可用和糟糕的客户体验要好。目标 准备工作 安装并初始化 Cloud SDK。gcloud 命令行工具命令在您部署资源时使用这些变量。此可用区定义用于为托管实例组创建映像的初始基础虚拟机的创建位置。
介绍
负载均衡器将流量定向到为内容提供服务的托管实例组中的 Compute Engine 实例。 如果发生服务中断,您需要更新外部 HTTP(S) 负载平衡配置并将故障转移到 Cloud Storage 中的静态站点。
在生产部署中,您的网站在托管实例组虚拟机 (VM) 上包含的文件和附加应用程序代码可能比本文档中显示的更多。 然后,Cloud Storage 托管一个功能更有限的静态版本,该版本提供的功能最少。 在热故障转移场景中,用户只能看到这个受限制的网站,直到托管实例组恢复并可以为完整的网站体验提供流量。
在本教程中,您将部署资源以创建环境,如下图所示:
如果需要故障转移,请更新负载均衡器配置以将流量定向到 Cloud Storage,如下图所示:
这种热故障转移模式平衡了在另一个区域中运行另一个托管实例组的成本,只有在主要区域发生故障时才使用这种模式。 使用 Cloud Storage 的静态网站比运行另一组托管实例的成本更低,但在托管选项之间更新负载均衡器配置时会有短暂的延迟。 Cloud Storage 中有限的网站体验比网站不可用和糟糕的客户体验要好。
目标 准备工作 安装并初始化 Cloud SDK。 您将为资源名称和位置定义一些变量。 gcloud 命令行工具命令在您部署资源时使用这些变量。 请将 PROJECT_ID 替换为您自己的项目 ID。 如果需要,您可以为资源提供自己的名称后缀,以帮助搜索和识别这些资源,例如应用程序。
指定两个区域(例如 us-west1 和 us-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 和子网
要提供对虚拟机的网络访问,请创建虚拟私有云 (VPC) 和子网。 当您需要两个区域中的托管实例组时,您可以在每个区域中创建一个子网。
创建具有自定义子网模式的 VPC:
gcloud compute networks create network-$NAME_SUFFIX --subnet-mode=custom
现在在新 VPC 中创建两个子网,每个区域一个。 定义适合您网络范围的地址范围(例如 10.1.0.0/20 和 10.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 内的网络流量,您可以使用防火墙规则。
创建防火墙规则以允许对负载均衡器和托管实例组进行网络流量和健康检查:
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 范围的任何源的流量。 对于健康检查规则,需要设置谷歌云的默认范围,让平台能够正确检查资源的健康状况。
要允许基本虚拟机映像初始配置 SSH 流量,请使用 --source-range 参数将防火墙规则的范围限定到您的环境。 您可能需要与您的网络团队合作来确定您的组织使用的资源范围。
! 重要提示:我们不建议使用允许所有流量的广泛 0.0.0.0/0 范围。 要将流量限制到单个 IP 地址,请使用 /32 网络掩码,例如 35.230.62.163/32。
将 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=35.230.62.163/32
创建防火墙规则后,验证是否添加了这三个规则:
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 配置虚拟机配置web服务器,并在后续步骤中用于在托管实例组中创建每个虚拟机。
在虚拟机上,在永久磁盘上创建一个基本的 index.html 文件并将其挂载到 /var/www/example.com。 位于 /etc/apache2/sites-available/example.com.conf 的 Apache 配置文件从挂载的永久磁盘位置提供 Web 内容。
下图显示了存储在永久磁盘上的 Apache 提供的基本 HTML 页面。
您可以按照以下步骤构建此环境。
创建一个附加了永久磁盘的基本虚拟机:
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
您可以使用本文档开头定义的参数来命名虚拟机并连接到正确的子网。 名称也是根据引导磁盘的数据参数和数据磁盘的参数分配的。
要安装和配置一个简单的网站,请使用 SSH 连接到基本虚拟机:
gcloud compute ssh vm-base-$NAME_SUFFIX --zone=$ZONE
在与虚拟机的 SSH 会话中,创建脚本以在您选择的编辑器中配置虚拟机。 下面的例子使用 Vim 作为编辑器:
vim 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'
HA / DR example
Welcome to a Compute Engine website with warm failover to Cloud Storage!
EOF
# Write out an Apache configuration file
sudo tee -a /etc/apache2/sites-available/example.com.conf >/dev/null <<'EOF'
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
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.
保存文件并退出编辑器。 使配置脚本可执行,然后运行它:
chmod +x configure-vm.sh
./configure-vm.sh
退出与虚拟机的 SSH 会话:
exit
获取虚拟机的IP地址,使用curl查看基本网页:
curl $(gcloud compute instances describe vm-base-$NAME_SUFFIX \
--zone $ZONE \
--format="value(networkInterfaces.accessConfigs.[0].natIP)")
返回基本网站,如以下示例输出所示:
HA / DR example
Welcome to a Compute Engine website with warm failover to Cloud Storage!
此步骤确认 Apache 配置正确并且页面从附加的永久性磁盘加载。 在以下部分中,您将使用此基础虚拟机创建映像并使用启动脚本配置实例模板。
部署 Compute Engine 资源
热故障转移模式使用托管实例组运行虚拟机。 托管实例组在两个区域中运行,每个组监控虚拟机的健康状况。 如果发生服务中断并且其中一个虚拟机出现故障,则托管实例组会重新创建该虚拟机。 此配置创建了一个高度可用的应用程序,即使没有热故障转移到 Cloud Storage 中的静态网站也是如此。
您必须在创建映像之前停止虚拟机:
gcloud compute instances stop vm-base-$NAME_SUFFIX --zone=$ZONE
运行以下一组命令来创建虚拟机映像、实例模板和托管实例组:
# 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#39;\n'echo\ UUID=\`blkid\ -s\ UUID\ -o\ value\ /dev/sdb\`\ /var/www/example.com\ ext4\ discard,defaults,nofail\ 0\ 2\ \|\ tee\ -a\ /etc/fstab#39;\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#39;\n'echo\ UUID=\`blkid\ -s\ UUID\ -o\ value\ /dev/sdb\`\ /var/www/example.com\ ext4\ discard,defaults,nofail\ 0\ 2\ \|\ tee\ -a\ /etc/fstab#39;\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
创建和配置负载均衡器
为了让用户访问您的网站,您需要允许流量流向在您的托管实例组中运行的虚拟机。 如果托管实例组出现区域性故障,您还需要自动将流量重定向到新的 VM。
在以下部分中,您将为端口 80 上的 HTTP 流量创建外部负载均衡器和后端服务,使用在前面的步骤中创建的运行状况检查,并将外部 IP 地址映射到后端服务。
为您的应用程序创建和配置负载均衡器:
# 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
获取网络流量转发规则的IP地址:
IP_ADDRESS=$(gcloud compute forwarding-rules describe http-content-rule-$NAME_SUFFIX \
--global \
--format="value(IPAddress)")
使用 curl 或打开 Web 浏览器,使用上一步中负载均衡器的 IP 地址查看网站:
curl $IP_ADDRESS
负载均衡器需要几分钟才能部署并将流量正确定向到您的后端。 如果负载平衡器仍处于部署状态,则会返回 HTTP 404 错误。 如有必要,请等待几分钟再尝试访问该网站。
返回基本网站,如以下示例输出所示:
HA / DR example
Welcome to a Compute Engine website with warm failover to Cloud Storage!
创建和配置存储桶
云存储用于存储静态网站文件。 在这个基本示例中,您将创建一个文本与虚拟机略有不同的文件。
在生产部署中,您的网站在托管实例组 VM 上包含的文件和附加应用程序代码可能比本文档中显示的更多。 但是,托管在 Cloud Storage 中的静态版本通常是提供最少功能的更受限制的版本。 在热故障转移场景中,这将显示 Cloud Storage 的有限网站,直到托管实例组恢复并可以提供完整网站体验的流量。
验证您要用于 Cloud Storage 存储桶的域。 创建一个 Cloud Storage 存储桶以匹配您拥有并想要使用的域名:
gsutil mb gs://static-web.$DOMAIN
使用本文档开头定义的 DOMAIN 变量,例如 example.com。 此示例将静态文件存储在 static-web.example.com 中。
创建您在下一步中复制到 Cloud Storage 存储桶的本地文件:
cat < index.html
HA / DR example
Welcome to a test static web server with warm failover from Cloud Storage!
EOF
将基本 HTML 文件上传到 Cloud Storage 存储桶:
gsutil cp index.html gs://static-web.$DOMAIN
要允许用户查看静态 Web 内容,请在 Cloud Storage 存储桶上设置适当的权限:
gsutil iam ch allUsers:objectViewer gs://static-web.$DOMAIN
配置 Cloud Storage 存储桶以使用 index.html 文件作为默认网页:
gsutil web set -m index.html gs://static-web.$DOMAIN
将 Cloud Storage 存储桶添加到负载平衡器
创建 Cloud Storage 存储桶并将其配置为托管静态 Web 内容后,您的负载均衡器需要信息来将流量定向到它。
在创建和配置负载均衡器中,您为托管实例组创建了后端服务。 后端服务有 URL 映射,HTTP 目标代理帮助通过负载均衡器将用户定向到虚拟机。
要将流量定向到 Cloud Storage 存储桶,请使用存储桶的新后端和 URL 映射配置负载平衡器。 如果需要故障转移,请更新负载平衡器以使用此配置。
为 Cloud Storage 存储桶添加后端:
gcloud compute backend-buckets create \
web-bucket-$NAME_SUFFIX \
--gcs-bucket-name=static-web.$DOMAIN
创建允许流量到后端的 URL 映射:
gcloud compute url-maps create \
web-map-http-bucket-$NAME_SUFFIX \
--default-backend-bucket=web-bucket-$NAME_SUFFIX
在模拟区域故障之前虚拟机配置web服务器,请查看资源部署。 支持环境的所有资源的创建如下图所示:
故障转移到 Cloud Storage 存储桶
在现实世界中,如果您的托管实例组出现问题,系统可能会提醒您使用 Cloud Monitoring 或其他监控解决方案。 此警报提示用户在更新负载均衡器以将流量重定向到 Cloud Storage 托管的静态网站之前了解故障的范围。 另一种方法是使用监控解决方案自动响应托管实例组的服务中断。