1. 總覽
簡介
在本程式碼研究室中,您將學習如何部署使用多個容器的 Cloud Run 服務。您將建立 node.js 應用程式做為 Cloud Run 輸入容器,以及做為補充資訊使用的 node.js 應用程式。
技術總覽
在 Cloud Run 執行個體中使用多個容器時,會有一個容器做為網路輸入的主要容器。一或多個額外容器稱為「補充容器」。
不同容器可透過以下兩種方式進行通訊:
- 容器會共用 localhost 網路介面,因此所有容器都能監聽通訊埠,例如:localhost:port.
- 您也可以使用記憶體內的磁碟區,將這些磁碟區掛接至容器以共用檔案。
用途
由於 Cloud Run 執行個體中的所有容器都共用 localhost 網路介面,因此您可以在主要容器前方使用補充資訊透過 Proxy 傳送要求。這類 Proxy 可攔截要求並轉送至適當的端點,在用戶端和伺服器之間提高應用程式流量的效率,提供額外的抽象層。例如,您可以使用 DockerHub 中的官方 Nginx 映像檔 (如這裡所示)。
多個容器可以透過共用磁碟區共用檔案,因此您可以新增各種補充資訊應用程式到您的服務。舉例來說,您可以檢測 Cloud Run 服務,以便使用 OpenTelemetry 等自訂代理程式來匯出記錄檔、指標和追蹤記錄 (OpenTelemetry 範例)。另一個例子是使用補充資訊連結至 Cloud Spanner PostgreSQL 資料庫 (Cloud Spanner Postgress 範例)。
本程式碼研究室的範例
在本程式碼研究室中,首先要部署 Cloud Run 服務,其輸入容器透過 localhost 通訊埠與補充容器進行通訊。接著,請更新 Ingress 容器和補充資訊,透過磁碟區掛接來分享檔案。
課程內容
- 如何建立使用補充容器的容器
- Ingress 容器如何使用 localhost 與補充容器通訊
- Ingress 容器和補充資訊可以透過掛接的磁碟區如何共用檔案
2. 設定和需求
必要條件
- 您已登入 Cloud 控制台。
- 先前已部署 Cloud Run 服務。舉例來說,您可以按照從原始碼部署網路服務的快速入門導覽課程著手。
啟用 Cloud Shell
- 在 Cloud 控制台中,按一下「啟用 Cloud Shell」圖示 。
如果您是第一次啟動 Cloud Shell,系統會顯示中繼畫面,說明這項服務的內容。如果系統顯示中繼畫面,請按一下「繼續」。
佈建並連線至 Cloud Shell 只需幾分鐘的時間。
這個虛擬機器已載入所有必要的開發工具。提供永久的 5 GB 主目錄,而且在 Google Cloud 中運作,大幅提高網路效能和驗證能力。在本程式碼研究室中,您的大部分作業都可透過瀏覽器完成。
連線至 Cloud Shell 後,您應會發現自己通過驗證,且專案已設為您的專案 ID。
- 在 Cloud Shell 中執行下列指令,確認您已通過驗證:
gcloud auth list
指令輸出
Credentialed Accounts ACTIVE ACCOUNT * <my_account>@<my_domain.com> To set the active account, run: $ gcloud config set account `ACCOUNT`
- 在 Cloud Shell 中執行下列指令,確認 gcloud 指令知道您的專案:
gcloud config list project
指令輸出
[core] project = <PROJECT_ID>
如果尚未設定,請使用下列指令進行設定:
gcloud config set project <PROJECT_ID>
指令輸出
Updated property [core/project].
3. 建立 Ingress 應用程式
設定環境變數
在本程式碼研究室中,您將建立幾個環境變數,改善本程式碼研究室中使用的 gcloud
指令可讀性。
REGION=<YOUR-REGION> PROJECT_ID=<YOUR-PROJECT-ID> SERVICE_NAME=sidecar-codelab REPO_NAME=sidecar-codelab
建立 ArtifactRegistry 存放區來存放容器映像檔
您可以在 Artifact Registry 中建立存放區,以儲存這個程式碼研究室的容器映像檔。
gcloud artifacts repositories create $REPO_NAME --repository-format=docker \ --location=$REGION --description="sidecar codelab"
接著,建立含有以下內容的 package.json
檔案:
{ "name": "sidecar-codelab", "version": "1.0.0", "private": true, "description": "demonstrates how to use sidecars in cloud run", "main": "index.js", "author": "Google LLC", "license": "Apache-2.0", "scripts": { "start": "node ingress.js" }, "dependencies": { "axios": "^1.6.2", "express": "^4.18.2" } }
現在建立名為 ingress.js
的檔案,並在其中加入下列內容:
const express = require('express'); const app = express(); const axios = require("axios"); app.get('/', async (req, res) => { let response = await axios.get("http://localhost:5000"); res.send("The sidecar says: " + response.data); }); const port = parseInt(process.env.PORT) || 8080; app.listen(port, () => { console.log(`Ingress container listening on port ${port}`); });
為輸入容器建立 dockerfile
FROM node:20.10.0-slim WORKDIR /usr/src/app COPY package*.json ./ RUN npm install --production # Copy local code to the container image. COPY . . # Run the web service on container startup. ENV PORT=8080 CMD [ "npm", "start" ]
接著為 Ingress 容器建立 ``.dockerignore` 檔案。
# Exclude locally installed dependencies node_modules/ # Exclude "build-time" ignore files. .dockerignore .gcloudignore # Exclude git history and configuration. .gitignore
現在您可以執行下列指令,建構 Ingress 容器的映像檔:
gcloud builds submit --tag $REGION-docker.pkg.dev/$PROJECT_ID/$REPO_NAME/ingress:latest
4. 建立補充資訊應用程式
在本節中,您將建立第二個 node.js 應用程式,用來做為 Cloud Run 服務中的補充容器。
前往補充資訊目錄。
cd ../sidecar
建立含有以下內容的 package.json
檔案:
{ "name": "sidecar-codelab", "version": "1.0.0", "private": true, "description": "demonstrates how to use sidecars in cloud run", "main": "index.js", "author": "Google LLC", "license": "Apache-2.0", "scripts": { "start": "node sidecar.js" }, "dependencies": { "axios": "^1.6.2", "express": "^4.18.2" } }
現在建立名為 sidecar.js
的檔案,並在其中加入下列內容:
const express = require('express'); const app = express(); app.get('/', async (req, res) => { res.send("Hello ingress container! I'm the sidecar."); }); const port = parseInt(process.env.PORT || 5000); app.listen(port, () => { console.log(`Sidecar container listening on port ${port}`); });
建立補充資訊容器的 Dockerfile
FROM node:20.10.0-slim WORKDIR /usr/src/app COPY package*.json ./ RUN npm install --production # Copy local code to the container image. COPY . . # Run the web service on container startup. ENV PORT=5000 CMD [ "npm", "start" ]
接著為補充資訊容器建立 ``.dockerignore` 檔案。
# Exclude locally installed dependencies node_modules/ # Exclude "build-time" ignore files. .dockerignore .gcloudignore # Exclude git history and configuration. .gitignore
現在您可以執行下列指令,建構 Ingress 容器的映像檔:
gcloud builds submit --tag $REGION-docker.pkg.dev/$PROJECT_ID/$REPO_NAME/sidecar:latest
部署 Cloud Run 服務
您也會使用 yaml 檔案部署 Cloud Run 服務。
前往父項目錄。
cd ..
建立名為 sidecar-codelab.yaml
的檔案,並在其中加入下列內容:
apiVersion: serving.knative.dev/v1 kind: Service metadata: annotations: name: sidecar-codelab labels: cloud.googleapis.com/location: "<YOUR_REGION>" spec: template: spec: containers: - image: "<YOUR_REGION>-docker.pkg.dev/<YOUR_PROJECT_ID>/sidecar-codelab/ingress:latest" ports: - containerPort: 8080 - image: "<YOUR_REGION>-docker.pkg.dev/<YOUR_PROJECT_ID>/sidecar-codelab/sidecar:latest" env: - name: PORT value: "5000"
接著使用下列指令來部署服務。由於磁碟區掛接為公開預先發布版,您必須使用 gcloud beta。
gcloud beta run services replace sidecar-codelab.yaml
部署完成後,將服務網址儲存在環境變數中。
SERVICE_URL=$(gcloud run services describe $SERVICE_NAME --platform managed --region $REGION --format 'value(status.url)')
5. 呼叫 Cloud Run 服務
您現在可以提供識別權杖來呼叫服務。
curl -X GET -H "Authorization: Bearer $(gcloud auth print-identity-token)" ${SERVICE_URL}
結果應該會與下方的範例輸出內容類似:
The sidecar says: Hello ingress container! I'm the sidecar.
6. 透過磁碟區掛接來共用檔案
在本節中,您將更新容器,透過磁碟區掛接來共用檔案。在這個範例中,輸入容器會寫入共用磁碟區中的檔案。補充資訊會讀取檔案並將內容傳回 Ingress 容器。
首先,請更新 Ingress 容器程式碼。前往輸入目錄。
cd ../ingress
然後將 ingress.js
檔案的內容替換為以下內容:
const express = require('express'); const app = express(); const fs = require('fs'); const axios = require("axios"); const filename = "test.txt" let path = "/my-volume-mount"; app.use(path, express.static(path)); try { fs.writeFileSync(`${path}/${filename}`, "The ingress container created this file."); } catch (err) { console.error(err); } app.get('/', async (req, res) => { let response = await axios.get("http://localhost:5000"); res.send("The sidecar says: " + response.data); }); const port = parseInt(process.env.PORT) || 8080; app.listen(port, () => { console.log(`Ingress container listening on port ${port}`); });
接著執行下列指令,為 Ingress 容器建構新映像檔:
gcloud builds submit --tag $REGION-docker.pkg.dev/$PROJECT_ID/$REPO_NAME/ingress:latest
現在請前往補充資訊目錄:
cd ../sidecar
並以下列內容更新 sidecar.js
:
const express = require('express'); const app = express(); const fs = require('fs'); const filename = "test.txt" let path = "/my-volume-mount"; app.use(path, express.static(path)); async function readFile() { try { return await fs.readFileSync(`${path}/${filename}`, { encoding: 'utf8' }); } catch (err) { console.log(err); } } app.get('/', async (req, res) => { let contents = await readFile(); res.send(contents); }); const port = parseInt(process.env.PORT || 5000); app.listen(port, () => { console.log(`Sidecar container listening on port ${port}`); });
接著執行下列指令,為補充資訊容器建立新映像檔:
gcloud builds submit --tag $REGION-docker.pkg.dev/$PROJECT_ID/$REPO_NAME/sidecar:latest
使用下列指令更新 sidecar-codelab.yaml
以共用磁碟區:
apiVersion: serving.knative.dev/v1 kind: Service metadata: annotations: name: sidecar-codelab labels: cloud.googleapis.com/location: "<YOUR_REGION>" spec: template: spec: containers: - image: "<YOUR_REGION>-docker.pkg.dev/<YOUR_PROJECT_ID>/sidecar-codelab/ingress:latest" ports: - containerPort: 8080 volumeMounts: - mountPath: /my-volume-mount name: in-memory-1 - image: "<YOUR_REGION>-docker.pkg.dev/<YOUR_PROJECT_ID>/sidecar-codelab/sidecar:latest" env: - name: PORT value: "5000" volumeMounts: - mountPath: /my-volume-mount name: in-memory-1 volumes: - emptyDir: medium: Memory name: in-memory-1
部署更新後的 sidecar-codelab.yaml
檔案
gcloud beta run services replace sidecar-codelab.yaml
您現在可以提供識別權杖來呼叫服務。
curl -X GET -H "Authorization: Bearer $(gcloud auth print-identity-token)" ${SERVICE_URL}
結果應該會與下方的範例輸出內容類似:
The sidecar says: the ingress container created this file.
7. 恭喜!
恭喜您完成本程式碼研究室!
建議您詳閱 Cloud Run 的說明文件,特別是部署多容器及使用記憶體內磁碟區掛接。
涵蓋內容
- 如何建立使用補充容器的容器
- Ingress 容器如何使用 localhost 與補充容器通訊
- Ingress 容器和補充車輛如何共用已掛接的磁碟區
8. 清除所用資源
為避免產生意外費用 (舉例來說,如果不小心叫用這個 Cloud 函式的次數超出免費方案的每月 Cloud Run 叫用分配數量),您可以刪除 Cloud Run 服務,或刪除步驟 2 建立的專案。
如要刪除 Cloud 函式,請前往 Cloud 函式 Cloud 控制台 (https://console.cloud.google.com/run/),然後刪除 sidecar-codelab
服務 (若您使用其他名稱,則會看到 $SERVICE_NAME)。
如果選擇刪除整個專案,您可以前往 https://console.cloud.google.com/cloud-resource-manager,選取您在步驟 2 建立的專案,然後選擇「刪除」。如果刪除專案,您必須變更 Cloud SDK 中的專案。您可以執行 gcloud projects list
來查看可用專案的清單。