使用 CephObjectStoreUser(Ceph 驱动)控制 COSI 桶的访问权限和配额
本指南向 Kubernetes 管理员展示如何结合 CephObjectStoreUser (COSU)、BucketClass/BucketClaim 和 BucketAccessClass/BucketAccess,实现基于 Ceph RGW 的 COSI 桶的最小权限访问和配额管理。
您将构建的内容
- 一个具有明确权限和可选用户配额的 CephObjectStoreUser;
- 一个告诉 Ceph COSI 驱动使用哪个 COSU 凭证的 BucketClass;
- 一个或多个用于创建桶的 BucketClaim;
- 使用 BucketAccessClass/BucketAccess 实现细粒度的每工作负载凭证(只读、只写、读写),并可选支持匿名读取。
目录
前提条件第 1 步 — 创建带权限和配额的 CephObjectStoreUser第 2 步 — 定义绑定到 CephObjectStoreUser 的 BucketClass第 3 步 — 使用 BucketClaim 创建桶第 4 步 — 使用 BucketAccessClass/BucketAccess 发放最小权限凭证示例BucketAccessClass(只读)使用 BucketAccess 生成凭证第 5 步 — 匿名公共读取(可选)第 6 步 — 配额控制:在哪里执行及如何修改运行与故障排查清理前提条件
- 一个健康的 Ceph 集群,已安装 RGW 和 Rook。
- 已安装 COSI 插件。
- 集群管理员权限(用于创建集群范围资源)。
第 1 步 — 创建带权限和配额的 CephObjectStoreUser
CephObjectStoreUser 是驱动用来在 RGW 中执行桶操作的服务账户。它必须存在于 rook-ceph 命名空间,并指向你的 CephObjectStore。
获取生成的访问密钥(Rook 会为该用户创建一个 Secret):
这些 COSU 凭证由驱动程序使用(而非你的应用)来代表你创建/删除桶。
第 2 步 — 定义绑定到 CephObjectStoreUser 的 BucketClass
BucketClass 指示驱动在创建桶时使用哪个 COSU Secret。
deletionPolicy控制删除BucketClaim时桶的物理生命周期(Delete或Retain)。
第 3 步 — 使用 BucketClaim 创建桶
通过引用 BucketClass 在你的应用命名空间中创建桶。
等待 status.bucketReady: true,并记录 status.bucketName,这是实际的 RGW 桶名称。
第 4 步 — 使用 BucketAccessClass/BucketAccess 发放最小权限凭证
通过 BucketAccessClass 定义策略模板,并通过 BucketAccess 为每个工作负载生成凭证。支持的策略有:readonly、writeonly、readwrite。通过设置 parameters.anonymous: "true"(字符串)可启用匿名读取。
示例 BucketAccessClass(只读)
使用 BucketAccess 生成凭证
驱动会写入名为 credentialsSecretName 的 Secret。解码 .data.BucketInfo(base64)即可获得 secretS3.endpoint、accessKeyID 和 accessSecretKey,供你的 S3 客户端使用。
提示:为每个 Deployment/Job 颁发不同的凭证,简化凭证轮换和撤销,避免影响其他工作负载。
第 5 步 — 匿名公共读取(可选)
如果需要公共静态资源托管:
将其绑定到你的 BucketClaim 的 BucketAccess。授权后,对象可通过未认证的 HTTP GET 访问(请确保网络暴露配置正确)。
第 6 步 — 配额控制:在哪里执行及如何修改
作用范围: CephObjectStoreUser 上的 quotas 块针对每个用户生效,由 RGW 在该用户拥有的所有桶中统一执行。
maxBuckets:用户可创建/拥有的桶数量上限。maxObjects:用户可存储的对象总数上限(跨桶)。maxSize:用户允许的总逻辑存储大小。
更新配额,编辑 COSU 资源:
设计选择: 保持 COSU 配额 较为严格,以限制影响范围。通过 BAC/BA 使用最小权限策略,限制应用凭证在桶内的操作权限。
运行与故障排查
- 命名空间位置:
CephObjectStoreUser及其 Secret 必须在rook-ceph,应用级资源(BucketClaim、BucketAccess)应在应用命名空间。 - 策略未生效:确认 BAC 中的
bucketAccessClassName和parameters.policy是否正确(readonly|writeonly|readwrite)。 - 匿名读取失败:确保
anonymous: "true"是字符串类型而非布尔值;检查 endpoint 暴露和 HTTP 访问路径(/<bucket>/<object>)。 - 找不到密钥:检查
BucketAccessSecret,解码.data.BucketInfo。 - 凭证轮换:创建新的
BucketAccess,将工作负载切换到新 Secret,随后删除旧 Secret 和 BA。
清理
- 删除工作负载凭证:删除对应的
BucketAccess和引用的 Secret。 - 删除桶:删除
BucketClaim(行为遵循BucketClass.deletionPolicy)。