本進階範例說明如何建構分別以 node.js 和 MySQL 做為前端和後端的 Logbook 範例應用程式。本範本也會建立和連結在兩個區域間進行負載平衡處理的 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,並且可讓使用者在網頁中張貼訊息。將會有兩個代管執行個體群組,每個群組又各自包含兩個執行個體 (分別為主要和次要代管執行個體群組),可供進行負載平衡作業。
如要建立這些前端範本,請按照下列指示操作。
建立執行個體範本。
您需要使用執行個體範本資源來建立代管執行個體群組;此執行個體群組是一組可集中管理的相同 VM 執行個體。本範例會為前端 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 負載平衡必須使用後端服務,也會定義該後端服務中的執行個體群組服務規模。在這個情況下,主要和次要代管執行個體群組屬於後端的一部分,因此同樣適用後端服務的預設屬性。
根據預設,後端服務會依據關聯執行個體群組的 CPU 使用率來執行負載平衡,但您也可以依據每秒要求數 (RPS) 來進行負載平衡。
注意事項:建立後端服務時,一律需要執行健康狀態檢查。
建立整合範本
最後,建立能結合前後端範本的整合範本。建立名為 application.[py|jinja]
的新檔案:
Jinja
Python
建立相對應的結構定義檔案:
Jinja
Python
除了前端和後端外,範本也會定義一些其他資源:
具有主要和次要代管執行個體群組的靜態服務。此靜態服務提供位於應用程式
/static
路徑的網頁。網址對應資源。HTTP 負載平衡必須具備網址對應,才能將不同的網址對應至正確路徑。在此範例中,由
defaultService
屬性表示的預設路徑即為您稍早建立的後端服務。如果使用者前往/static
,網址對應就會將該路徑對應到靜態服務,如同pathMatchers
區段的定義。通用轉送規則和目標 HTTP Proxy。由於應用程式是在兩個個別區域之間進行負載平衡,因此您必須具備提供單一外部 IP 位址的通用轉送規則。此外,HTTP 負載平衡設定須具備目標 HTTP Proxy。
允許流量通過連接埠 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 映像檔:
使用容器最佳化的映像檔建立新的 VM 執行個體:
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 映像檔。sudo docker build --no-cache -t username/nodejsservicestatic .
將映像檔推送至 Docker 存放區:
sudo docker push username/nodejsservicestatic
您現在已經具備可執行 Node.js 和 MySQL 的 Docker 映像檔。當您搜尋映像檔名稱時,即可在存放區實際看到這些映像檔。如要試用映像檔,您可以使用個別的映像檔取代 gcr.io/deployment-manager-examples/mysql
和 gcr.io/deployment-manager-examples/nodejsservice
的所有執行個體。
後續步驟
完成本範例後,您可以: