本高级示例演示了如何构建使用 node.js 作为前端并使用 MySQL 作为后端的日志应用。本模板还创建并连接了 HTTP 负载平衡器和自动扩缩程序,前者用于跨越两个区域平衡负载,后者用于自动扩缩应用。
本示例假定使用者熟悉 Docker 容器以及 Compute Engine 资源,尤其是 HTTP 负载平衡、自动调节、托管实例组和实例模板。
准备工作
- 如果要使用本指南中的命令行示例,请安装 “gcloud” 命令行工具。
- 如果希望使用本指南中的 API 示例,请设置 API 访问权限。
- 熟悉 Compute Engine HTTP 负载平衡。
- 熟悉 Docker 容器。
创建模板
本示例启动的部署包含多种资源。首先,您需要创建可重复使用的模板来分别定义这些资源。稍后,您将在最终配置中使用这些模板。
完成本示例中的操作后,您将拥有包含以下资源的部署:
- 用于后端 MySQL 虚拟机的单个 Compute Engine 实例。
- 使用 Docker 映像的实例模板。
- 位于两个不同地区的两个自动调节的托管实例组,用于运行前端 node.js 服务。
- 另外两个自动调节的托管实例组,用于传送静态数据。
- 健康检查程序和 HTTP 负载均衡器,用于在各个托管实例组之间分配流量。
创建后端模板
此应用的后端是一个运行 MySQL Docker 容器的单个 Compute Engine 实例。请创建一个模板,用于定义使用容器优化映像的 Compute Engine 实例。为 container_vm.[py|jinja]
文件命名。
Jinja
Python
该模板定义了一些变量,例如 containerImage
和 manifest
,您将在定义配置时填写这些变量。本模板只创建了单个虚拟机 (VM) 实例。
您在 Compute Engine 实例上使用容器映像时,还需要提供清单文件(与 Deployment Manager 清单不同),以向 Compute Engine 描述要使用的容器映像。创建一个名为 container_helper.[py|jinja]
的辅助方法,用于动态定义容器清单:
Jinja
Python
创建前端模板
此应用的前端运行 Node.js,并允许用户将消息发布到网页上。在本例中,将有两个托管实例组(每个实例组包含两个实例):用于负载平衡的主托管实例组和辅助托管实例组。
要创建前端模板,请按照以下说明操作。
创建一个实例模板。
您需要“实例模板”资源来创建托管实例组,这是一组集中管理的相同虚拟机实例。此示例为前端 node.js 实例创建了一个托管实例组,但您必须先创建实例模板。
定义一个名为
container_instance_template.[py|jinja]
的文件:Jinja
Python
创建自动扩缩的托管实例组。
现在您已拥有一个实例模板,您可以使用这个实例模板进一步定义一个能够创建自动调节托管实例组的模板。创建名为
autoscaled_group.[py|jinja]
且包含以下内容的新文件:Jinja
Python
创建相应的架构文件:
Jinja
Python
使用这些模板创建资源。
到目前为止,您已定义了用于确定资源属性的基本模板。可使用这些模板定义前端的设置。创建名为
service.[py|jinja]
且包含以下内容的新文件:Jinja
Python
创建相应的架构文件:
Jinja
Python
让我们分别介绍此模板创建的内容:
两个托管实例组,一个主实例组和一个辅助实例组。
该模板使用
autoscaled_group.[py|jinja]
模板创建主辅自动调节托管实例组。接下来,模板将创建后端服务和健康检查程序。若要实现 HTTP 负载平衡,需要使用后端服务。HTTP 负载平衡将定义该后端服务中实例组的服务容量。在这种情况下,主托管实例组和辅助托管实例组是此后端的一部分,并且后端服务的默认属性均适用。
默认情况下,后端服务根据关联的实例组的 CPU 利用率执行负载平衡,但是您也可以根据每秒请求数 (RPS) 执行负载平衡。
注意:创建后端服务时,始终需要执行健康检查。
创建统一模板
最后,创建一个整合了后端和前端模板的统一模板。创建名为 application.[py|jinja]
的新文件:
Jinja
Python
创建相应的架构文件:
Jinja
Python
除了前端和后端之外,此模板还定义了一些其他资源:
包含主托管实例组和辅助托管实例组的静态服务。此静态服务可处理位于应用的
/static
路径中的网页。网址映射资源。HTTP 负载平衡需要使用网址映射来将不同的网址映射到正确的路径。在这种情况下,
defaultService
属性指示的默认路径是您之前创建的后端服务。如果用户导航到/static
,则网址映射会将该路径映射到pathMatchers
部分中定义的静态服务。全局转发规则和目标 HTTP 代理。由于应用在两个单独的地区之间执行负载平衡,因此您需要一个处理单个外部 IP 地址的全局转发规则。此外,还需要使用目标 HTTP 代理来设置 HTTP 负载平衡。
允许流量通过端口 8080 的防火墙规则。
创建配置
现在您已准备好模板和相关架构,可以创建部署这些资源的配置了。创建名为 application.yaml
且包含以下内容的配置文件,并将 ZONE_TO_RUN
和 SECONDARY_ZONE_TO_RUN
替换为您选择的主区域和辅助区域。
Jinja
Python
部署配置
现在,可以部署资源了。使用 Google Cloud CLI 运行以下命令,可选择将 advanced-configuration-l7
替换为您选择的部署名称。请注意,您的部署名称将自动用于资源的命名。
在此示例中,部署名称为 advanced-configuration-l7
。如果您选择更改部署名称,请确保在以下所有示例中使用更改后的部署名称。
gcloud deployment-manager deployments create advanced-configuration-l7 --config application.yaml
响应应类似于以下资源:
Waiting for create operation-1469468950934-5387966d431f0-49b11bc4-1421b2f0...done. Create operation operation-1469468950934-5387966d431f0-49b11bc4-1421b2f0 completed successfully. NAME TYPE STATE ERRORS advanced-configuration-l7-application-fw compute.v1.firewall COMPLETED [] advanced-configuration-l7-application-l7lb compute.v1.globalForwardingRule COMPLETED [] advanced-configuration-l7-application-targetproxy compute.v1.targetHttpProxy COMPLETED [] advanced-configuration-l7-application-urlmap compute.v1.urlMap COMPLETED [] advanced-configuration-l7-backend compute.v1.instance COMPLETED [] advanced-configuration-l7-frontend-bes compute.v1.backendService COMPLETED [] advanced-configuration-l7-frontend-hc compute.v1.httpHealthCheck COMPLETED [] advanced-configuration-l7-frontend-it compute.v1.instanceTemplate COMPLETED [] advanced-configuration-l7-frontend-pri-as compute.v1.autoscaler COMPLETED [] advanced-configuration-l7-frontend-pri-igm compute.v1.instanceGroupManager COMPLETED [] advanced-configuration-l7-frontend-sec-as compute.v1.autoscaler COMPLETED [] advanced-configuration-l7-frontend-sec-igm compute.v1.instanceGroupManager COMPLETED [] advanced-configuration-l7-static-service-bes compute.v1.backendService COMPLETED [] advanced-configuration-l7-static-service-hc compute.v1.httpHealthCheck COMPLETED [] advanced-configuration-l7-static-service-it compute.v1.instanceTemplate COMPLETED [] advanced-configuration-l7-static-service-pri-as compute.v1.autoscaler COMPLETED [] advanced-configuration-l7-static-service-pri-igm compute.v1.instanceGroupManager COMPLETED [] advanced-configuration-l7-static-service-sec-as compute.v1.autoscaler COMPLETED [] advanced-configuration-l7-static-service-sec-igm compute.v1.instanceGroupManager COMPLETED []
添加服务标签
接下来,为托管实例组指定相应的服务标签。服务标签是负载平衡服务用于对资源进行分组的元数据。
要添加服务标签,请运行以下命令,将主要区域和次要区域与您在部署配置文件中选择的区域相匹配:
gcloud compute instance-groups unmanaged set-named-ports advanced-configuration-l7-frontend-pri-igm \
--named-ports http:8080,httpstatic:8080 \
--zone [PRIMARY_ZONE]
gcloud compute instance-groups unmanaged set-named-ports advanced-configuration-l7-frontend-sec-igm \
--named-ports http:8080,httpstatic:8080 \
--zone [SECONDARY_ZONE]
测试配置
要测试配置,请查询转发规则,以获取用于处理流量的外部 IP 地址:
gcloud compute forwarding-rules list | grep advanced-configuration-l7-l7lb advanced-configuration-l7-l7lb 107.178.249.126 TCP advanced-configuration-l7-targetproxy
在此示例中,外部 IP 为 107.178.249.126
。
在浏览器中,通过端口 8080 访问外部 IP 地址。例如,如果您的外部 IP 是 107.178.249.126
,则网址为:
http://107.178.249.126:8080
系统应该会显示一个空白页面。下一步,在页面发布消息。转到以下网址:
http://107.178.249.126:8080?msg=hello_world!
系统会向您发送确认消息,告知您消息已添加至页面。返回主网址,这时,该页面应显示以下消息:
hello_world!
您还可以访问您创建的静态页面,或通过访问以下网址来检查应用的运行状况:
# Static web page
http://107.178.249.126:8080/static
# Health check
http://107.178.249.126:8080/_ah/health
恭喜!您已成功部署配置。
(可选)创建 Docker 映像
借助 Docker,您可以在容器内实现软件的自动化运行。容器支持在其内部隔离不同的服务,而所有容器都可以在单个 Linux 实例上运行。
此示例使用了一些现有的 Docker 映像,但您也可以创建自己的 Docker 映像版本。如需了解创建 MySQL 后端映像和 Node.js 前端映像的说明,请参阅创建资源模板部分。
要创建一个处理静态网页的 Docker 映像,请执行以下操作:
使用容器优化映像创建新的虚拟机实例:
gcloud compute instances create docker-playground \ --image-family container-vm \ --image-project google-containers \ --zone us-central1-a \ --machine-type f1-micro
连接实例:
gcloud compute ssh --zone us-central1-a docker-playground
创建名为
Dockerfile
且包含以下内容的文件:FROM node:latest RUN mkdir /var/www/ ADD service.js /var/www/service.js WORKDIR /var/www/ RUN npm install mysql CMD ["node", "service.js"]
创建名为
service.js
且包含以下内容的文件:var http = require('http'); var url = require('url'); console.log('Started static node server') http.createServer(function (req, res) { reqUrl = url.parse(req.url, true); res.useChunkedEncodingByDefault = false; res.writeHead(200, {'Content-Type': 'text/html'}); if (reqUrl.pathname == '/_ah/health') { res.end('ok'); } else if (reqUrl.pathname == '/exit') { process.exit(-1) } else { res.end('static server'); } }).listen(8080, '0.0.0.0'); console.log('Static server running at http://127.0.0.1:8080/');
构建 Docker 映像,将
username
替换为您的 Docker Hub 用户名。如果您没有 Docker Hub 用户名,请在构建 Docker 映像之前先创建 Docker Hub 用户名。sudo docker build --no-cache -t username/nodejsservicestatic .
将映像推送到 Docker 代码库:
sudo docker push username/nodejsservicestatic
现在,您可以使用 Docker 映像来运行 Node.js 和 MySQL 了。实际上,您还可以通过代码库查看这些映像,只需搜索映像名称即可。要尝试删除映像,您可以将 gcr.io/deployment-manager-examples/mysql
和 gcr.io/deployment-manager-examples/nodejsservice
的所有实例替换为各自的映像。
后续步骤
完成此示例后,您可以: