ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

使用 C AWS SDK 对接 Ceph RGW S3 网关:从连接建立、桶与对象操作到预签名 URL 的完整实践

使用 C AWS SDK 对接 Ceph RGW S3 网关:从连接建立、桶与对象操作到预签名 URL 的完整实践 存储分布式文件系统对象存储后端高可用【免费下载链接】cephCeph is a distributed object, block, and file storage platform项目地址https://gitcode.com/gh_mirrors/ce/ceph点击查看免费下载本文以 Ceph RADOS GatewayRGW的 S3 兼容接口为核心系统讲解如何使用 C# AWS SDKAmazon.S3完成从建立连接、管理桶、读写对象、设置对象 ACL 到生成预签名下载 URL 的全流程操作。读完本文你将掌握一套可直接复用的 C# S3 客户端代码骨架并理解其背后 RGW 的认证、ACL 与签名 URL 机制从而在自己的 .NET 应用中稳定对接 Ceph 对象存储。前置准备RGW 的 S3 兼容能力与客户端配置RGWRADOS Gateway为 Ceph 提供对象存储服务对外暴露 S3 与 Swift 两套 API。本文使用的 C# 示例均基于 S3 API任何实现了 AWS S3 协议的官方 SDK 或第三方客户端包括 .NET 的AWSSDK.S3NuGet 包都可以直接对接无需额外插件。要使用 S3 API客户端必须具备一对S3 access key 与 secret key即用户凭据RGW 依据 AWS SignatureSigV2 / SigV4对请求进行认证。大多数 S3 客户端与 AWS SDK 会在你提供凭据后自动完成签名计算RGW 对 AWS Signature v4 支持x-amz-content-sha256头部的多种取值实际载荷校验值、UNSIGNED-PAYLOAD、STREAMING-UNSIGNED-PAYLOAD-TRAILER、STREAMING-AWS4-HMAC-SHA256-PAYLOAD等并继续兼容已被 AWS 弃用的 v2 签名详见 S3 认证与 ACL 文档。在编写代码前还需要确认网关的访问地址endpoint。Ceph 对象网关支持两种桶访问模式详见 S3 公共实体文档路径式path-style桶名作为请求路径的顶层目录例如GET /mybucket HTTP/1.1请求的Host为cname.domain.com虚拟主机式virtual-hosted-style桶名作为域名的一部分例如GET / HTTP/1.1Host: mybucket.cname.domain.com。这是大多数 S3 客户端默认采用的模式AWS 已弃用路径式访问。网关用于解析桶名的 FQDN域名可以通过配置项rgw_dns_name设置也可在 zonegroup 配置的hostnames中声明例如ceph config set client.rgw.ceph authx client for rgw rgw_dns_name cname.domain.dom实际使用中的注意事项rgw_dns_name支持用逗号分隔多个主机名启用 SSL 时证书必须使用匹配桶子域名的通配符网关位于代理之后时应使用代理的 DNS 名称并可通过ceph config set client.rgw为所有实例统一设置s3websiteAPI 的静态网站视图必须使用与rgw_dns_name不同的域名由rgw_dns_s3website_name单独配置。创建连接AmazonS3Client 的初始化连接到 RGW 只需构造AmazonS3Client实例并把网关地址配置到AmazonS3Config.ServiceURL。以下代码建立与服务器的连接是后续所有操作的前提using System; using Amazon; using Amazon.S3; using Amazon.S3.Model; string accessKey put your access key here!; string secretKey put your secret key here!; AmazonS3Config config new AmazonS3Config(); config.ServiceURL objects.dreamhost.com; AmazonS3Client s3Client new AmazonS3Client( accessKey, secretKey, config );说明accessKey/secretKey替换为在 Ceph 中创建 S3 用户后获得的真实凭据ServiceURL指向 RGW 网关地址示例中的objects.dreamhost.com为原文档使用的演示域名实际部署时应填写自己的网关 FQDN 或 IP:端口若网关走 HTTPS可在AmazonS3Config上启用相应的安全传输配置若走自定义端口需在ServiceURL中带上端口号。桶操作创建、列举与删除列出自己拥有的桶ListBuckets()返回当前凭据拥有即有权限列举的桶列表并输出每个桶的名称与创建时间ListBucketsResponse response client.ListBuckets(); foreach (S3Bucket b in response.Buckets) { Console.WriteLine({0}\t{1}, b.BucketName, b.CreationDate); }输出形如mahbuckat1 2011-04-21T18:05:39.000Z mahbuckat2 2011-04-21T18:05:48.000Z mahbuckat3 2011-04-21T18:07:18.000Z在 RGW 中s3:ListAllMyBuckets操作映射为 ACL 的READ权限见 S3 认证与 ACL 文档 中的操作—权限映射表因此该调用要求凭据对相应租户/用户空间具备读取权限。创建一个桶PutBucketRequest request new PutBucketRequest(); request.BucketName my-new-bucket; client.PutBucket(request);创建一个名为my-new-bucket的新桶。注意 S3 桶名有全局唯一的命名约束若同名桶已存在RGW 会返回409 BucketAlreadyExists。列出桶内对象列举桶内对象并打印每个对象的名称Key、大小与最后修改时间ListObjectsRequest request new ListObjectsRequest(); request.BucketName my-new-bucket; ListObjectsResponse response client.ListObjects(request); foreach (S3Object o in response.S3Objects) { Console.WriteLine({0}\t{1}\t{2}, o.Key, o.Size, o.LastModified); }输出形如myphoto1.jpg 251262 2011-08-08T21:35:48.000Z myphoto2.jpg 262518 2011-08-08T21:38:01.000ZListObjects对应s3:ListBucket映射为READ权限。对于对象数量庞大的桶SDK 会分页返回可通过响应中的IsTruncated与NextMarker继续拉取。删除一个桶DeleteBucketRequest request new DeleteBucketRequest(); request.BucketName my-new-bucket; client.DeleteBucket(request);重要约束桶必须为空否则删除不会成功若桶内仍有对象RGW 将返回409 BucketNotEmpty。因此删除前通常需要先删除桶内全部对象包括未完成的分片上传。强制删除非空桶原文档明确指出该功能当前不可用not available。RGW 不提供“递归清空并删除桶”的 S3 操作客户端必须先枚举并删除所有对象含未完成的分片上传后才能成功删除桶。对象操作上传、下载与删除创建上传一个对象以下代码在桶中创建hello.txt内容为字符串Hello World!并设置ContentType为text/plainPutObjectRequest request new PutObjectRequest(); request.BucketName my-new-bucket; request.Key hello.txt; request.ContentType text/plain; request.ContentBody Hello World!; client.PutObject(request);PutObject对应s3:PutObject映射为WRITE权限。对超大文件建议改用分片上传Multipart Upload以获得更好的断点续传与并发性能RGW 同样实现了完整的 S3 Multipart Upload 协议。下载对象到本地文件GetObjectRequest request new GetObjectRequest(); request.BucketName my-new-bucket; request.Key perl_poetry.pdf; GetObjectResponse response client.GetObject(request); response.WriteResponseStreamToFile(C:\\Users\\larry\\Documents\\perl_poetry.pdf);该示例将对象perl_poetry.pdf下载并保存到本地路径C:\Users\larry\Documents\perl_poetry.pdfWindows 路径中\\为转义后的单个反斜杠。GetObject对应s3:GetObject映射为READ权限。删除一个对象DeleteObjectRequest request new DeleteObjectRequest(); request.BucketName my-new-bucket; request.Key goodbye.txt; client.DeleteObject(request);DeleteObject对应s3:DeleteObject映射为WRITE权限。若需批量删除可改用DeleteObjects对应 S3 的POST ?delete多对象删除接口。修改对象 ACLPublicRead 与 Private对象默认继承桶的访问控制策略。通过PutACL可以把对象设置为公开可读或私有PutACLRequest request new PutACLRequest(); request.BucketName my-new-bucket; request.Key hello.txt; request.CannedACL S3CannedACL.PublicRead; client.PutACL(request); PutACLRequest request2 new PutACLRequest(); request2.BucketName my-new-bucket; request2.Key secret_plans.txt; request2.CannedACL S3CannedACL.Private; client.PutACL(request2);上述代码将hello.txt设置为公开可读将secret_plans.txt设置为私有。PutACL对应s3:PutObjectAcl映射为WRITE_ACP权限。理解 ACL 需要先掌握 RGW 的权限模型。RGW 支持 S3 兼容的 ACL 功能ACL 是一组访问授权grant列表指明某个主体grantee可以对桶或对象执行哪些操作。同一个权限作用于桶与作用于对象时含义不同权限作用于桶作用于对象READGrantee 可以列出桶内对象Grantee 可以读取对象WRITEGrantee 可以写入或删除桶内对象不适用N/AREAD_ACPGrantee 可以读取桶的 ACLGrantee 可以读取对象的 ACLWRITE_ACPGrantee 可以写入桶的 ACLGrantee 可以写入对象的 ACLFULL_CONTROLGrantee 对桶内对象拥有完全权限Grantee 可以读写对象的 ACLRGW 内部把 S3 操作映射为上述 ACL 权限例如s3:GetObject、s3:ListBucket映射为READs3:PutObject、s3:DeleteObject、s3:CreateBucket映射为WRITEs3:GetBucketAcl、s3:GetObjectAcl映射为READ_ACPs3:PutBucketAcl、s3:PutObjectAcl映射为WRITE_ACP完整映射表见 S3 认证与 ACL 文档。在源码层面这些权限位定义于 rgw_acl.h如RGW_PERM_FULL_CONTROL等RGW 在 rgw_rest_s3.cc 中依据请求携带的 canned ACL 头部x-amz-acl调用create_canned_acl生成对应的访问控制策略。从源码结构看S3CannedACL.PublicRead对应 RGW 的public-read策略S3CannedACL.Private对应private策略。需要提醒的是官方文档建议在可行时优先使用S3 桶策略Bucket Policy而非 ACL因为部分操作如s3:CreateBucket映射到WRITE仅是为了让 Swift 与 S3 在共享资源时保持语义一致ACL 模型在复杂授权场景下表达能力有限。生成对象下载 URL预签名 URL 详解预签名 URLPre-Signed URL用于把“临时可用的下载链接”分发给未持有凭据的第三方。本文场景中hello.txt已被上面的 ACL 设置为公开可读因此它天然拥有未签名 URL任何人无需凭据即可下载secret_plans.txt是私有对象必须借助签名 URL才能临时授权下载。官方文档特别注明C# 的 AWS S3 库没有生成未签名 URL 的方法因此下面只演示签名 URL 的生成GetPreSignedUrlRequest request new GetPreSignedUrlRequest(); request.BucketName my-bucket-name; request.Key secret_plans.txt; request.Expires DateTime.Now.AddHours(1); request.Protocol Protocol.HTTP; string url client.GetPreSignedURL(request); Console.WriteLine(url);输出形如http://objects.dreamhost.com/my-bucket-name/secret_plans.txt?SignatureXXXXXXXXXXXXXXXXXXXXXXXXXXXExpires1316027075AWSAccessKeyIdXXXXXXXXXXXXXXXXXXX关键语义Expires DateTime.Now.AddHours(1)表示该 URL 在1 小时内有效即使对象是私有的签名 URL 在有效期内也可以正常下载一旦超过Expires指定的时间戳URL 立即失效Protocol.HTTP决定生成的链接协议可按需改为Protocol.HTTPSURL 中的Signature、Expires、AWSAccessKeyId参数是签名认证的核心要素RGW 会在收到请求时用同样的算法重新计算签名并校验时间窗从而完成对匿名携带 URL 的请求的身份验证。在 Ceph 多租户multitenancy与 Keystone 认证场景下私有对象上的签名 URL 与公开读 ACL 有特殊的处理考量部署时需注意相关约束参见 S3 认证与 ACL 文档 中的说明。常见 HTTP 状态码与排错参考与 RGW 交互时客户端收到的 HTTP 状态码可以直接指导排查方向。以下是 S3 公共实体文档 整理的常用状态码HTTP 状态响应码典型含义200Success操作成功201Created资源创建成功如 PutObject 成功204NoContent操作成功但无返回体如 DeleteObject 成功400InvalidBucketName / InvalidObjectName / InvalidDigest / BadDigest 等请求参数或校验不合法403AccessDenied / RequestTimeTooSkewed凭据无效、权限不足或客户端时钟偏差过大签名时间校验失败404NoSuchKey / NoSuchBucket / NoSuchUpload对象、桶或分片上传不存在409BucketAlreadyExists / BucketNotEmpty桶已存在 / 桶非空无法删除411MissingContentLength缺少请求体长度412PreconditionFailed条件请求前置条件不满足416InvalidRange请求的 Range 越界500InternalError服务端内部错误常见公共请求头包括CONTENT_LENGTH请求体长度、DATEUTC 请求时间、HOST主机名、AUTHORIZATION认证令牌。当遇到403 RequestTimeTooSkewed时优先检查客户端与网关的系统时钟同步遇到404 NoSuchBucket时优先检查rgw_dns_name与桶访问模式path-style / virtual-hosted-style是否配置一致。小结从示例到生产实践本文完整覆盖了 C# AWS SDK 对接 Ceph RGW S3 网关的核心操作链连接初始化 → 列举/创建/删除桶 → 上传/下载/删除对象 → 修改对象 ACL → 生成预签名 URL。在此基础上向生产环境迁移时还应注意使用真实凭据并妥善保管 secret key、为网关正确配置rgw_dns_name与 SSL 通配符证书、优先使用桶策略做细粒度授权、对大对象采用分片上传、关注多租户与 Keystone 认证对签名 URL 的影响。如需继续深入可阅读仓库中的以下资源C# S3 示例原文本文章节的原始出处S3 认证与 ACL 文档SigV2/SigV4 认证细节、ACL 权限语义与 S3 操作映射表S3 公共实体文档桶访问模式、请求头与状态码说明S3 桶操作文档 与 S3 对象操作文档更多桶与对象级 REST 操作细节rgw_acl.hACL 数据结构与权限位定义rgw_rest_s3.cccanned ACL 的解析与策略生成实现。赞分享存储分布式文件系统对象存储后端高可用【免费下载链接】cephCeph is a distributed object, block, and file storage platform项目地址https://gitcode.com/gh_mirrors/ce/ceph点击查看免费下载相关推荐如何用 start-cluster.sh 为 LibreChat 本地搭建三节点 Redis Cluster 并通过 .env 连接验证如何用 start cluster.sh 为 LibreChat 本地搭建三节点 Redis Cluster 并通过 .env 连接验证 LibreChat 本存储分布式文件系统对象存储后端高可用Ceph 对象存储 Java S3 开发实战基于 AWS Java SDK 2.17 的完整操作指南Ceph 对象存储 Java S3 开发实战基于 AWS Java SDK 2.17 的完整操作指南 本指南以 Ceph 对象网关RADOS Gateway存储分布式文件系统对象存储后端高可用Ceph RGW Cloud Restore从 S3 兼容云端存储类恢复对象的完整实践指南Ceph RGW Cloud Restore从 S3 兼容云端存储类恢复对象的完整实践指南 Cloud Restore 是 Ceph 对象网关RGW在 c存储分布式文件系统对象存储后端高可用创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表