配置自动基础映像更新

通过为 Cloud Run 配置自动基础映像更新,使 Google 能够自动为基础映像的操作系统和语言运行时组件进行安全补丁。您无需重新构建或重新部署服务即可更新基础映像。更新基础映像时,系统不会创建新的修订版本。

下图显示了应用代码和依赖项(“应用映像”)如何在语言运行时、操作系统软件包和操作系统(“基础映像”)之上分层。Google 会自动更新基础映像的组件。

Cloud Run 基础映像示意图

如需配置基础映像自动更新,请执行以下操作:

  • 选择兼容的 Cloud Run 基础映像。
  • 构建和部署应用映像的方式应能保留安全地重新设置正在运行的服务的能力。

选择基础映像

基础映像是大多数基于容器的开发工作流的起点。开发者从基础映像开始,在其上叠加用于运行应用的必要库、二进制文件和配置文件。

Google Cloud 的 Buildpack 发布和维护用于构建无服务器应用的基础映像。这些基础映像基于 Ubuntu Linux 发行版构建。

Cloud Run 仅支持使用 Google Cloud 的 Buildpack 基础映像的自动基础映像。

选择 Google Cloud 的 Buildpack 时,您必须考虑以下事项:

  • 堆栈堆栈由 Linux 发行版版本和系统软件包(例如 OpenSSL 和 curl)组成。
  • 语言:应用使用的编程语言的具体版本

如需详细了解基础映像变体,请参阅运行时基础映像

构建应用映像

启用了自动更新的服务将需要提供省略基本操作系统层的应用映像。有两种方法可以做到这一点:

从源代码部署

您可以使用 Cloud Run 从源代码部署功能构建和部署代码,使您的服务与接收自动更新兼容。为此,您必须在创建应用时提供 --base-image 标志。

例如,如需部署启用了自动基础映像更新的 Node.js 服务或函数,您可以使用以下命令:

gcloud beta run deploy \
  --source . \
  --base-image nodejs20

scratch 上构建

您还可以使用构建工具链来创建与自动基础映像更新兼容的应用容器映像。

当您部署具有自动基础映像更新的 Cloud Run 服务时,应用容器映像会在基础容器映像上分层。应用容器映像应仅包含应用,而非基础容器映像中提供的操作系统或运行时。

如需创建应用容器映像,请执行以下操作:

  1. 创建一个多阶段 Dockerfile,用于:
    1. 使用包含所需依赖项的适当基础映像构建应用。
    2. 将构建的组件复制到暂存映像上。
  2. 构建应用容器映像并将其推送到 Artifact Registry。
  3. 将应用容器映像部署到 Cloud Run,并指定基础映像。

创建多阶段 Dockerfile

在本指南中,我们将使用 Node.js 应用。本指南不局限于特定语言,可根据您的应用和语言进行自定义。

  • 在项目的根目录中创建一个 Dockerfile,其中包含以下内容:

    # This Dockerfile will produce an image that only includes the Node.js app and *not* the Node.js runtime.
    # The resulting image will not run locally. It is intented at being layered on top of a Node.js base image.
    
    FROM node:20-slim as builder
    
    # Create and change to the app directory.
    WORKDIR /usr/src/app
    
    # Copy application dependency manifests to the container image and install
    # production dependencies.
    COPY package*.json ./
    RUN npm install --only=production
    
    # Copy local code to the container image.
    COPY . ./
    
    # Copy the application source code and depenencies onto a scratch image.
    FROM scratch
    WORKDIR /workspace
    COPY --from=builder --chown=33:33 /usr/src/app/ ./
    
    # Run the web service on container startup.
    CMD [ "node", "index.js" ]
    

此 Dockerfile 使用多阶段构建将应用源代码和依赖项复制到 scratch 映像,该映像会省略 Cloud Run 托管式基础映像在运行时提供的操作系统、软件包和运行时组件。

构建应用映像

构建应用映像并将其上传到 Artifact Registry。如需详细了解如何使用 Cloud Build 构建 Dockerfile 并将其上传到 Artifact Registry,请参阅构建容器

部署应用映像

现在,您可以使用与应用最兼容的基础映像,部署已启用自动更新的应用映像了。在本示例中,我们将使用 us-central1 中的 Node.js 20 运行时。如需详细了解基础映像变体,请参阅运行时基础映像

如需详细了解所需的角色和权限,请参阅将容器映像部署到 Cloud Run

gcloud

  1. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

    At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.

  2. 如需在部署应用映像时为 Node.js 20 运行时启用自动更新,请运行以下命令:

    gcloud beta run deploy SERVICE \
    --image APP_IMAGE \
    --base-image BASE_IMAGE

    您需要进行如下替换:

    • SERVICE 替换为您要部署到的服务的名称。
    • APP_IMAGE 替换为应用容器映像的网址。
    • BASE_IMAGE 替换为基础映像的网址,例如 nodejs20us-central1-docker.pkg.dev/serverless-runtimes/google-22/runtimes/nodejs20。如需详细了解基础映像变体,请参阅运行时基础映像

YAML

  1. 如果您要创建新的服务,请跳过此步骤。如果您要更新现有服务,请下载其 YAML 配置

    gcloud run services describe SERVICE --format export > service.yaml
  2. 更新 runtimeClassNamerun.googleapis.com/base-images 注解:

    apiVersion: serving.knative.dev/v1
    kind: Service
    metadata:
    name: SERVICE
    annotations:
      ...
      run.googleapis.com/launch-stage: BETA
      ...
    spec:
    template:
      metadata:
        annotations:
          run.googleapis.com/base-images: '{"NAME":"BASE_IMAGE"}'
        spec:
          containers:
          - name: NAME
            image: APP_IMAGE
          runtimeClassName: run.googleapis.com/linux-base-image-update

    您需要进行如下替换:

    • SERVICE 替换为您要部署到的服务的名称。
    • APP_IMAGE 替换为应用容器映像的网址。
    • BASE_IMAGE 替换为基础映像的网址,例如 us-central1-docker.pkg.dev/serverless-runtimes/google-22/runtimes/nodejs20。如需详细了解基础映像变体,请参阅运行时基础映像

重组容器映像以在本地运行

在与自动基础映像更新结合使用的自动容器映像基于 scratch 构建,无法在启用了基础映像更新的 Cloud Run 之外运行。您可以通过在兼容的基础映像上对应用映像变基来使应用映像可运行。

  1. 在工作站上安装 Docker 社区版 (CE)

  2. 下载应用映像:

    docker pull APP_IMAGE
    

    您需要进行如下替换:

    • APP_IMAGE 替换为容器映像的网址。
  3. 下载基础映像:

    docker pull BASE_IMAGE
    

    您需要进行如下替换:

    • BASE_IMAGE 替换为兼容的基础映像的网址。如需查看可用的基础映像列表,请参阅 Google Cloud 的 Buildpack 基础映像。例如,如果您使用 google-22 创建了 Node.JS 20 应用,则应选择 us-central1-docker.pkg.dev/serverless-runtimes/google-22/runtimes/nodejs20:latest
  4. 重组映像:

    使用 Dockerfile 将应用映像中的所有文件复制回基础映像:

    ARG APP_IMAGE
    ARG NEW_BASE_IMAGE
    
    # first copy all files from the app image onto the builder image
    FROM ${APP_IMAGE} AS app
    FROM ${NEW_BASE_IMAGE} AS builder
    COPY --from=app / /
    
    # restore the app image config by copying everything from previous step back
    # back onto the app image
    FROM ${APP_IMAGE}
    COPY --from=builder / /
    

    构建映像:

    docker build \
        -t IMAGE \
        --build-arg APP_IMAGE=APP_IMAGE \
        --build-arg NEW_BASE_IMAGE=BASE_IMAGE \
        .
    

    您需要进行如下替换:

    • IMAGE 替换为您重新组合后的映像的名称。

    如果您看到 ARG ${APP_IMAGE}ARG ${NEW_BASE_IMAGE} 不是有效基础映像的警告,可以放心地忽略这些警告并运行映像:

    docker run -p 8080:8080 IMAGE
    

停用自动更新

从源代码部署时

从源代码部署时,您可以使用 --no-automatic-updates 标志停用自动基础映像更新。以下示例展示了如何为 Node.js 服务停用自动基础映像更新:

gcloud

gcloud beta run deploy SERVICE \
    --source . \
    --base-image nodejs20 \
    --no-automatic-updates

部署容器映像时

如需为使用基于暂存映像构建的容器映像的服务停用基础映像更新,您必须部署包含基础映像的新容器映像并移除基础映像:

gcloud

  1. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

    At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.

  2. 如需停用自动基础映像更新,请运行以下命令:

    gcloud beta run deploy SERVICE \
        --image IMAGE \
        --base-image ""

    您需要进行如下替换:

    • SERVICE 替换为您要部署到的服务的名称。
    • IMAGE 替换为包含应用、运行时和操作系统的容器映像的网址。

YAML

  1. 如果您要创建新的服务,请跳过此步骤。如果您要更新现有服务,请下载其 YAML 配置

    gcloud run services describe SERVICE --format export > service.yaml
  2. 删除 run.googleapis.com/base-images 注解。

  3. 删除 runtimeClassName 属性。

  4. image 中,请务必使用包含应用、运行时和操作系统的容器映像。

  5. 使用以下命令创建或更新服务:

    gcloud run services replace service.yaml

已知限制

  • 自动基础映像更新仅支持 Google Cloud 的 Buildpack 基础映像。您无法使用自己的基础映像。

  • 自动更新基础映像后,使用编译后语言的应用不会重新编译。

  • 应用映像的安全扫描可能不完整。由于您的应用映像现在基于 scratch 构建,因此安全扫描器只会扫描映像的应用部分。如需获取更完整的容器安全映像,您还必须针对 Google 提供的相应基础映像运行扫描。您可以下载基础映像并使用开源工具运行扫描。