借助 Cloud Run,只需三个简单的步骤,即可从开发到生产

1. 简介

为什么管理应用如此困难?

其中一个主要原因是开发者通常必须担任兼职系统管理员。请考虑以下(部分)问题列表,以便开发、部署和管理现代化的生产级 Web 应用:

4d018476b4a73b47

不知道你是谁,但这些都是我不想担心的!我真正想考虑的是应用逻辑:

6dfd143d20e5548b

简而言之,Cloud Run 就是要做的事情:让大家能够专注于自己的应用,而将所有的管理和维护工作交由其他人负责,也就是 Google,他们投入了数百万小时的时间来优化自己在该领域的技能。

除了上述管理方面的挑战,您还需要处理:

  • 依赖项 - 运行应用的环境应尽可能与测试所在的环境完全匹配。这可能涉及多个维度,包括操作系统、支持库、语言解释器或编译器、硬件配置以及许多其他因素。
  • 分发 - 若要从应用的本地版本转为在互联网上广泛分享的应用,通常需要更改运行时环境、实现复杂性方面的巨大飞跃,并完成一个陡峭的学习曲线。

Cloud Run 会为您处理这些以及许多其他问题。但我并未这样说,让我们一起构建一款应用,看看通过几个简单的步骤,从本地开发环境过渡到生产级云应用是多么容易。

实践内容…

  • 您将构建一个简单的 Web 应用,并验证该应用在开发环境中是否按预期运行。
  • 然后,移至同一应用的容器化版本。在此过程中,您将探索容器化的意义以及它为何如此有用。
  • 最后,将应用部署到云端,您会发现使用命令行和 Google Cloud 控制台管理 Cloud Run 服务是多么容易。

学习内容…

  • 如何使用 Python 创建简单的 Web 服务器应用
  • 如何将应用打包到在任何位置运行的 Docker 容器
  • 如何将应用部署到云端,以便任何人都可以试用您的新创建内容
  • 如何使用 Buildpack 进一步简化上述步骤
  • 如何使用 Google Cloud 命令行工具和 Cloud 控制台网页界面

所需条件…

  • 网络浏览器
  • Google 账号

本实验的适用对象为各种水平的开发者,包括新手。尽管您将使用 Python,但您无需熟悉 Python 编程就能理解代码内容,因为我们将为您介绍使用的所有代码。

2. 进行设置

5110b5081a1e1c49

本部分涵盖了开始此实验所需执行的所有操作。

自定进度的环境设置

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

96a9c957bc475304

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

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

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

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

启动 Cloud Shell

在本实验中,您将使用 Cloud Shell 会话,这是一个由在 Google 云中运行的虚拟机托管的命令解释器。您可以在自己的计算机本地轻松运行此部分,但借助 Cloud Shell,每个人都可以在一致的环境中获得可重现的体验。完成实验后,您可以在自己的计算机上重试本部分。

704a7b7491bd157

激活 Cloud Shell

  1. 在 Cloud Console 中,点击激活 Cloud Shell4292cbf4971c9786

bce75f34b2c53987.png

如果您以前从未启动过 Cloud Shell,系统会显示一个中间屏幕(非首屏)来介绍 Cloud Shell。如果是这种情况,请点击继续(此后您将不会再看到此通知)。一次性屏幕如下所示:

70f315d7b402b476

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

fbe3a0674c982259.png

这个虚拟机装有您需要的所有开发工具。它提供了一个持久的 5GB 主目录,并且在 Google Cloud 中运行,大大增强了网络性能和身份验证。只需使用一个浏览器或 Google Chromebook 即可完成本 Codelab 中的大部分(甚至全部)工作。

在连接到 Cloud Shell 后,您应该会看到自己已通过身份验证,并且相关项目已设置为您的项目 ID:

  1. 在 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`
  1. 在 Cloud Shell 中运行以下命令,以确认 gcloud 命令了解您的项目:
gcloud config list project

命令输出

[core]
project = <PROJECT_ID>

如果不是上述结果,您可以使用以下命令进行设置:

gcloud config set project <PROJECT_ID>

命令输出

Updated property [core/project].

在终端中设置一些环境变量,以简化后续步骤:

export PROJ=$GOOGLE_CLOUD_PROJECT 
export APP=hello 
export PORT=8080
export REGION="us-central1"
export TAG="gcr.io/$PROJ/$APP"

启用 API

在后续步骤中,您将看到需要这些服务的位置(及其原因),但现在,请运行以下命令,为您的项目授予对 Cloud Build、Container Registry 和 Cloud Run 服务的访问权限:

gcloud services enable cloudbuild.googleapis.com         \
                       containerregistry.googleapis.com  \
                       run.googleapis.com          

这将生成类似于以下内容的成功消息:

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

3. 构建简单的 Web 应用

eef530b56b8e93a3.png

首先,点击 Cloud Shell 面板顶部的 Open Editor 按钮。如下所示:

9b81c8a37a6bcdd8.png

然后,您会进入一个类似于 Visual Studio Code 的 IDE 环境中,您可以在其中创建项目、修改源代码、运行程序等。如果屏幕太狭窄,则可以通过拖动这两个区域之间的水平栏来扩大或缩小控制台与编辑/终端窗口之间的分界线,下面突出显示了相关信息:

8dea35450851af53

您可以通过分别点击 Open EditorOpen Terminal 按钮,在编辑器和终端之间来回切换。现在,请尝试在这两种环境之间来回切换。

接下来,创建一个文件夹来存储本实验中的工作内容,方法是依次选择“文件”->“新建文件夹”,输入 hello,然后点击 OK。您在本实验中创建的所有文件,以及在 Cloud Shell 中执行的所有工作,都将在此文件夹中进行。

现在,创建一个 requirements.txt 文件。这会告知 Python 您的应用依赖于哪些库。对于这个简单的 Web 应用,您将使用一个常用的 Python 模块来构建名为 Flask 的 Web 服务器,以及一个名为 gunicorn 的 Web 服务器框架。在 Cloud Editor 窗口中,依次点击“File”->“New File”菜单以创建新文件。当系统提示您输入新文件的名称时,请输入 requirements.txt 并按 OK 按钮。确保新文件最终位于 hello 项目文件夹中。

在新文件中输入以下行,指定您的应用依赖于 Python Flask 软件包和 gunicorn Web 服务器。

Flask
gunicorn

您无需明确保存此文件,因为 Cloud Editor 会自动为您保存更改。

版本 1:Hello world!

使用相同的方法,创建另一个名为 main.py 的新文件。这将是您的应用的主要(也是唯一的)Python 源文件。同样,确保新文件最终位于 hello 项目文件夹中。

将以下代码插入此文件:

from flask import Flask
import os
import random

app = Flask(__name__)  # Create a Flask object.
PORT = os.environ.get("PORT")  # Get PORT setting from the environment.

# The app.route decorator routes any GET requests sent to the root path
# to this function, which responds with a "Hello world!" HTML document.
@app.route("/", methods=["GET"])
def say_hello():
    html = "<h1>Hello world!</h1>"
    return html


# This code ensures that your Flask app is started and listens for
# incoming connections on the local interface and port 8080.
if __name__ == "__main__":
    app.run(host="0.0.0.0", port=PORT)

切换回终端,然后使用以下命令切换到项目文件夹:

cd hello

运行以下命令以安装项目依赖项:

pip3 install -r requirements.txt

现在,在终端中运行以下命令来启动您的应用:

python3 main.py

此时,您的应用正在专用于 Cloud Shell 会话的虚拟机上运行。Cloud Shell 包含一种代理机制,可让您从全球互联网的任意位置访问在虚拟机上运行的 Web 服务器(比如您刚刚启动的网络服务器)。

点击 web preview 按钮,然后点击 Preview on Port 8080 菜单项,如下所示:

fe45e0192080efd6.png

这将打开您正在运行的应用的网络浏览器标签页,如下所示:

b1f06501509aefb9.png

版本 2:与网址路径相呼应

返回 Cloud Editor(通过 Open Editor 按钮),然后通过更新 main.py 文件来添加对回显可选网址后缀的支持,如下所示:

from flask import Flask
import os
import random

app = Flask(__name__)  # Create a Flask object.
PORT = os.environ.get("PORT")  # Get PORT setting from environment.

# The app.route decorator routes any GET requests sent to the root path
# to this function, which responds with a "Hello world!" HTML document.
# If something is specified as the URL path (after the '/'), say_hello()
# responds with "Hello X", where X is the string at the end of the URL.
@app.route("/", methods=["GET"])
@app.route("/<name>", methods=["GET"])     # ← NEW
def say_hello(name="world"):               # ← MODIFIED
    html = f"<h1>Hello {name}!</h1>"       # ← MODIFIED
    return html


# This code ensures that your Flask app is started and listens for
# incoming connections on the local interface and port 8080.
if __name__ == "__main__":
    app.run(host="0.0.0.0", port=PORT)

切换回终端(通过 Open Terminal 按钮),然后输入 control-C(在按住 Control 键的同时按 C 键)停止正在运行的应用,然后输入以下命令以重启该应用:

python3 main.py

同样,依次点击 web preview 按钮和 Preview on Port 8080 菜单项,打开网络浏览器标签页并打开正在运行的应用。您应该会再次看到“Hello world!”消息,但现在将斜杠字符后面的网址文字替换为您选择的任意字符串(例如 /your-name),并验证是否显示如下内容:

93b87996f88fa370

版本 3:随机颜色

现在,通过返回 Cloud Editor(通过 Open Editor 按钮)并更新 main.py 文件,添加对随机背景颜色的支持,如下所示:

from flask import Flask
import os
import random

app = Flask(__name__)  # Create a Flask object.
PORT = os.environ.get("PORT")  # Get PORT setting from the environment.

# This function decides whether foreground text should be
# displayed in black or white, to maximize fg/bg contrast.
def set_text_color(rgb):                      # ← NEW
    sum = round(                              # ← NEW
        (int(rgb[0]) * 0.299)                 # ← NEW
        + (int(rgb[1]) * 0.587)               # ← NEW
        + (int(rgb[2]) * 0.114)               # ← NEW
    )                                         # ← NEW
    return "black" if sum > 186 else "white"  # ← NEW


# The app.route decorator routes any GET requests sent to the root path
# to this function, which responds with a "Hello world!" HTML document.
# If something is specified as the URL path (after the '/'), say_hello()
# responds with "Hello X", where X is the string at the end of the URL.
# To verify each new invocation of these requests, the HTML document
# includes CSS styling to produce a randomly colored background.
@app.route("/", methods=["GET"])
@app.route("/<name>", methods=["GET"])
def say_hello(name="world"):
    bg = random.sample(range(1, 255), 3)                       # ← NEW
    hex = (int(bg[0]) * 256) + (int(bg[1]) * 16) + int(bg[2])  # ← NEW
    fg_color = set_text_color(bg)                              # ← NEW
    bg_color = f"#{hex:06x}"                                   # ← NEW
    style = f"color:{fg_color}; background-color:{bg_color}"   # ← NEW
    html = f'<h1 style="{style}">Hello {name}!</h1>'           # ← MODIFIED
    return html


# This code ensures that your Flask app is started and listens for
# incoming connections on the local interface and port 8080.
if __name__ == "__main__":
    app.run(host="0.0.0.0", port=PORT)

切换回终端(通过 Open Terminal 按钮),然后输入 control-C(在按住 Control 键的同时按 C 键)停止正在运行的应用,然后输入以下命令以重启该应用:

python3 main.py

同样,依次点击 web preview 按钮和 Preview on Port 8080 菜单项,打开网络浏览器标签页并打开正在运行的应用。您应该会看到生成的文本,带有任何指定的后缀或默认的“Hello world!”字符串,显示在随机颜色的背景前,如下所示:

baf8d028f15ea7f4.png

重新加载页面几次,看看您每次访问应用时随机的背景颜色都会发生变化。

大功告成,恭喜!在下一步中,您将学习如何将应用打包到容器中,以及这样做的好处何在。

4. 将应用容器化

17cc234ec3325a8a

什么是容器?

一般而言,容器(尤其是 Docker)使我们能够创建一个模块化盒子,在其中运行打包在一起所有依赖项的应用。我们将结果称为容器映像。在本部分中,您将创建一个容器映像,用于封装应用及其所有依赖项。

说到依赖项,在上一步中,当您在开发者环境中运行应用时,必须运行 pip3 install -r requirements.txt,并确保 requirements.txt 文件包含所有依赖库和相应版本。借助容器,您可以在生成容器映像时满足这些要求,因此容器的使用者无需担心安装任何内容

此容器映像将构成在 Cloud Run 上部署应用的基本构建块。由于容器几乎可以在任何虚拟或真实服务器上使用,因此我们可以在您需要的任何地方部署您的应用,并且可以将您的应用从一个服务提供商迁移到另一个服务提供商,或者从本地迁移到云端。

容器可帮助您的应用:

  • 可重现 - 容器独立且完整
  • 可移植 - 容器是跨行业的构建块,可跨云提供商和环境实现应用可移植性

简而言之,容器可实现“一次编写并在任何地方运行”的功能。该规则的一个例外情况是,生成的容器被限制为在创建时所在的处理器类型上运行,但也有一些方法可以为其他硬件配置生成容器版本。

话不多说,我们来创建容器吧!您将使用一种特定的技术来创建名为 Docker 的容器。

在 Cloud Editor 中,新建一个名为 Dockerfile 的文件。此文件是构建映像的蓝图。它会告知 Docker 您的操作环境和源代码、如何安装依赖项、构建应用以及运行代码。

# Use an official lightweight Python image.
FROM python:3.9-slim

# Copy local code to the container image.
WORKDIR /app
COPY main.py .
COPY requirements.txt .

# Install dependencies into this container so there's no need to 
# install anything at container run time.
RUN pip install -r requirements.txt

# Service must listen to $PORT environment variable.
# This default value facilitates local development.
ENV PORT 8080

# Run the web service on container startup. Here you use the gunicorn
# server, with one worker process and 8 threads. For environments 
# with multiple CPU cores, increase the number of workers to match 
# the number of cores available.
CMD exec gunicorn --bind 0.0.0.0:$PORT --workers 1 --threads 8 --timeout 0 main:app

在 Cloud 终端中,通过运行以下命令使用 Cloud Build 构建容器映像:

gcloud builds submit --tag $TAG

推送到注册表后,您会看到一条包含映像名称的 SUCCESS 消息,其内容应如下所示:gcr.io/<project-id>/hello。该映像现在存储在 Google Container Registry 中,并可随时随地重复使用。

您可以使用以下命令列出与当前项目关联的所有容器映像:

gcloud container images list

现在,使用下面的 docker 命令,通过 Cloud Shell 在本地运行并测试应用:

docker run -p $PORT:$PORT -e PORT=$PORT $TAG

-p $PORT:$PORT 选项用于指示 Docker 将主机环境中的外部端口 $PORT(上面设置为 8080)映射到正在运行的容器内的同一端口号。这会简化操作,因为您编写的服务器代码和测试应用时连接的外部端口号将是相同的 (8080),但您也可以使用 -p 选项轻松使用 -p 选项,将主机上任意外部端口映射到容器内所需的任何内部端口。

-e PORT=$PORT 选项用于指示 Docker 将 $PORT 环境变量(在上述代码中设置为 8080)提供给在容器内运行的应用使用。

现在,您就可以通过网络浏览器指向容器内运行的 Python 代码来测试您的应用。在 Cloud Shell 窗口中,点击“网页预览”图标,然后选择“在端口 8080 上预览”,如上一步一样。

结果应该看起来很熟悉 - 您应该会在随机彩色的背景前看到生成的文本,就像您在 Cloud Shell 终端中直接运行应用时一样。重新加载页面几次,看看您每次访问应用时随机的背景颜色都会发生变化。

恭喜!现在,您已经运行了应用的容器化版本。在下一部分中,您会将容器映像变为生产级质量的 Web 应用,

5. 迁移到云端...

1b0665d94750ded6.gif

既然您已对应用进行了容器化,接下来想要与其他人一起分享这种酷炫功能,是时候将应用部署到云端了。但你确实希望能做的不仅仅是分享。您希望确保:

  • 运行可靠 - 在运行您应用的计算机崩溃时,您具备自动容错能力
  • 自动扩缩 - 您的应用可以跟上巨大的流量水平,并且在不使用时会自动减少其占用空间
  • 可最大限度地降低费用,因为它不会针对未使用的资源向您收费 - 您只需为响应流量时消耗的资源付费
  • 可通过自定义域名访问 - 您可以使用一键式解决方案为您的服务分配自定义域名
  • 响应时间极短,冷启动的响应速度比较快,但您可以通过指定实例数下限配置进行微调
  • 支持使用标准 SSL/TLS 网络安全的端到端加密。部署服务时,免费且自动地获得标准网络加密以及所需的相应证书

将应用部署到 Google Cloud Run 后,您可以获享上述所有优势及其他优势。

将应用部署到 Cloud Run

首先,我们来修改应用,以便能够区分新修订版本与旧修订版本。为此,请修改 main.py 文件,使默认消息从“Hello world!”更改为“Hello from Cloud Run!”。换句话说,将 main.py 中的下面这行代码从以下代码更改为:

def say_hello(name="world"):

更改为:

def say_hello(name="from Cloud Run"):

Cloud Run 是区域级的,这意味着运行 Cloud Run 服务的基础架构位于特定区域并由 Google 托管,以便在该区域内的所有可用区以冗余方式提供。在“设置”部分您已在上面的部分中通过 REGION 环境变量定义了默认区域。

使用以下命令重新构建容器映像,并将容器化应用部署到 Cloud Run:

gcloud builds submit --tag $TAG
gcloud run deploy "$APP"   \
  --image "$TAG"           \
  --platform "managed"     \
  --region "$REGION"       \
  --allow-unauthenticated
  • 您还可以使用 gcloud config set run/region $REGION 定义默认区域。
  • --allow-unauthenticated 选项可公开提供该服务。为避免出现未经身份验证的请求,请改用 --no-allow-unauthenticated

此处指定的映像是您在上一步中构建的 Docker 映像。得益于将生成的映像存储在 Google Container Registry 中的 Cloud Build 服务,Cloud Run 服务可以找到并部署该映像。

等待部署完成。 成功部署后,命令行中便会显示该服务的网址:

Deploying container to Cloud Run service [hello] in project [PROJECT_ID...
✓ Deploying new service... Done.                                   
  ✓ Creating Revision... Revision deployment finished. Waiting for health check...
  ✓ Routing traffic...
  ✓ Setting IAM Policy...
Done.
Service [hello] revision [hello-...] has been deployed and is serving 100 percent of traffic.
Service URL: https://hello-....a.run.app

您还可以使用以下命令检索服务网址:

gcloud run services describe hello  \
  --platform managed                \
  --region $REGION                  \
  --format "value(status.url)"

显示的内容应如下所示:

https://hello-....a.run.app

此链接是您的 Cloud Run 服务的专用网址,其中包含 TLS 安全性。此链接是永久性的(只要您未停用服务),可在互联网的任何地方使用。它并不使用前面提到的 Cloud Shell 的代理机制,该机制依赖于临时虚拟机。

点击突出显示的 Service URL,打开一个网络浏览器标签页,跳转到正在运行的应用。结果应该会显示“Hello from Cloud Run!”消息前附加一个随机颜色的背景。

恭喜!您的应用现在正在 Google 的云中运行。无需费心考虑,您的应用便已公开发布,支持 TLS (HTTPS) 加密,并可自动扩容至令人难以置信的流量水平。

但我认为这个过程可以更加简单...

6. 自动创建容器

一切都很酷,但是如果我不想考虑 Dockerfile 和容器呢?如果像大多数开发者一样,我只想专心编写应用代码,让其他人负责容器化,该怎么办?恭喜您,因为 Cloud Run 支持名为 Buildpack 的开源标准,而这个标准正是出于以下原因:自动执行从一系列源文件构建容器的流程。

请注意,在某些情况下,开发者可能更倾向于使用明确的 Dockerfile,例如,当他们想要对容器的构建方式进行高度自定义时。但对于像本练习这样的常见用例,build 包可以很好地满足您的需求,让您无需手动构建 Dockerfile。我们来修改代码以使用 buildpack。

首先,我们来修改应用,以便能够区分新修订版本与旧修订版本。为此,请修改 main.py 文件,使默认消息从“Hello from Cloud Run!”更改为其他消息。更改为“Hello from Cloud Run with Buildpacks!”。换句话说,将 main.py 中的下面这行代码从以下代码更改为:

def say_hello(name="from Cloud Run"):

更改为:

def say_hello(name="from Cloud Run with Buildpacks"):

现在,我们创建一个名为 Procfile 的新文件,以便利用 buildpack。接下来,在 Cloud Editor 中创建该文件并插入下面一行文本:

web: python3 main.py

这将告知构建系统如何在自动生成的容器中运行您的应用。有了这些说明,您甚至不再需要 Dockerfile。如需验证这一点,请删除 Dockerfile 并在 Cloud Shell 终端中运行以下命令:

gcloud beta run deploy "$APP"  \
    --source .                 \
    --platform "managed"       \
    --region "$REGION"         \
    --allow-unauthenticated

这类似于您在上一步中为了部署应用而运行的命令,但这次您已将 --image 选项替换为 --source . 选项。这会告知 gcloud 命令,您希望它根据在当前目录中找到的源文件(--source . 中的 dot 是当前目录的简写形式)使用 buildpack 创建容器映像。由于该服务隐式处理容器映像,因此您无需在此 gcloud 命令中指定映像。

再次确认此部署是否有效,具体方法是点击突出显示的 Service URL,打开正在运行的应用的网络浏览器标签页,并确保您的服务显示“Hello from Cloud Run with Buildpacks!”放在随机颜色的背景前面。

请注意,通过使用 buildpack 构建 Dockerfile,您已经将三个简单的步骤缩减为两个:

  1. 在开发环境中创建一个应用。
  2. 只需一个命令,即可将完全相同的代码部署到云端。

7. 是否必须使用命令行?

否!与几乎所有 Google Cloud 服务一样,您可以通过三种方式与 Cloud Run 交互:

  • 您刚刚看到的 gcloud 命令行工具。
  • 功能丰富的 Web 界面(通过 Cloud 控制台实现),支持直观的点选式互动方式。
  • 以编程方式使用适用于许多热门语言的 Google 客户端库,包括 Java、C#、Python、Go、JavaScript、Ruby、C/C++ 等。

下面我们使用控制台界面部署 Cloud Run 应用的另一个实例。通过左上方的菜单转到 Cloud Run 服务着陆页:

e2b4983b38c81796.png

然后,您应该会看到 Cloud Run 服务的摘要,如下所示:

b335e7bf0a3af845.png

点击“创建服务”开始部署过程的链接:

51f61a8ddc7a4c0b

输入“hello-again”作为服务名称,采用默认部署平台和区域,然后点击“Next”。

8a17baa45336c4c9

为容器映像输入以下网址:gcr.io/cloudrun/hello(Google 为测试目的而构建的容器),然后点击“高级设置”下拉菜单中列出了您可以使用的部分配置设置。仅指出几个可以自定义的方式:

  • 端口号和容器入口点(这将替换构建容器时指定的入口点)
  • 硬件:内存和 CPU 数量
  • 扩缩:实例数下限和上限
  • 环境变量
  • 其他:请求超时设置、每个容器的最大请求数、HTTP/2

点击“下一步”按钮以推进对话框。您可以在下一个对话框中指定服务的触发方式。对于“入站流量”,请选择“允许所有流量”;对于“身份验证”,请选择“允许未经身份验证的流量”。

e78281d1cff3418.png

这些是最自由的设置,它们允许任何人从公共互联网上的任何位置访问您的 Cloud Run 应用,而无需指定身份验证凭据。您可能需要为应用设置更严格的设置,但为了简单起见,我们在此练习中会尽量简化您的设置。

现在,点击 Create 按钮以创建 Cloud Run 服务。几秒钟后,您应该会在 Cloud Run 服务的摘要列表中看到新服务。摘要行提供最近的部署(日期/时间和执行者)以及一些关键配置设置。点击服务名称链接,深入了解有关新服务的详细信息。

如需验证您的服务,请点击摘要页面顶部附近显示的网址,如下例中突出显示的部分:

6c35cf0636dddc51

您应该会看到与以下类似的内容:

3ba6ab4fe0da1f84

现在,您已经部署了新的 Cloud Run 服务,请选择 REVISIONS 标签页,查看管理多个部署的一些方法。

2351ee7ec4a356f0

如需直接从控制台部署新的修订版本,您可以点击 EDIT & DEPLOY NEW REVISION 按钮,如下方示例屏幕截图中突出显示的那样:

a599fa88d00d6776.png

立即点击该按钮创建新修订版本。点击容器网址附近的 SELECT 按钮,如下所示:

5fd1b1f8e1f11d40

在弹出的对话框中,找到您之前使用 Buildpack 从 Cloud Build 部署的简单 Web 应用,然后点击“选择”。确保您在

gcr.io/<project>/cloud-run-source-deploy

folder,如下所示:

8a756c6157face3a

选择后,滚动到底部,然后点击 DEPLOY 按钮。现在,您已经部署了应用的新修订版本。如需进行验证,请再次重新访问您的服务网址,并验证您现在是否看到彩色的“Hello from Cloud Run with Buildpacks!”Web 应用。

如您所见,“修订版本”标签页提供了已部署的每个修订版本的摘要,您现在应该会看到此服务的两个修订版本。您可以点击修订版本名称左侧的单选按钮来选择给定修订版本,该单选按钮将在屏幕右侧显示修订版本详情的摘要。选择这些按钮后,您可以看到您的两个修订版本源自两个不同的容器映像。

借助 MANAGE TRAFFIC 按钮,您可以修改发送到指定修订版本的传入请求的分配情况。这种对发送到给定修订版本的流量进行微调的功能可实现多种有价值的用例:

  • 使用一小部分传入流量对应用的新版本进行 Canary 测试
  • 将来自有问题的版本的流量还原到先前修订版本
  • A/B 测试

您可以在此处找到 MANAGE TRAFFIC 按钮:

519d3c22ae028287

通过指定 50/50 的流量分配比例,在两个修订版本之间配置 50/50 的流量分配比例,如下所示:

8c37d4f115d9ded4

现在,点击“Save”(保存)按钮,并通过反复访问服务的网址来验证按 50/50 的比例分配比例,然后检查是否平均而言,一半的请求由当前版本(“Hello from Cloud Run with Buildpacks!”)处理,一半的请求由先前修订版本提供(“它正在运行!”)。

“服务详情”页面中的其他标签页提供了监控性能、流量和日志的功能,可让您深入了解服务的难易程度和运行状况。您还可以通过“权限”页面微调对服务的访问权限标签页。请花些时间浏览此页面上的各个标签,了解此处提供的功能。

程序化界面

如前所述,您还可以选择以编程方式创建、部署和管理 Cloud Run 服务。对于手动任务,此选项比命令行或 Web 控制台更高级,但它绝对是自动执行 Cloud Run 服务的理想选择。您可以选择使用多种常用编程语言的 Google 客户端库

8. 测试您的应用

198ada162d1f0bf1.png

在最后一步中,您将运行一项人为负载测试,对您的应用进行压力测试,并观察应用如何随传入需求进行扩缩。您将使用一个名为 hey 的工具,此工具已预安装在 Cloud Shell 中,让我们能够运行负载测试并显示结果。

运行测试

在 Cloud Shell 终端中,运行以下命令来运行负载测试:

hey -q 1000 -c 200 -z 30s https://hello-...run.app

命令参数的解释如下:

  • -q 1000 - 尝试以大约每秒 1,000 个请求的速度提升负载
  • -c 200 - 分配 200 个并行工作器
  • -z 30s - 运行负载测试 30 秒
  • 务必将您的服务网址用作此命令行中的最后一个参数

测试结果应如下所示:

 Summary:
 Total:        30.2767 secs
 Slowest:      3.3633 secs
 Fastest:      0.1071 secs
 Average:      0.1828 secs
 Requests/sec: 1087.2387
 Total data:   3028456 bytes
 Size/request: 92 bytes

Response time histogram:
 0.107 [1]     |
 0.433 [31346] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
 0.758 [1472]  |■■
 1.084 [82]    |
 1.410 [4]     |
...

Latency distribution:
...
 50% in 0.1528 secs
 75% in 0.1949 secs
 90% in 0.2442 secs
 95% in 0.4052 secs
 99% in 0.7062 secs

Details (average, fastest, slowest):
...
 req write:    0.0000 secs, 0.0000 secs, 0.0232 secs
 resp wait:    0.1824 secs, 0.1070 secs, 3.2953 secs
 resp read:    0.0000 secs, 0.0000 secs, 0.0010 secs
Status code distribution:
 [200] 32918 responses

此摘要告诉我们一些值得注意的内容:

  • 以大约 1K/秒的速度发送 32,918 个请求,持续 30 秒。
  • 无错误(只有 200 个 HTTP 响应)。
  • 平均延迟时间为 180 毫秒。
  • 最短延迟时间为 107 毫秒,最糟糕的情况为 3.3 秒
  • 第 90 百分位的延迟时间为 244 毫秒。

如果您查看 Cloud Run 控制台上的 METRICS 标签页,则可以了解服务器端的性能情况:

e635c6831c468dd3.png

9. 清理

虽然 Cloud Run 不会针对未使用的服务收费,但您可能仍然需要为您构建的容器映像支付存储费用。

您可以删除 GCP 项目以避免产生费用(这会导致系统停止对该项目中使用的所有资源计费),或者使用以下命令直接删除您的容器映像:

gcloud container images delete $TAG

如需删除 Cloud Run 服务,请使用以下命令:

gcloud run services delete hello --platform managed --region $REGION --quiet
gcloud run services delete hello-again --platform managed --region $REGION --quiet

10. 您做到了!

9a31f4fdbbf1ddcb

恭喜 - 您已成功构建和部署正式版 Cloud Run 应用。在此过程中,您了解了容器以及如何构建自己的容器。您了解了使用 gcloud 命令行工具和 Cloud 控制台通过 Cloud Run 部署应用是多么容易。现在,你已经知道如何与全世界分享你的精彩创意了!

我想给大家留下一个重要的问题:

让您的应用在开发者环境中运行后,要使用 Cloud Run 提供的所有生产级属性,您必须修改多少行代码才能将其部署到云端?

答案当然是零。:)

值得查看的 Codelab...

其他炫酷功能等您探索...

参考文档…

11. 号召性用语

Google Cloud 徽标

如果您喜欢此 Codelab,并且可能会花更多时间亲自体验 Google Cloud,那么真正应该加入 Google Cloud Innovators 计划

创新者一般成员徽章徽标

Google Cloud Innovators 完全免费,包含以下内容:

  • 通过实时讨论、AMA 和路线图会议,直接向 Google 员工学习最新动态
  • 最新的 Google Cloud 资讯直接送到您的收件箱
  • 数字徽章和视频会议背景
  • 价值 500 积分的 Skills Boost 实验和学习积分

点击此处报名!