透過 Compute Engine 在 Google Cloud 中託管及擴充網頁應用程式

1. 簡介

在 Google Cloud 部署網站的方式有很多種,且特色、功能及控管能力各不相同。Compute Engine 可深入控管用於執行網站的基礎架構,但與 Google Kubernetes Engine、App Engine 和其他解決方案相比,需要較多的營運管理。透過 Compute Engine,即可精細控管基礎架構的各個環節,包括虛擬機器及負載平衡器等。今天,您將部署範例應用程式「Fancy Store」電子商務網站,瞭解如何使用 Compute Engine 輕鬆部署網站及調度資源。

課程內容

完成本程式碼研究室後,您將擁有位於代管執行個體群組中的執行個體,可為您的網站提供自動修復、負載平衡、自動調度資源及滾動式更新功能。

必要條件

2. 環境設定

自修實驗室環境設定

  1. 登入 Cloud 控制台,建立新專案或重複使用現有專案。如果沒有 Gmail 或 Google Workspace 帳戶,請先建立帳戶

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

請記住專案 ID,這是所有 Google Cloud 專案中不重複的名稱 (上述名稱已遭占用,因此不適用於您,抱歉!)。本程式碼研究室稍後會將其稱為 PROJECT_ID

  1. 接著,您必須在 Cloud 控制台中啟用帳單,才能使用 Google Cloud 資源。

完成本程式碼研究室的費用應該不高,甚至完全免費。請務必按照「清除」部分的指示操作,瞭解如何停用資源,避免在本教學課程結束後繼續產生帳單費用。Google Cloud 新使用者可參加價值$300 美元的免費試用計畫。

啟用 Compute Engine API

接著,您需要啟用 Compute Engine API。啟用 API 時,您必須接受服務條款,並承擔 API 的計費責任。

在 Cloud Shell 中執行下列指令,啟用 Compute Engine API:

gcloud services enable compute.googleapis.com

Cloud Shell

雖然您可以透過筆電遠端操作 Google Cloud,但在本程式碼研究室中,您將使用 Cloud Shell,這是 Cloud 中執行的指令列環境。

這部以 Debian 為基礎的虛擬機器,搭載各種您需要的開發工具,並提供永久的 5GB 主目錄,而且可在 Google Cloud 運作,大幅提升網路效能並強化驗證功能。也就是說,您只需要瀏覽器 (Chromebook 也可以) 就能完成本程式碼研究室。

  1. 如要從 Cloud 控制台啟用 Cloud Shell,只要按一下「啟用 Cloud Shell」 a8460e837e9f5fda.png 即可 (佈建並連線至環境的作業需要一些時間才能完成)。

b532b2f19ab85dda.png

Screen Shot 2017-06-14 at 10.13.43 PM.png

連至 Cloud Shell 後,您應該會看到驗證已完成,專案也已設為獲派的專案 ID PROJECT_ID

gcloud auth list

指令輸出

Credentialed accounts:
 - <myaccount>@<mydomain>.com (active)
gcloud config list project

指令輸出

[core]
project = <PROJECT_ID>

如果專案未設定,請發出下列指令:

gcloud config set project <PROJECT_ID>

在尋找「PROJECT_ID」嗎?請檢查您在設定步驟中使用的 ID,或在 Cloud 控制台資訊主頁中尋找:

2485e00c1223af09.png

Cloud Shell 也會預設設定部分環境變數,這些變數在您執行後續指令時可能很有用。

echo $GOOGLE_CLOUD_PROJECT

指令輸出

<PROJECT_ID>
  1. 最後,設定預設可用區和專案。
gcloud config set compute/zone us-central1-f

你可以選擇各種不同區域。詳情請參閱「地區和區域」。

建立 Cloud Storage bucket

我們將使用 Cloud Storage bucket 來儲存建構的程式碼及開機指令碼。在 Cloud Shell 中執行下列指令,建立新的 Cloud Storage bucket:

gsutil mb gs://fancy-store-$DEVSHELL_PROJECT_ID

3. 複製來源存放區

您將使用 Fancy Store 現有的電子商務網站 (以 monolith-to-microservices 存放區為基礎),做為網站基礎。請從存放區複製原始碼,以便專心將應用程式部署至 Compute Engine。稍後,您將稍微修改一下程式碼,看看在 Compute Engine 更新內容有多簡單。

您可以透過下列連結自動將程式碼存放區複製到專案中,並開啟 Cloud Shell 和內建的程式碼編輯器:在 Cloud Shell 中開啟

或者,您也可以在 Cloud Shell 中使用下列指令,手動複製存放區:

cd ~
git clone https://github.com/googlecodelabs/monolith-to-microservices.git
cd ~/monolith-to-microservices

在 Cloud Shell 命令提示字元中,執行程式碼的初始版本,讓應用程式可在本機執行。指令碼可能需要幾分鐘才能執行完畢。

./setup.sh

請進行盡職調查並測試應用程式。執行下列指令啟動網路伺服器:

cd microservices
npm start

輸出內容:

Products microservice listening on port 8082!
Frontend microservice listening on port 8080!
Orders microservice listening on port 8081!

點選「網頁預覽」圖示,然後選取「透過以下通訊埠預覽:8080」,即可預覽應用程式。

6634c06dd0b9172c.png

系統應會開啟新視窗,顯示 Fancy Store 前端的實際運作情形!

abf2ca314bf80d03.png

查看網站後,即可關閉這個視窗。如要停止網路伺服器程序,請在終端機視窗中按下 Control+C 鍵 (Macintosh 上的 Command+C 鍵)。

4. 建立 Compute Engine 執行個體

現在您已建立可運作的開發環境,接下來可以部署一些 Compute Engine 執行個體。您將在後續步驟執行下列操作:

  1. 建立開機指令碼以設定執行個體。
  2. 複製原始碼並上傳至 Cloud Storage。
  3. 部署用於託管後端微服務的 Compute Engine 執行個體。
  4. 重新設定前端程式碼,以使用後端微服務執行個體。
  5. 部署用於託管前端微服務的 Compute Engine 執行個體。
  6. 設定網路來允許通訊。

建立開機指令碼

開機指令碼會在每次啟動時,指示執行個體應採取何種行動,以便自動設定執行個體。

按一下 Cloud Shell 工具列的鉛筆圖示,開啟程式碼編輯器。

前往 monolith-to-microservices 資料夾。依序點選「File」 >「New File」,建立檔案並命名為 startup-script.sh。

439553c934139b82.png

在新的檔案中貼上下列程式碼,貼上後請編輯部分程式碼:

#!/bin/bash

# Install logging monitor. The monitor will automatically pick up logs sent to
# syslog.
curl -s "https://storage.googleapis.com/signals-agents/logging/google-fluentd-install.sh" | bash
service google-fluentd restart &

# Install dependencies from apt
apt-get update
apt-get install -yq ca-certificates git build-essential supervisor psmisc

# Install nodejs
mkdir /opt/nodejs
curl https://nodejs.org/dist/v8.12.0/node-v8.12.0-linux-x64.tar.gz | tar xvzf - -C /opt/nodejs --strip-components=1
ln -s /opt/nodejs/bin/node /usr/bin/node
ln -s /opt/nodejs/bin/npm /usr/bin/npm

# Get the application source code from the Google Cloud Storage bucket.
mkdir /fancy-store
gsutil -m cp -r gs://fancy-store-[DEVSHELL_PROJECT_ID]/monolith-to-microservices/microservices/* /fancy-store/

# Install app dependencies.
cd /fancy-store/
npm install

# Create a nodeapp user. The application will run as this user.
useradd -m -d /home/nodeapp nodeapp
chown -R nodeapp:nodeapp /opt/app

# Configure supervisor to run the node app.
cat >/etc/supervisor/conf.d/node-app.conf << EOF
[program:nodeapp]
directory=/fancy-store
command=npm start
autostart=true
autorestart=true
user=nodeapp
environment=HOME="/home/nodeapp",USER="nodeapp",NODE_ENV="production"
stdout_logfile=syslog
stderr_logfile=syslog
EOF

supervisorctl reread
supervisorctl update

現在,在程式碼編輯器中找出 [DEVSHELL_PROJECT_ID],然後將這個部分改為下列指令的輸出內容:

echo $DEVSHELL_PROJECT_ID

輸出內容範例:

my-gce-codelab-253520

startup-script.sh 中的程式碼應類似下列內容:

gs://fancy-store-my-gce-codelab-253520/monolith-to-microservices/microservices/* /fancy-store/

開機指令碼會執行下列工作:

  • 安裝 Logging 代理程式,自動收集 syslog 記錄
  • 安裝 Node.js 和 Supervisor,後者會以 Daemon 形式執行應用程式
  • 從 Cloud Storage bucket 複製應用程式的原始碼,並安裝依附元件
  • 設定 Supervisor (執行應用程式),確保應用程式非正常結束或遭管理員或程序停止時會重新啟動,並將應用程式的 stdout 和 stderr 傳送至 syslog,供 Logging 代理程式收集

現在將建立的 startup-script.sh 檔案複製到先前建立的 Cloud Storage bucket:

gsutil cp ~/monolith-to-microservices/startup-script.sh gs://fancy-store-$DEVSHELL_PROJECT_ID

該檔案目前可從下列網址存取:https://storage.googleapis.com/[BUCKET_NAME]/startup-script.sh[BUCKET_NAME] 代表 Cloud Storage bucket 的名稱。這項資訊預設為只有獲得授權的使用者和服務帳戶能查看,因此無法透過網路瀏覽器存取。Compute Engine 執行個體會自動透過服務帳戶存取這個名稱。

將程式碼複製到 Cloud Storage bucket

執行個體啟動後,會從 Cloud Storage bucket 提取程式碼,因此您可以在程式碼的「.env」檔案中儲存一些設定變數。

將複製的程式碼複製到 Cloud Storage bucket:

cd ~
rm -rf monolith-to-microservices/*/node_modules
gsutil -m cp -r monolith-to-microservices gs://fancy-store-$DEVSHELL_PROJECT_ID/

部署後端執行個體

首先要部署的是後端執行個體,用於儲存訂單和產品微服務。

在 Cloud Shell 中執行下列指令,建立設為使用先前建立的開機指令碼的 f1-micro 執行個體,並將其標為後端執行個體,以便稍後為該執行個體套用特定防火牆規則:

gcloud compute instances create backend \
    --machine-type=f1-micro \
    --image=debian-9-stretch-v20190905 \
    --image-project=debian-cloud \
    --tags=backend \
    --metadata=startup-script-url=https://storage.googleapis.com/fancy-store-$DEVSHELL_PROJECT_ID/startup-script.sh

設定與後端的連線

部署應用程式前端之前,您需要先更新設定,指向您部署的後端。

擷取後端的外部 IP 位址,在後端執行個體的 EXTERNAL_IP 欄位下,透過下列指令查看:

gcloud compute instances list

輸出內容範例:

NAME     ZONE           MACHINE_TYPE  PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP   STATUS
backend  us-central1-a  f1-micro                   10.128.0.2   34.68.223.88  RUNNING

在 Cloud Shell 的程式碼編輯器中,依序前往 monolith-to-microservices > react-app 資料夾。在程式碼編輯器選單中,依序選取「View」>「Toggle Hidden Files」,即可查看 .env 檔案。

e7314ceda643e16.png

編輯 .env 檔案,指向後端的外部 IP 位址。下方的 [BACKEND_ADDRESS] 代表後端執行個體的外部 IP 位址 (執行 gcloud 工具中的前一個指令後即可判斷)。

REACT_APP_ORDERS_URL=http://[BACKEND_ADDRESS]:8081/api/orders
REACT_APP_PRODUCTS_URL=http://[BACKEND_ADDRESS]:8082/api/products

儲存檔案。

使用下列指令重新建構 react-app,更新前端程式碼:

cd ~/monolith-to-microservices/react-app
npm install && npm run-script build

將應用程式程式碼複製到 Cloud Storage bucket:

cd ~
rm -rf monolith-to-microservices/*/node_modules
gsutil -m cp -r monolith-to-microservices gs://fancy-store-$DEVSHELL_PROJECT_ID/

部署前端執行個體

程式碼設定完畢後,即可部署前端執行個體。執行下列指令,透過與先前類似的指令來部署前端執行個體,但基於防火牆用途,這個執行個體會標記為「frontend」。

gcloud compute instances create frontend \
    --machine-type=f1-micro \
    --image=debian-9-stretch-v20190905 \
    --image-project=debian-cloud \
    --tags=frontend \
    --metadata=startup-script-url=https://storage.googleapis.com/fancy-store-$DEVSHELL_PROJECT_ID/startup-script.sh 

設定網路

建立防火牆規則,允許前端存取通訊埠 8080,後端存取通訊埠 8081 和 8082。這些防火牆指令會使用為應用程式建立執行個體時所指派的標記:

gcloud compute firewall-rules create fw-fe \
    --allow tcp:8080 \
    --target-tags=frontend
gcloud compute firewall-rules create fw-be \
    --allow tcp:8081-8082 \
    --target-tags=backend

現在網站應該可以正常運作。判斷前端的外部 IP 位址。如要判斷位址,請找出前端執行個體的 EXTERNAL_IP:

gcloud compute instances list

輸出內容範例:

NAME      ZONE           MACHINE_TYPE  PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP      STATUS
backend   us-central1-a  f1-micro                   10.128.0.2   104.198.235.171  RUNNING
frontend  us-central1-a  f1-micro                   10.128.0.3   34.69.141.9      RUNNING

執行個體會在幾分鐘內啟動及設定完成。執行下列指令,監控應用程式的就緒狀態:

watch -n 5 curl http://[EXTERNAL_IP]:8080 

看到類似下列內容的輸出結果時,代表網站應該已就緒。在命令提示字元中按下 Control+C 鍵 (Macintosh 則為 Command+C 鍵),取消監看指令。

80dc8721dc08d7e4.png

開啟新的瀏覽器分頁,然後前往 http://[FRONTEND_ADDRESS]:8080 來存取網站,其中的 [FRONTEND_ADDRESS] 是前述步驟中輸出的 EXTERNAL_IP。

試著前往「Products」和「Orders」頁面,現在網頁應該也會正常運作。

a11460a1fffb07d8.png

5. 建立代管執行個體群組

如要允許應用程式調度資源,需建立代管執行個體群組,並使用 frontendbackend 執行個體做為執行個體範本。

代管執行個體群組包含相同的執行個體,可做為單一可用區中的單一實體來管理。這類群組會主動讓執行個體保持可用狀態 (即處於 RUNNING 狀態),以維持應用程式的高可用性。您將為前端和後端執行個體使用代管執行個體群組,以便提供自動修復、負載平衡、自動調度資源和滾動式更新功能。

根據來源執行個體建立執行個體範本

建立代管執行個體群組前,必須先建立執行個體範本,用來做為群組的基礎。建立新的虛擬機器 (VM) 執行個體時,執行個體範本可定義要使用的機型、開機磁碟映像檔或容器映像檔、網路,以及其他執行個體屬性。您可以利用執行個體範本建立代管執行個體群組中的執行個體,甚至建立個別的執行個體。

如要建立執行個體範本,請使用您建立的現有執行個體。

首先,請停止兩個執行個體。

gcloud compute instances stop frontend
gcloud compute instances stop backend

現在,請根據來源執行個體建立執行個體範本。

gcloud compute instance-templates create fancy-fe \
    --source-instance=frontend
gcloud compute instance-templates create fancy-be \
    --source-instance=backend

確認執行個體範本已建立完畢:

gcloud compute instance-templates list

輸出內容範例:

NAME      MACHINE_TYPE  PREEMPTIBLE  CREATION_TIMESTAMP
fancy-be  f1-micro                   2019-09-12T07:52:57.544-07:00
fancy-fe  f1-micro                   2019-09-12T07:52:48.238-07:00

建立代管執行個體群組

您將建立兩個代管執行個體群組,分別用於前端和後端。這些代管執行個體群組會使用先前建立的執行個體範本,並設定為每個群組有兩個要啟動的執行個體。執行個體的名稱會由「base-instance-name」指定,並附上隨機字串。

gcloud compute instance-groups managed create fancy-fe-mig \
    --base-instance-name fancy-fe \
    --size 2 \
    --template fancy-fe
gcloud compute instance-groups managed create fancy-be-mig \
    --base-instance-name fancy-be \
    --size 2 \
    --template fancy-be

應用程式的前端微服務會在通訊埠 8080 上執行,後端微服務則是在通訊埠 8081 上執行,通訊埠 8081 用於 orders,通訊埠 8082 則用於 products。這些是非標準通訊埠,因此請指定已命名通訊埠來識別。已命名通訊埠是以鍵/值組成的中繼資料,表示服務名稱及其執行的通訊埠。您可以將已命名通訊埠指派給執行個體群組,表示群組中的所有執行個體皆可使用該服務。負載平衡器會使用這項資訊,我們將在後續章節設定。

gcloud compute instance-groups set-named-ports fancy-fe-mig \ 
    --named-ports frontend:8080
gcloud compute instance-groups set-named-ports fancy-be-mig \
    --named-ports orders:8081,products:8082

設定自動修復功能

如要提高應用程式可用性並驗證回應能力,您可以為代管執行個體群組設定自動修復政策。

自動修復政策會利用以應用程式為基礎的健康狀態檢查機制,確認應用程式的回應符合預期。只確認執行個體是否處於「執行中」狀態 (預設行為) 意義不大,檢查其是否有回應,才是比較精確的做法。

建立健康狀態檢查,在前端和後端執行個體連續三次傳回健康狀態不良時,修復執行個體:

gcloud compute health-checks create http fancy-fe-hc \
    --port 8080 \
    --check-interval 30s \
    --healthy-threshold 1 \
    --timeout 10s \
    --unhealthy-threshold 3
gcloud compute health-checks create http fancy-be-hc \
    --port 8081 \
    --request-path=/api/orders \
    --check-interval 30s \
    --healthy-threshold 1 \
    --timeout 10s \
    --unhealthy-threshold 3

建立防火牆規則,允許健康狀態檢查探測器連線至通訊埠 8080 和 8081 上的微服務:

gcloud compute firewall-rules create allow-health-check \
    --allow tcp:8080-8081 \
    --source-ranges 130.211.0.0/22,35.191.0.0/16 \
    --network default

將健康狀態檢查套用至對應的服務:

gcloud compute instance-groups managed update fancy-fe-mig \
    --health-check fancy-fe-hc \
    --initial-delay 300
gcloud compute instance-groups managed update fancy-be-mig \
    --health-check fancy-be-hc \
    --initial-delay 300

請先繼續完成程式碼研究室的活動,給自動修復功能一些時間監控群組中的執行個體。稍後,您將模擬故障情形,測試自動修復功能。

6. 建立負載平衡器

為配合代管執行個體群組,請使用 HTTP(S) 負載平衡器將流量導向前端和後端微服務,並透過路徑規則的對應設定,將流量傳送到適當的後端服務,這樣所有服務都會使用同一個負載平衡 IP 位址。

如要進一步瞭解 Google Cloud 提供的負載平衡選項,請參閱「負載平衡總覽」。

建立 HTTP(S) 負載平衡

Google Cloud 提供多種類型的負載平衡,但您將使用 HTTP(S) 負載平衡來處理流量。HTTP(S) 負載平衡的結構如下:

  1. 轉送規則將傳入要求導向至目標 HTTP Proxy。
  2. 目標 HTTP Proxy 會根據網址對應檢查每個要求,以決定適合要求的後端服務。
  3. 後端服務會根據其連接的後端處理能力、可用區和執行個體健康狀態,將每個要求導向到合適的後端。系統會使用 HTTP 健康狀態檢查,驗證每個後端執行個體的健康狀態。如果將後端服務設定為使用 HTTPS 或 HTTP/2 健康狀態檢查,則要求會在前往後端執行個體的途中加密。
  4. 負載平衡器和執行個體之間的工作階段可以使用 HTTP、HTTPS 或 HTTP/2 通訊協定。如果您使用 HTTPS 或 HTTP/2,後端服務中的每個執行個體都必須具備 SSL 憑證。

建立健康狀態檢查,用於決定要使用哪個執行個體為各服務提供流量。

gcloud compute http-health-checks create fancy-fe-frontend-hc \
  --request-path / \
  --port 8080
gcloud compute http-health-checks create fancy-be-orders-hc \
  --request-path /api/orders \
  --port 8081
gcloud compute http-health-checks create fancy-be-products-hc \
  --request-path /api/products \
  --port 8082

建立後端服務,做為負載平衡流量的目標。後端服務會使用您建立的健康檢查和已命名通訊埠。

gcloud compute backend-services create fancy-fe-frontend \
  --http-health-checks fancy-fe-frontend-hc \
  --port-name frontend \
  --global
gcloud compute backend-services create fancy-be-orders \
  --http-health-checks fancy-be-orders-hc \
  --port-name orders \
  --global
gcloud compute backend-services create fancy-be-products \
  --http-health-checks fancy-be-products-hc \
  --port-name products \
  --global

新增後端服務。

gcloud compute backend-services add-backend fancy-fe-frontend \
  --instance-group fancy-fe-mig \
  --instance-group-zone us-central1-f \
  --global
gcloud compute backend-services add-backend fancy-be-orders \
  --instance-group fancy-be-mig \
  --instance-group-zone us-central1-f \
  --global
gcloud compute backend-services add-backend fancy-be-products \
  --instance-group fancy-be-mig \
  --instance-group-zone us-central1-f \
  --global

建立網址對應。網址對應定義了應將哪些網址導向至哪些後端服務。

gcloud compute url-maps create fancy-map \
  --default-service fancy-fe-frontend

建立路徑比對器,允許 /api/orders 和 /api/products 路徑轉送個別服務。

gcloud compute url-maps add-path-matcher fancy-map \
   --default-service fancy-fe-frontend \
   --path-matcher-name orders \
   --path-rules "/api/orders=fancy-be-orders,/api/products=fancy-be-products"

建立要與所建網址對應繫結的 Proxy。

gcloud compute target-http-proxies create fancy-proxy \
  --url-map fancy-map

建立全域轉送規則,將公開 IP 位址及通訊埠與 Proxy 繫結在一起。

gcloud compute forwarding-rules create fancy-http-rule \
  --global \
  --target-http-proxy fancy-proxy \
  --ports 80

更新設定

現在您有新的靜態 IP 位址,請更新前端的程式碼,指向這個新位址,不要使用先前指向 backend 執行個體的臨時 IP 位址。

在 Cloud Shell 中,切換到儲存 .env 檔案的 react-app 資料夾,該檔案內含相關設定。

cd ~/monolith-to-microservices/react-app/

找出負載平衡器的 IP 位址:

gcloud compute forwarding-rules list --global

輸出內容範例:

NAME                    REGION  IP_ADDRESS     IP_PROTOCOL  TARGET
fancy-http-rule          34.102.237.51  TCP          fancy-proxy

使用慣用的文字編輯器 (例如 GNU nano) 編輯 .env 檔案,指向負載平衡器的公開 IP 位址。[LB_IP] 代表後端執行個體的外部 IP 位址。

REACT_APP_ORDERS_URL=http://[LB_IP]/api/orders
REACT_APP_PRODUCTS_URL=http://[LB_IP]/api/products

重新建構 react-app,更新前端程式碼。

cd ~/monolith-to-microservices/react-app
npm install && npm run-script build

將應用程式程式碼複製到 GCS bucket。

cd ~
rm -rf monolith-to-microservices/*/node_modules
gsutil -m cp -r monolith-to-microservices gs://fancy-store-$DEVSHELL_PROJECT_ID/

更新前端執行個體

現在您要使用代管執行個體群組中的前端執行個體提取新程式碼。執行個體會在啟動時提取程式碼,因此您可以執行滾動式重新啟動指令。

gcloud compute instance-groups managed rolling-action restart fancy-fe-mig \
    --max-unavailable 100%

測試網站

執行 rolling-action restart 指令後,請等待 30 秒左右,讓系統處理執行個體。接著等執行個體出現在清單中後,再檢查代管執行個體群組的狀態。

watch -n 5 gcloud compute instance-groups list-instances fancy-fe-mig

待執行個體出現在清單後,按下 Control+C 鍵 (Macintosh 上的 Command+C 鍵),結束 watch 指令。

確認服務狀態為「健康狀態良好」。

watch -n 5 gcloud compute backend-services get-health fancy-fe-frontend --global

輸出內容範例:

---
backend: https://www.googleapis.com/compute/v1/projects/my-gce-codelab/zones/us-central1-a/instanceGroups/fancy-fe-mig
status:
  healthStatus:
  - healthState: HEALTHY
    instance: https://www.googleapis.com/compute/v1/projects/my-gce-codelab/zones/us-central1-a/instances/fancy-fe-x151
    ipAddress: 10.128.0.7
    port: 8080
  - healthState: HEALTHY
    instance: https://www.googleapis.com/compute/v1/projects/my-gce-codelab/zones/us-central1-a/instances/fancy-fe-cgrt
    ipAddress: 10.128.0.11
    port: 8080
  kind: compute#backendServiceGroupHealth

待執行個體出現在清單後,按下 Control+C 鍵 (Macintosh 為 Command+C 鍵),結束 watch 指令。

應用程式將可透過 http://[LB_IP] 存取,[LB_IP] 是系統為負載平衡器指定的 IP_ADDRESS,您可使用下列指令找出該位址:

gcloud compute forwarding-rules list --global

7. 調度 Compute Engine 的資源

目前您已建立兩個代管執行個體群組,且每個群組皆含有兩個執行個體。這項設定可以正常運作,但無論負載狀況如何,都不會變動。接下來,您要根據使用率建立自動調度資源政策,讓每個代管執行個體群組自動調整資源配置。

根據使用率自動調整資源配置

如要建立自動調度資源政策,請在 Cloud Shell 中執行下列指令。他們會在代管執行個體群組建立自動配置器。這項工具會在使用率高於 60% 時,自動新增執行個體,如果負載平衡器的使用率低於 60%,則會移除執行個體。

gcloud compute instance-groups managed set-autoscaling \
  fancy-fe-mig \
  --max-num-replicas 5 \
  --target-load-balancing-utilization 0.60
gcloud compute instance-groups managed set-autoscaling \
  fancy-be-mig \
  --max-num-replicas 5 \
  --target-load-balancing-utilization 0.60

啟用內容傳遞網路

啟用 Cloud CDN (內容傳遞網路服務) 也有助於資源調度,啟用後即可為前端服務提供快取。如要這麼做,請在前端服務執行下列指令:

gcloud compute backend-services update fancy-fe-frontend \
    --enable-cdn --global

現在,當使用者向負載平衡器要求內容時,系統會將要求傳送到 Google 前端,該前端首先會在 Cloud CDN 快取中尋找使用者要求的回應。如果前端找到快取回應,就會傳送給使用者。這稱為「快取命中」。

假如前端找不到要求的快取回應,會向後端直接提出要求。如果該要求的回應可快取,前端會將回應儲存在 Cloud CDN 快取中,以便將快取用於後續要求。

8. 更新網站

更新執行個體範本

現有的執行個體範本無法編輯。不過,由於您的執行個體為無狀態,且已透過開機指令碼完成所有設定,若您想要變更範本設定核心映像檔本身,只需要變更執行個體範本即可。接下來要稍做調整,改用較大的機型,然後將這項變更推送出去。

更新前端執行個體,做為執行個體範本的基礎。更新時,請將檔案儲存在更新版執行個體範本映像檔,接著更新執行個體範本、推出新的範本,然後確認代管執行個體群組的執行個體中確實有該檔案。

您將修改執行個體範本的機型,從 f1-micro 標準機型改為配備 4 個 vCPU 和 3840MiB RAM 的自訂機型。

在 Cloud Shell 中執行下列指令,修改前端執行個體的機型:

gcloud compute instances set-machine-type frontend --machine-type custom-4-3840

建立新的執行個體範本:

gcloud compute instance-templates create fancy-fe-new \
    --source-instance=frontend \
    --source-instance-zone=us-central1-a

將更新後的執行個體範本推出至代管執行個體群組:

gcloud compute instance-groups managed rolling-action start-update fancy-fe-mig \
    --version template=fancy-fe-new

監控更新狀態:

watch -n 2 gcloud compute instance-groups managed list-instances fancy-fe-mig

如果有多個執行個體處於「RUNNING」狀態,且「ACTION」設為「None」,並將「INSTANCE_TEMPLATE」設為新的範本名稱 (fancy-fe-new),請複製其中一個列出的機器名稱,下一個指令會用到。

(Macintosh 上為 Command+S) 鍵,退出 watch 程序。Control+S

執行下列指令,查看虛擬機器是否改用新機型 (custom-4-3840),指令中的 [VM_NAME] 是新建立的執行個體:

gcloud compute instances describe [VM_NAME] | grep machineType

預期的輸出內容範例如下:

machineType: https://www.googleapis.com/compute/v1/projects/project-name/zones/us-central1-f/machineTypes/custom-4-3840

變更網站內容

您的行銷團隊想請您變更網站首頁,希望包含更多公司簡介與銷售產品等資訊。在本節中,您要在首頁加入一些文字,滿足行銷團隊的要求!看來有某位開發人員已做了變更,檔案名稱為 index.js.new。您可以將檔案複製到 index.js,網站應該就會反映新內容。按照下方說明操作,進行適當變更。

執行下列指令,將更新後的檔案複製為正確檔名,然後顯示檔案內容來確認變更:

cd ~/monolith-to-microservices/react-app/src/pages/Home
mv index.js.new index.js
cat ~/monolith-to-microservices/react-app/src/pages/Home/index.js

顯示的程式碼應如下所示:

/*
Copyright 2019 Google LLC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import Paper from "@material-ui/core/Paper";
import Typography from "@material-ui/core/Typography";
const useStyles = makeStyles(theme => ({
  root: {
    flexGrow: 1
  },
  paper: {
    width: "800px",
    margin: "0 auto",
    padding: theme.spacing(3, 2)
  }
}));
export default function Home() {
  const classes = useStyles();
  return (
    <div className={classes.root}>
      <Paper className={classes.paper}>
        <Typography variant="h5">
          Fancy Fashion &amp; Style Online
        </Typography>
        <br />
        <Typography variant="body1">
          Tired of mainstream fashion ideas, popular trends and societal norms?
          This line of lifestyle products will help you catch up with the Fancy trend and express your personal style.
          Start shopping Fancy items now!
        </Typography>
      </Paper>
    </div>
  );
}

您已更新 React 元件,但還得建構 React 應用程式,才能產生靜態檔案。執行下列指令即可建構 React 應用程式,並將其複製到單體公開目錄:

cd ~/monolith-to-microservices/react-app
npm install && npm run-script build

然後再次將程式碼推送至 Cloud Storage bucket。

cd ~
rm -rf monolith-to-microservices/*/node_modules
gsutil -m cp -r monolith-to-microservices gs://fancy-store-$DEVSHELL_PROJECT_ID/

透過滾動式更新推送變更

現在可以強制重新啟動所有執行個體,以便提取更新內容。

gcloud compute instance-groups managed rolling-action restart fancy-fe-mig \
    --max-unavailable=100%

執行 rolling-action restart 指令後,請稍候 30 秒左右,讓系統有時間處理執行個體,然後等執行個體出現在清單中後,再檢查代管執行個體群組的狀態。

watch -n 5 gcloud compute instance-groups list-instances fancy-fe-mig

待執行個體出現在清單後,按下 Control+S 鍵 (Macintosh 上的 Command+S 鍵),結束 watch 指令。

執行下列指令,確認服務顯示的狀態為「健康狀態良好」

watch -n 5 gcloud compute backend-services get-health fancy-fe-frontend --global

輸出內容範例:

---
backend: https://www.googleapis.com/compute/v1/projects/my-gce-codelab/zones/us-central1-a/instanceGroups/fancy-fe-mig
status:
  healthStatus:
  - healthState: HEALTHY
    instance: https://www.googleapis.com/compute/v1/projects/my-gce-codelab/zones/us-central1-a/instances/fancy-fe-x151
    ipAddress: 10.128.0.7
    port: 8080
  - healthState: HEALTHY
    instance: https://www.googleapis.com/compute/v1/projects/my-gce-codelab/zones/us-central1-a/instances/fancy-fe-cgrt
    ipAddress: 10.128.0.11
    port: 8080
  kind: compute#backendServiceGroupHealth

待執行個體出現在清單後,按下 Control+S 鍵 (Macintosh 上的 Command+S 鍵),結束 watch 指令。

如要撤銷內容傳遞網路中的快取內容,並確保顯示最新內容,請執行下列指令:

gcloud compute url-maps invalidate-cdn-cache fancy-map \
    --path "/*"

透過 http://[LB_IP] 瀏覽網站,[LB_IP] 是系統為負載平衡器指定的 IP_ADDRESS,您可使用下列指令找出該位址:

gcloud compute forwarding-rules list --global

現在您應該可以看到網站變更後的內容。

b081b8e885bf0723.png

模擬失敗情形

如要確認健康狀態檢查正常運作,請登入執行個體並停止服務。如要找出執行個體名稱,請執行以下指令:

gcloud compute instance-groups list-instances fancy-fe-mig

接著透過安全殼層連線至其中一個執行個體,INSTANCE_NAME 代表清單中的一個執行個體:

gcloud compute ssh [INSTANCE_NAME]

在執行個體中,使用 supervisorctl 停止應用程式。

sudo supervisorctl stop nodeapp; sudo killall node

結束執行個體。

exit

監控修復作業。

watch -n 5 gcloud compute operations list \
--filter='operationType~compute.instances.repair.*'

輸出內容應如下列範例所示。

NAME                                                  TYPE                                       TARGET                                 HTTP_STATUS  STATUS  TIMESTAMP
repair-1568314034627-5925f90ee238d-fe645bf0-7becce15  compute.instances.repair.recreateInstance  us-central1-a/instances/fancy-fe-1vqq  200          DONE    2019-09-12T11:47:14.627-07:00

發現問題已修正後,請按 Control+C (Macintosh 上的 Command+S) 結束手錶指令。此時,代管執行個體群組會重新建立執行個體來修復問題。

9. 清理

準備就緒後,如要清除所有活動,最簡單的方法就是刪除專案。刪除專案會一併刪除在程式碼研究室中建立的負載平衡器、執行個體、範本等項目,確保不會產生非預期的週期性費用。在 Cloud Shell 中執行下列指令,其中 PROJECT_ID 是完整專案 ID,不只是專案名稱。

gcloud projects delete [PROJECT_ID]

系統提示時,輸入「Y」確認刪除。

10. 恭喜!

您已在 Compute Engine 部署、調度資源及更新網站。現在您已具備使用 Compute Engine、代管執行個體群組、負載平衡和健康狀態檢查的經驗!