在 Node.js 上使用 Cloud Run 部署及執行容器

1. 事前準備

6a5cf23c8e20491f.png

Cloud Run 是代管運算平台,能夠讓您執行可透過 HTTP 要求叫用的無狀態容器。Cloud Run 採用無伺服器技術省去管理基礎架構的麻煩,讓您專心處理最重要的事務,也就是建構出色的應用程式。這項服務是以 Knative 打造而成,可讓您透過 Cloud Run (全代管) 或 Cloud Run for Anthos 執行容器。本程式碼研究室的目標是協助您建構容器映像檔,並部署至 Cloud Run。

必要條件

不適用

2. 設定和需求

自修環境設定

  1. 登入 Cloud 控制台建立新專案,或是重複使用現有專案。(如果您還沒有 Gmail 或 G Suite 帳戶,請先建立帳戶)。

dMbN6g9RawQj_VXCSYpdYncY-DbaRzr2GbnwoV7jFf1u3avxJtmGPmKpMYgiaMH-qu80a_NJ9p2IIXFppYk8x3wyymZXavjglNLJJhuXieCem56H30hwXtd8PvXGpXJO9gEUDu3cZw

ci9Oe6PgnbNuSYlMyvbXF1JdQyiHoEgnhl4PlV_MFagm2ppzhueRkqX4eLjJllZco_2zCp0V0bpTupUSKji9KkQyWqj11pqit1K1faS1V6aFxLGQdkuzGp4rsQTan7F01iePL5DtqQ

8-tA_Lheyo8SscAVKrGii2coplQp2_D1Iosb2ViABY0UUO1A8cimXUu6Wf1R9zJIRExL5OB2j946aIiFtyKTzxDcNnuznmR45vZ2HMoK3o67jxuoUJCAnqvEX6NgPGFjCVNgASc-lg

提醒您,專案 ID 是所有 Google Cloud 專案的專屬名稱 (已經有人使用上述名稱,很抱歉對您不符!)。稍後在本程式碼研究室中會稱為 PROJECT_ID

  1. 接下來,您需要在 Cloud 控制台中啟用計費功能,才能使用 Google Cloud 資源。

執行這個程式碼研究室並不會產生任何費用,如果有的話。請務必依照「清除所用資源」一節指示本節將說明如何關閉資源,這樣您就不會產生本教學課程結束後產生的費用。Google Cloud 的新使用者符合 $300 美元免費試用計畫的資格。

Cloud Shell

雖然 Google Cloud 可以從筆記型電腦遠端操作,不過您將使用 Cloud Shell,這是在 Google Cloud 中運作的指令列環境。

這種以 Debian 為基礎的虛擬機器,搭載各種您需要的開發工具。提供永久的 5 GB 主目錄,而且在 Google Cloud 中運作,大幅提高網路效能和驗證能力。換言之,本程式碼研究室只需要在 Chromebook 上運作即可。

  1. 如要透過 Cloud 控制台啟用 Cloud Shell,只要點選「啟用 Cloud Shell」 圖示 fEbHefbRynwXpq1vj2wJw6Dr17O0np8l-WOekxAZYlZQIORsWQE_xJl-cNhogjATLn-YxLVz8CgLvIW1Ncc0yXKJsfzJGMYgUeLsVB7zSwz7p6ItNgx4tXqQjag7BfWPcZN5kP-X3Q 即可 (整個佈建作業只需幾分鐘的時間,操作完畢即可)。

I5aEsuNurCxHoDFjZRZrKBdarPPKPoKuExYpdagmdaOLKe7eig3DAKJitIKyuOpuwmrMAyZhp5AXpmD_k66cBuc1aUnWlJeSfo_aTKPY9aNMurhfegg1CYaE11jdpSTYNNIYARe01A

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

連線至 Cloud Shell 後,您應會發現自己通過驗證,且專案已設為 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 控制台資訊主頁查詢:

R7chO4PKQfLC3bvFBNZJALLTUiCgyLEq_67ECX7ohs_0ZnSjC7GxDNxWrJJUaoM53LnqABYamrBJhCuXF-J9XBzuUgaz7VvaxNrkP2TAn93Drxccyj2-5zz4AxL-G3hzxZ4PsM5HHQ

根據預設,Cloud Shell 也會設定一些環境變數,方便您之後執行指令。

echo $GOOGLE_CLOUD_PROJECT

指令輸出

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

您可以選擇各種不同的可用區。詳情請參閱「區域與可用區

啟用 Cloud Run API

在 Cloud Shell 中啟用 Cloud Run API。

gcloud services enable run.googleapis.com

這樣應該就能產生類似下列內容的成功訊息:

Operation "operations/acf.cc11852d-40af-47ad-9d59-477a12847c9e" finished successfully.

3. 編寫範例應用程式

您將建構一個以 Express 為基礎的簡易型 Node.js 應用程式來回應 HTTP 要求。

如要建構應用程式,請使用 Cloud Shell 建立名為 helloworld-nodejs 的新目錄,並將目錄變更為該目錄。

mkdir helloworld-nodejs
cd helloworld-nodejs

建立含有以下內容的 package.json 檔案:

{
  "name": "cloudrun-helloworld",
  "version": "1.0.0",
  "description": "Simple hello world sample in Node",
  "main": "index.js",
  "scripts": {
    "start": "node index.js"
  },
  "author": "",
  "license": "Apache-2.0",
  "dependencies": {
    "express": "^4.17.1"
  }
}

最重要的是,上述檔案包含 start 指令碼指令和 Express 網頁應用程式架構的依附元件。

接著,在同一個目錄中建立 index.js 檔案,並將下列內容複製到檔案中:

const express = require('express');
const app = express();

app.get('/', (req, res) => {
  console.log('Hello world received a request.');

  const target = process.env.TARGET || 'World';
  res.send(`Hello ${target}!`);
});

const port = process.env.PORT || 8080;
app.listen(port, () => {
  console.log('Hello world listening on port', port);
});

這段程式碼會建立基本的網路伺服器,藉此監聽 PORT 環境變數定義的通訊埠。應用程式現在可以進行容器化、測試,並上傳至 Container Registry。

4. 將應用程式容器化並上傳至 Container Registry

如要將範例應用程式容器化,請在來源檔案所在的目錄中建立名為 Dockerfile 的新檔案,然後將下列內容複製到檔案中:

# Use the official lightweight Node.js 12 image.
# https://hub.docker.com/_/node
FROM node:12-slim

# Create and change to the app directory.
WORKDIR /usr/src/app

# Copy application dependency manifests to the container image.
# A wildcard is used to ensure both package.json AND package-lock.json are copied.
# Copying this separately prevents re-running npm install on every code change.
COPY package*.json ./

# Install production dependencies.
RUN npm install --only=production

# Copy local code to the container image.
COPY . ./

# Run the web service on container startup.
CMD [ "npm", "start" ]

接著,從內含 Dockerfile 的目錄執行下列指令,透過 Cloud Build 建立容器映像檔:

gcloud builds submit --tag gcr.io/$GOOGLE_CLOUD_PROJECT/helloworld

在 Cloud Shell 中執行時,$GOOGLE_CLOUD_PROJECT 是含有 Google Cloud 專案 ID 的環境變數。執行 gcloud config get-value project 也可以取得這項資訊。

推送至登錄檔後,您會看到包含映像檔名稱 (gcr.io/$GOOGLE_CLOUD_PROJECT/helloworld) 的 SUCCESS 訊息。映像檔儲存在 Container Registry 中,日後可以視需要重複使用。

您可以使用下列指令,列出與目前專案相關聯的所有容器映像檔:

gcloud container images list

如要在本機環境中從 Cloud Shell 執行並測試應用程式,可使用下列標準 docker 指令啟動:

docker run -d -p 8080:8080 gcr.io/$GOOGLE_CLOUD_PROJECT/helloworld

在 Cloud Shell 中,按一下「網頁預覽」圖示 170b7a95be8c6296.png,然後選取「透過以下通訊埠預覽:8080」

3618ca3a4a135570.png

系統隨即會開啟瀏覽器視窗,顯示「Hello World!」

a0307f34cacf9e6a.png

您也可以直接使用 curl localhost:8080

5. 部署至 Cloud Run

您可以使用下列指令,將容器化應用程式部署至 Cloud Run (請務必為您建構的應用程式,或是使用 gcr.io/cloudrun/hello 預先建構的映像檔,將映像檔調整為正確的映像檔名稱):

gcloud run deploy helloworld \
  --image gcr.io/$GOOGLE_CLOUD_PROJECT/helloworld \
  --platform managed \
  --region us-central1 \
  --allow-unauthenticated

--allow-unauthenticated 部署選項可讓您在不驗證的情況下觸及應用程式。--platform managed \ 部署選項表示您要求的是全代管環境 (而非透過 Anthos 的 Kubernetes 基礎架構)。

稍候片刻,等待部署作業完成。完成後,指令列會顯示服務網址。

Service [helloworld] revision [helloworld-00001] has been deployed
and is serving traffic at https://helloworld-wdl7fdwaaa-uc.a.run.app

您現在可以在網路瀏覽器中開啟服務網址,造訪您部署的容器:

63260b4d3aee42b8.png

Cloud Run 會自動及水平擴充您的容器映像檔,以處理收到的要求,然後在需求減少時縮減規模。您只需要支付處理要求期間使用的 CPU、記憶體和網路費用。

6. 清除所用資源

不使用服務時,Cloud Run 不會收費,但您可能仍須支付儲存所建構容器映像檔的費用。

如要避免產生費用,您可以刪除 Google Cloud 專案,讓該專案使用的所有資源不再產生費用。您也可以執行下列指令,直接刪除 helloworld 映像檔:

gcloud container images delete gcr.io/$GOOGLE_CLOUD_PROJECT/helloworld

如要刪除 Cloud Run 中的服務,請執行下列指令:

gcloud run services delete helloworld \
  --platform managed \
  --region us-central1

7. 恭喜

恭喜!您已將封裝在容器映像檔中的應用程式部署至 Cloud Run。

瞭解詳情

您也可以參閱快速入門導覽課程:部署至 Google Cloud 中的 Cloud Run for Anthos

如要進一步瞭解如何從程式碼來源建立適用於 Cloud Run 的無狀態 HTTP 容器,並推送至 Container Registry,請參閱下列資源:

如要進一步瞭解基礎開放原始碼專案 Knative,請參閱 Knative