JuiceFS S3 Gateway 基于 MinIO Gateway 开发,实现了S3 API,允许用户通过任何兼容 S3 的客户端访问和管理 JuiceFS 文件系统中的数据。
底层是对象存储,为什么还要 S3 Gateway ? 这是用户对 JuiceFS S3 Gateway 常提出的疑问,作为文章的开篇先来解答这个问题。
这个问题的关键在于,尽管 JuiceFS 的底层采用的是对象存储,但它构建的是一个具有独特的数据格式和存储结构的分布式文件系统,这与普通对象存储有着本质的不同。此外,JuiceFS 提供了多协议访问、缓存能力、容量配额等能力,这也是一般对象存储所不具备的。
JuiceFS v1.2 带来的 S3 Gateway 新变化
在早期,JuiceFS S3 Gateway 的开发重点主要放在 S3 访问接口的实现方面,近期发布的 JuiceFS v1.2 广泛采纳社区用户的需求,进一步实现了身份和访问控制(IAM)和事件通知两项新功能。
身份和访问控制(IAM)功能用于管理和控制用户对存储资源访问权限,让管理员可以按需创建和管理多用户账户,定义并应用访问策略,确保用户和组只能访问授权的数据。
存储桶事件通知功能则用于监控存储桶中对象的创建、删除、修改等事件,并将这些事件通知到指定服务。比如,可以配置为将事件通知发送到消息队列、HTTP 端点或其他兼容的服务,从而实现自动化工作流、实时监控数据变化和集成其他系统等。
接下来将分别为读者介绍如何使用这两项功能。
准备工作
在介绍新功能之前,需要先准备新版 JuiceFS 客户端和 Minio 客户端。
新版 JuiceFS 客户端
确保你安装使用的是 JuiceFS v1.2 及以上版本,需要注意的是,截止本文发表,当前最新版本是 v1.2.0-rc1,你可以在 Github Release 页面下载合适的预编译版本,这里以 x86_64 架构的 Linux 系统为例。
# 创建并进入下载目录
mkdir juicefs && cd juicefs
# 下载预编译的客户端
curl -LO https://github.com/juicedata/juicefs/releases/download/v1.2.0-rc1/juicefs-1.2.0-rc1-linux-amd64.tar.gz
# 解压
tar xvf juicefs-1.2.0-rc1-linux-amd64.tar.gz
# 安装到系统的可执行路径
sudo install juicefs /usr/local/bin
随后还需要准备一个文件系统,可以参考 JuiceFS 官方文档,了解如何创建一个文件系统。这里假设使用 Redis 创建了一个名为 “myjfs” 的文件系统,启动 S3 Gateway:
export MINIO_ROOT_USER=admin
export MINIO_ROOT_PASSWORD=abc123abc
juicefs gateway redis://your-redis.com/1 192.168.1.23:9898
JuiceFS v1.2 为 S3 Gateway 新增加了后台运行选项,在启动网关时通过 --background 或 -d 即可让进程在后台运行。
用浏览器访问 http://192.168.1.23:9898 就能打开 WebUI:
在 Access Key 和 Secret Key 中分别输入前面环境变量中设置的用户名和密码即可登录:
安装 MinIO Client(mc)
MinIO Client 简称 mc,是 Minio 提供的用来管理其对象存储服务的客户端,不只是 MinIO Server,所有 S3 API 兼容的对象存储以及本地文件系统都可以用 mc 来管理。
JuiceFS S3 Gateway 是采用 Apache 2.0 协议发布的 MinIO S3 Gateway 实现而来的,因此新增的高级功能需要使用 mc 进行管理。
为了保证兼容性,建议下载使用 RELEASE.2021-04-22T17-40-00Z 版本的 mc 客户端,可以在这里找到适配各种系统和架构的版本,这里以 x86_64 架构的 Linux 系统为例。
# 下载版本号为 RELEASE.2021-04-22T17-40-00Z 的 mc 客户端
curl -L https://dl.min.io/client/mc/release/linux-amd64/archive/mc.RELEASE.2021-04-22T17-40-00Z -o mc
# 将客户端安装到可执行路径
sudo install mc /usr/local/bin
然后将前面准备的基于 JuiceFS 的 S3 API 添加为 mc 的存储服务:
# 命令格式
mc alias set <ALIAS> <URL> <ACCESS-KEY> <SECRET-KEY>
# 命令示例
mc alias set juicefs http://192.168.1.23:9898 admin abc123abc
这样就可以用 mc 来管理 juicefs 中存储的文件了。根据上面的设置,使用别名 “juicefs” 访问文件系统,比如列出里面的文件:
身份和访问控制(IAM)
在以前,一个 S3 Gateway 进程只能设置一个用户(S3 API 的 Access Key ID 和 Access Key Secret),如果需要设置多个用户,则需要另起新的进程。
JuiceFS v1.2 引入了“身份和访问控制”,在启动 Gateway 时与旧版本一样仍然需要通过环境变量设置一个初始用户,但随后可以使用 mc admin 创建更多用户并按需分配不同的权限,可以创建和管理以下三种类型的账户:
- 普通用户
- 服务账户
- STS 安全令牌服务
管理普通用户
下面使用 mc admin user 创建一个新用户:
# 命令格式
mc admin user add <ALIAS> <USERNAME> <PASSWORD>
# 命令示例
mc admin user add juicefs tom abc123abc
# 列出用户
mc admin user list juicefs
可以在 WebUI 上尝试以新用户 tom 的身份登录,此时会发现这个用户完全没有读写权限。如下图,看不到文件系统中的文件,也没有上传文件的权限。
mc 预置了四个权限策略,可以用 mc admin policy ls 查看,分别如下:
- consoleAdmin - 授予用户全部资源的完全访问权限;
- readonly - 授予所有对象的只读权限;
- readwrite - 授予所有桶和对象的读写权限;
- writeonly - 授予用户所有位置的只写权限;
使用 mc admin policy set 可以将一个策略分配给用户:
# 命令语法
mc admin policy set TARGET POLICYNAME [ user=username1 ]
# 为用户赋予读写权限
mc admin policy set juicefs readwrite user=tom
再次以 tom 用户身份回到 WebUI 并刷新页面,现在就可以看到 myjfs 文件系统中的所有文件,而且也可以自由上传文件了。
同样的,用 mc admin policy unset 可以撤销对一个用户的授权。
管理服务账户
对于 JuiceFS S3 Gateway 而言,服务账户(service accounts)的作用是为现有用户创建一个相同权限的副本,让不同的应用可以使用独立的访问密钥。
接着前面的例子,用户 tom 已经被分配了 readwrite 读写权限。现在有一个应用需要访问文件系统,但不想把 tom 的访问密钥直接分配给它,这时就可以为 tom 创建一个服务账户。
# 命令格式
mc admin user svcacct add ALIAS ACCOUNT
# 命令示例
mc admin user svcacct add juicefs tom --access-key tom-sc1 --secret-key abc123abc
需要注意的是,服务账户会从主账户继承权限并保持与主账户权限一致,而且服务账户不可以直接附加权限策略。
在上面的示例中, tom-sc1 服务账户的主账户是 tom ,因为 tom 有读写权限,所以 tom-sc1 就可以直接读写文件系统。当需要限制 tom-sc1 权限时,根据规则,需要调整 tom 的权限策略。比如,想让 tom-sc1 是 readonly 权限,就要给 tom 设置 readonly 策略。
管理 STS 安全令牌
安全令牌服务(Security Token Service,STS)用来获取临时的安全凭证,这些临时凭证允许用户或应用程序以短期访问权限访问存储桶和对象。STS 通常用于在需要临时、安全地访问资源的场景中,替代长期凭证以增强安全性。
可以参照文档中的 API 参数,以编程的方式构建连接进行 STS 安全令牌的请求。也可以使用 AWS CLI 来简化这个过程,这里以 AWS CLI 为例介绍 STS 安全令牌的请求方法。
需要注意的是,启动网关时的超级用户不可用于申请 STS 安全令牌,因此需要使用 mc 创建一个拥有 consoleAdmin 权限的用户来执行请求,基本操作步骤如下:
1. 准备 aws cli 客户端
可以在 Github 仓库下载安装 AWS CLI。
2. 创建 consoleAdmin 权限用户
# 新建一个名为 tom 的用户
mc admin user add juicefs tom abc123abc
# 将 consoleAdmin 权限授权给 tom
mc admin policy set juicefs consoleAdmin user=tom
3. 配置 AWS CLI 访问密钥
编辑 AWS CLI 保存访问密钥的配置文件,通常为 .aws/credentials
,写入用户 tom 相关的访问密钥,例如:
[myjfs]
aws_access_key_id = tom
aws_secret_access_key = abc123abc
3. 请求 STS 令牌
aws --profile myjfs --region none --endpoint-url http://192.168.1.23:9898 sts assume-role --role-arn '12345678901234567890' --role-session-name 'xy'
其中,--role-arn
要求至少 20 个字符,--role-session-name
要求至少 2 个字符,它们对生成 STS 没有影响,可以随意填写。
如下图,执行命令会返回 JSON 格式的临时密钥,生成的 STS 令牌有效期默认为 3600 秒,可以通过指定 --duration-seconds
选项修改有效期。
匿名访问
另外,S3 Gateway 也支持匿名访问,让指定的资源在没有密钥的情况下也可以被访问,这包括两种方式:
- 使用 mc share 创建临时 URL
- 使用 mc policy 配置持久的匿名访问策略
1. 临时的匿名访问 URL
# 为 bucket 中的一个文件生成临时的匿名访问 URL
mc share download juicefs/test1/1683712494111569410.jpg
如下图,mc share 会生成一个 7 天有效期的共享链接,无需访问密钥就可以打开文件。
2. 配置持久的匿名访问策略
在配置持久的匿名访问时可以使用以下四种策略:
- none - 禁止匿名访问
- download - 只读访问
- upload - 只写访问
- public - 读写访问
# 为一个文件赋予只读的匿名访问权限
mc policy set download juicefs/test1/icon/cloud.svg
# 为一个目录赋予只读的匿名访问权限
mc policy set download juicefs/test1/icon/
# 禁止匿名访问
mc policy set none juicefs/test1/icon/
当为一个文件或目录分配的持久的匿名访问策略,就可以使用“网关地址 + 文件路径”去访问相应的文件,例如,完成上面的设置以后,可以无需访问密钥直接使用 “http://192.168.1.23:9898/test1/icon/office.svg“ 地址打开文件。
多 S3 Gateway 实例
JuiceFS 的分布式特性决定了它支持在一个文件系统上同时启动多个 S3 Gateway 实例,但需要注意以下事项:
-
需要保证所有实例在启动时使用相同的用户,并且其 UID 和 GID 相同;
-
实例之间,IAM 设置的同步间隔为 5 分钟;
桶事件通知
桶事件通知(bucket notifications)功能允许用户在对象存储桶(bucket)中发生特定事件时触发通知。这些通知可以被发送到外部服务,如消息队列或其他兼容的系统。
比如,可以设置监听“对象删除事件”,当桶中有对象被删除时,S3 Gateway 会将事件写入设定的发布系统。然后进一步使用其他工具去实时获取发布系统中的记录,从而实现监控报警等功能。
在可监控的事件类型上主要分为:桶级事件和对象级事件
桶级事件
目前支持的桶级事件有:
- s3:BucketCreated
- s3:BucketRemoved
对象级事件
目前支持的对象级事件有:
- s3:ObjectCreated:Put
- s3:ObjectCreated:CompleteMultipartUpload
- s3:ObjectAccessed:Head
- s3:ObjectCreated:Post
- s3:ObjectRemoved:Delete
- s3:ObjectCreated:Copy
- s3:ObjectAccessed:Get
发布目标
所谓发布目标,就是外部用来接收事件通知的系统,目前支持的目标有:
- Redis
- MySQL
- PostgreSQL
- WebHooks
可以使用 mc 命令列出当前支持的发布目标,例如:
# 命令格式
mc admin config get ALIAS | grep notify
# 命令示例
mc admin config get juicefs | grep notify
通过 Redis 发布通知的配置示例
这里以 Redis 为例,简要介绍事件通知的设置方法。配置桶事件通知主要涉及两个环节:
- 配置发布目标(本例为 Redis 服务)
- 配置监听事件
1. 配置发布目标
使用以下命令可以列出 notify_redis 可以设置的项:
mc admin config get ALIAS notify_redis
- notify_redis - 是发布目标的名称,按照 notify_redis[:name] 格式可以设置多个 redis 服务,比如 notify_redis:1
- format - 是通知的格式,默认为 namespace,也可以使用 access;
- key - 是记录通知事件的哈希表名,其中的 key 会自动创建;
- password - 是 Redis 服务的密码
- queue_dir - 是队列消息暂存目录,例如 /home/events ;
- queue_limit - 是队列的最大长度,默认是 100000 ;
根据 JuiceFS 文档,通过 Redis 发布事件通知时支持 namespace 和 access 两种格式。简单来说,就是事件通知写入 Redis 时有这样两种可以选择的存储格式。不同的格式,适用的场景也有所不同。
Namespace 格式
这种格式的每一条事件通知记录的键(Key)都对应桶中的对象,例如:bucketName/objectName ;值(value)则是用 JSON 编码的事件数据。
它的特点是“同步对象信息”,当对象被更新或删除时,相应的记录也会更新或删除。
这种事件记录格式通常适用于需要保持对象存储状态实时同步或需要实时监控和管理的对象的场景,如数据备份和同步。
Access 格式
这种格式通过 RPUSH 将每个事件追加到一个列表中,列表中的一个项包含时间戳字符串 和事件数据的 JSON 对象。
它的特点是“追加记录”和“不更新或删除”,也就是说,它会像日志一样持续追加记录对象的状态,但不会因为对象的更新或删除而修改历史记录。
这种事件记录格式适用于需要记录和分析对象访问历史或需要追踪对象访问事件的场景,如安全审计和访问统计。
这里以默认的 Namespace 为例,设置一个通知目标:
mc admin config set juicefs notify_redis:2 address="192.168.1.80:6379" password="abc123abc" key="bucketevents"
需要注意的是,“notify_redis:2” 中的 “2” 是这个事件通知目标的名称,你可以随意修改成其他字符。在使用 Redis 作为通知目标时,通知信息会默认写入到 Redis 实例的 “0” 号数据库。
如下图,在添加了一个通知目标后,mc 客户端提示需要重启 S3 服务,由于 JuiceFS S3 Gateway 暂时还不支持客户端自动重启,因此需要手动重启 JuiceFS S3 Gateway。
重启后,在终端控制台可以看到出现了下图所示的 SQS ARNs 信息,这个地址在设置事件通知时需要使用。
再次执行列出命令,可以看到新添加的通知目标 notify_redis:2,接下来就可以将要监听的事件关联到这个通知目标。
2. 配置监听事件
在为存储桶配置事件通知时,需要使用前面配置的“发布目标”的 SQS ARN 地址,启用方式如下:
# 命令格式
mc event add TARGET ARN [FLAGS]
# 命令示例
mc event add juicefs/myjfs arn:minio:sqs::2:redis
# 列出监听设置
mc event list juicefs/myjfs
如图,只需要指定“发布目标”,即可为一个存储桶启用事件通知,该功能默认会监听所有支持的对象级事件。
为了验证事件通知的效果,可以另起一个终端用 redis-cli 连接 Redis 实例,并通过 monitor 功能观测事件通知的写入情况,例如:
# 连接到 Redis 服务
redis-cli -h 192.168.1.80
# 身份认证
192.168.1.80:6379> AUTH <password>
# 启用实时动态监听
192.168.1.80:6379> monitor
拷贝一个文件到存储桶
mc cp 1683712494111569410.jpg juicefs/myjfs
当文件拷贝完毕,在 redis-cli 这边可以看到在 “bucektevents” 哈希表中增加了新的记录,key 为 “myjfs/1683712494111569410.jpg” 是包含路径的文件名,值为记录该事件详情的 JSON。
如前所述,事件通知默认记录在 Redis 的 “0“ 号数据库,可以用 redis-cli 查看它的内容:
这就是桶事件通知的基本设置方法,可以参考 JuiceFS 文档深入了解更多使用方法。
重置 IAM 和事件通知设置
IAM 和事件通知的设置会被写入 JuiceFS 文件系统根目录的 .minio.sys 目录中,如果想彻底重置相关的设置,可以参照以下步骤操作:
- 停止 S3 Gateway
- 使用 mount 方式挂载文件系统
- 删除文件系统根目录中的 .minio.sys 目录(例如: rm -rf .minio.sys)
总结
本文简要介绍了 JuiceFS v1.2 在 S3 Gateway 方面新增的两项功能,身份和访问控制,以及桶事件通知。用真实环境中的示例,介绍了基本的配置和使用方法。
希望本文分享的内容能够对读者在使用 JuiceFS 时提供一定的帮助,您可以访问 JuiceFS 官方文档了解详情和更多高级使用方法,也欢迎大家加入 JuiceFS 社区微信群共同探讨相关技术主题。