为 Cloud Run 服务配置临时磁盘

Cloud Run 提供了一个临时磁盘卷,该卷仅在实例运行期间保留。借助此功能,您可以指定所需的磁盘容量和装载位置。然后,Cloud Run 会将该数量的磁盘分配给您的资源。

系统会在启动时自动预配磁盘,将其预先格式化为 ext4,并使用实例专用密钥进行加密。临时磁盘会创建卷,以便任何用户都可以对其进行读取或写入。由于存储空间是临时的,因此当实例关停时,所有数据都会被永久删除。这包括由以下原因导致的关停:

  • 实例崩溃
  • 服务扩缩
  • 将流量迁移到新修订版本

磁盘专用于特定实例,不会在其他实例或修订版本之间共享。您可以通过为每个卷配置装载点来控制文件系统结构。

在关停实例之前,Cloud Run 会向实例中的所有容器发送一个 SIGTERM 信号,指示实例将于 10 秒后进行实际的关停,届时 Cloud Run 则会发送一个 SIGKILL 信号。您可以使用这 10 秒的时间窗口来执行清理操作,例如对磁盘内容永久性存储执行最后一轮复制。

使用场景

您可以将临时磁盘用于以下用途:

  • 数据处理工作负载:在 Cloud Run 中处理大型数据文件时,您通常会将整个文件存储在内存中,或编排将其拆分为较小的部分。使用临时存储空间,您无需为大量内存付费即可创建数据的临时本地副本。您还可以处理更大的数据集。
  • 缓存:在 Web 服务用例中,将数据缓存在磁盘上而不是从远程存储中提取数据可以优化应用的延迟时间。

存储空间和实例限制

适用的限制如下:

  • 卷大小限制:每个卷的大小必须介于 1Gi 到 100Gi 之间。
  • 实例存储空间上限:默认情况下,每个实例的总空间上限为 10 GiB。如需为每个实例配置超过 10 GiB 的内存,需要申请增加配额。
  • 实例卷限制:每个实例最多只能有 10 个临时磁盘卷。
  • 项目限制:默认情况下,每个项目起初的总区域分配限制为 0 GiB。首次在某个区域中部署具有临时磁盘的资源时,项目会自动获得该区域 100 GiB 的配额。在运行时,此区域配额由该区域中所有正在运行的实例共享。部署资源时,每个实例的临时磁盘总大小乘以其最大实例数不能超过区域分配限制。例如,如果区域限制为 100 GiB,则具有 10 GiB 磁盘的资源最多可以配置 10 个实例。如有必要,请申请增加配额。

申请增加配额

如果您需要额外的容量,则必须为 Cloud Run 服务申请增加配额。点击以下按钮中提供的链接可申请所需的配额。

当前配额 配额链接
每个实例 10 GiB 申请提高每个实例的配额
每个项目 100 GiB 申请提高每个项目的配额

如需详细了解如何申请增加配额,请参阅如何增加配额。

限制

临时磁盘仅在第二代执行环境中可用。

不允许的路径

Cloud Run 不允许您将卷装载到 /dev、/proc 或 /sys,以及它们的子目录。

支持的区域

临时磁盘可在所有 Cloud Run 位置使用。

准备工作

  1. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  2. Verify that billing is enabled for your Google Cloud project.

  3. 安装并初始化 gcloud CLI。
  4. 更新组件:
    gcloud components update
  5. 查看 Cloud Run 价格页面,了解 CPU、内存和网络出站流量的价格。预配磁盘的整个大小以及使用该磁盘的实例的生命周期都会影响您的费用。

所需的角色

如需获得配置临时磁盘所需的权限,请让管理员向您授予以下 IAM 角色:

如需查看与 Cloud Run 关联的 IAM 角色和权限的列表,请参阅 Cloud Run IAM 角色和 Cloud Run IAM 权限。如果您的 Cloud Run 服务与Google Cloud API(例如 Cloud 客户端库)进行交互,请参阅服务身份配置指南。如需详细了解如何授予角色,请参阅部署权限和管理访问权限。

创建并装载临时磁盘

您可以使用 Google Cloud 控制台、Google Cloud CLI、YAML 或 Terraform 创建和装载临时磁盘:

控制台

  1. 在 Google Cloud 控制台中,前往 Cloud Run:

    转到 Cloud Run

  2. 从 Cloud Run 导航菜单中选择服务,然后点击部署容器以配置新服务。如果您要配置现有服务,请点击该服务,然后点击容器标签页。

  3. 如果您要配置新服务,请填写初始服务设置页面,然后点击容器、网络、安全性。

  4. 选择临时磁盘。

  5. 从菜单中选择大小,然后在装载路径字段中输入装载路径。

  6. 点击创建(对于新服务)。对于现有服务,请依次点击查看差异并重新部署和部署更改。

gcloud

如需添加卷并装载,请运行以下命令:

gcloud run services update SERVICE \
    --execution-environment=gen2 \
    --add-volume=name=VOLUME_NAME,type=ephemeral-disk,size=SIZE \
    --add-volume-mount=volume=VOLUME_NAME,mount-path=MOUNT_PATH

替换以下内容:

  • SERVICE:服务的名称。
  • VOLUME_NAME:您要为卷指定的名称。
  • SIZE:磁盘大小,例如 10Gi。对于 ephemeral-disk 卷,大小必须介于 1Gi 和 100Gi 之间。
  • MOUNT_PATH:您用于装载卷的相对路径,例如 /mnt/my-volume。

YAML

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

    gcloud run services describe SERVICE --format export > service.yaml
  2. 配置 YAML 文件:

    apiVersion: serving.knative.dev/v1
    kind: Service
    metadata:
      name: SERVICE
      labels:
        cloud.googleapis.com/location: REGION
    spec:
      template:
        spec:
          containers:
          - name: CONTAINER_NAME
            image: IMAGE_URL
            volumeMounts:
            - name: VOLUME_NAME
              mountPath: MOUNT_PATH
          volumes:
          - name: VOLUME_NAME
            emptyDir:
              medium: Disk
              sizeLimit: SIZE
    

    替换以下内容:

    • SERVICE:服务的名称。
    • REGION: Google Cloud 区域。
    • CONTAINER_NAME:您要为容器指定的名称。
    • IMAGE_URL:对容器映像的引用,例如 us-docker.pkg.dev/cloudrun/container/hello:latest。如果您使用 Artifact Registry,则必须预先创建制品库 REPO_NAME。网址采用 LOCATION-docker.pkg.dev/PROJECT_ID/REPO_NAME/PATH:TAG 格式。
    • VOLUME_NAME:您要为卷指定的名称。
    • MOUNT_PATH:您用于装载卷的相对路径,例如 /mnt/my-volume。
    • SIZE:磁盘大小,例如 10Gi。对于 ephemeral-disk 卷,大小必须介于 1Gi 和 100Gi 之间。
  3. 使用以下命令创建或更新服务:

    gcloud run services replace service.yaml

    gcloud run services replace 命令默认使用 service.yaml 文件(如果存在)。

Terraform

如需了解如何应用或移除 Terraform 配置,请参阅基本 Terraform 命令。

将以下内容添加到 Terraform 配置中的 google_cloud_run_v2_service 资源:
  resource "google_cloud_run_v2_service" "default" {
    name     = "SERVICE"
    location = "REGION"
    deletion_protection =  "true"
    ingress = "INGRESS_TRAFFIC_ALL"
  template {
    containers {
      image = "IMAGE_URL"
      volume_mounts {
        name = "VOLUME_NAME"
        mount_path = "MOUNT_PATH"
      }
    }
    volumes {
      name = "VOLUME_NAME"
      empty_dir {
        medium = "DISK"
        size_limit = "SIZE"
      }
    }
  }
  lifecycle {
    ignore_changes = [
      launch_stage,
    ]
  }
}

替换以下内容:

  • SERVICE:服务的名称。
  • REGION: Google Cloud 区域。
  • IMAGE_URL:对容器映像的引用,例如 us-docker.pkg.dev/cloudrun/container/hello:latest。如果您使用 Artifact Registry,则必须预先创建制品库 REPO_NAME。网址采用 LOCATION-docker.pkg.dev/PROJECT_ID/REPO_NAME/PATH:TAG 格式。
  • VOLUME_NAME:您要为卷指定的名称。
  • MOUNT_PATH:您用于装载卷的相对路径,例如 /mnt/my-volume。
  • SIZE:磁盘大小,例如 10Gi。对于 ephemeral-disk 卷,大小必须介于 1Gi 和 100Gi 之间。

读取和写入卷

如果您使用 Cloud Run 卷装载功能,则可以使用编程语言中用于在本地文件系统上读写文件的相同库来访问已装载的卷。

如果您使用的是期望数据存储在本地文件系统中并使用常规文件系统操作来访问数据的现有容器,此方法会特别有用。

以下代码段假定一个 mountPath 设置为 /mnt/my-volume 的卷装载。

Nodejs

使用文件系统模块创建新文件或附加到卷 /mnt/my-volume 中的现有文件:

var fs = require('fs');
fs.appendFileSync('/mnt/my-volume/sample-logfile.txt', 'Hello logs!', { flag: 'a+' });

Python

写入保存在卷 /mnt/my-volume 中的文件:

f = open("/mnt/my-volume/sample-logfile.txt", "a")

Go

使用 os 软件包创建一个保存在卷 /mnt/my-volume 中的新文件:

f, err := os.Create("/mnt/my-volume/sample-logfile.txt")

Java

使用 Java.io.File 类在卷 /mnt/my-volume 中创建日志文件:

import java.io.File;
File f = new File("/mnt/my-volume/sample-logfile.txt");

清除并移除卷和卷装载

您可以清除所有卷和卷装载,也可以移除个别卷和卷装载。

清除所有卷和卷装载

如需从单容器服务中清除所有卷和卷装载,请运行以下命令:

gcloud run services update SERVICE \
    --clear-volumes \
    --clear-volume-mounts
如果您有多个容器,请遵循边车 CLI 惯例来清除卷和卷装载:

gcloud run services update SERVICE \
    --container=container1 \
    --clear-volumes \
    --clear-volume-mounts \
    --container=container2 \
    --clear-volumes \
    --clear-volume-mounts

移除个别卷和卷装载

如需移除某个卷,您还必须移除使用该卷的所有卷装载。

如需移除个别卷或卷装载,请使用 remove-volume 和 remove-volume-mount 标志:

gcloud run services update SERVICE \
    --remove-volume VOLUME_NAME \
    --container=container1 \
    --remove-volume-mount MOUNT_PATH \
    --container=container2 \
    --remove-volume-mount MOUNT_PATH

最佳做法

请遵循以下最佳实践,以有效管理临时数据并优化存储性能。

复制到永久性存储空间

如果您打算将临时磁盘内容复制到永久性存储(例如 Cloud Storage 存储桶),我们建议您以增量方式复制,而不是依赖 10 秒的 SIGTERM 到 SIGKILL 宽限期。如需详细了解实例关停,请参阅容器运行时合同。

Cloud Run 无需任何额外的网络设置即可读取和写入 Cloud Storage。为实现最佳性能,我们建议使用直接 VPC 通过 VPC 网络路由进出 Cloud Storage 的流量。

如果您不需要 Cloud Run 资源访问互联网,则此方法适用。如果您确实需要访问互联网,请设置 Cloud NAT,或参阅流向 Google API 的内部流量。

如需为服务配置直接 VPC 出站流量,请完成以下步骤:

  1. 在 Google Cloud 控制台中,前往 Cloud Run 页面。

    转到 Cloud Run

  2. 如果您是要配置一个新服务来作为部署目标,请点击创建服务。如果您要配置和部署现有服务,请点击该服务。

  3. 如果您要配置新服务,请根据需要填写初始服务设置页面,然后点击容器、网络、安全性以展开服务配置页面。

  4. 点击网络标签页。

  5. 点击连接到 VPC 以发送出站流量。

  6. 点击将流量直接发送到 VPC。

  7. 在网络字段中,选择要向其发送流量的 VPC 网络。

  8. 在子网字段中,选择您的服务用于接收 IP 地址的子网。 您可以在同一子网上部署多个服务。

  9. 对于流量路由,选择将所有流量路由到 VPC,以通过 VPC 网络发送所有出站流量。

    1. 点击创建(对于新服务)。对于现有服务,请依次点击查看差异并重新部署和部署更改。

    2. 如需验证您的服务是否在 VPC 网络上,请点击该服务,然后点击网络标签页。VPC 卡片中列出了网络和子网。

      现在,您可以根据防火墙规则允许将来自 Cloud Run 服务的请求发送到 VPC 网络上的任何资源。

    3. 在您连接到的子网上启用专用 Google 访问通道。

问题排查

如果您遇到问题,请检查以下各项:

  • 如果您的容器内存不足,并且您使用了 Google Cloud 控制台部署附加了临时磁盘的服务的新修订版本,则 Google Cloud 控制台可能已将磁盘卷转换为内存中卷。这会导致磁盘写入操作写入内存,从而导致容器内存不足。如需解决此问题,请再次使用 gcloud CLI 重新部署服务,并确保 YAML 文件在 volumes 下指定 medium: Disk。
  • 如果您在将大量数据下载到临时磁盘时发现网速较慢,请按照开启直接 VPC 的步骤操作。如果未启用直接 VPC,网络传输速度会变慢。