使用 Cloud Run on Node.js 部署并运行容器

1. 准备工作

6a5cf23c8e20491f

Cloud Run 是一个代管式计算平台,供您运行可通过 HTTP 请求调用的无状态容器。Cloud Run 采用无服务器架构;因此您无需管理基础架构,因此可以专注于最重要的工作,即构建出色的应用。它基于 Knative 构建而成,可让您选择使用 Cloud Run(全代管式)或 Cloud Run for Anthos 来运行容器。此 Codelab 的目标是构建容器映像并将其部署到 Cloud Run。

前提条件

不适用

2. 设置和要求

自定进度的环境设置

  1. 登录 Cloud 控制台,然后创建一个新项目或重复使用现有项目。 (如果您还没有 Gmail 或 G Suite 账号,则必须创建一个。)

dMbN6g9RawQj_VXCSYpdYncY-DbaRzr2GbnwoV7jFf1u3avxJtmGPmKpMYgiaMH-qu80a_NJ9p2IIXFppYk8x3wyymZXavjglNLJJhuXieCem56H30hwXtd8PvXGpXJO9gEUDu3cZw

ci9Oe6PgnbNuSYlMyvbXF1JdQyiHoEgnhl4PlV_MFagm2ppzhueRkqX4eLjJllZco_2zCp0V0bpTupUSKji9KkQyWqj11pqit1K1faS1V6aFxLGQdkuzGp4rsQTan7F01iePL5DtqQ

8-tA_Lheyo8SscAVKrGii2coplQp2_D1Iosb2ViABY0UUO1A8cimXUu6Wf1R9zJIRExL5OB2j946aIiFtyKTzxDcNnuznmR45vZ2HMoK3o67jxuoUJCAnqvEX6NgPGFjCVNgASc-lg

请记住项目 ID,它在所有 Google Cloud 项目中都是唯一的名称(上述名称已被占用,您无法使用,抱歉!)。它稍后将在此 Codelab 中被称为 PROJECT_ID

  1. 接下来,您需要在 Cloud 控制台中启用结算功能,才能使用 Google Cloud 资源。

运行此 Codelab 应该不会产生太多的费用(如果有费用的话)。请务必按照“清理”部分部分,其中会指导您如何关停资源,以免产生超出本教程范围的结算费用。Google Cloud 的新用户符合参与 $300 USD 免费试用计划的条件。

Cloud Shell

虽然可以通过笔记本电脑远程操作 Google Cloud,但您需要使用 Cloud Shell,这是一个在 Google Cloud 中运行的命令行环境。

基于 Debian 的这个虚拟机已加载了您需要的所有开发工具。它提供了一个持久的 5GB 主目录,并且在 Google Cloud 中运行,大大增强了网络性能和身份验证。这意味着在本 Codelab 中,您只需要一个浏览器(没错,它适用于 Chromebook)。

  1. 如需从 Cloud Console 激活 Cloud Shell,只需点击激活 Cloud ShellfEbHefbRynwXpq1vj2wJw6Dr17O0np8l-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 Console 信息中心查找该 ID:

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 Web 应用框架依赖项。

接下来,在同一目录中,创建一个 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);
});

该代码会创建一个基本 Web 服务器,监听由 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

$GOOGLE_CLOUD_PROJECT 是一个环境变量,其中包含在 Cloud Shell 中运行时的 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,然后选择在端口 8080 上预览

3618ca3a4a135570

系统随即会打开一个显示 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

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。

了解详情

建议您查看快速入门:部署到 Cloud Run for Anthos on Google Cloud

如需详细了解如何使用源代码构建适用于 Cloud Run 的无状态 HTTP 容器并将其推送到 Container Registry,请参阅以下资源:

如需详细了解底层开源项目 Knative,请参阅 Knative