使用 CephObjectStoreUser(Ceph Driver)控制 COSI Bucket 的访问权限和配额

Kubernetes 管理员可以结合 CephObjectStoreUser(COSU)BucketClass/BucketClaim 以及 BucketAccessClass/BucketAccess,为由 Ceph RGW 支持的 COSI bucket 实现 最小权限访问配额强制执行

你将构建的内容

  1. 一个带有显式 capability 和可选按用户配额的 CephObjectStoreUser;
  2. 一个 BucketClass,用于告诉 Ceph COSI driver 需要使用哪个 COSU 凭证;
  3. 一个或多个 BucketClaim,用于创建 bucket;
  4. 使用 BucketAccessClass/BucketAccess 为不同 workload 提供细粒度凭证(只读、只写、读写),并支持可选的匿名读取。

前提条件

  • 一个运行正常的 Ceph 集群,已安装 RGW 和 Rook。
  • 已安装 COSI 插件。
  • 集群管理员权限(用于创建集群作用域资源)。

步骤 1 — 创建 CephObjectStoreUser(包含 capability 和配额)

CephObjectStoreUser 是 driver 用于在 RGW 中执行 bucket 操作的 service account。它必须位于 rook-ceph namespace 中,并且目标指向你的 CephObjectStore

apiVersion: ceph.rook.io/v1
kind: CephObjectStoreUser
metadata:
  name: user-for-cosi
  namespace: rook-ceph
spec:
  # Target CephObjectStore
  store: object-store
  # Required capabilities for COSI bucket lifecycle
  capabilities:
    bucket: read, write
    user: read, write
  # Optional per-user quotas enforced by RGW
  quotas:
    maxBuckets: 50        # limit number of buckets this user can own
    maxObjects: 500        # total objects across buckets (example)
    maxSize: 100Gi       # total logical size across buckets
  displayName: "User for COSI driver"

获取生成的访问密钥(Rook 会为该用户创建一个 Secret):

kubectl get cephobjectstoreuser user-for-cosi -n rook-ceph -o yaml
# Read status.info.secretName -> the Secret holding AccessKey/SecretKey

这些 COSU 凭证由 driver(而不是你的应用)使用,用于代表你创建/删除 bucket。

步骤 2 — 定义绑定到 CephObjectStoreUser 的 BucketClass

BucketClass 会指示 driver 在创建 bucket 时使用哪个 COSU Secret。

apiVersion: objectstorage.k8s.io/v1alpha1
kind: BucketClass
metadata:
  name: ceph-cosi-driver-class
deletionPolicy: Delete
# Must match the driver name
driverName: ceph.objectstorage.k8s.io
parameters:
  # Reference the Secret created for the CephObjectStoreUser
  objectStoreUserSecretName: <secret-name-from-step-1>
  objectStoreUserSecretNamespace: rook-ceph

deletionPolicy 控制在删除 BucketClaim 时 bucket 的物理生命周期(Delete vs Retain)。

步骤 3 — 使用 BucketClaim 创建 bucket

通过引用 BucketClass,在你的应用 namespace 中创建 bucket。

apiVersion: objectstorage.k8s.io/v1alpha1
kind: BucketClaim
metadata:
  name: my-bucket-claim
  namespace: app-a
spec:
  bucketClassName: ceph-cosi-driver-class
  # Required by the COSI API (choose the data API you need)
  protocols:
  - S3

等待 status.bucketReady: true,并记录 status.bucketName,它表示实际的 RGW bucket 名称。

步骤 4 — 使用 BucketAccessClass/BucketAccess 发放最小权限凭证

使用 BucketAccessClass 定义策略模板,并通过 BucketAccess 为每个 workload 签发凭证。支持的策略包括:readonlywriteonlyreadwrite。通过设置 parameters.anonymous: "true"(字符串)即可启用匿名读取。

示例 BucketAccessClass(只读)

apiVersion: objectstorage.k8s.io/v1alpha1
kind: BucketAccessClass
metadata:
  name: ceph-readonly-access-class
authenticationType: KEY
driverName: ceph.objectstorage.k8s.io
parameters:
  policy: readonly
  anonymous: "false"

使用 BucketAccess 签发凭证

apiVersion: objectstorage.k8s.io/v1alpha1
kind: BucketAccess
metadata:
  name: my-bucket-readonly-access
  namespace: app-a
spec:
  bucketAccessClassName: ceph-readonly-access-class
  bucketClaimName: my-bucket-claim
  credentialsSecretName: my-bucket-readonly-credentials

driver 会写入一个在 credentialsSecretName 中指定名称的 Secret。对 .data.BucketInfo 进行解码(base64)后,即可获得 S3 client 所需的 secretS3.endpointaccessKeyIDaccessSecretKey

提示:为每个 Deployment/Job 签发不同的凭证,便于在不影响其他 workload 的情况下进行轮换和吊销。

步骤 5 — 匿名公开读取(可选)

如果你需要公开静态资源托管:

apiVersion: objectstorage.k8s.io/v1alpha1
kind: BucketAccessClass
metadata:
  name: ceph-anonymous-readonly-class
authenticationType: KEY
driverName: ceph.objectstorage.k8s.io
parameters:
  policy: readonly
  anonymous: "true"

将它通过 BucketAccess 绑定到你的 BucketClaim。一旦授予成功,对象即可通过未认证的 HTTP GET 访问(请确保网络暴露方式符合要求)。

步骤 6 — 配额控制:在哪里强制以及如何修改

作用范围: CephObjectStoreUser 上的 quotas 区块按 用户级别 生效,并由 RGW 对该用户拥有的所有 bucket 统一执行。

  • maxBuckets:用户可创建/拥有的 bucket 数上限。
  • maxObjects:用户可存储的对象总数上限(跨 bucket)。
  • maxSize:允许该用户使用的总逻辑大小。

更新配额 通过编辑 COSU 资源完成:

kubectl -n rook-ceph edit cephobjectstoreuser user-for-cosi
# Modify spec.quotas.{maxBuckets,maxObjects,maxSize}; save and exit.
# Rook reconciles and applies the new RGW user quotas.

设计选择: 保持 COSU 配额 相对严格,以限制影响范围。使用 最小权限策略 通过 BAC/BA 限制某一组应用凭证在 bucket 内 可以执行的操作。

运维与故障排查

  • Namespace 放置CephObjectStoreUser 及其 Secret 必须位于 rook-ceph。应用级资源(BucketClaimBucketAccess)应位于应用 namespace 中。
  • 策略未生效:确认 BAC 中的 bucketAccessClassNameparameters.policyreadonly|writeonly|readwrite)。
  • 匿名读取失败:确保 anonymous: "true"字符串,不是布尔值;检查 endpoint 暴露以及 HTTP 访问路径(/<bucket>/<object>)。
  • 找不到密钥:检查 BucketAccess Secret,并解码 .data.BucketInfo
  • Bucket 一直未就绪:检查 controller/driver 日志(例如 kubectl -n cpaas-system logs deploy/ceph-cosi-driver -c ceph-cosi-driver)。
  • 轮换:创建新的 BucketAccess,将 workload 切换到新的 Secret,然后删除旧的 Secret/BA。

清理

  • 通过删除其 BucketAccess 以及引用的 Secret,移除某个 workload 的凭证。
  • 删除 bucket:删除 BucketClaim(行为取决于 BucketClass.deletionPolicy)。如果后端因为 bucket 非空而拒绝删除,请先删除对象。