使用 Ruby AWS SDK 访问 Ceph RGW S3 接口:桶与对象操作完整指南
2026/9/24 0:04:14 网站建设 项目流程
  • 存储
  • 分布式文件系统
  • 对象存储
  • 后端
  • 高可用

【免费下载链接】ceph

Ceph is a distributed object, block, and file storage platform

项目地址:https://gitcode.com/gh_mirrors/ce/ceph
点击查看免费下载

导读

Ceph Object Gateway(RGW)对外提供与 Amazon S3 API 兼容的 RESTful 接口,任何遵循 S3 协议的客户端(包括 Ruby 生态中的aws-sdkaws-s3两个 gem)都可以直接对接。本文以 Ceph 官方文档 doc/radosgw/s3/ruby.rst 为骨架,系统讲解用 Ruby 完成连接配置、桶的增删查、对象的上传下载与 ACL 管理、签名/未签名 URL 生成等完整操作,并结合仓库中的 RGW 源码(如 src/rgw/rgw_acl_s3.cc)与配套文档(如 doc/radosgw/s3/authentication.rst、doc/radosgw/s3/commons.rst)补充底层原理与实操细节。读完本文,你将能够用两种主流 Ruby SDK 快速接入 Ceph RGW,并理解其认证、ACL 与路径访问模式的实现机制。

适用前提:本文示例面向 Ceph RGW 的 S3 兼容接口,文中出现的objects.dreamhost.com为官方文档沿用的示例主机名,实际使用时请替换为你的 RGW 网关地址(如rgw.example.com),并替换为自己的access_key_id/secret_access_key。两种 SDK 的适用版本分别为aws-sdk gem ~>2aws-s3 gem(老一代 gem)。


一、Ceph RGW 的 S3 兼容接口与 Ruby 生态选型

Ceph 通过 RGW 组件暴露一套与 Amazon S3 API 基本数据访问模型兼容的 RESTful API,其功能支持清单(List Buckets、Create/Delete Bucket、Put/Get/Delete Object、Object ACL、Multipart Uploads、Object/Bucket Tagging、Bucket Policy、S3-select 等)详见 doc/radosgw/s3.rst 中的特性支持表。Ruby 开发者对接 RGW 主要有两条技术路线:

路线gem适用场景
现代 SDKaws-sdk~> 2官方文档 doc/radosgw/s3/ruby.rst 前半部分示例,面向Aws::S3::Client接口,推荐新项目使用
经典 gemaws-s3官方文档后半部分示例,面向AWS::S3命名空间,接口更贴近早期 S3 REST 语义

两种 SDK 均通过 HTTP 调用 RGW 的 S3 端点,认证依赖 AWS 签名(Signature v2/v4),因此只要是合法的 S3 凭据即可工作,无需任何 Ceph 专用客户端库。


二、现代 SDK(aws-sdk gem ~>2):连接配置与客户端初始化

2.1 全局连接设置

官方推荐使用Aws.config.update进行全局配置,一次性声明端点、凭据与访问模式:

Aws.config.update( endpoint: 'https://objects.dreamhost.com.', access_key_id: 'my-access-key', secret_access_key: 'my-secret-key', force_path_style: true, region: 'us-east-1' )

参数含义与注意事项:

  • endpoint:RGW 网关地址。必须显式指定,否则 SDK 会默认指向 AWS 官方 S3 服务。
  • access_key_id/secret_access_key:S3 凭据,可由radosgw-admin user create创建用户时生成(详见下文"准备凭据"小节)。
  • force_path_style: true:强制使用path-style访问模式(GET /mybucket)。这几乎总是对接 RGW 的正确选择——因为 RGW 默认并未为每个桶分配子域名,virtual-hosted-style(GET /Host: mybucket.cname.domain.com)需要额外配置rgw_dns_name或 zonegroup 的hostnames。两种访问模式的差异与配置方法参见 doc/radosgw/s3/commons.rst。
  • region:RGW 对 region 值不做强制校验,填写任意值(如us-east-1)即可满足签名计算要求。

2.2 实例化客户端

s3_client = Aws::S3::Client.new

之后所有桶与对象操作均通过s3_client完成。

2.3 准备凭据(对接 RGW 前的账号准备)

在真实环境中,你需要先在 RGW 中创建 S3 用户并获取访问密钥,这属于 RGW 管理面操作,可参考 doc/radosgw/adminops.rst 中的用户管理章节,典型命令形如:

radosgw-admin user create --uid=ruby-user --display-name="Ruby User" --gen-access-key --gen-secret-key

创建成功后命令会返回access_keysecret_key,将其填入上面的Aws.config.update即可。RGW 对请求的认证基于 AWS 签名(v2/v4),SDK 会自动完成签名计算;只有手工构造原始 HTTP 请求时才需要自行计算签名,详见 doc/radosgw/s3/authentication.rst。


三、桶操作:列出、创建、清空与删除

3.1 列出自己拥有的桶(List Owned Buckets)

s3_client.list_buckets.buckets.each do |bucket| puts "#{bucket.name}\t#{bucket.creation_date}" end

输出形如:

mahbuckat1 2011-04-21T18:05:39.000Z mahbuckat2 2011-04-21T18:05:48.000Z mahbuckat3 2011-04-21T18:07:18.000Z

该操作对应 S3 的GET /服务级请求(Service Ops),在 RGW 侧由s3:ListAllMyBuckets权限控制。

3.2 创建桶(Create Bucket)

s3_client.create_bucket(bucket: 'my-new-bucket')

若希望桶默认为私有,可显式传入acl选项:

s3_client.create_bucket(bucket: 'my-new-bucket', acl: 'private')

acl选项(canned ACL)支持以下取值:

  • private:仅所有者可读写(默认)
  • public-read:公开可读
  • public-read-write:公开读写(慎用)
  • authenticated-read:仅已认证用户可读

这四个 canned ACL 值与 RGW 服务端实现一一对应,见 src/rgw/rgw_acl_s3.cc 中的解析逻辑(private/public-read/public-read-write/authenticated-read)。需要注意的是,官方文档 doc/radosgw/s3.rst 明确指出 RGW 对桶的 canned ACL 集合与 AWS 存在差异("Different set of canned ACLs")。

3.3 列出桶内容(List a Bucket's Content)

s3_client.get_objects(bucket: 'my-new-bucket').contents.each do |object| puts "#{object.key}\t#{object.size}\t#{object.last-modified}" end

输出形如:

myphoto1.jpg 251262 2011-08-08T21:35:48.000Z myphoto2.jpg 262518 2011-08-08T21:38:01.000Z

注意:官方文档此处写的是get_objects,实际现代aws-sdk(v2+)中列出对象的标准方法是list_objectslist_objects_v2,返回结构均为contents数组,字段keysizelast_modified一致。若你的 SDK 版本提示找不到get_objects,请改用:

s3_client.list_objects(bucket: 'my-new-bucket').contents.each do |object| puts "#{object.key}\t#{object.size}\t#{object.last_modified}" end

3.4 删除桶(Delete Bucket)

⚠️ 注意:桶必须为空才能删除成功,否则操作会失败!

s3_client.delete_bucket(bucket: 'my-new-bucket')

3.5 非空桶的强制删除

删除非空桶前必须先清空桶,SDK 提供了便捷方法:

Aws::S3::Bucket.new('my-new-bucket', client: s3_client).clear!

清空之后即可删除桶:

s3_client.delete_bucket(bucket: 'my-new-bucket')

clear!会遍历桶内对象并逐个调用delete_object,等效于先list_objects再循环删除,因此数据量极大时建议评估耗时与请求配额。


四、对象操作:上传、ACL 管理、下载与删除

4.1 创建对象(Put Object)

在桶my-new-bucket中创建hello.txt,内容为字符串"Hello World!"

s3_client.put_object( key: 'hello.txt', body: 'Hello World!', bucket: 'my-new-bucket', content_type: 'text/plain' )

content_type显式指定Content-Type元数据;若省略,SDK 会根据body类型推断。上传大文件时可改用put_object的文件流形式,或使用 Multipart Upload(RGW 支持,见 doc/radosgw/s3.rst 功能表)。

4.2 修改对象 ACL

使hello.txt公开可读、secret_plans.txt私有:

s3_client.put_object_acl(bucket: 'my-new-bucket', key: 'hello.txt', acl: 'public-read') s3_client.put_object_acl(bucket: 'my-new-bucket', key: 'private.txt', acl: 'private')

RGW 的 ACL 模型包含READWRITEREAD_ACPWRITE_ACPFULL_CONTROL五种权限,作用于桶与对象时语义不同(例如READ在桶上表示"可列出桶内对象",在对象上表示"可读取该对象"),完整权限对照与 S3 操作到 ACL 权限的映射表见 doc/radosgw/s3/authentication.rst。

4.3 下载对象到本地文件(Get Object)

将对象poetry.pdf下载并保存到本地目录:

s3_client.get_object( bucket: 'my-new-bucket', key: 'poetry.pdf', response_target: '/home/larry/documents/poetry.pdf' )

response_target指定本地保存路径,SDK 会以文件流方式落盘,避免将大对象整体读入内存。

4.4 删除对象(Delete Object)

s3_client.delete_object(key: 'goodbye.txt', bucket: 'my-new-bucket')

RGW 侧由s3:DeleteObject权限控制,对应WRITE级 ACL 权限。


五、生成对象下载 URL:未签名(公开)与预签名(限时)

对于公开对象(已通过 ACL 设为public-read),可以生成无需签名的直接访问 URL:

puts Aws::S3::Object.new( key: 'hello.txt', bucket_name: 'my-new-bucket', client: s3_client ).public_url

对于私有对象(如secret_plans.txt),生成预签名 URL(presigned URL),在有效期内任何人都可通过该 URL 下载,即使对象本身是私有的;有效期过后 URL 立即失效:

puts Aws::S3::Object.new( key: 'secret_plans.txt', bucket_name: 'hermes_ceph_gem', client: s3_client ).presigned_url(:get, expires_in: 60 * 60)

expires_in单位为秒,上例为 1 小时(60 * 60)。输出形如:

http://objects.dreamhost.com/my-bucket-name/hello.txt http://objects.dreamhost.com/my-bucket-name/secret_plans.txt?Signature=XXXXXXXXXXXXXXXXXXXXXXXXXXX&Expires=1316027075&AWSAccessKeyId=XXXXXXXXXXXXXXXXXXX

预签名 URL 的本质是将签名作为查询参数(SignatureExpiresAWSAccessKeyId)附加到 URL 上,RGW 在收到请求时会校验签名与有效期。这是临时授权下载最常用的手段,适合"限时分享私有文件"场景。

小提示:示例中第二个 URL 的桶名为hermes_ceph_gem,这是官方文档的历史笔误,实际应为你自己的桶名(如my-new-bucket),请按需替换。


六、经典 gem(aws-s3):老一代 SDK 的对应操作

aws-s3gem 提供与aws-sdk平行的操作集合,接口风格更接近早期 S3 REST 语义,适合维护旧项目。以下逐一给出对应实现。

6.1 建立连接

AWS::S3::Base.establish_connection!( :server => 'objects.dreamhost.com', :use_ssl => true, :access_key_id => 'my-access-key', :secret_access_key => 'my-secret-key' )

establish_connection!建立全局连接;use_ssl决定是否走 HTTPS。注意该接口没有force_path_style参数,若 RGW 未配置桶子域名,需要注意主机名与路径的解析方式。

6.2 列出自己拥有的桶

AWS::S3::Service.buckets.each do |bucket| puts "#{bucket.name}\t#{bucket.creation_date}" end

输出同上(mahbuckat1 ...)。

6.3 创建桶

AWS::S3::Bucket.create('my-new-bucket')

6.4 列出桶内容

new_bucket = AWS::S3::Bucket.find('my-new-bucket') new_bucket.each do |object| puts "#{object.key}\t#{object.about['content-length']}\t#{object.about['last-modified']}" end

object.about返回对象的元数据哈希,包含content-length(字节数)与last-modified

6.5 删除桶

⚠️ 同样要求桶为空,否则失败!

AWS::S3::Bucket.delete('my-new-bucket')

6.6 非空桶强制删除

aws-s3直接支持:force => true,一步完成清空与删除:

AWS::S3::Bucket.delete('my-new-bucket', :force => true)

这是与aws-sdk实现(先clear!delete_bucket)最明显的 API 差异。

6.7 创建对象

AWS::S3::S3Object.store( 'hello.txt', 'Hello World!', 'my-new-bucket', :content_type => 'text/plain' )

6.8 修改对象 ACL

通过 Grant 列表改写 ACL:公开hello.txt、私有化secret_plans.txt

policy = AWS::S3::S3Object.acl('hello.txt', 'my-new-bucket') policy.grants = [ AWS::S3::ACL::Grant.grant(:public_read) ] AWS::S3::S3Object.acl('hello.txt', 'my-new-bucket', policy) policy = AWS::S3::S3Object.acl('secret_plans.txt', 'my-new-bucket') policy.grants = [] AWS::S3::S3Object.acl('secret_plans.txt', 'my-new-bucket', policy)

这里先读取对象当前 ACL,再整体替换grants列表(空列表即私有),最后回写。

6.9 下载对象到本地文件

aws-s3以流式分块方式下载并写入文件:

open('/home/larry/documents/poetry.pdf', 'w') do |file| AWS::S3::S3Object.stream('poetry.pdf', 'my-new-bucket') do |chunk| file.write(chunk) end end

6.10 删除对象

AWS::S3::S3Object.delete('goodbye.txt', 'my-new-bucket')

6.11 生成下载 URL(签名/未签名)

# 未签名(公开对象)URL puts AWS::S3::S3Object.url_for( 'hello.txt', 'my-new-bucket', :authenticated => false ) # 预签名(限时 1 小时)URL puts AWS::S3::S3Object.url_for( 'secret_plans.txt', 'my-new-bucket', :expires_in => 60 * 60 )

:authenticated => false生成不带签名的公开 URL;:expires_in生成带签名的限时 URL。输出格式与aws-sdk示例一致。


七、两种 SDK 操作对照一览

操作aws-sdk(~>2)aws-s3
连接配置Aws.config.update+Aws::S3::Client.newAWS::S3::Base.establish_connection!
列出桶s3_client.list_buckets.bucketsAWS::S3::Service.buckets
创建桶s3_client.create_bucket(bucket: ...)AWS::S3::Bucket.create(...)
列出桶内容list_objects(bucket: ...).contentsBucket.find(...)后迭代
删除桶(空)s3_client.delete_bucket(bucket: ...)AWS::S3::Bucket.delete(...)
强制删除Bucket.new(...).clear!后删除AWS::S3::Bucket.delete(..., :force => true)
创建对象put_object(key:, body:, bucket:, content_type:)S3Object.store(key, value, bucket, :content_type => ...)
修改 ACLput_object_acl(bucket:, key:, acl:)读写S3Object.acl+policy.grants
下载对象get_object(bucket:, key:, response_target:)S3Object.stream分块写文件
删除对象delete_object(key:, bucket:)S3Object.delete(key, bucket)
未签名 URLObject#public_urlurl_for(..., :authenticated => false)
预签名 URLObject#presigned_url(:get, expires_in:)url_for(..., :expires_in => ...)

八、背后的实现要点(结合 RGW 源码)

  • canned ACL 的服务端解析create_bucketput_object_acl传入的acl字符串在 RGW 服务端由 src/rgw/rgw_acl_s3.cc 解析并映射为具体的 grant 集合,支持privatepublic-readpublic-read-writeauthenticated-read四种取值;非法取值会返回参数错误。
  • 认证机制:RGW 支持 AWS Signature v4 与 v2 两种签名算法,SDK 自动完成签名;x-amz-content-sha256头支持实际负载校验值、UNSIGNED-PAYLOAD以及多种流式负载模式,详见 doc/radosgw/s3/authentication.rst。
  • 访问模式force_path_style: true对应 path-style 请求(GET /mybucket),是 RGW 部署的常见形态;如需 virtual-hosted-style(Host: mybucket.cname.domain.com),需通过rgw_dns_name配置或在 zonegroup 中声明hostnames,参见 doc/radosgw/s3/commons.rst。
  • 签名 URL 的校验:预签名 URL 通过查询参数携带签名与过期时间,RGW 校验通过后放行匿名下载,因此时效性与签名完整性由 RGW 统一保障,客户端无需额外处理。

九、常见问题与排错建议

  1. endpoint忘记配置:SDK 会默认连向 AWS 官方 S3,请求将失败或指向错误服务;务必显式设置 RGW 地址。
  2. 桶删除失败:检查桶是否为空。非空桶需先clear!(或:force => true)。
  3. 403 AccessDenied:确认access_key_id/secret_access_key正确,且该用户对目标桶/对象拥有相应 ACL 或桶策略权限;RGW 支持桶策略与 ACL 两种授权模型,官方建议优先使用桶策略,见 doc/radosgw/s3/authentication.rst 末尾说明。
  4. URL 上出现异常主机名:检查是否启用了 virtual-hosted-style 而 RGW 未配置桶子域名;保持force_path_style: true通常是更稳妥的选择。
  5. 对象上传大文件put_object直接上传适合中小文件,超大对象建议使用 Multipart Upload API(RGW 支持,见 doc/radosgw/s3.rst 特性表)。
  • 存储
  • 分布式文件系统
  • 对象存储
  • 后端
  • 高可用

【免费下载链接】ceph

Ceph is a distributed object, block, and file storage platform

项目地址:https://gitcode.com/gh_mirrors/ce/ceph
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询