为实例配置内存中卷装载

本页面介绍如何配置专用的内存中卷,您可以通过 Cloud Run 卷装载使用该卷进行文件读取和写入。请注意,此功能与 Cloud Run 提供的内置内存中文件系统不同。

在 Cloud Run 中装载内存中的卷时,内存中的卷在容器文件系统中显示为文件。装载内存中卷后,您可以使用编程语言的文件系统操作和库来访问该卷,就像访问本地文件系统上的目录一样。

您可以使用内存中卷执行以下操作:

  • 限制内存中卷的大小。当您限制卷的大小时,对已满的卷进行写入会失败,这比让 Cloud Run 因卷占用过多内存而终止实例更可取。

行为

创建内存中卷时,建议指定大小限制。如果卷达到其大小限制,再进行其他写入会失败并发生内存不足错误。您的实例可以处理此错误并继续运行。

请注意,大小限制只是一个限制:它不会为内存中卷分配更多空间。内存中卷会占用您为容器配置的内存。如果您部署多个容器,则每次向卷写入时所使用的内存都会计为写入数据的那个容器的内存用量。

如果未指定大小限制,则它会自动设置为实例中所有容器总大小的一半。例如,emptyDir 卷大小 = [内存(容器 A)+ 内存(容器 B)+ 内存(容器 N)]/2。 此默认行为可能会导致内存中卷的大小限制高于为某些容器分配的内存。如果单个容器在尝试向卷写入更多数据时超出其自身分配的内存,即使尚未达到卷大小限制,也可能会导致意外崩溃。

虽然并不强制要求设置大小限制,但建议您设置一个限制来防止容器用光内存和崩溃。

不允许的路径

Cloud Run 不允许您在 /dev/proc/sys 或其子目录上装载卷。

所需的角色

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

配置内存中卷

为 Cloud Run 实例配置内存中卷后,系统会为启动的每个 Cloud Run 实例都创建一个空卷,并且只要该实例运行,该卷便会存在。当实例停止运行时,该卷中的数据会被永久删除。

使用 Google Cloud CLI 或 YAML 配置内存中卷装载。

gcloud

  • 如需装载卷,请执行以下操作:

    gcloud beta run instances update INSTANCE \
      --add-volume mount-path=MOUNT_PATH,type=in-memory,size-limit=SIZE_LIMIT

    替换以下内容:

    • INSTANCE:实例的名称。
    • MOUNT_PATH:要装载此卷的容器文件系统中的相对路径,例如 /mnt/my-volume
    • SIZE_LIMIT:您要分配给卷的内存限制,以 MiB 或 GiB 为单位(指定为 Mi 或 Gi),例如 500Mi。此限制必须小于为容器指定的总内存
  • 如果您使用多个容器,请先指定卷,然后为每个容器指定卷装载

    gcloud beta run instances update INSTANCE \
      --add-volume=name=VOLUME_NAME,type=in-memory,size-limit=SIZE_LIMIT \
      --container=CONTAINER_1 \
      --add-volume-mount=volume=VOLUME_NAME,mount-path=MOUNT_PATH \
      --container=CONTAINER_2 \
      --add-volume-mount volume=VOLUME_NAME,mount-path=MOUNT_PATH2

YAML

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

    gcloud beta run instances describe INSTANCE --format export > instance.yaml
  2. 以下示例包含 YAML 配置:

    apiVersion: run.googleapis.com/v1
    kind: Instance
    metadata:
      name: INSTANCE
      annotations:
        run.googleapis.com/launch-stage: BETA
    spec:
        containers:
          - name: CONTAINER_NAME
            image: IMAGE_URL
            volumeMounts:
            - name: VOLUME_NAME
              mountPath: MOUNT_PATH
          volumes:
          - name: VOLUME_NAME
            emptyDir:
              medium: Memory
              sizeLimit: SIZE_LIMIT

    替换以下内容:

    • INSTANCE:Cloud Run 实例的名称。
    • CONTAINER_NAME:容器的名称。
    • IMAGE_URL:对容器映像的引用,例如 us-docker.pkg.dev/cloudrun/container/hello:latest
    • VOLUME_NAME:您要用于卷的任何名称。VOLUME_NAME 值用于将卷映射到卷装载。
    • MOUNT_PATH:您用于装载卷的相对路径,例如 /mnt/my-volume
    • SIZE_LIMIT:您要分配给卷的内存限制,以 MiB 或 GiB 为单位(指定为 Mi 或 Gi),例如 500Mi。此限制必须小于为容器指定的总内存
  3. 使用以下命令创建或更新实例:

    gcloud beta run instances replace instance.yaml

读取和写入卷

如果您使用 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 beta run instances update INSTANCE \
    --clear-volumes \
    --clear-volume-mounts

移除个别卷和卷装载

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

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

gcloud beta run instances update INSTANCE \
    --remove-volume VOLUME_NAME \
    --container=container1 \
    --remove-volume-mount MOUNT_PATH \
    --container=container2 \
    --remove-volume-mount MOUNT_PATH