S3 网关
JuiceFS S3 网关是 JuiceFS 支持的多种访问方式之一,它可以将 JuiceFS 文件系统以 S3 协议对外提供服务,使得应用可以通过 S3 SDK 访问 JuiceFS 上存储的文件。
架构与原理
在 JuiceFS 中,文件是以对象的形式分块存储到底层的对象存储中。JuiceFS 提供了 FUSE POSIX、WebDAV、S3 网关、CSI 驱动等多种访问方式,其中 S3 网关是较为常用的一种,其架构图如下:
JuiceFS S3 网关功能是通过 MinIO S3 网关实现的。我们利用 MinIO 的 object 接口
将 JuiceFS 文件系统作为 MinIO 服务器的后端存储,提供接 近原生 MinIO 的使用体验,同时继承 MinIO 的许多高级功能。在这种架构中,JuiceFS 就相当于 MinIO 实例的一块本地磁盘,原理与 minio server /data1
命令类似。
JuiceFS S3 网关的常见的使用场景有:
- 为 JuiceFS 开放 S3 接口:应用可以通过 S3 SDK 访问 JuiceFS 上存储的文件;
- 使用 S3 客户端:使用 s3cmd、AWS CLI、MinIO 客户端来方便地访问和操作 JuiceFS 上存储的文件;
- 管理 JuiceFS 中的文件:S3 网关提供了一个基于网页的文件管理器,可以在浏览器中管理 JuiceFS 中的文件;
- 集群复制:在跨集群复制数据的场景下,作为集群的统一数据出口,避免跨区访问元数据以提升数据传输性能,详见「使用 S3 网关进行跨区域数据同步」
快速开始
启动 S3 网关需要一个已经创建完毕的 JuiceFS 文件系统,如果尚不存在,请参考文档来创建。下方假定元数据引擎 URL 为 redis://localhost:6379/1
。
由于网关基于 MinIO 开发,因此需要先设置 MINIO_ROOT_USER
和 MINIO_ROOT_PASSWORD
两个环境变量,他们会成为访问 S3 API 时认证身份用的 Access Key 和 Secret Key,是拥有最高权限的管理员凭证。
export MINIO_ROOT_USER=admin
export MINIO_ROOT_PASSWORD=12345678
# Windows 用户请改用 set 命令设置环境变量
set MINIO_ROOT_USER=admin
注意,MINIO_ROOT_USER
的长度至少 3 个字符, MINIO_ROOT_PASSWORD
的长度至少 8 个字符,如果未能正确设置,将会遭遇类似 MINIO_ROOT_USER should be specified as an environment variable with at least 3 characters
的报错,注意排查。
启动 S3 网关:
# 第一个参数是元数据引擎的 URL,第二个是 S3 网关监听的地址和端口
juicefs gateway redis://localhost:6379/1 localhost:9000
# 从 v1.2 开始,S3 网关支持后台启动,追加 --background 或 -d 参数均可
# 后台运行场景下,使用 --log 指定日志输出文件路径
juicefs gateway redis://localhost:6379 localhost:9000 -d --log=/var/log/juicefs-s3-gateway.log
S3 Gateway 默认没有启用多桶支持,可以添加 --multi-buckets
选项开启。还可以添加其他选项优化 S3 网关,比如,可以将默认的本地缓存设置为 20 GiB。
juicefs gateway --cache-size 20480 redis://localhost:6379/1 localhost:9000
在这个例子中,我们假设 JuiceFS 文件系统使用的是本地的 Redis 数据库。当 S3 网关启用时,在当前主机上可以使用 http://localhost:9000
这个地址访问到 S3 网关的管理界面。
如果你希望通过局域网或互联网上的其他主机访问 S3 网关,则需要调整监听地址,例如:
juicefs gateway redis://localhost:6379/1 0.0.0.0:9000
这 样一来,S3 网关将会默认接受所有网络请求。不同的位置的 S3 客户端可以使用不同的地址访问 S3 网关,例如:
- S3 网关所在主机中的第三方客户端可以使用
http://127.0.0.1:9000
或http://localhost:9000
进行访问; - 与 S3 网关所在主机处于同一局域网的第三方客户端可以使用
http://192.168.1.8:9000
访问(假设启用 S3 网关的主机内网 IP 地址为 192.168.1.8); - 通过互联网访问 S3 网关可以使用
http://110.220.110.220:9000
访问(假设启用 S3 网关的主机公网 IP 地址为 110.220.110.220)。
访问 S3 网关
各类支持 S3 API 的客户端、桌面程序、Web 程序等都可以访问 JuiceFS S3 网关。使用时请注意 S3 网关监听的地址和端口。
以下示例均为使用第三方客户端访问本地主机上运行的 S3 网关。在具体场景下,请根据实际情况调整访问 S3 网关的地址。
使用 AWS CLI
从 https://aws.amazon.com/cli 下载并安装 AWS CLI,然后进行配置:
$ aws configure
AWS Access Key ID [None]: admin
AWS Secret Access Key [None]: 12345678
Default region name [None]:
Default output format [None]:
程序会通过交互式的方式引导你完成新配置的添加,其中 Access Key ID
与 MINIO_ROOT_USER
相同,Secret Access Key
与 MINIO_ROOT_PASSWORD
相同,区域名称和输出格式请留空。
之后,即可使用 aws s3
命令访问 JuiceFS 存储,例如:
# List buckets
$ aws --endpoint-url http://localhost:9000 s3 ls
# List objects in bucket
$ aws --endpoint-url http://localhost:9000 s3 ls s3://<bucket>
使用 MinIO 客户端
为避免兼容性问题,我们推荐采用的 mc 的版本为 RELEASE.2021-04-22T17-40-00Z,你可以在这个地址找到历史版本和不同架构的 mc,比如这是 amd64 架构 RELEASE.2021-04-22T17-40-00Z 版本的 mc 的下载地址
下载安装完成 mc 后添加一个新的 alias:
mc alias set juicefs http://localhost:9000 admin 12345678
然后,你可以通过 mc 客户端自由的在本地磁盘与 JuiceFS 存储以及其他云存储之间进行文件和文件夹的复制、移动、增删等管理操作。
$ mc ls juicefs/jfs
[2021-10-20 11:59:00 CST] 130KiB avatar-2191932_1920.png
[2021-10-20 11:59:00 CST] 4.9KiB box-1297327.svg
[2021-10-20 11:59:00 CST] 21KiB cloud-4273197.svg
[2021-10-20 11:59:05 CST] 17KiB hero.svg
[2021-10-20 11:59:06 CST] 1.7MiB hugo-rocha-qFpnvZ_j9HU-unsplash.jpg
[2021-10-20 11:59:06 CST] 16KiB man-1352025.svg
[2021-10-20 11:59:06 CST] 1.3MiB man-1459246.ai
[2021-10-20 11:59:08 CST] 19KiB sign-up-accent-left.07ab168.svg
[2021-10-20 11:59:10 CST] 11MiB work-4997565.svg
常用功能
多桶支持
默认情况下,juicefs gateway
只允许一个 bucket,bucket 名字为文件系统名字,如果需要多个桶,可以在启动时添加 --multi-buckets
开启多桶支持,该参数将会把 JuiceFS 文件系统顶级目录下的每个子目录都导出为一个 bucket。创建 bucket 的行为在文件系统上的反映是顶级目录下创建了一个同名的子目录。
juicefs gateway redis://localhost:6379/1 localhost:9000 --multi-buckets
保留 etag
默认 S3 网关不会保存和返回对象的 etag 信息,可以通过--keep-etag
开启
开启对象标签
默认不支持对象标签,可以通过--object-tag
开启
开启对象元数据 新增自 v1.3
默认不支持对象元数据,可以通过 --object-meta
开启,参考文档
启用虚拟主机风格请求
默认情况下,S3 网关支持格式为 http://mydomain.com/bucket/object
的路径类型请求。MINIO_DOMAIN
环境变量被用来启用虚拟主机类型请求。如果请求的 Host
头信息匹配 (.+).mydomain.com
,则匹配的模式 $1
被用作 bucket,并且路径被用作 object.
示例:
export MINIO_DOMAIN=mydomain.com
调整 IAM 刷新时间
默认 IAM 缓存的刷新时间为 5 分钟,可以通过 --refresh-iam-interval
调整,该参数的值是一个带单位的时间字符串,例如 "300ms", "-1.5h" 或者 "2h45m",有效的时间单位是 "ns"、"us" (或 "µs")、"ms"、"s"、"m"、"h"。
例如设置 1 分钟刷新:
juicefs gateway xxxx xxxx --refresh-iam-interval 1m
多 Gateway 实例
JuiceFS 的分布式特性使得可以在多个节点上同时启动多个 S3 网关实例,这样可以提高 S3 网关的可用性和性能。在这种情况下,每个 S3 网关实例都会独立地处理请求,但是它们都会访问同一个 JuiceFS 文件系统。在这种情况下,需要注意以下几点:
- 需要保证所有实例在启动时使用相同的用户,其 UID 和 GID 相同;
- 节点之间 IAM 刷新时间可以不同,但是需要保证 IAM 刷新时间不要太短,以免对 JuiceFS 造成过大的压力;
- 每个实例的监听的地址和端口可以自由设置,如果在同一台机器上启动多个实例,需要确保端口不冲突。
以守护进程的形式运行
S3 网关 可以通过以下配置以 Linux 守护进程的形式在后台运行。
cat > /lib/systemd/system/juicefs-gateway.service<<EOF
[Unit]
Description=Juicefs S3 Gateway
Requires=network.target
After=multi-user.target
StartLimitIntervalSec=0
[Service]
Type=simple
User=root
Environment="MINIO_ROOT_USER=admin"
Environment="MINIO_ROOT_PASSWORD=12345678"
ExecStart=/usr/local/bin/juicefs gateway redis://localhost:6379 localhost:9000
Restart=on-failure
RestartSec=60
[Install]
WantedBy=multi-user.target
EOF
设置进程开机自启动
systemctl daemon-reload
systemctl enable juicefs-gateway --now
systemctl status juicefs-gateway
检阅进程的日志
journalctl -xefu juicefs-gateway.service
在 Kubernetes 上部署 S3 网关
安装需要 Helm 3.1.0 及以上版 本,请参照 Helm 文档进行安装。
helm repo add juicefs https://juicedata.github.io/charts/
helm repo update
Helm chart 同时支持 JuiceFS 社区版和企业版,通过填写 values 中不同的字段来区分具体使用的版本,默认的 values 使用了社区版 JuiceFS 客户端镜像:
secret:
name: "<name>"
metaurl: "<meta-url>"
storage: "<storage-type>"
accessKey: "<access-key>"
secretKey: "<secret-key>"
bucket: "<bucket>"
别忘了把上方的 values-mycluster.yaml
纳入 Git 项目(或者其他的源码管理方式)管理起来,这样一来,就算 values 的配置不断变化,也能对其进行追溯和回滚。
填写完毕 保存,就可以使用下方命令部署了:
# 不论是初次安装,还是后续调整配置重新上线,都可以使用下方命令
helm upgrade --install -f values-mycluster.yaml s3-gateway juicefs/juicefs-s3-gateway
部署完毕以后,按照输出文本的提示,获取 Kubernetes Service 的地址,并测试是否可以正常访问。
$ kubectl -n kube-system get svc -l app.kubernetes.io/name=juicefs-s3-gateway
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
juicefs-s3-gateway ClusterIP 10.101.108.42 <none> 9000/TCP 142m
部署完成后,会启动一个名为 juicefs-s3-gateway
的 Deploy。用下方命令查看部署的 Pod:
$ kubectl -n kube-system get po -l app.kubernetes.io/name=juicefs-s3-gateway
NAME READY STATUS RESTARTS AGE
juicefs-s3-gateway-5c69d574cc-t92b6 1/1 Running 0 136m