1. 概览
简介
在此 Codelab 中,您将学习如何部署使用多个容器的 Cloud Run 服务。您将创建一个 Node.js 应用,用作 Cloud Run 入站流量容器,并创建一个额外的 Node.js 应用,用作辅助信息文件。
技术概览
在 Cloud Run 实例中使用多个容器时,其中一个容器用作 Web 入站流量的主要容器。一个或多个附加容器称为边车。
多个容器之间可以通过以下两种方式进行通信:
- 容器共享 localhost 网络接口,因此所有容器都可以监听某个端口(例如 localhost:port)。
- 您还可以使用内存中卷并将其装载到容器上以共享文件。
使用场景
由于 Cloud Run 实例中的所有容器共享 localhost 网络接口,因此您可以在主容器前面使用边车来代理请求。此类代理可以拦截请求并将其转发到相应的端点,从而为客户端与服务器之间更高效的应用流量提供额外的抽象层。例如,您可以使用 DockerHub 中的官方 Nginx 映像(如此处所示)。
由于多个容器可以通过共享卷共享文件来通信,因此您可以向服务添加各种边车应用。例如,您可以对 Cloud Run 服务进行插桩,以使用 OpenTelemetry 等自定义代理导出日志、指标和跟踪记录(OpenTelemetry 示例)。另一个示例是使用边车连接到 Cloud Spanner PostgreSQL 数据库 (Cloud Spanner Postgress 示例)。
此 Codelab 中的示例
在此 Codelab 中,您将首先部署一个 Cloud Run 服务,其中入站流量容器通过 localhost 端口与边车通信。然后,您将更新入站流量容器和边车,以通过卷装载共享文件。
学习内容
- 如何创建使用边车的容器
- 入站流量容器如何使用 localhost 与边车通信
- Ingress 容器和边车如何通过装载的卷共享文件
2. 设置和要求
前提条件
- 您已登录 Cloud 控制台。
- 您之前已部署过 Cloud Run 服务。例如,您可以按照从源代码部署 Web 服务快速入门中的步骤开始操作。
激活 Cloud Shell
- 在 Cloud Console 中,点击激活 Cloud Shell
。

如果您是第一次启动 Cloud Shell,系统会显示一个介绍其功能的过渡页面。如果您看到了过渡页面,请点击继续。

预配和连接到 Cloud Shell 只需花几分钟时间。

这个虚拟机已加载了所需的所有开发工具。它提供了一个持久的 5 GB 主目录,并且在 Google Cloud 中运行,大大增强了网络性能和身份验证。只需使用一个浏览器即可完成本 Codelab 中的大部分工作。
连接到 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. 创建入站流量应用
设置环境变量
在此 Codelab 中,您将创建一些环境变量,以提高本 Codelab 中使用的 gcloud 命令的可读性。
REGION=<YOUR-REGION> PROJECT_ID=<YOUR-PROJECT-ID> SERVICE_NAME=sidecar-codelab REPO_NAME=sidecar-codelab
创建 ArtifactRegistry 制品库以存放容器映像
您可以在 Artifact Registry 中创建一个代码库,用于存储此 Codelab 的容器映像。
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}`);
});
为 Ingress 容器创建 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" ]
并为入口容器创建 `.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. 通过卷装载共享文件
在本部分中,您将更新容器,以通过卷挂载共享文件。在此示例中,入口容器将写入共享卷上的文件。边车将读取该文件,并将其内容返回给入站容器。
首先,您需要更新入口容器代码。导航到入口目录。
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. 恭喜!
恭喜您完成此 Codelab!
我们建议您查看有关 Cloud Run 的文档,特别是有关部署多容器和使用内存中卷装载的文档。
所学内容
- 如何创建使用边车的容器
- 入站流量容器如何使用 localhost 与边车通信
- Ingress 容器和边车如何共享已装载的卷
8. 清理
为避免产生意外费用(例如,如果此 Cloud Functions 函数被意外调用的次数超过了免费层级中每月 Cloud Run 调用次数的分配额度),您可以删除 Cloud Run 服务或删除您在第 2 步中创建的项目。
如需删除 Cloud Functions 函数,请前往 Cloud Functions 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 查看所有可用项目的列表。