本页面介绍如何使用 Cloud Run 卷装载将 Cloud Storage 存储桶作为存储卷进行装载。
在 Cloud Run 中将存储桶作为卷进行装载会将存储桶内容以文件的形式呈现在容器文件系统中。将存储桶作为卷装载后,您可以使用编程语言的文件系统操作和库(而不是使用 Google API 客户端库)来访问该存储桶,就像访问本地文件系统上的目录一样。
内存要求
Cloud Storage 卷装载使用 Cloud Run 容器内存执行以下活动:对于所有 Cloud Storage FUSE 缓存,Cloud Run 默认使用存留时间 (TTL) 为 60 秒的统计信息缓存设置。统计信息缓存的默认大小上限为 32 MB,类型缓存的默认大小上限为 4 MB。
读取时,Cloud Storage FUSE 还会消耗统计信息和类型缓存以外的内存,例如,为每个所读取的文件和 goroutine 使用 1 MiB 的数组。
写入 Cloud Storage 时,整个文件会先暂存到 Cloud Run 内存中,然后文件才会写入 Cloud Storage。
限制
由于 Cloud Run 使用 Cloud Storage FUSE 进行此卷装载,因此在将 Cloud Storage 存储桶作为卷进行装载时,有一些注意事项:
- Cloud Storage FUSE 不会为对同一文件的多次写入提供并发控制(文件锁定)。如果多次写入操作尝试替换某个文件,则最后一次写入的内容会生效,而先前写入的所有内容都会丢失。
- Cloud Storage FUSE 不是完全符合 POSIX 标准的文件系统。如需了解详情,请参阅 Cloud Storage FUSE 文档。
不允许的路径
Cloud Run 不允许您在 /dev
、/proc
和 /sys
或其子目录上装载卷。
准备工作
您需要一个 Cloud Storage 存储桶来作为卷进行装载。
如需实现对 Cloud Storage 的最佳读/写性能,请参阅优化 Cloud Storage FUSE 网络带宽性能。
所需的角色
如需获得配置 Cloud Storage 卷装载所需的权限,请让您的管理员为您授予以下 IAM 角色:
-
Cloud Run 作业的 Cloud Run Developer (
roles/run.developer
) 角色 -
服务身份的 Service Account User (
roles/iam.serviceAccountUser
) 角色
如需获得服务身份访问文件和 Cloud Storage 存储桶所需的权限,请让您的管理员为服务身份授予以下 IAM 角色:
- Storage Admin (
roles/storage.admin
)
如需详细了解 Cloud Storage 角色和权限,请参阅适用于 Cloud Storage 的 IAM。
如需查看与 Cloud Run 关联的 IAM 角色和权限的列表,请参阅 Cloud Run IAM 角色和 Cloud Run IAM 权限。如果您的 Cloud Run 作业与 Google Cloud API(例如 Cloud 客户端库)进行交互,请参阅服务身份配置指南。如需详细了解如何授予角色,请参阅部署权限和管理访问权限。
装载 Cloud Storage 卷
您可以在不同的装载路径中装载多个存储桶。您还可以跨容器使用相同或不同的装载路径将卷装载到多个容器。
如果您使用多个容器,请先指定卷,然后为每个容器指定卷装载。
控制台
在 Google Cloud 控制台中,进入 Cloud Run 作业页面:
点击部署容器,然后选择作业以填写初始作业设置页面。如果要配置现有作业,请点击作业,然后点击修改。
点击容器、变量和 Secret、连接、安全性以展开作业属性页面。
点击卷标签页。
- 在卷下:
- 点击添加卷。
- 在卷类型下拉列表中,选择 Cloud Storage 存储桶作为卷类型。
- 在卷名称字段中,输入要用于卷的名称。
- 浏览并选择要用于卷的存储桶。
- (可选)选中只读复选框以将存储桶设为只读。
- 点击完成。
- 点击“容器”标签页,然后展开要将卷装载到的容器,以修改该容器。
- 点击卷装载标签页。
- 点击装载卷。
- 从菜单中选择 Cloud Storage 卷。
- 指定您要用于装载卷的路径。
- 点击装载卷
- 在卷下:
点击创建或更新。
gcloud
如需添加卷并装载,请运行以下命令:
gcloud run jobs update JOB \ --add-volume name=VOLUME_NAME,type=cloud-storage,bucket=BUCKET_NAME \ --add-volume-mount volume=VOLUME_NAME,mount-path=MOUNT_PATH
您需要进行如下替换:
- 将
JOB
替换为作业的名称。 - 将 MOUNT_PATH 替换为您用于装载卷的相对路径,例如
/mnt/my-volume
。 - 将 VOLUME_NAME 替换为您要用于卷的任何名称。VOLUME_NAME 值用于将卷映射到卷装载。
- 将 BUCKET_NAME 替换为 Cloud Storage 存储桶的名称。
- 将
如需将卷装载为只读卷,请运行以下命令:
--add-volume=name=VOLUME_NAME,type=cloud-storage,bucket=BUCKET_NAME,readonly=true
如果您使用多个容器,请先指定卷,然后为每个容器指定卷装载:
gcloud run jobs update JOB \ --add-volume name=VOLUME_NAME,type=cloud-storage,bucket=BUCKET_NAME \ --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
根据需要更新 MOUNT_PATH、VOLUME_NAME、BUCKET_NAME 和 IS_READ_ONLY。
apiVersion: run.googleapis.com/v1 kind: Job metadata: name: JOB_NAME spec: template: metadata: annotations: run.googleapis.com/execution-environment: gen2 spec: template: spec: containers: - image: IMAGE_URL volumeMounts: - mountPath: MOUNT_PATH name: VOLUME_NAME volumes: - name: VOLUME_NAME csi: driver: gcsfuse.run.googleapis.com readOnly: IS_READ_ONLY volumeAttributes: bucketName: BUCKET_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
- 将 MOUNT_PATH 替换为您用于装载卷的相对路径,例如
/mnt/my-volume
。 - 将 VOLUME_NAME 替换为您要用于卷的任何名称。VOLUME_NAME 值用于将卷映射到卷装载。
- 将 IS_READ_ONLY 替换为
True
以将卷设为只读,或替换为False
以允许写入。 - 将 BUCKET_NAME 替换为 Cloud Storage 存储桶的名称。
- 将 IMAGE_URL 替换为对容器映像的引用,例如
使用以下命令创建或更新作业:
gcloud 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");
查看卷装载设置
控制台
在 Google Cloud 控制台中,进入 Cloud Run 作业页面:
点击相关作业以打开作业详情页面。
点击卷标签页。
在卷详情页面中找到卷装载设置。
gcloud
使用以下命令:
gcloud run jobs describe JOB_NAME
在返回的配置中找到卷装载设置。
优化 Cloud Storage FUSE 网络带宽性能
如需提高读写性能,请使用直接 VPC 将 Cloud Run 作业连接到 VPC 网络,并通过 VPC 网络路由所有出站流量。您可以使用以下方案之一来执行此操作:
- 启用专用 Google 访问通道,并确保将
vpc-egress
参数设置为all-traffic
。 - 使用“网络最佳实践”页面中示例 2(发送到 Google API 的内部流量)中所述的方案之一。
容器启动时间和 Cloud Storage FUSE 装载
使用 Cloud Storage FUSE 可能会略微增加 Cloud Run 容器的冷启动时间,因为卷装载是在启动容器之前启动的。只有在 Cloud Storage FUSE 成功装载后,容器才会启动。
请注意,只有在与 Cloud Storage 建立连接后,Cloud Storage FUSE 才会成功装载卷。任何网络延迟都可能会影响容器的启动时间。相应地,如果连接尝试失败,Cloud Storage FUSE 将无法装载,并且 Cloud Run 作业将无法启动。此外,如果 Cloud Storage FUSE 的装载时间超过 30 秒,Cloud Run 作业将无法启动,因为 Cloud Run 执行所有装载的总超时为 30 秒。
Cloud Storage FUSE 性能特征
如果您定义了两个卷,每个卷都指向不同的存储桶,系统将启动两个 Cloud Storage FUSE 进程。装载和进程并行进行。
使用 Cloud Storage FUSE 的操作会受到网络带宽的影响,因为 Cloud Storage FUSE 使用 Cloud Storage API 与 Cloud Storage 进行通信。如果网络带宽较低,某些操作(例如列出存储桶的内容)可能会变慢。同样,读取大型文件也可能需要一段时间,因为这也受网络带宽的限制。
当您写入存储桶时,Cloud Storage FUSE 会在内存中完全暂存对象。这意味着,写入大文件受容器实例可用内存量的限制(容器内存上限为 32 GiB)。
只有在您执行 close
或 fsync
时,写入操作才会刷新到存储桶中:然后系统会将完整对象上传/重新上传到存储桶。将对象完全重新上传到存储桶的唯一例外是文件附加了内容且文件大小为 2 MiB 或更大。
如需了解详情,请参阅以下资源: