本页面介绍如何配置专用的内存中卷,您可以通过 Cloud Run 卷装载使用该卷进行文件读取和写入。请注意,此功能与 Cloud Run 提供的内置内存中文件系统不同。
在 Cloud Run 中装载内存中的卷时,内存中的卷在容器文件系统中显示为文件。装载内存中的卷后,您可以使用编程语言的文件系统操作和库来访问该文件共享,就像访问本地文件系统上的目录一样。
您可以使用内存中卷执行以下操作:
- 限制内存中卷的大小。当您限制卷的大小时,对已满的卷进行写入会失败,这比让 Cloud Run 因卷占用过多内存而终止实例更可取。
- 在一个 Cloud Run 实例中的不同容器之间共享内存中卷。当 Cloud Run 扩容到服务的多个实例时,每个实例都会有自己的内存中卷,并由该实例上的所有容器共享。当 Cloud Run 扩容以处理流量时,所有容器都可以使用此卷。
行为
创建内存中卷时,建议指定大小限制。如果卷达到其大小限制,再进行其他写入会失败并发生内存不足错误。您的实例可以处理此错误并继续运行。
请注意,大小限制只是一个限制:它不会为内存中卷分配更多空间。内存中卷会占用您为容器配置的内存。如果您部署多个容器,则每次向卷写入时所使用的内存都会计为写入数据的那个容器的内存用量。
如果未指定大小限制,则它会自动设置为作业或服务中所有容器总大小的一半。例如,emptyDir
卷大小 = [内存(容器 A)+ 内存(容器 B)+ 内存(容器 N)]/2。
此默认行为可能会导致内存中卷的大小限制高于为某些容器分配的内存。在这种情况下,如果容器不断向卷写入内存,它将超出分配的内存,并在达到卷大小限制之前崩溃。
虽然并不强制要求设置大小限制,但建议您设置一个限制来防止容器用光内存和崩溃。
不允许的路径
Cloud Run 不允许您在 /dev
、/proc
和 /sys
或其子目录上装载卷。
卷所有权因执行环境和部署类型而异
装载卷时,拥有文件和目录的身份将因工作负载的执行环境以及部署是包含一个或多个容器而有所不同。
在要部署单个容器的第一代执行环境中,卷归容器使用的身份所有。 在所有其他情况下,卷归 root 用户所有。其中包括:
- 在其中部署多个容器的第一代执行环境
- 第二代环境
配置内存中卷
任何配置更改都会导致新修订版本的创建。后续修订版本也将自动采用此配置设置,除非您进行了明确更新。
为 Cloud Run 服务配置内存中卷后,系统会为启动的每个 Cloud Run 实例都创建一个空卷,并且只要该实例运行,该卷便会存在。当实例停止运行时,该卷中的数据会被永久删除。
控制台
在 Google Cloud 控制台中,进入 Cloud Run 作业页面:
点击部署容器,然后选择“作业”以填写初始作业设置页面。如果要配置现有作业,请点击作业,然后点击修改。
点击容器、变量和 Secret、连接、安全性以展开作业属性页面。
点击卷标签页。
- 在卷下:
- 点击添加卷。
- 在卷类型下拉列表中,选择内存中作为卷类型。
- 在卷名称字段中,输入要用于卷的名称。
- 在大小限制字段中,指定要分配给卷的内存限制。此限制必须小于为容器指定的总内存。此卷中存储的数据会占用写入数据的容器所预留的内存。
- 点击完成。
- 点击“容器”标签页,然后展开要将卷装载到的容器,以修改该容器。
- 点击卷装载标签页。
- 点击装载卷。
- 从菜单中选择内存中卷。
- 指定您要用于装载卷的路径。
- 点击装载卷
- 在卷下:
点击创建或更新。
gcloud
如需添加卷并装载,请运行以下命令:
gcloud beta run jobs update JOB \ --add-volume=name=VOLUME_NAME,type=in-memory,size-limit=SIZE_LIMIT \ --add-volume-mount=volume=VOLUME_NAME,mount-path=MOUNT_PATH
您需要将其中的:
- 将
JOB
替换为作业的名称。 - VOLUME_NAME 替换为您要为卷使用的任何名称。VOLUME_NAME 值用于将卷映射到卷装载。
MOUNT_PATH
替换为要装载此卷的容器文件系统中的相对路径,例如/mnt/my-volume
。- 将 SIZE_LIMIT 替换为您要分配给卷的内存限制,以 MiB 或 GiB 为单位(指定为 Mi 或 Gi),例如
500Mi
。此限制必须小于为容器指定的总内存。
- 将
如果您使用多个容器,请先指定卷,然后为每个容器指定卷装载:
gcloud beta run jobs update JOB \ --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
如果您要创建新的作业,请跳过此步骤。如果您要更新现有作业,请下载其 YAML 配置:
gcloud run jobs describe JOB_NAME --format export > job.yaml
配置
volumeMounts
和volumes
属性,如下所示:apiVersion: run.googleapis.com/v1 kind: Job metadata: name: JOB_NAME metadata: annotations: run.googleapis.com/launch-stage: BETA spec: template: metadata: spec: containers: - image: IMAGE_URL volumeMounts: - mountPath: MOUNT_PATH name: VOLUME_NAME volumes: - name: VOLUME_NAME emptyDir: sizeLimit: SIZE_LIMIT medium: Memory
您需要将其中的:
- 将 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 替换为您要为卷使用的任何名称。VOLUME_NAME 值用于将卷映射到卷装载。
MOUNT_PATH
替换为要装载此卷的容器文件系统中的相对路径,例如/mnt/my-volume
。- 将 SIZE_LIMIT 替换为您要分配给卷的内存限制,以 MiB 或 GiB 为单位(指定为 Mi 或 Gi),例如
500Mi
。此限制必须小于为容器指定的总内存。
- 将 IMAGE_URL 替换为对容器映像的引用,例如
使用以下命令将服务替换为其新配置:
gcloud beta run jobs replace job.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");