3406 lines
180 KiB
Markdown
3406 lines
180 KiB
Markdown
> 基于 Ceph 官方文档整理 | 文档版本:**Tentacle v20.2.4** | 抓取日期:2026-09-17 | 源文:ceph/ceph@v20.2.4 `doc/radosgw/`
|
||
> 官网入口:https://docs.ceph.com/en/tentacle/radosgw/
|
||
|
||
# 09 · RGW 对象存储篇(一):核心架构、部署与运维
|
||
|
||
---
|
||
|
||
## 本册导读
|
||
|
||
本册是 **RGW 对象存储四册中的第一册**,聚焦「RGW 是什么、怎么跑起来、怎么管」。
|
||
|
||
| 分册 | 主题 | 覆盖内容(对应 `doc/radosgw/` 页面) |
|
||
|---|---|---|
|
||
| **第 09 册(本册)** | 核心架构、部署与运维 | `index`, `frontends`, `pools`, `placement`, `layout`, `config-ref`, `admin`, `adminops`, `account`, `multitenancy`, `nfs`, `metrics`, `troubleshooting` |
|
||
| 第 10 册 | 多站点(Multisite)与数据同步 | `multisite`, `multisite-sync-policy`, `zone-features`, `sync-modules`, `cloud-sync-module`, `elastic-sync-module`, `archive-sync-module`, `orphans`, `cloud-transition`, `cloud-restore` |
|
||
| 第 11 册 | 数据面 API 与安全体系 | `s3`, `swift`, `iam`, `STS`, `STSLite`, `role`, `keycloak`, `oidc`, `session-tags`, `bucketpolicy`, `encryption`, `barbican`, `vault`, `kmip`, `opa`, `ldap-auth`, `keystone`, `mfa` |
|
||
| 第 12 册 | 高级特性与扩展能力 | `notifications`, `s3-notification-compatibility`, `bucket_logging`, `compression`, `s3select`, `lua-scripting`, `rgw-cache`, `d3n_datacache`, `dynamicresharding`, `qat-accel`, `uadk-accel`, `api` |
|
||
|
||
> 💡 补充:上表的「四册分工」是本手册的编排方案,Ceph 官方并未将 `doc/radosgw/` 划分为四册。官方 `index.rst` 的 toctree 是一个扁平的 50+ 页面列表,本手册按其主题相关性做了归组,页面→分册的映射以 `index.rst` 中真实的 toctree 条目为准。
|
||
|
||
**阅读建议**:本册是其余三册的基础。建议先读完第二、三、四章(架构/数据布局/存储池)建立心智模型,再读第六、七章(管理命令与管理 API)作为日常操作手册,第十二章(配置参考)作为查阅字典。
|
||
|
||
---
|
||
|
||
## 一、RGW 是什么
|
||
|
||
### 1.1 定位
|
||
|
||
:term:`Ceph Object Gateway`(RGW,守护进程名 `radosgw`)是构建在 `librados` 之上的**对象存储接口层**。它在应用与 Ceph 存储集群之间提供了一层 RESTful 网关。
|
||
|
||
官方文档对 RGW 的原始定义(直译):
|
||
|
||
> Ceph 对象网关是一个构建在 `librados` 之上的对象存储接口,为应用与 Ceph 存储集群之间提供 RESTful 网关。Ceph 对象存储支持两种接口:
|
||
> 1. **S3 兼容**:提供与 Amazon S3 RESTful API 的很大一个子集兼容的对象存储功能。
|
||
> 2. **Swift 兼容**:提供与 OpenStack Swift API 的很大一个子集兼容的对象存储功能。
|
||
>
|
||
> Ceph 对象存储使用 Ceph 对象网关守护进程(`radosgw`),这是一个为与 Ceph 存储集群交互而设计的 HTTP 服务器。
|
||
|
||
关键事实(全部来自 `index.rst`):
|
||
|
||
| 事实 | 说明 |
|
||
|---|---|
|
||
| 底层依赖 | `librados`,不是独立的存储引擎 |
|
||
| 守护进程 | `radosgw`(HTTP 服务器) |
|
||
| 兼容接口 | Amazon S3 RESTful API 的**大子集**、OpenStack Swift API 的**大子集** |
|
||
| 用户体系 | **自带**用户管理(独立于 Ceph 集群的 `client.*` 认证) |
|
||
| 命名空间 | **S3 API 与 Swift API 共享同一个命名空间**——用一种 API 写入,可用另一种 API 读出 |
|
||
| 与 CephFS/RBD 的关系 | 可以用**同一个** Ceph 存储集群同时承载 Ceph 文件系统、Ceph 块设备客户端与 RGW 的数据 |
|
||
| MDS 依赖 | **不使用** Ceph Metadata Server(官方 note 明确强调:Ceph Object Storage does **NOT** use the Ceph Metadata Server) |
|
||
|
||
官方给出的分层示意图(`index.rst` 的 ditaa,此处转为文本):
|
||
|
||
```text
|
||
+------------------------+ +------------------------+
|
||
| S3 compatible API | | Swift compatible API |
|
||
+------------------------+-+------------------------+
|
||
| radosgw |
|
||
+---------------------------------------------------+
|
||
| librados |
|
||
+------------------------+-+------------------------+
|
||
| OSDs | | Monitors |
|
||
+------------------------+ +------------------------+
|
||
```
|
||
|
||
### 1.2 S3 / Swift 双接口与共享命名空间
|
||
|
||
- **S3 接口**:面向使用 AWS S3 SDK 的应用。认证使用 access key / secret key 的签名机制。
|
||
- **Swift 接口**:面向 OpenStack Swift 生态。认证使用 Swift 的账号/用户/密钥机制,在 RGW 内部体现为 **subuser**(见第六章)。
|
||
- **共享命名空间**:两 API 共享同一份 bucket/object 数据。Swift 的 *container* 在 RGW 中就是 S3 的 *bucket*,文档里两者互换使用(`layout.rst`:「Swift 所谓的 *container* 与 S3 术语 *bucket* 可以互换使用,因此我们说 RGW 的 bucket 实现了 Swift container」)。
|
||
|
||
### 1.3 与原生 AWS S3 的能力差异(本册源文可确证的部分)
|
||
|
||
> ⚠️ 本册范围内的官方文档**没有**给出一份完整的「RGW vs AWS S3 差异清单」。以下是本册所读源文中**明确提到**的差异点,其余差异官方文档未在本册范围内说明(将在第 11 册展开)。
|
||
|
||
| 差异点 | 官方文档原文/含义 | 出处 |
|
||
|---|---|---|
|
||
| API 只是「大子集」 | 「compatible with a *large subset* of the Amazon S3 RESTful API」——并非 100% 兼容 | `index.rst` |
|
||
| Storage Class 命名 | 使用 AWS S3 SDK(如 `boto3`)时,storage class 名称**必须**与 AWS S3 提供的名称一致,否则 SDK 会丢弃请求并抛异常 | `placement.rst` |
|
||
| `GLACIER` 前缀的坑 | 部分 S3 客户端/库对名为或以 `GLACIER` 为前缀的 storage class 有 AWS 特有行为的预期,用于 Ceph RGW 时会失败 | `placement.rst` |
|
||
| Bucket 命名规则 | 可通过 `rgw_relaxed_s3_bucket_names` 放宽 S3 bucket 命名限制(例如 Swift container 名含下划线时不被 S3 规则接受) | `nfs.rst`, `config-ref.rst` |
|
||
| 多租户 | 原生 S3 API **不处理**多租户,而 radosgw 的实现处理——这在签名 URL 与 public read ACL 场景下带来额外复杂度 | `multitenancy.rst` |
|
||
| NFS 语义限制 | 通过 NFS 导出时:不支持链接(含 symlink)、不支持 NFS ACL、目录不可移动/重命名、只支持完整顺序写 | `nfs.rst` |
|
||
|
||
官方建议的 storage class 命名(`placement.rst`):优先使用 `INTELLIGENT-TIERING`、`STANDARD_IA`、`REDUCED_REDUNDANCY`、`ONEZONE_IA`;自定义名如 `CHEAPNDEEP` 虽然 Ceph 接受,但部分客户端/库可能不接受。
|
||
|
||
### 1.4 适用场景与不适用场景
|
||
|
||
> 💡 补充:官方文档在本册范围内**没有**列出适用/不适用场景清单。以下为基于本册源文事实(1.1/1.2/1.3 节 + NFS 限制 + 顺序写限制)的归纳,非官方原文。
|
||
|
||
**适用场景**
|
||
|
||
| 场景 | 依据 |
|
||
|---|---|
|
||
| 需要 S3/Swift 兼容 API 的私有云/自建对象存储 | 双接口 + 共享命名空间(`index.rst`) |
|
||
| 同一套 Ceph 集群要同时服务块、文件、对象 | 「single Ceph Storage cluster to store data from CephFS and Ceph block device clients」(`index.rst`) |
|
||
| 需要按业务/成本分层存储 | placement target + storage class + S3 Lifecycle `Transition`(`placement.rst`) |
|
||
| 多业务方共用且 bucket 名易冲突 | 多租户 `tenant`(`multitenancy.rst`)、账号 `account`(`account.rst`) |
|
||
| 需要细粒度配额与限流 | quota(user/bucket/account)、ratelimit(`admin.rst`, `adminops.rst`) |
|
||
| 需要把对象存储挂成文件系统给遗留应用 | NFSv4 导出(`nfs.rst`) |
|
||
| 需要 S3 兼容的监控指标 | RGW op metrics → Prometheus(`metrics.rst`) |
|
||
|
||
**不适用场景(或需谨慎评估)**
|
||
|
||
| 场景 | 原因(依据) |
|
||
|---|---|
|
||
| 期望 100% AWS S3 语义/行为 | 官方明确只兼容「large subset」(`index.rst`) |
|
||
| 需要 POSIX 完整语义的文件访问 | NFS 导出不支持链接、不支持 NFS ACL、目录不可重命名、只支持顺序写(`nfs.rst`) |
|
||
| 作为数据库/随机读写块设备使用 | 非对象存储设计目标;本册范围内文档未明确说明,属常识性判断 |
|
||
| 依赖 MDS 的元数据服务 | RGW 明确不使用 MDS(`index.rst`) |
|
||
|
||
---
|
||
|
||
## 二、架构
|
||
|
||
### 2.1 RGW 在 Ceph 中的位置
|
||
|
||
RGW 是 **Ceph 客户端**,不是 Ceph 集群的核心组件:
|
||
|
||
- 它对上暴露 HTTP/REST(S3、Swift、Admin、STS、IAM、Notifications 等,由 `rgw_enable_apis` 控制,默认值见第十二章);
|
||
- 它对下通过 `librados` 与 MON / OSD 通信;
|
||
- 它**不经过** Ceph Metadata Server(MDS);
|
||
- 它自带用户管理与元数据(user、bucket、bucket.instance、roles、account 等),这些元数据本身也存放在 RADOS 的专用 pool 中(见第三、四章)。
|
||
|
||
### 2.2 RGW 与 RADOS 的关系
|
||
|
||
RGW 把「S3/Swift 的对象语义」翻译成「RADOS 的 pool + object + omap + xattr」:
|
||
|
||
| RGW 概念 | 落到 RADOS |
|
||
|---|---|
|
||
| user | 一个 RADOS 对象,名字为 `<user_id>`,位于 pool `default.rgw.meta` 的 `users.uid` namespace |
|
||
| bucket(名字→实例的映射) | pool `default.rgw.meta` 的 `root` namespace |
|
||
| bucket index | 默认每个 bucket 一个 RADOS 对象 `.dir.<marker>`,位于 `default.rgw.buckets.index`;omap 存 key-value 映射 |
|
||
| object data | 一个或多个 RADOS 对象,位于 `default.rgw.buckets.data`,对象名 `<marker>_<key>` |
|
||
| 用户的 bucket 列表 | 对象 `<user_id>.buckets` 的 omap,位于 `default.rgw.meta` 的 `users.uid` namespace |
|
||
| 不完整 multipart 的元数据 | `data_extra_pool`,默认 `default.rgw.buckets.non-ec` |
|
||
|
||
### 2.3 zone / zonegroup / realm / period 概念
|
||
|
||
> 本册范围内,`pools.rst` 与 `placement.rst` 只涉及 **zone** 与 **zonegroup**;`realm` 与 `period` 属多站点(Multisite)范畴,详见第 10 册(源文 `multisite.rst`)。本节仅就本册源文可确证部分说明。
|
||
|
||
| 概念 | 本册源文中的定义/作用 |
|
||
|---|---|
|
||
| **zone** | 一组具体的 RADOS pool 及其用途映射。每个 zone 的 pool 名遵循 `{zone-name}.pool-name` 命名约定。默认自动创建一个名为 `default` 的 zone,其 pool 名以 `default.rgw.` 开头。zone 配置里包含 domain_root、placement_pools 等 |
|
||
| **zonegroup** | 包含一组 zone;其配置中持有 **placement targets 列表**(初始有一个名为 `default-placement` 的 target),以及 `default_placement`、`api_name`、`hostnames` 等 |
|
||
| **realm** | 多站点顶层容器。本册源文只在 `placement.rst` 的 note 中提及:「如果你为 multisite 创建了 realm,zone/zonegroup 的改动需要 `radosgw-admin period update --commit` 提交后才生效」 |
|
||
| **period** | realm 的配置版本/纪元。同上,通过 `radosgw-admin period update --commit` 提交变更 |
|
||
|
||
**默认 zone(非多站点)下的行为**(`placement.rst` note):
|
||
|
||
```text
|
||
如果没有做过 Multisite 配置,系统会为你自动创建 default zone 与 zonegroup,
|
||
且对 zone/zonegroup 的修改要等到 Ceph 对象网关重启后才会生效。
|
||
如果创建了用于 multisite 的 realm,则 zone/zonegroup 的修改在
|
||
`radosgw-admin period update --commit` 提交后生效。
|
||
```
|
||
|
||
**zone/zonegroup 配置的查看**:
|
||
|
||
```bash
|
||
radosgw-admin zonegroup get
|
||
radosgw-admin zone get
|
||
```
|
||
|
||
`zonegroup get` 输出中的 placement 部分:
|
||
|
||
```json
|
||
{
|
||
"id": "ab01123f-e0df-4f29-9d71-b44888d67cd5",
|
||
"name": "default",
|
||
"api_name": "default",
|
||
"placement_targets": [
|
||
{
|
||
"name": "default-placement",
|
||
"tags": [],
|
||
"storage_classes": [
|
||
"STANDARD"
|
||
]
|
||
}
|
||
],
|
||
"default_placement": "default-placement"
|
||
}
|
||
```
|
||
|
||
`zone get` 输出中的 placement 部分:
|
||
|
||
```json
|
||
{
|
||
"id": "557cdcee-3aae-4e9e-85c7-2f86f5eddb1f",
|
||
"name": "default",
|
||
"domain_root": "default.rgw.meta:root",
|
||
"placement_pools": [
|
||
{
|
||
"key": "default-placement",
|
||
"val": {
|
||
"index_pool": "default.rgw.buckets.index",
|
||
"storage_classes": {
|
||
"STANDARD": {
|
||
"data_pool": "default.rgw.buckets.data"
|
||
}
|
||
},
|
||
"data_extra_pool": "default.rgw.buckets.non-ec",
|
||
"index_type": 0,
|
||
"inline_data": true
|
||
}
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
### 2.4 相关配置项(zone/zonegroup/realm 定位)
|
||
|
||
| 配置项 | 类型 | 默认值(默认值取自 src/common/options/*.yaml.in @ v20.2.4) | 含义 |
|
||
|---|---|---|---|
|
||
| `rgw_zone` | str | (无默认值) | Zone name |
|
||
| `rgw_zonegroup` | str | (无默认值) | Zonegroup name |
|
||
| `rgw_realm` | str | (无默认值) | 网关实例所属 realm 名。若未设置 realm,可用 `radosgw-admin realm default` 配置一个集群级默认值 |
|
||
|
||
> 引自:[Ceph Object Gateway](https://docs.ceph.com/en/tentacle/radosgw/)
|
||
|
||
---
|
||
|
||
## 三、数据布局(Data Layout in RADOS)
|
||
|
||
来源:`layout.rst`(全文 8KB,本节逐节展开)。
|
||
|
||
### 3.1 概念视图:三类信息
|
||
|
||
RADOS 只认识 pool、object、xattr 和 omap。但在概念上,RGW 维护**三类**信息:
|
||
|
||
| 类别 | 说明 |
|
||
|---|---|
|
||
| **metadata(元数据)** | 用户、bucket、bucket instance、角色、账号、OTP、group、topic 等 |
|
||
| **bucket index(桶索引)** | 一种特殊元数据,单独存放;是挂在 RADOS 对象上的 key-value map |
|
||
| **data(载荷数据)** | 每个 RGW object 对应一个或多个 RADOS object |
|
||
|
||
> **Omap 定义(源文脚注 [1])**:Omap 是关联在某个对象上的 key-value 存储,类似于 POSIX 文件上的扩展属性(XATTR)。对象的 omap 与其 payload 数据**不物理同置**,其具体实现对 RGW 守护进程不可见也不重要。
|
||
|
||
### 3.2 Metadata(元数据)
|
||
|
||
查看当前支持的元数据类型:
|
||
|
||
```bash
|
||
radosgw-admin metadata list
|
||
```
|
||
|
||
输出(2025 年 4 月的类型列表,源文原文):
|
||
|
||
```json
|
||
[
|
||
"account",
|
||
"bucket",
|
||
"bucket.instance",
|
||
"group",
|
||
"otp",
|
||
"roles",
|
||
"topic",
|
||
"user"
|
||
]
|
||
```
|
||
|
||
常用检查命令(源文原文):
|
||
|
||
```bash
|
||
radosgw-admin metadata list
|
||
radosgw-admin metadata list bucket
|
||
radosgw-admin metadata list bucket.instance
|
||
radosgw-admin metadata list user
|
||
radosgw-admin metadata get bucket:<bucket>
|
||
radosgw-admin metadata get bucket.instance:<bucket>:<bucket_id>
|
||
radosgw-admin metadata get user:<user> # get or set
|
||
```
|
||
|
||
变量含义(源文原文):
|
||
|
||
| 变量 | 含义 |
|
||
|---|---|
|
||
| `_user_` | 持有用户信息(Holds user information) |
|
||
| `_bucket_` | 持有 bucket 名 → bucket instance id 的映射 |
|
||
| `_bucket.instance_` | 持有 bucket instance 信息 |
|
||
|
||
要点:
|
||
|
||
- **每条元数据条目保存在单个 RADOS 对象上**。
|
||
- **元数据没有索引**。列举某个 metadata section 时,是对所在 pool 执行一次 RADOS `pgls` 操作。
|
||
- **历史坑(脚注 [2])**:Dumpling 版本之前不存在 `bucket.instance` 元数据,其信息包含在 `bucket` 元数据中。老集群中可能遇到这种 bucket。
|
||
|
||
### 3.3 Bucket Index(桶索引)
|
||
|
||
- bucket index 是一种**不同种类**的元数据,单独保存。
|
||
- 它保存的是**挂在 RADOS 对象上的 key-value map**。
|
||
- **默认每个 bucket 一个 RADOS 对象**;自 **Hammer** 版本起可以把这个 map **分片(shard)** 到多个 RADOS 对象上。
|
||
- map 本身存放在 **omap** 中,与每个 RADOS 对象关联。
|
||
- **omap 的 key** = 对象名;
|
||
- **omap 的 value** = 该对象的基本元数据(即 list bucket 时显示的那些元数据)。
|
||
- 每个 omap 还有一个 **header**,RGW 在 header 里保存一些 **bucket 账目元数据**(对象数、总大小等)。
|
||
- bucket index 中还保存**其它信息**,位于**其它 key namespace**:
|
||
- bucket index log(bilog);
|
||
- 版本化(versioned)对象的额外信息。
|
||
|
||
### 3.4 Data(对象数据)
|
||
|
||
每个 RGW object 的数据存放在**一个或多个** RADOS object 中。
|
||
|
||
#### 对象查找路径(Object Lookup Path)
|
||
|
||
访问 S3/Swift 对象时,REST API 带给 RGW 三个参数:
|
||
|
||
| 参数 | 说明 |
|
||
|---|---|
|
||
| account 信息 | S3 的 access key 或 Swift 的 account name。**目前 RGW 只用 account 信息来查 user ID 和做访问控制** |
|
||
| bucket / container 名 | 用于寻址 |
|
||
| object 名(key) | 用于寻址 |
|
||
|
||
> **只有 bucket 名和 object key 用于在一个 pool 中寻址对象。**
|
||
> RGW 中的 user ID 就是一个字符串,通常就是来自用户凭据的真实用户名,而不是哈希或映射后的标识符。
|
||
|
||
完整查找链:
|
||
|
||
```text
|
||
1) user 记录 → pool default.rgw.meta, namespace users.uid, 对象名 <user_id>
|
||
2) bucket 记录 → pool default.rgw.meta, namespace root
|
||
(读取该记录以获得所谓 marker,marker 充当 bucket ID)
|
||
3) 对象数据 → pool default.rgw.buckets.data
|
||
RADOS 对象名 = <marker>_<key>
|
||
例:default.7593.4_image.png
|
||
marker = default.7593.4,key = image.png
|
||
```
|
||
|
||
关于分隔符(源文原文要点):
|
||
|
||
- 这些拼起来的名字**不会被解析**,只是原样下传给 RADOS,因此**分隔符的选择不重要、也不会产生歧义**。
|
||
- 同样因为不解析,**对象名(key)中允许出现斜杠 `/`**。
|
||
|
||
多数据池与扩展(源文原文):
|
||
|
||
> 可以创建多个 data pool,并让不同用户的 bucket 默认创建在不同的 RADOS pool 中,从而提供所需的扩展能力。这些 pool 的布局与命名由 'policy' 设置控制。
|
||
|
||
#### HEAD 与 tail 对象
|
||
|
||
- 一个 RGW object 可由**多个 RADOS object** 组成,**第一个**是 `HEAD`。
|
||
- `HEAD` 包含的元数据(存放在 **xattrs** 中):
|
||
- manifest(清单,描述该 RGW object 如何分布到各 RADOS object 上)
|
||
- ACLs
|
||
- content type
|
||
- ETag
|
||
- 用户自定义元数据
|
||
- `HEAD` 对象还可以**内联(inline)最多 `rgw_max_chunk_size` 大小的对象数据**,以提高效率与原子性。
|
||
|
||
`rgw_max_chunk_size` 官方完整说明(默认值取自 src/common/options/rgw.yaml.in @ v20.2.4):
|
||
|
||
| 配置项 | 类型 | 默认值 | 说明 |
|
||
|---|---|---|---|
|
||
| `rgw_max_chunk_size` | size | `4_M` | chunk size 是 RGW 访问 RADOS 对象时发给 OSD 的请求大小。RGW 的读写操作单次请求永远不会超过这个量。它也定义了 RGW HEAD 对象的大小,因为 head 操作需要是原子的,超过这个量就需要多于一次操作。当 RGW 对象写入**默认 storage class** 时,最多会有这么多的载荷数据与元数据一起存在 head 对象中。注意:当把 RGW 对象写入**非默认 storage class** 时,HEAD RADOS 对象**始终**存放在默认 storage class 的 pool 中,但**不会**内联载荷数据。 |
|
||
|
||
官方给出的分层(tiering)策略(源文原文要点):
|
||
|
||
> 这带来一个方便的分层策略:index pool 必须是副本池(不能是 EC),应放在快速 SSD OSD 上。当 RGW 对象混合了小/热对象与更大、温/冷的对象(如视频文件)时,较大的对象会自动落到 `buckets.data` pool,后者可以是 EC 池和/或更慢的介质(HDD 或 QLC SSD)。
|
||
|
||
### 3.5 multipart 与分片(sharding)——本册可确证部分
|
||
|
||
| 主题 | 本册源文可确证内容 |
|
||
|---|---|
|
||
| **bucket index 分片** | 自 Hammer 起支持把 bucket index map 分片到多个 RADOS 对象;分片时每个 shard 在 marker 之后追加 shard index。相关配置:`rgw_override_bucket_index_max_shards`(默认 `0`,见第十二章);动态分片另见 `dynamicresharding.rst`(第 12 册) |
|
||
| **multipart 的 RADOS 布局** | 对象名示例:`default.7593.4__shadow_.488urDFerTYXavx4yAd-Op8mxehnvTI_1`(`layout.rst` 附录) |
|
||
| **不完整 multipart 的元数据** | 存放在 `data_extra_pool`,zone 默认值为 `default.rgw.buckets.non-ec`(`placement.rst`:「`data_extra_pool` name for metadata about incomplete multipart uploads」) |
|
||
| **multipart 最小分片大小** | `rgw_multipart_min_part_size`,默认 `5_M`(见第十二章) |
|
||
| **multipart 计数一致性检查** | Admin Ops API `Check Bucket Index` 的 `check-objects` 参数用于「Check multipart object accounting」,且必须同时 `fix=True` 才生效(见第七章) |
|
||
|
||
> 💡 补充:`layout.rst` 并未系统讲述 multipart upload 的完整 RADOS 布局(如 `shadow` 对象的切分规则、`rgw_obj_stripe_size` 与 tail 的关系)。官方源文只给出了上面这些零散事实点,未说明的部分本手册不臆测。
|
||
|
||
### 3.6 Bucket 与 Object 列举(Listing)
|
||
|
||
| 列举对象 | 实现方式 |
|
||
|---|---|
|
||
| 某用户拥有的 bucket 列表 | 对象 `<user_id>.buckets`(例如 `foo.buckets`)的 **omap**,位于 pool `default.rgw.meta`、namespace `users.uid`。在列举 bucket、更新 bucket 内容、更新与获取 bucket 统计(如 quota)时访问这些对象 |
|
||
| 某 bucket 中的对象列表 | 走 **bucket index**(见 3.3);index 对象默认命名 `.dir.<marker>`,位于 pool `default.rgw.buckets.index` |
|
||
|
||
- bucket 列表的 omap 值结构:见用户可见的编码类 **`cls_user_bucket_entry`** 及其嵌套类 **`cls_user_bucket`**。
|
||
- 这些列举与 pool 名为 `.rgw` 中的 bucket 保持一致性(源文:「These listings are kept consistent with buckets in the pool named `.rgw`」)。
|
||
|
||
### 3.7 附录:已知 pool 与对象命名速查(源文原文汇总)
|
||
|
||
```text
|
||
.rgw.root
|
||
Region, zone, and global information records, one per object.
|
||
|
||
<zone>.rgw.control
|
||
notify.<N>
|
||
|
||
<zone>.rgw.meta
|
||
Multiple namespaces with different kinds of metadata:
|
||
|
||
namespace: root
|
||
<bucket>
|
||
.bucket.meta.<bucket>:<marker> # see put_bucket_instance_info()
|
||
|
||
The tenant is used to disambiguate buckets, but not bucket instances.
|
||
Example:
|
||
.bucket.meta.prodtx:test%25star:default.84099.6
|
||
.bucket.meta.testcont:default.4126.1
|
||
.bucket.meta.prodtx:testcont:default.84099.4
|
||
prodtx/testcont
|
||
prodtx/test%25star
|
||
testcont
|
||
|
||
namespace: users.uid
|
||
Contains *both* per-user information (RGWUserInfo) in "<user>" objects
|
||
and per-user lists of buckets in omaps of "<user>.buckets" objects.
|
||
The "<user>" may contain the tenant if non-empty, for example:
|
||
prodtx$prodt
|
||
test2.buckets
|
||
prodtx$prodt.buckets
|
||
test2
|
||
|
||
namespace: users.email
|
||
Unimportant
|
||
|
||
namespace: users.keys
|
||
example: 47UA98JSTJZ9YAN3OS3O
|
||
This allows radosgw to look up users by their access keys during authentication.
|
||
|
||
namespace: users.swift
|
||
test:tester
|
||
|
||
<zone>.rgw.buckets.index
|
||
Objects are named .dir.<marker>: each contains a bucket index.
|
||
If the index is sharded, each shard appends the shard index after
|
||
the marker.
|
||
|
||
<zone>.rgw.buckets.data
|
||
example: default.7593.4__shadow_.488urDFerTYXavx4yAd-Op8mxehnvTI_1
|
||
<marker>_<key>
|
||
```
|
||
|
||
**marker 格式**(源文原文):marker 示例为 `default.16004.1` 或 `default.7593.4`。当前格式为 `<zone>.<instance_id>.<bucket_id>`。但 marker 一旦生成就不再被解析,所以其格式未来可自由变化。
|
||
|
||
> 引自:[Data Layout in RADOS](https://docs.ceph.com/en/tentacle/radosgw/layout/)
|
||
|
||
---
|
||
|
||
## 四、存储池与放置策略
|
||
|
||
### 4.1 RGW 用到的 pool
|
||
|
||
> 来源:`pools.rst` + `layout.rst` 附录 + `placement.rst`。
|
||
> 重要提示(源文原文):Ceph 对象网关为其各种存储需求使用若干 pool,**这些 pool 列在 Zone 对象中(见 `radosgw-admin zone get`)**。系统会自动创建一个名为 `default` 的 zone,其 pool 名以 `default.rgw.` 开头;而 Multisite 配置会有多个 zone。
|
||
|
||
#### 4.1.1 核心 pool 表
|
||
|
||
| pool 名(以 zone 名为 `default` 为例) | 用途 | 建议 PG |
|
||
|---|---|---|
|
||
| `.rgw.root` | Region、zone 以及 global 信息记录,每个对象一条 | 文档未明确(初始按 `osd pool default pg num` 创建,见下) |
|
||
| `default.rgw.control` | RGW 控制面(对象形如 `notify.<N>`),用于跨 RGW 通信 | 文档未明确 |
|
||
| `default.rgw.meta` | 多 namespace 元数据池,含 `root` / `users.uid` / `users.email` / `users.keys` / `users.swift` | 文档未明确 |
|
||
| `default.rgw.log` | 日志(源文仅列出名字,未展开用途) | 文档未明确 |
|
||
| `default.rgw.buckets.index` | **bucket index**。对象命名 `.dir.<marker>`;分片时追加 shard index。**必须**是副本池(不能 EC),且应放在快速 SSD OSD 上(`layout.rst` 明示) | 文档未明确;源文提示该池「需要额外调优」 |
|
||
| `default.rgw.buckets.data` | **对象数据**。对象命名 `<marker>_<key>`。可以是 EC 池和/或更慢介质(HDD / QLC SSD) | 文档未明确;源文提示该池「需要额外调优」 |
|
||
| `default.rgw.buckets.non-ec` | **data_extra_pool**:存放**未完成 multipart 上传**的元数据;`zone get` 中 `default-placement` 的默认值 | 文档未明确 |
|
||
|
||
> ⚠️ **关于「建议 PG」**:本册范围内的官方文档**没有**给出任何 pool 的 PG 数量建议数值,全部标注「文档未明确」。文档只说明了创建时机与默认值来源,见 4.1.2。
|
||
>
|
||
> 💡 补充:源文 `pools.rst` 只列出 `.rgw.root` 与 5 个 `<zone>.rgw.*` pool 共 6 个名字,`default.rgw.buckets.non-ec` 来自 `placement.rst` 的 `zone get` 示例。完整的 zone 定义中还有**更多** pool 条目(官方原文:「The zone definitions list several more pools than that」),但本册范围(`pools.rst`/`layout.rst`/`placement.rst`)未逐一列出,故不在此表中杜撰。
|
||
|
||
#### 4.1.2 pool 的创建与调优(源文原文)
|
||
|
||
> 当 `radosgw` 首次尝试操作一个尚不存在的 zone pool 时,它会用 `osd pool default pg num` 和 `osd pool default pgp num` 的默认值来创建该 pool。这些默认值对某些 pool 是够用的,但**其它 pool(尤其是 `placement_pools` 中列出的 bucket index 与 data 池)需要额外的调优**。
|
||
|
||
相关配置项(默认值取自 src/common/options/*.yaml.in @ v20.2.4):
|
||
|
||
| 配置项 | 类型 | 默认值 | 说明 |
|
||
|---|---|---|---|
|
||
| `osd pool default pg num` | 文档未在本册范围内查证 | 文档未明确 | pool 创建时的默认 PG 数 |
|
||
| `osd pool default pgp num` | 文档未在本册范围内查证 | 文档未明确 | pool 创建时的默认 PGP 数 |
|
||
|
||
#### 4.1.3 Pool Namespaces(自 Luminous 起)
|
||
|
||
pool 名遵循 `{zone-name}.pool-name` 约定。例如一个名为 `us-east` 的 zone 会有:
|
||
|
||
```text
|
||
.rgw.root
|
||
us-east.rgw.control
|
||
us-east.rgw.meta
|
||
us-east.rgw.log
|
||
us-east.rgw.buckets.index
|
||
us-east.rgw.buckets.data
|
||
```
|
||
|
||
**许多 pool 条目通过 rados namespace 被合并**。例如以下 pool 条目其实都是 `us-east.rgw.meta` pool 的 namespace:
|
||
|
||
```json
|
||
"user_keys_pool": "us-east.rgw.meta:users.keys",
|
||
"user_email_pool": "us-east.rgw.meta:users.email",
|
||
"user_swift_pool": "us-east.rgw.meta:users.swift",
|
||
"user_uid_pool": "us-east.rgw.meta:users.uid",
|
||
```
|
||
|
||
### 4.2 Placement Target(放置目标)
|
||
|
||
> versionadded:: Jewel
|
||
|
||
**定义**:placement target 控制**哪些 pool 与某个特定 bucket 关联**。
|
||
|
||
| 要点 | 说明 |
|
||
|---|---|
|
||
| 选择时机 | **在 bucket 创建时**选定 |
|
||
| 可否修改 | **不可修改**("A bucket's placement target is selected on creation, and cannot be modified.") |
|
||
| 查看方式 | `radosgw-admin bucket stats` 会显示其 `placement_rule` |
|
||
| zonegroup 侧 | 持有 placement target 列表,初始有一个名为 **`default-placement`** 的 target |
|
||
| zone 侧 | 把 zonegroup 中的每个 placement target 名字映射到本地存储。包含:`index_pool`(bucket index)、`data_extra_pool`(未完成 multipart 元数据)、以及**每个 storage class 一个 `data_pool`** |
|
||
|
||
### 4.3 Storage Class(存储类)
|
||
|
||
> versionadded:: Nautilus
|
||
|
||
**定义**:storage class 指定**对象数据的放置位置**。S3 Bucket Lifecycle(LC)规则可以自动化对象在 storage class 之间的转换(Transition)。
|
||
|
||
| 要点 | 说明 |
|
||
|---|---|
|
||
| 定义层级 | 以 placement target 为单位定义 |
|
||
| zonegroup 侧 | 每个 placement target 列出其可用 storage class,初始有一个名为 **`STANDARD`** 的 class |
|
||
| zone 侧 | 负责为 zonegroup 的每个 storage class 提供一个 `data_pool` 名 |
|
||
|
||
### 4.4 新增 placement target / storage class 的操作
|
||
|
||
**新增名为 `temporary` 的 placement target**——先加到 zonegroup:
|
||
|
||
```bash
|
||
radosgw-admin zonegroup placement add \
|
||
--rgw-zonegroup default \
|
||
--placement-id temporary
|
||
```
|
||
|
||
然后为该 target 提供 zone 侧的 placement 信息:
|
||
|
||
```bash
|
||
radosgw-admin zone placement add \
|
||
--rgw-zone default \
|
||
--placement-id temporary \
|
||
--data-pool default.rgw.temporary.data \
|
||
--index-pool default.rgw.temporary.index \
|
||
--data-extra-pool default.rgw.temporary.non-ec
|
||
```
|
||
|
||
**新增名为 `STANDARD_IA` 的 storage class 到 `default-placement`**——先加到 zonegroup:
|
||
|
||
```bash
|
||
radosgw-admin zonegroup placement add \
|
||
--rgw-zonegroup default \
|
||
--placement-id default-placement \
|
||
--storage-class STANDARD_IA
|
||
```
|
||
|
||
然后提供 zone 侧该 storage class 的 placement 信息(示例中还指定了压缩):
|
||
|
||
```bash
|
||
radosgw-admin zone placement add \
|
||
--rgw-zone default \
|
||
--placement-id default-placement \
|
||
--storage-class STANDARD_IA \
|
||
--data-pool default.rgw.glacier.data \
|
||
--compression lz4
|
||
```
|
||
|
||
#### inline data 的说明(官方 note 全文要点)
|
||
|
||
`zone placement add` / `zone placement modify` 支持 `--placement-inline-data=false`:
|
||
|
||
| 行为 | 说明 |
|
||
|---|---|
|
||
| 默认(inline) | RGW 把对象的**第一个数据块**与 XATTR 元数据一起存放在 RADOS `HEAD` 对象里。**优势**:读写工作负载下,首块数据可随对象元数据在一次 librados 调用中取回/写入 |
|
||
| 非 inline | 当 **BlueStore DB 位于比 bucket data 更快的存储**上时,对 **RGW 客户端 delete 请求**有性能优势——省去了处理客户端请求时同步访问慢设备。此时被删除对象的数据由**后台 GC 异步**清除 |
|
||
| 限制 | **只有写入默认 storage class 时才会 inline**;写入**非默认** storage class 时**永不** inline |
|
||
|
||
### 4.5 定制放置(Customizing Placement)
|
||
|
||
#### 4.5.1 Default Placement
|
||
|
||
新建 bucket 默认使用 zonegroup 的 `default_placement` target。可用以下命令修改:
|
||
|
||
```bash
|
||
radosgw-admin zonegroup placement default \
|
||
--rgw-zonegroup default \
|
||
--placement-id new-placement
|
||
```
|
||
|
||
#### 4.5.2 User Placement
|
||
|
||
用户可以用其 user info 中**非空**的 `default_placement` 字段覆盖 zonegroup 的默认 placement target;同理 `default_storage_class` 可覆盖默认施加到对象上的 `STANDARD`。
|
||
|
||
```bash
|
||
$ radosgw-admin user info --uid testid
|
||
{
|
||
...
|
||
"default_placement": "",
|
||
"default_storage_class": "",
|
||
"placement_tags": [],
|
||
...
|
||
}
|
||
```
|
||
|
||
**tags 的访问控制作用**:如果 zonegroup 的 placement target 含有任何 `tags`,那么**除非**用户的 user info 中 `placement_tags` 字段至少含有一个匹配的 tag,否则该用户无法用该 placement target 创建 bucket。这可用于限制对某类存储的访问。
|
||
|
||
直接修改这些字段:
|
||
|
||
```bash
|
||
radosgw-admin user modify \
|
||
--uid <user-id> \
|
||
--placement-id <default-placement-id> \
|
||
--storage-class <default-storage-class> \
|
||
--tags <tag1,tag2>
|
||
```
|
||
|
||
#### 4.5.3 S3 Bucket Placement
|
||
|
||
用 S3 协议创建 bucket 时,可通过 **LocationConstraint** 提供 placement target,覆盖用户与 zonegroup 的默认值。
|
||
|
||
- 常规情况下 LocationConstraint 必须匹配 zonegroup 的 `api_name`:
|
||
|
||
```xml
|
||
<LocationConstraint>default</LocationConstraint>
|
||
```
|
||
|
||
- 在 `api_name` 后加冒号即可指定自定义 placement target:
|
||
|
||
```xml
|
||
<LocationConstraint>default:new-placement</LocationConstraint>
|
||
```
|
||
|
||
#### 4.5.4 Swift Bucket Placement
|
||
|
||
用 Swift 协议创建 bucket 时,通过 HTTP header **`X-Storage-Policy`** 提供 placement target:
|
||
|
||
```http
|
||
X-Storage-Policy: new-placement
|
||
```
|
||
|
||
### 4.6 使用 Storage Class
|
||
|
||
| 场景 | 做法 |
|
||
|---|---|
|
||
| 默认 | 所有 placement target 都有一个 `STANDARD` storage class,默认施加到新对象上 |
|
||
| 用户级覆盖 | 用户用其 `default_storage_class` 覆盖 |
|
||
| 单对象指定 | 在请求的 HTTP header 中给出 storage class 名:**S3 用 `X-Amz-Storage-Class`**,**Swift 用 `X-Object-Storage-Class`** |
|
||
| 自动流转 | 用 S3 Object Lifecycle Management 的 `Transition` action 在 storage class 间搬移对象数据 |
|
||
|
||
**与 AWS SDK 的兼容性警告(源文原文要点)**:
|
||
|
||
1. 使用 `boto3` 这类 AWS S3 SDK 时,**storage class 名称必须匹配 AWS S3 提供的名称**,否则 SDK 会丢弃请求并抛异常。
|
||
2. 部分 S3 客户端与库对名为或以 **`GLACIER`** 为前缀的 storage class 有 AWS 特有行为的预期,用在 Ceph RGW 上会失败。
|
||
3. 官方建议改用:`INTELLIGENT-TIERING`、`STANDARD_IA`、`REDUCED_REDUNDANCY`、`ONEZONE_IA`。
|
||
4. 自定义名(如 `CHEAPNDEEP`)Ceph 接受,但部分客户端/库可能不接受。
|
||
|
||
> 引自:[Configuring Pools](https://docs.ceph.com/en/tentacle/radosgw/pools/) / [Pool Placement and Storage Classes](https://docs.ceph.com/en/tentacle/radosgw/placement/)
|
||
|
||
---
|
||
|
||
## 五、前端与部署(HTTP Frontends)
|
||
|
||
来源:`frontends.rst` 全文。
|
||
|
||
### 5.1 总览
|
||
|
||
Ceph 对象网关支持**两个嵌入式 HTTP 前端库**,通过 `rgw_frontends` 配置(语法见 `Config Reference`)。
|
||
|
||
| 前端 | 状态 | 引入版本 | 实现 |
|
||
|---|---|---|---|
|
||
| **beast** | **当前默认** | Mimic(`versionadded:: Mimic`) | 用 **Boost.Beast** 做 HTTP 解析,用 **Boost.Asio** 做异步网络 I/O |
|
||
| **civetweb** | 旧版、现已非默认 | 文档未明确(源文只说是 "older and now non-default") | 每连接一个线程的线程模型,因此在接受连接时**自动**受 `rgw_thread_pool_size` 节流 |
|
||
|
||
**线程模型与 QoS 的关键差异**(`config-ref.rst` 的 QoS 章节):
|
||
|
||
> 较新的、也是默认的 `beast` 前端在接受新连接时**不受**线程池大小限制,因此在 Nautilus 版本引入了一个 scheduler 抽象以支持额外的请求调度方式。当前 scheduler 默认是一个 throttler,把活跃连接数限制在一个配置上限。基于 mClock 的 QoS 限流目前处于**实验(experimental)**阶段,**不建议用于生产**。当前 *dmclock_client* op queue 的实现把 RGW op 分为 admin、auth(swift auth、sts)、metadata、data 四类请求。
|
||
|
||
### 5.2 `rgw_frontends` 主配置项
|
||
|
||
| 配置项 | 类型 | 默认值(默认值取自 src/common/options/rgw.yaml.in @ v20.2.4) | 含义 |
|
||
|---|---|---|---|
|
||
| `rgw_frontends` | str | `beast port=7480` | RGW frontends configuration |
|
||
| `rgw_nfs_frontends` | str | `rgw-nfs` | 以 librgw/nfs 方式运行时的前端配置。逗号分隔的前端配置列表,每个配置由前端类型 + 可选的空格分隔 `key=value` 参数集组成。默认只启动 `rgw-nfs` 前端;其它前端(如 `beast`)通过此项启用,语法与 `rgw_frontends` 相同 |
|
||
|
||
### 5.3 Beast 前端选项(逐项)
|
||
|
||
| 选项 | 描述 | 类型 | 默认值 |
|
||
|---|---|---|---|
|
||
| `port` / `ssl_port` | 设置 IPv4 与 IPv6 监听端口号。可多次指定,如 `port=80 port=8000` | Integer | `80` |
|
||
| `endpoint` / `ssl_endpoint` | 以 `address[:port]` 形式设置监听地址。地址可以是点分十进制 IPv4,或用方括号包围的十六进制 IPv6。**指定 IPv6 endpoint 将只监听 v6**。可选端口对 `endpoint` 默认 80,对 `ssl_endpoint` 默认 443。可多次指定,如 `endpoint=[::1] endpoint=192.168.0.100:8000` | Integer | None |
|
||
| `ssl_certificate` | SSL endpoint 使用的证书文件路径。若路径以 `config://` 为前缀,证书会从 ceph monitor 的 `config-key` 数据库中拉取 | String | None |
|
||
| `ssl_private_key` | SSL endpoint 使用的私钥文件路径,可选。若未给出,则使用 `ssl_certificate` 文件作为私钥。同样支持 `config://` 前缀 | String | None |
|
||
| `ssl_options` | 可选的冒号分隔 SSL context 选项列表(取值见下表) | String | `no_sslv2:no_sslv3:no_tlsv1:no_tlsv1_1` |
|
||
| `ssl_ciphers` / `ssl_ciphersuites` | 可选的、冒号分隔的一个或多个 cipher 字符串,格式见 OpenSSL 的 `ciphers(1)` 手册。`ssl_ciphers` **只适用于 TLS v1.2 及以下**;`ssl_ciphersuites` **只适用于 TLS v1.3** | String | None |
|
||
| `tcp_nodelay` | 置位则在连接上禁用 Nagle 算法(包尽快发出,而不等缓冲区满或超时)。`1`=对所有 socket 禁用 Nagle;`0`=保持默认(Nagle 启用) | Integer (0 or 1) | `0` |
|
||
| `max_connection_backlog` | 可选的、等待 accept 的连接队列最大长度。未配置则使用 `boost::asio::socket_base::max_connections` 的值 | Integer | None |
|
||
| `request_timeout_ms` | Beast 等待更多入站数据或出站数据的毫秒数,超时即放弃。**设为 0 表示禁用超时** | Integer | `65000` |
|
||
| `max_header_size` | 单个请求可用的最大 header 字节数 | Integer | `16384`(Maximum: `65536`) |
|
||
| `so_reuseport` | 置位则允许同一主机上的多个 RGW 实例监听同一 TCP 端口。`1`=允许;`0`=不允许 | Integer (0 or 1) | `0` |
|
||
|
||
**`ssl_options` 可选值**:
|
||
|
||
| 值 | 含义 |
|
||
|---|---|
|
||
| `default_workarounds` | Implement various bug workarounds |
|
||
| `no_compression` | Disable compression |
|
||
| `no_sslv2` | Disable SSL v2 |
|
||
| `no_sslv3` | Disable SSL v3 |
|
||
| `no_tlsv1` | Disable TLS v1 |
|
||
| `no_tlsv1_1` | Disable TLS v1.1 |
|
||
| `no_tlsv1_2` | Disable TLS v1.2 |
|
||
| `single_dh_use` | Always create a new key when using tmp_dh parameters |
|
||
|
||
### 5.4 通用选项(所有前端都支持)
|
||
|
||
| 选项 | 描述 | 类型 | 默认值 |
|
||
|---|---|---|---|
|
||
| `prefix` | 插入到所有请求 URI 中的前缀字符串。例如一个 swift-only 前端可以提供 `/swift` 的 URI 前缀 | String | None |
|
||
|
||
### 5.5 前端相关的性能/调优参数
|
||
|
||
| 配置项 | 类型 | 默认值(默认值取自 src/common/options/rgw.yaml.in @ v20.2.4) | 含义 / 与前端的关系 |
|
||
|---|---|---|---|
|
||
| `rgw_thread_pool_size` | int | `512` | RGW 请求处理线程池大小。官方 `long_desc`:**该参数决定在使用 civetweb 或 fastcgi 前端时 RGW 能处理的并发请求数**。数值越大可处理越多并发请求,代价是资源占用更高 |
|
||
| `rgw_max_concurrent_requests` | int | `1024` | 最大并发 HTTP 请求数(beast 前端的 throttler 上限) |
|
||
| `rgw_scheduler_type` | str | `throttler` | dmclock scheduler 类型,默认 throttler;另一个合法值 `dmclock` 是实验性的 |
|
||
| `rgw_exit_timeout_secs` | int | `2_min` | RGW 关闭超时 |
|
||
| `rgw_init_timeout` | int | `5_min` | 初始化超时 |
|
||
| `rgw_num_control_oids` | int | `8` | 用于跨 RGW 通信的控制对象数量 |
|
||
| `rgw_op_thread_timeout` | int | `10_min` | 异步 rados 协程操作的超时 |
|
||
| `rgw_op_thread_suicide_timeout` | int | `0` | Ceph 对象网关进程死亡前的 timeout 秒数;设为 `0` 表示禁用 |
|
||
| `rgw_print_continue` | bool | `true` | RGW 是否支持 100-continue |
|
||
| `rgw_content_length_compat` | bool | `false` | 多个 content length header 的兼容性 |
|
||
|
||
### 5.6 配置示例
|
||
|
||
**最小 beast 前端(默认)**:
|
||
|
||
```ini
|
||
[client.rgw.node1]
|
||
rgw_frontends = beast port=7480
|
||
```
|
||
|
||
**同时监听 80 与 8000、并开启 IPv6 端点**:
|
||
|
||
```ini
|
||
[client.rgw.node1]
|
||
rgw_frontends = beast port=80 port=8000 endpoint=[::1] endpoint=192.168.0.100:8000
|
||
```
|
||
|
||
**启用 SSL(证书走 monitor config-key)**:
|
||
|
||
```ini
|
||
[client.rgw.node1]
|
||
rgw_frontends = beast ssl_endpoint=0.0.0.0:443 ssl_certificate=config://rgw/cert.pem ssl_private_key=config://rgw/key.pem
|
||
```
|
||
|
||
**为 swift-only 前端加 URI 前缀 + 关闭 Nagle + 允许多实例同端口**:
|
||
|
||
```ini
|
||
[client.rgw.node1]
|
||
rgw_frontends = beast port=7480 prefix=/swift tcp_nodelay=1 so_reuseport=1
|
||
```
|
||
|
||
**注意**:配置写在 `[client.radosgw.{instance-name}]` 段时,对**未指定 instance-name** 的 `rgw`/`radosgw-admin` 命令不生效。要对所有 RGW 实例或所有 `radosgw-admin` 选项生效,应放到 `[global]` 或 `[client]` 段(`config-ref.rst` 原文要点)。
|
||
|
||
> 引自:[HTTP Frontends](https://docs.ceph.com/en/tentacle/radosgw/frontends/)
|
||
|
||
---
|
||
|
||
## 六、管理(Admin Guide)
|
||
|
||
来源:`admin.rst` 全文(30KB)+ `placement.rst` / `account.rst` / `layout.rst` / `troubleshooting.rst` / `config-ref.rst` 中出现的子命令。
|
||
|
||
### 6.1 用户与子用户模型
|
||
|
||
Ceph 对象存储的用户管理**仅指 Ceph 对象存储服务的用户**,不是 Ceph 对象网关作为 Ceph 存储集群用户(`client.rgw.*`)的概念。
|
||
|
||
| 类型 | 说明 |
|
||
|---|---|
|
||
| **User** | 指 **S3 接口**的用户 |
|
||
| **Subuser** | 指 **Swift 接口**的用户。subuser 归属于某个 user |
|
||
|
||
层级关系(官方 ditaa 转文本):
|
||
|
||
```text
|
||
+---------+
|
||
| Account |
|
||
+----+----+
|
||
|
|
||
| +---------+
|
||
+-----+ User |
|
||
+----+----+
|
||
|
|
||
| +-----------+
|
||
+-----+ Subuser |
|
||
+-----------+
|
||
```
|
||
|
||
要点(源文原文):
|
||
|
||
- users 与 subusers 都可被创建、修改、查看、暂停(suspend)和删除。
|
||
- 可以为 user 添加 display name 和 email 地址。
|
||
- key 与 secret 可以指定,也可以自动生成。
|
||
- **生成或指定 key 时记住:user ID 对应 S3 key 类型,subuser ID 对应 Swift key 类型。**
|
||
- **Swift key 有 access level:`read`、`write`、`readwrite`、`full`。**
|
||
|
||
### 6.2 `radosgw-admin` 子命令总表
|
||
|
||
> 下表把本册范围内出现的**每一个** `radosgw-admin` 子命令逐项列出。
|
||
|
||
#### 6.2.1 用户 / 子用户管理
|
||
|
||
| 子命令 | 用途 | 关键参数 | 示例 |
|
||
|---|---|---|---|
|
||
| `user create` | 创建 S3 用户(同时生成 access_key/secret_key) | `--uid`、`--display-name`、`--email`、`--key-type`、`--access-key`、`--secret-key`、`--gen-access-key`、`--gen-secret`、`--generate-key`、`--max-buckets`、`--suspended`、`--tenant`、`--account-id`、`--account-root`、`--admin`、`--system` | `radosgw-admin user create --uid=johndoe --display-name="John Doe" --email=john@example.com` |
|
||
| `user info` | 查看用户信息(含 quota 设置) | `--uid` | `radosgw-admin user info --uid=johndoe` |
|
||
| `user modify` | 修改用户属性(display name、email、placement、storage class、tags、account 归属、admin 标志) | `--uid`、`--display-name`、`--email`、`--placement-id`、`--storage-class`、`--tags`、`--account-id`、`--admin` / `--admin=0`、`--max-buckets`、`--suspended`、`--op-mask` | `radosgw-admin user modify --uid=johndoe --display-name="John E. Doe"` |
|
||
| `user suspend` | 暂停用户(创建时默认启用) | `--uid` | `radosgw-admin user suspend --uid=johndoe` |
|
||
| `user enable` | 重新启用被暂停的用户 | `--uid` | `radosgw-admin user enable --uid=johndoe` |
|
||
| `user rm` | 删除用户及其所有 subuser | `--uid`、`--purge-data`、`--purge-keys` | `radosgw-admin user rm --uid=johndoe` |
|
||
| `user stats` | 查看用户已消耗的配额用量 | `--uid`、`--sync-stats` | `radosgw-admin user stats --uid=<uid> --sync-stats` |
|
||
| `subuser create` | 为某 user 创建 Swift 子用户 | `--uid`、`--subuser`、`--access=[read\|write\|readwrite\|full]`、`--key-type`、`--secret-key`、`--generate-secret` | `radosgw-admin subuser create --uid=johndoe --subuser=johndoe:swift --access=full` |
|
||
| `subuser modify` | 修改子用户(主要是 access level) | `--uid`、`--subuser`、`--access`、`--secret`、`--key-type`、`--generate-secret` | `radosgw-admin subuser modify --uid=johndoe --subuser=johndoe:swift --access=full` |
|
||
| `subuser rm` | 删除子用户(其所属 user 保留) | `--subuser`、`--purge-keys` | `radosgw-admin subuser rm --subuser=johndoe:swift` |
|
||
|
||
关于 `user rm` 的选项:
|
||
|
||
| 选项 | 说明 |
|
||
|---|---|
|
||
| `--purge-data` | 清除与该 UID 关联的所有数据 |
|
||
| `--purge-keys` | 清除与该 UID 关联的所有 key |
|
||
|
||
关于 `user suspend`:**禁用用户同时也禁用其所有 subuser**。
|
||
|
||
#### 6.2.2 密钥管理(`key`)
|
||
|
||
Key 相关通用选项(源文原文):
|
||
|
||
| 选项 | 说明 |
|
||
|---|---|
|
||
| `--key-type=<type>` | 指定 key 类型,可选 `s3`、`swift` |
|
||
| `--access-key=<key>` | 手动指定 S3 access key |
|
||
| `--secret-key=<key>` | 手动指定 S3 secret key 或 Swift secret key |
|
||
| `--gen-access-key` | 自动生成随机 S3 access key |
|
||
| `--gen-secret` | 自动生成随机 S3 secret key 或随机 Swift secret key |
|
||
| `--generate-key` | 创建用户时是否带凭据。**若为 false,则用户不能设置 `gen-secret`/`gen-access-key`/`access-key`/`secret-key`** |
|
||
|
||
| 子命令 | 用途 | 关键参数 | 示例 |
|
||
|---|---|---|---|
|
||
| `key create`(S3) | 为 user 添加指定 S3 key 对 | `--uid`、`--key-type=s3`、`--access-key`、`--secret-key` | `radosgw-admin key create --uid=foo --key-type=s3 --access-key fooAccessKey --secret-key fooSecretKey` |
|
||
| `key create`(Swift) | 为 subuser 附加指定 Swift secret key | `--subuser`、`--key-type=swift`、`--secret-key` | `radosgw-admin key create --subuser=foo:bar --key-type=swift --secret-key barSecret` |
|
||
| `key create`(subuser + S3) | 把 subuser 与 S3 key 对关联,使 subuser 也能用 S3 API | `--subuser`、`--key-type=s3`、`--access-key`、`--secret-key` | `radosgw-admin key create --subuser=foo:bar --key-type=s3 --access-key barAccessKey --secret-key barSecretKey` |
|
||
| `key rm`(S3) | 删除指定 S3 key 对 | `--uid`、`--key-type=s3`、`--access-key` | `radosgw-admin key rm --uid=foo --key-type=s3 --access-key=fooAccessKey` |
|
||
| `key rm`(Swift) | 删除 Swift secret key | `--subuser`、`--key-type=swift` | `radosgw-admin key rm --subuser=foo:bar --key-type=swift` |
|
||
|
||
规则:
|
||
|
||
- **一个 user 可以创建多对 S3 key。**
|
||
- **一个 subuser 只能有一个 Swift secret key。**
|
||
- 关于 `full` vs `readwrite`(官方 note):`full` **不等同于** `readwrite`。`full` 包含 `read` 与 `write`,**还包含访问控制策略(access control policy)**。
|
||
|
||
#### 6.2.3 管理能力(caps)与 admin/system 用户
|
||
|
||
| 子命令 | 用途 | 关键参数 | 示例 |
|
||
|---|---|---|---|
|
||
| `caps add` | 为用户添加管理能力 | `--uid`、`--caps` | `radosgw-admin caps add --uid=johndoe --caps="users=*;buckets=*"` |
|
||
| `caps rm` | 移除用户的管理能力 | `--uid`、`--caps` | `radosgw-admin caps rm --uid=johndoe --caps="users=*"` |
|
||
|
||
`--caps` 的取值语法(源文原文):
|
||
|
||
```text
|
||
--caps="[users|buckets|metadata|usage|zone|amz-cache|info|bilog|mdlog|datalog|user-policy|oidc-provider|roles|ratelimit|user-info-without-keys|accounts]=[\*|read|write|read, write]"
|
||
```
|
||
|
||
可对 **users、buckets、metadata、usage、zone、amz-cache、info、bilog、mdlog、datalog、user-policy、oidc-provider、roles、ratelimit、user-info-without-keys、accounts** 授予 `*`、`read`、`write` 或 `read, write`。
|
||
|
||
**Admin / System 用户**:
|
||
|
||
| 标志 | 说明 |
|
||
|---|---|
|
||
| `--admin` | 拥有**全局读写权限**,适用于**所有 API(包括 S3 和 Swift)**,与 Admin Capabilities 不同,**且不能被 IAM policy 拒绝**。可用于排障恢复(例如用户误删了自己对 bucket/object 的权限时)。**警告**:不使用时考虑删除该用户或禁用其 access key,不要把 admin 权限给不可信用户 |
|
||
| `--system` | 同样拥有全局读写权限。**仅应按 `Multisite Configuration` 文档所述使用** |
|
||
|
||
```bash
|
||
# 创建 admin 用户
|
||
radosgw-admin user create --uid={username} --display-name="{display-name}" --admin
|
||
|
||
# 给已有用户加 admin 标志
|
||
radosgw-admin user modify --uid={username} --admin
|
||
|
||
# 移除 admin 标志
|
||
radosgw-admin user modify --uid={username} --admin=0
|
||
```
|
||
|
||
#### 6.2.4 配额(quota)
|
||
|
||
配额可设在 **user** 及 user 拥有的 **bucket** 上(账号级见第八章)。
|
||
|
||
| 参数 | 说明 |
|
||
|---|---|
|
||
| `--max-objects` | 最大对象数。**负值禁用**该设置 |
|
||
| `--max-size` | 配额大小,单位 B/K/M/G/T,**B 为默认**。负值禁用 |
|
||
| `--quota-scope` | 配额作用域,可选 `bucket`、`user`(账号级为 `account`) |
|
||
| `--bucket` | 指定 bucket 名(使 quota 作用于单个 bucket) |
|
||
| `--uid` | 指定用户 |
|
||
|
||
| 子命令 | 用途 | 关键参数 | 示例 |
|
||
|---|---|---|---|
|
||
| `quota set`(user 级) | 设置用户配额参数(**设置后必须 enable 才生效**) | `--quota-scope=user`、`--uid`、`--max-objects`、`--max-size` | `radosgw-admin quota set --quota-scope=user --uid=johndoe --max-objects=1024 --max-size=1024B` |
|
||
| `quota enable`(user 级) | 启用已设置的用户配额 | `--quota-scope=user`、`--uid` | `radosgw-admin quota enable --quota-scope=user --uid=<uid>` |
|
||
| `quota disable`(user 级) | 禁用已启用的用户配额 | `--quota-scope=user`、`--uid` | `radosgw-admin quota disable --quota-scope=user --uid=<uid>` |
|
||
| `quota set`(bucket 级) | 设置 bucket 配额。指定 `--bucket` 则作用于单个 bucket;指定 `--uid` 则作用于该用户拥有的**所有** bucket | `--quota-scope=bucket`、`{--bucket\|--uid}`、`--max-objects`、`--max-size` | `radosgw-admin quota set --quota-scope=bucket --bucket=mybucket --max-size=10G` |
|
||
| `quota enable`(bucket 级) | 启用 bucket 配额 | `--quota-scope=bucket`、`--uid` | `radosgw-admin quota enable --quota-scope=bucket --uid=<uid>` |
|
||
| `quota disable`(bucket 级) | 禁用 bucket 配额 | `--quota-scope=bucket`、`--uid` | `radosgw-admin quota disable --quota-scope=bucket --uid=<uid>` |
|
||
| `quota set`(account 级) | 设置账号配额 | `--quota-scope=account`、`--account-id`、`--max-size`、`--max-objects` | `radosgw-admin quota set --quota-scope=account --account-id={accountid} --max-size=10G` |
|
||
| `quota enable`(account 级) | 启用账号配额 | `--quota-scope=account`、`--account-id` | `radosgw-admin quota enable --quota-scope=account --account-id={accountid}` |
|
||
| `quota set`(account 下的 bucket 级) | 为账号设置 bucket 级配额 | `--quota-scope=bucket`、`--account-id`、`--max-objects` | `radosgw-admin quota set --quota-scope=bucket --account-id={accountid} --max-objects=1000000` |
|
||
| `global quota get` | 读取 period 配置中的全局配额设置 | 无 | `radosgw-admin global quota get` |
|
||
| `global quota set` | 写入全局配额设置 | `--quota-scope`、`--max-objects`、`--max-size` 等 | `radosgw-admin global quota set --quota-scope bucket --max-objects 1024` |
|
||
| `global quota enable` | 启用全局配额 | `--quota-scope` | `radosgw-admin global quota enable --quota-scope bucket` |
|
||
|
||
要点:
|
||
|
||
- **User Quotas are summed across all buckets owned by the user**(用户配额是该用户所有 bucket 的求和)。
|
||
- **设置配额参数后必须 enable 才生效**。
|
||
- **Update Quota Stats**:配额统计是异步更新的。可手动强制更新所有用户与所有 bucket 的配额统计:`radosgw-admin user stats --uid=<uid> --sync-stats`。
|
||
- **Default Quotas**:可以在 RGW 配置中设置默认配额。**这些默认值只在创建新用户时使用,对已有用户无影响。** 若设置了默认配额,则后续创建的所有用户都会设置该配额并**自动启用**。相关配置项:`rgw_bucket_default_quota_max_objects`、`rgw_bucket_default_quota_max_size`、`rgw_user_default_quota_max_objects`、`rgw_user_default_quota_max_size`、`rgw_account_default_quota_max_objects`、`rgw_account_default_quota_max_size`。
|
||
- **Global Quota 的生效方式(官方 note)**:在存在 realm 与 period 的多站点配置中,全局配额的改动必须用 `period update --commit` 提交;若没有 period,则必须重启 RGW 实例。
|
||
|
||
**Quota Cache(配额缓存)**:
|
||
|
||
配额统计被每个 RGW 实例缓存。若部署了多个 RGW 实例,该缓存可能导致配额无法被完美执行,因为每个实例可能持有不同的配额设置。
|
||
|
||
| 配置项 | 类型 | 默认值(默认值取自 src/common/options/rgw.yaml.in @ v20.2.4) | 含义 |
|
||
|---|---|---|---|
|
||
| `rgw_bucket_quota_ttl` | int | `10_min` | Bucket quota stats 缓存 TTL |
|
||
| `rgw_user_quota_bucket_sync_interval` | int | `3_min` | User quota bucket 同步间隔 |
|
||
| `rgw_user_quota_sync_interval` | int | `1_day` | User quota 同步间隔 |
|
||
|
||
- **增大**这些值 → quota 操作更高效,但多 RGW 实例间配额设置不一致的可能性上升。
|
||
- **减小**这些值 → 多 RGW 实例间更接近完美的配额同步。
|
||
- **三个值都设为 `0`** → 配额缓存实际上被禁用,多实例将有完美的配额执行。
|
||
|
||
#### 6.2.5 速率限制(ratelimit)
|
||
|
||
「rate limit」包括:每分钟的**读操作数 / 写操作数**,以及每个用户或每个 bucket 每分钟可写/可读的**字节数**。
|
||
|
||
**读请求 vs 写请求**:REST 请求中使用 `GET` 或 `HEAD` 方法的操作是「读请求」,**所有其它请求**都是「写请求」。
|
||
|
||
**Metrics 如何工作(源文原文要点)**:
|
||
|
||
- 每个对象网关**分别**跟踪 per-user 指标与 bucket 指标,**不与其它网关共享**。
|
||
- **配置的限制应除以活跃对象网关的数量。** 例:若要限制「user A」10 ops/分钟而集群有 2 个 RGW,则该限制应设为 `5`。
|
||
- 若请求在 RGW 之间**不均衡**,rate limit 可能利用不足。例:限制为 5 且有 2 个 RGW,但 LB 只把流量发给其中一个,则**有效限制就是 5 ops**(因为限制是按 RGW 强制的)。
|
||
- **bucket 限流到达但 user 限流未到达 → 请求被取消**;反之亦然。
|
||
- **带宽计量只在请求被接受之后发生**。这意味着即使 bucket 或 user 的 rate limit 在请求执行期间被达到,请求也会继续进行。
|
||
- RGW 会跟踪超出配置值的「**debt(欠账)**」;欠账的用户/bucket 会被阻止发送更多请求,直到欠账还清。**debt 的最大值是 max-read/write-bytes per minute 的两倍。**
|
||
- 举例:若「user A」被限制为每分钟 1 字节读,而它尝试 `GET` 一个 1 GB 的对象,则该 `GET` 会失败。完成这个 1 GB 操作后,RGW 会阻止该用户的请求**最多两分钟**;两分钟后可再次发送 `GET`。
|
||
|
||
| 参数 | 说明 |
|
||
|---|---|
|
||
| `--bucket` | 为某个 bucket 指定 rate limit |
|
||
| `--uid` | 为某个 user 指定 rate limit |
|
||
| `--max-read-ops` | 限制每个 RGW 实例每分钟的读操作次数。`0` 禁用节流 |
|
||
| `--max-read-bytes` | 限制每个 RGW 实例每分钟的读字节数。`0` 禁用节流 |
|
||
| `--max-write-ops` | 限制每个 RGW 实例每分钟的写操作次数。`0` 禁用节流 |
|
||
| `--max-write-bytes` | 限制每个 RGW 实例每分钟的写字节数。`0` 禁用节流 |
|
||
| `--ratelimit-scope` | 限流作用域,可选 `bucket`、`user`、`anonymous`。**`anonymous` 仅对 global rate limit 可用** |
|
||
|
||
| 子命令 | 用途 | 关键参数 | 示例 |
|
||
|---|---|---|---|
|
||
| `ratelimit set`(user) | 设置 user 限流参数 | `--ratelimit-scope=user`、`--uid`、`--max-read-ops`、`--max-read-bytes`、`--max-write-ops`、`--max-write-bytes` | `radosgw-admin ratelimit set --ratelimit-scope=user --uid=johndoe --max-read-ops=1024 --max-write-bytes=10240` |
|
||
| `ratelimit get`(user) | 返回当前已配置的 user 限流参数 | `--ratelimit-scope=user`、`--uid` | `radosgw-admin ratelimit get --ratelimit-scope=user --uid=johndoe` |
|
||
| `ratelimit enable`(user) | 启用已设置的 user 限流 | `--ratelimit-scope=user`、`--uid` | `radosgw-admin ratelimit enable --ratelimit-scope=user --uid=<uid>` |
|
||
| `ratelimit disable`(user) | 禁用 user 限流 | `--ratelimit-scope=user`、`--uid` | `radosgw-admin ratelimit disable --ratelimit-scope=user --uid=johndoe` |
|
||
| `ratelimit set`(bucket) | 设置 bucket 限流参数 | `--ratelimit-scope=bucket`、`--bucket`、`--max-read-ops`、`--max-read-bytes`、`--max-write-ops`、`--max-write-bytes` | `radosgw-admin ratelimit set --ratelimit-scope=bucket --bucket=mybucket --max-read-ops=1024 --max-write-bytes=10240` |
|
||
| `ratelimit get`(bucket) | 返回 bucket 限流参数 | `--ratelimit-scope=bucket`、`--bucket` | `radosgw-admin ratelimit get --ratelimit-scope=bucket --bucket=mybucket` |
|
||
| `ratelimit enable`(bucket) | 启用 bucket 限流 | `--ratelimit-scope=bucket`、`--bucket` | `radosgw-admin ratelimit enable --ratelimit-scope=bucket --bucket=<bucket>` |
|
||
| `ratelimit disable`(bucket) | 禁用 bucket 限流 | `--ratelimit-scope=bucket`、`--uid` | `radosgw-admin ratelimit disable --ratelimit-scope=bucket --uid=mybucket` |
|
||
| `global ratelimit get` | 读取 period 配置中的全局限流设置 | 无 | `radosgw-admin global ratelimit get` |
|
||
| `global ratelimit set` | 设置全局限流(bucket / user / anonymous 三种 scope) | `--ratelimit-scope`、`--max-read-ops`、`--max-read-bytes`、`--max-write-ops`、`--max-write-bytes` | `radosgw-admin global ratelimit set --ratelimit-scope bucket --max-read-ops=1024` |
|
||
| `global ratelimit enable` | 启用全局限流 | `--ratelimit-scope` | `radosgw-admin global ratelimit enable --ratelimit-scope bucket` |
|
||
|
||
**全局限流的三种用法**:
|
||
|
||
```bash
|
||
# 1) 为所有 bucket 配置全局限流
|
||
radosgw-admin global ratelimit set --ratelimit-scope bucket --max-read-ops=1024
|
||
radosgw-admin global ratelimit enable --ratelimit-scope bucket
|
||
|
||
# 2) 为所有已认证用户配置全局限流
|
||
radosgw-admin global ratelimit set --ratelimit-scope user --max-read-ops=1024
|
||
radosgw-admin global ratelimit enable --ratelimit-scope user
|
||
|
||
# 3) 为所有未认证(匿名)用户配置全局限流
|
||
radosgw-admin global ratelimit set --ratelimit-scope=anonymous --max-read-ops=1024
|
||
radosgw-admin global ratelimit enable --ratelimit-scope=anonymous
|
||
```
|
||
|
||
要点:**per-user 与 per-bucket 的 ratelimit 配置会覆盖 global 配置。** 在存在 realm 与 period 的多站点配置中,全局限流的任何改动必须用 `period update --commit` 提交;若无 period,则必须重启 RGW。
|
||
|
||
#### 6.2.6 用量(usage)
|
||
|
||
**前提**:需要启用 usage log。在 `ceph.conf` 的 `[client.rgw]` 段加入 `rgw_enable_usage_log = true` 并重启 `radosgw` 服务。
|
||
|
||
> 官方 note:在 Ceph 提供一个能处理所有选项设置方式的可链接宏之前,建议在 central config 或 `ceph.conf` 中设置 `rgw_enable_usage_log = true` 并重启所有 RGW。
|
||
|
||
| 选项 | 说明 |
|
||
|---|---|
|
||
| `--start-date` | 过滤起始日期与可选的起始时间(**格式**:`yyyy-mm-dd [HH:MM:SS]`) |
|
||
| `--end-date` | 过滤截止日期与可选的截止时间(**格式**:`yyyy-mm-dd [HH:MM:SS]`) |
|
||
| `--show-log-entries` | 是否在统计中包含日志条目(`true` \| `false`) |
|
||
|
||
| 子命令 | 用途 | 关键参数 | 示例 |
|
||
|---|---|---|---|
|
||
| `usage show` | 显示用量统计;省略 `--uid` 则显示所有用户的汇总 | `--uid`、`--start-date`、`--end-date`、`--show-log-entries` | `radosgw-admin usage show --uid=johndoe --start-date=2012-03-01 --end-date=2012-04-01` |
|
||
| `usage trim` | 裁剪用量日志(可指定用户与日期范围) | `--uid`、`--start-date`、`--end-date` | `radosgw-admin usage trim --uid=johndoe --end-date=2013-12-31` |
|
||
|
||
> **注意**:可以指定到分秒精度,但**指定的时间只以 1 小时分辨率存储**。
|
||
|
||
示例:
|
||
|
||
```bash
|
||
radosgw-admin usage show --uid=johndoe --start-date=2012-03-01 --end-date=2012-04-01
|
||
radosgw-admin usage show --show-log-entries=false
|
||
radosgw-admin usage trim --start-date=2010-01-01 --end-date=2010-12-31
|
||
radosgw-admin usage trim --uid=johndoe
|
||
radosgw-admin usage trim --uid=johndoe --end-date=2013-12-31
|
||
```
|
||
|
||
#### 6.2.7 其它本册出现的子命令
|
||
|
||
| 子命令 | 用途 | 关键参数 | 示例 |
|
||
|---|---|---|---|
|
||
| `zonegroup get` | 查看 zonegroup 配置(含 placement_targets、default_placement、api_name) | `--rgw-zonegroup` | `radosgw-admin zonegroup get` |
|
||
| `zone get` | 查看 zone 配置(含 domain_root、placement_pools) | `--rgw-zone` | `radosgw-admin zone get --rgw-zone=default` |
|
||
| `zone set` | 应用修改后的 zone 配置 | `--rgw-zone`、`--infile` | `radosgw-admin zone set --rgw-zone=default --infile=zone.json` |
|
||
| `zonegroup placement add` | 向 zonegroup 添加 placement target 或 storage class | `--rgw-zonegroup`、`--placement-id`、`--storage-class` | `radosgw-admin zonegroup placement add --rgw-zonegroup default --placement-id temporary` |
|
||
| `zone placement add` | 为 placement target / storage class 提供 zone 侧 pool 映射 | `--rgw-zone`、`--placement-id`、`--storage-class`、`--data-pool`、`--index-pool`、`--data-extra-pool`、`--compression`、`--placement-inline-data` | `radosgw-admin zone placement add --rgw-zone default --placement-id temporary --data-pool default.rgw.temporary.data --index-pool default.rgw.temporary.index --data-extra-pool default.rgw.temporary.non-ec` |
|
||
| `zone placement modify` | 修改 placement(支持 `--placement-inline-data`) | 同上 | 文档未给出独立示例 |
|
||
| `zonegroup placement default` | 修改 zonegroup 的默认 placement target | `--rgw-zonegroup`、`--placement-id` | `radosgw-admin zonegroup placement default --rgw-zonegroup default --placement-id new-placement` |
|
||
| `bucket stats` | 查看 bucket 统计,会显示其 `placement_rule` | `--bucket` | `radosgw-admin bucket stats` |
|
||
| `period update` | 提交 period 变更(多站点/全局配额/全局限流) | `--commit` | `radosgw-admin period update --commit` |
|
||
| `gc list` | 查看等待垃圾回收的对象队列 | `--include-all` | `radosgw-admin gc list` |
|
||
| `metadata list` | 列出元数据类型或某类型的条目 | 可选类型名(如 `bucket`、`bucket.instance`、`user`) | `radosgw-admin metadata list user` |
|
||
| `metadata get` | 获取(或 set)元数据条目 | `bucket:<bucket>`、`bucket.instance:<bucket>:<bucket_id>`、`user:<user>` | `radosgw-admin metadata get user:johndoe` |
|
||
| `topic rm` | 删除通知 topic(账号迁移后清理旧 topic) | `--topic` | `radosgw-admin topic rm --topic topic1` |
|
||
| `account create` | 创建账号 | `--account-name`、`--account-id`、`--email` | `radosgw-admin account create --account-name=acct1 --email=a@b.com` |
|
||
| `account rm` | 删除账号 | `--account-id` | `radosgw-admin account rm --account-id={accountid}` |
|
||
| `account stats` | 查看账号统计 | `--account-id`、`--sync-stats` | `radosgw-admin account stats --account-id={accountid} --sync-stats` |
|
||
|
||
### 6.3 输出与常见坑
|
||
|
||
**JSON 转义字符问题(官方 important)**:
|
||
|
||
> 检查 key 输出。有时 `radosgw-admin` 会生成 JSON 转义字符(`\`),而某些客户端不知道如何处理 JSON 转义字符。补救办法包括:删除 JSON 转义字符(`\`)、把字符串用引号包起来、重新生成 key 并确保其不含 JSON 转义字符、或者手动指定 key 与 secret。
|
||
|
||
**创建用户的输出结构示例**:
|
||
|
||
```json
|
||
{ "user_id": "johndoe",
|
||
"display_name": "John Doe",
|
||
"email": "john@example.com",
|
||
"suspended": 0,
|
||
"max_buckets": 1000,
|
||
"subusers": [],
|
||
"keys": [
|
||
{ "user": "johndoe",
|
||
"access_key": "11BS02LGFB6AL6H1ADMW",
|
||
"secret_key": "vzCEkuryfn060dfee4fgQPqFrncKEIkh3ZcdOANY"}],
|
||
"swift_keys": [],
|
||
"caps": [],
|
||
"op_mask": "read, write, delete",
|
||
"default_placement": "",
|
||
"placement_tags": [],
|
||
"bucket_quota": { "enabled": false,
|
||
"max_size_kb": -1,
|
||
"max_objects": -1},
|
||
"user_quota": { "enabled": false,
|
||
"max_size_kb": -1,
|
||
"max_objects": -1},
|
||
"temp_url_keys": []}
|
||
```
|
||
|
||
**创建 subuser 后的输出结构示例**:
|
||
|
||
```json
|
||
{ "user_id": "johndoe",
|
||
"display_name": "John Doe",
|
||
"email": "john@example.com",
|
||
"suspended": 0,
|
||
"max_buckets": 1000,
|
||
"subusers": [
|
||
{ "id": "johndoe:swift",
|
||
"permissions": "full-control"}],
|
||
"keys": [
|
||
{ "user": "johndoe",
|
||
"access_key": "11BS02LGFB6AL6H1ADMW",
|
||
"secret_key": "vzCEkuryfn060dfee4fgQPqFrncKEIkh3ZcdOANY"}],
|
||
"swift_keys": [],
|
||
"caps": [],
|
||
"op_mask": "read, write, delete",
|
||
"default_placement": "",
|
||
"placement_tags": [],
|
||
"bucket_quota": { "enabled": false,
|
||
"max_size_kb": -1,
|
||
"max_objects": -1},
|
||
"user_quota": { "enabled": false,
|
||
"max_size_kb": -1,
|
||
"max_objects": -1},
|
||
"temp_url_keys": []}
|
||
```
|
||
|
||
**添加 S3 key 的输出示例**:
|
||
|
||
```json
|
||
{ "user_id": "foo",
|
||
"rados_uid": 0,
|
||
"display_name": "foo",
|
||
"email": "foo@example.com",
|
||
"suspended": 0,
|
||
"keys": [
|
||
{ "user": "foo",
|
||
"access_key": "fooAccessKey",
|
||
"secret_key": "fooSecretKey"}],
|
||
}
|
||
```
|
||
|
||
**添加 Swift secret key 的输出示例**:
|
||
|
||
```json
|
||
{ "user_id": "foo",
|
||
"rados_uid": 0,
|
||
"display_name": "foo",
|
||
"email": "foo@example.com",
|
||
"suspended": 0,
|
||
"subusers": [
|
||
{ "id": "foo:bar",
|
||
"permissions": "full-control"}],
|
||
"swift_keys": [
|
||
{ "user": "foo:bar",
|
||
"secret_key": "asfghjghghmgm"}]}
|
||
```
|
||
|
||
**subuser 关联 S3 key 对的输出示例**:
|
||
|
||
```json
|
||
{ "user_id": "foo",
|
||
"rados_uid": 0,
|
||
"display_name": "foo",
|
||
"email": "foo@example.com",
|
||
"suspended": 0,
|
||
"subusers": [
|
||
{ "id": "foo:bar",
|
||
"permissions": "full-control"}],
|
||
"keys": [
|
||
{ "user": "foo:bar",
|
||
"access_key": "barAccessKey",
|
||
"secret_key": "barSecretKey"}],
|
||
}
|
||
```
|
||
|
||
> 引自:[Admin Guide](https://docs.ceph.com/en/tentacle/radosgw/admin/)
|
||
|
||
---
|
||
|
||
## 七、管理 API(Admin Ops API)
|
||
|
||
来源:`adminops.rst` 全文(55KB)。
|
||
|
||
### 7.1 通用约定
|
||
|
||
| 约定 | 说明(源文原文要点) |
|
||
|---|---|
|
||
| 入口 | admin API 请求的 URI 以可配置的 **'admin' resource entry point** 开头(配置项 `rgw_admin_entry`,默认 `admin`,见第十二章) |
|
||
| 认证 | **Authorization for the admin API duplicates the S3 authorization mechanism**(复用 S3 的认证机制) |
|
||
| 授权 | 部分操作要求用户持有**特殊的管理能力(administrative capabilities)** |
|
||
| 响应格式 | 实体类型(XML 或 JSON)可用请求中的 **`format`** 选项指定;**未指定时默认为 JSON** |
|
||
| 请求/响应符号 | 下文语法中的 `{admin}` = admin 入口点;`{fqdn}` = 网关的完全限定域名 |
|
||
|
||
### 7.2 操作总览表
|
||
|
||
| # | 操作 | HTTP 方法 | 路径 | 所需 caps |
|
||
|---|---|---|---|---|
|
||
| 1 | Get Usage | `GET` | `/{admin}/usage` | `usage=read` |
|
||
| 2 | Trim Usage | `DELETE` | `/{admin}/usage` | `usage=write` |
|
||
| 3 | Get User Info | `GET` | `/{admin}/user` | `users=read` 或 `user-info-without-keys=read` |
|
||
| 4 | Create Account | `POST` | `/{admin}/account` | `accounts=write` |
|
||
| 5 | Modify Account | `PUT` | `/{admin}/account` | `accounts=write` |
|
||
| 6 | Get Account Info | `GET` | `/{admin}/account` | `accounts=write` |
|
||
| 7 | Remove Account | `DELETE` | `/{admin}/account` | `accounts=write` |
|
||
| 8 | Create User | `PUT` | `/{admin}/user` | `users=write` |
|
||
| 9 | Modify User | `POST` | `/{admin}/user` | `users=write` |
|
||
| 10 | Remove User | `DELETE` | `/{admin}/user` | `users=write` |
|
||
| 11 | Create Subuser | `PUT` | `/{admin}/user?subuser` | `users=write` |
|
||
| 12 | Modify Subuser | `POST` | `/{admin}/user?subuser` | `users=write` |
|
||
| 13 | Remove Subuser | `DELETE` | `/{admin}/user?subuser` | `users=write` |
|
||
| 14 | Create Key | `PUT` | `/{admin}/user?key` | `users=write` |
|
||
| 15 | Remove Key | `DELETE` | `/{admin}/user?key` | `users=write` |
|
||
| 16 | Get Bucket Info | `GET` | `/{admin}/bucket` | `buckets=read` |
|
||
| 17 | Check Bucket Index | `GET` | `/{admin}/bucket?index` | `buckets=write` |
|
||
| 18 | Remove Bucket | `DELETE` | `/{admin}/bucket` | `buckets=write` |
|
||
| 19 | Unlink Bucket | `POST` | `/{admin}/bucket` | `buckets=write` |
|
||
| 20 | Link Bucket | `PUT` | `/{admin}/bucket` | `buckets=write` |
|
||
| 21 | Remove Object | `DELETE` | `/{admin}/bucket?object` | `buckets=write` |
|
||
| 22 | Get Bucket or Object Policy | `GET` | `/{admin}/bucket?policy` | `buckets=read` |
|
||
| 23 | Add A User Capability | `PUT` | `/{admin}/user?caps` | `users=write` |
|
||
| 24 | Remove A User Capability | `DELETE` | `/{admin}/user?caps` | `users=write` |
|
||
| 25 | Get/Set User Quota | `GET` / `PUT` | `/{admin}/user?quota"a-type=user` | `users=read` / `users=write` |
|
||
| 26 | Get/Set Bucket Quota(user 下) | `GET` / `PUT` | `/{admin}/user?quota"a-type=bucket` | `users=read` / `users=write` |
|
||
| 27 | Set Quota for an Individual Bucket | `PUT` | `/{admin}/bucket?quota` | `buckets=write` |
|
||
| 28 | Set Account Quota | `PUT` | `/{admin}/account?quota"a-type=account` | `accounts=write` |
|
||
| 29 | Set Bucket Quota under an Account | `PUT` | `/{admin}/account?quota"a-type=bucket` | `accounts=write` |
|
||
| 30 | Get User Rate Limit | `GET` | `/{admin}/ratelimit?ratelimit-scope=user` | `ratelimit=read` |
|
||
| 31 | Set User Rate Limit | `POST` | `/{admin}/ratelimit?ratelimit-scope=user` | `ratelimit=write` |
|
||
| 32 | Get Bucket Rate Limit | `GET` | `/{admin}/ratelimit?ratelimit-scope=bucket` | `users=read`(源文如此) |
|
||
| 33 | Set Rate Limit for an Individual Bucket | `POST` | `/{admin}/ratelimit?ratelimit-scope=bucket` | `ratelimit=write` |
|
||
| 34 | Get Global Rate Limit | `GET` | `/{admin}/ratelimit?global` | `ratelimit=read` |
|
||
| 35 | Set Global User Rate Limit | `POST` | `/{admin}/ratelimit?ratelimit-scope=user&global` | `ratelimit=write` |
|
||
| 36 | Set Global Rate Limit Bucket | `POST` | `/{admin}/ratelimit?ratelimit-scope=bucket&global` | `ratelimit=write` |
|
||
| 37 | Set Global Anonymous User Rate Limit | `POST` | `/{admin}/ratelimit?ratelimit-scope=anon&global` | `ratelimit=write` |
|
||
| 38 | Get RGW cluster/endpoint Info | `GET` | `/{admin}/info` | `info=read` |
|
||
|
||
### 7.3 Info
|
||
|
||
**Get RGW cluster/endpoint information.** `:caps: info=read`
|
||
|
||
```http
|
||
GET /{admin}/info?format=json HTTP/1.1
|
||
Host: {fqdn}
|
||
```
|
||
|
||
**Request Parameters**:None.
|
||
|
||
**Response Entities**(成功时含 `info` section):
|
||
|
||
| 实体 | 描述 | 类型 | Parent |
|
||
|---|---|---|---|
|
||
| `info` | 所有返回信息的容器 | Container | — |
|
||
| `cluster_id` | RGW 集群的后端存储控制标识符(典型情况下即 `librados::rados::cluster_fsid()` 的返回值),通常唯一 | String | `info` |
|
||
|
||
**Special Error Responses**:None.
|
||
|
||
### 7.4 Get Usage
|
||
|
||
**Request bandwidth usage information.** `:caps: usage=read`
|
||
|
||
> 注意:**该特性默认禁用**,可在 `ceph.conf` 适当段中设置 `rgw enable usage log = true` 启用;`ceph.conf` 的修改需要重启 radosgw 进程生效。
|
||
|
||
```http
|
||
GET /{admin}/usage?format=json HTTP/1.1
|
||
Host: {fqdn}
|
||
```
|
||
|
||
**Request Parameters**:
|
||
|
||
| 参数 | 描述 | 类型 | 示例 | 必填 |
|
||
|---|---|---|---|---|
|
||
| `uid` | 请求信息的用户。未指定则应用于所有用户 | String | `foo_user` | No |
|
||
| `start` | 指定所请求数据起始时间的日期与(可选)时间 | String | `2012-09-25 16:00:00` | No |
|
||
| `end` | 指定所请求数据结束时间的日期与(可选)时间(**不含**) | String | `2012-09-25 16:00:00` | No |
|
||
| `show-entries` | 是否返回数据条目 | Boolean | True [True] | No |
|
||
| `show-summary` | 是否返回数据汇总 | Boolean | True [True] | No |
|
||
|
||
**Response Entities**:
|
||
|
||
| 实体 | 描述 | 类型 |
|
||
|---|---|---|
|
||
| `usage` | 用量信息的容器 | Container |
|
||
| `entries` | 用量条目信息的容器 | Container |
|
||
| `user` | 用户数据信息的容器 | Container |
|
||
| `owner` | 拥有这些 bucket 的用户名 | String |
|
||
| `bucket` | bucket 名 | String |
|
||
| `time` | 数据的时间下界(**取整到相关第一个小时的起点**) | String |
|
||
| `epoch` | 以自 1970-01-01 起的秒数表示的时间 | String |
|
||
| `categories` | 统计类别的容器 | Container |
|
||
| `entry` | 统计条目的容器 | Container |
|
||
| `category` | 提供统计的请求类别名 | String |
|
||
| `bytes_sent` | RADOS Gateway 发出的字节数 | Integer |
|
||
| `bytes_received` | RADOS Gateway 收到的字节数 | Integer |
|
||
| `ops` | 操作次数 | Integer |
|
||
| `successful_ops` | 成功操作次数 | Integer |
|
||
| `summary` | 统计汇总的容器 | Container |
|
||
| `total` | 汇总聚合总计的容器 | Container |
|
||
|
||
**Special Error Responses**:TBD.
|
||
|
||
### 7.5 Trim Usage
|
||
|
||
**Remove usage information.** 未指定日期则移除**全部**用量信息。`:caps: usage=write`
|
||
|
||
```http
|
||
DELETE /{admin}/usage?format=json HTTP/1.1
|
||
Host: {fqdn}
|
||
```
|
||
|
||
**Request Parameters**:
|
||
|
||
| 参数 | 描述 | 类型 | 示例 | 必填 |
|
||
|---|---|---|---|---|
|
||
| `uid` | 请求信息的用户。未指定则应用于所有用户 | String | `foo_user` | No |
|
||
| `start` | 起始日期与(可选)时间 | String | `2012-09-25 16:00:00` | No |
|
||
| `end` | 结束日期与(可选)时间(不含) | String | `2012-09-25 16:00:00` | No |
|
||
| `remove-all` | **当未指定 uid 时必需**,用于确认多用户数据移除 | Boolean | True [False] | No |
|
||
|
||
**Special Error Responses**:TBD.
|
||
|
||
### 7.6 Get User Info
|
||
|
||
`:caps: users=read` 或 `user-info-without-keys=read`
|
||
|
||
> 若 cap `user-info-without-keys` 设为 `read` 或 `*`,**响应中不会包含 S3 keys 与 Swift keys**,除非执行该操作的用户是 system user、admin user,或者 cap `users` 设为 `read`。
|
||
>
|
||
> 必须以请求参数形式提供 `uid` 或 `access-key` 之一。**推荐使用 uid。** 若两者都提供但对应不同用户,则返回 `uid` 所指定用户的信息。
|
||
|
||
```http
|
||
GET /{admin}/user?format=json HTTP/1.1
|
||
Host: {fqdn}
|
||
```
|
||
|
||
**Request Parameters**:
|
||
|
||
| 参数 | 描述 | 类型 | 示例 | 必填 |
|
||
|---|---|---|---|---|
|
||
| `uid` | 请求信息的用户 | String | `foo_user` | Yes |
|
||
| `access-key` | 请求信息用户的 S3 access key | String | `ABCD0EF12GHIJ2K34LMN` | No |
|
||
|
||
**Response Entities**:
|
||
|
||
| 实体 | 描述 | 类型 | Parent |
|
||
|---|---|---|---|
|
||
| `user` | 用户数据信息的容器 | Container | — |
|
||
| `user_id` | 用户 id | String | `user` |
|
||
| `display_name` | 用户的显示名 | String | `user` |
|
||
| `suspended` | 用户是否被暂停 | Boolean | `user` |
|
||
| `max_buckets` | 用户可拥有的最大 bucket 数 | Integer | `user` |
|
||
| `subusers` | 与该用户账号关联的 subuser | Container | `user` |
|
||
| `keys` | 与该用户账号关联的 S3 key | Container | `user` |
|
||
| `swift_keys` | 与该用户账号关联的 Swift key | Container | `user` |
|
||
| `caps` | 用户能力 | Container | `user` |
|
||
|
||
**Special Error Responses**:None.
|
||
|
||
### 7.7 Create Account
|
||
|
||
> versionadded:: Squid — `:caps: accounts=write`
|
||
|
||
```http
|
||
POST /{admin}/account?format=json HTTP/1.1
|
||
Host: {fqdn}
|
||
```
|
||
|
||
**Request Parameters**:
|
||
|
||
| 参数 | 描述 | 类型 | 示例 | 必填 |
|
||
|---|---|---|---|---|
|
||
| `id` | 待创建 account 的 ID | String | `RGW00000000000000001` | Yes |
|
||
| `name` | 待创建 account 的名称 | String | `account_name` | Yes |
|
||
| `email` | 与 account 关联的 email 地址 | String | `foo@bar.com` | No |
|
||
| `tenant` | account 所属的 Tenant | string | `tenant1` | No |
|
||
| `max-users` | account 可拥有的最大用户数,默认 1000 | Integer | 500 [1000] | No |
|
||
| `max-roles` | account 可拥有的最大 role 数,默认 1000 | Integer | 500 [1000] | No |
|
||
| `max-groups` | account 可拥有的最大 group 数,默认 1000 | Integer | 500 [1000] | No |
|
||
| `max-access-keys` | account 可拥有的最大 access key 数,默认 4 | Integer | 1 [4] | No |
|
||
| `max-buckets` | account 可拥有的最大 bucket 数,默认 1000 | Integer | 500 [1000] | No |
|
||
|
||
> **Account ID 格式**:必须为 **20 个字符**,格式为字符串 `RGW` 后跟 **17 个数字字符**。
|
||
|
||
**Response Entities**:
|
||
|
||
| 实体 | 描述 | 类型 | Parent |
|
||
|---|---|---|---|
|
||
| `account` | account 信息的容器 | Container | — |
|
||
| `id` | 创建的 account ID | String | `account` |
|
||
| `tenant` | account 所属的 Tenant | String | `account` |
|
||
| `name` | 创建的 account 名称 | String | `account` |
|
||
| `email` | 关联的 email 地址 | String | `account` |
|
||
| `max_users` | 可拥有的最大用户数 | Integer | `account` |
|
||
| `max_roles` | 可拥有的最大 role 数 | Integer | `account` |
|
||
| `max_groups` | 可拥有的最大 group 数 | Integer | `account` |
|
||
| `max_buckets` | 可拥有的最大 bucket 数 | Integer | `account` |
|
||
| `max_access_keys` | 可拥有的最大 access key 数 | Integer | `account` |
|
||
| `quota` | account 级配额信息容器 | Container | `account` |
|
||
| `enabled` | account 级配额是否启用 | Bool | `quota` |
|
||
| `check_on_raw` | 配额是否基于 raw usage 而非 4 KiB 向上取整后的用量检查 | Bool | `quota` |
|
||
| `max_size` | 最大配额大小(字节) | Integer | `quota` |
|
||
| `max_size_kb` | 最大配额大小(KB) | Integer | `quota` |
|
||
| `max_objects` | account 可拥有的最大对象数 | Integer | `quota` |
|
||
| `bucket_quota` | account 的 bucket 级配额信息容器 | Container | `account` |
|
||
| `enabled` | account 的 bucket 级配额是否启用 | Bool | `bucket_quota` |
|
||
| `check_on_raw` | bucket 配额是否基于 raw usage 检查 | Bool | `bucket_quota` |
|
||
| `max_size` | account 下 bucket 的最大配额字节数 | Integer | `bucket_quota` |
|
||
| `max_size_kb` | account 下 bucket 的最大配额 KB 数 | Integer | `bucket_quota` |
|
||
| `max_objects` | account 下单个 bucket 可拥有的最大对象数 | Integer | `bucket_quota` |
|
||
|
||
**Special Error Responses**:
|
||
|
||
| 错误 | 描述 | Code |
|
||
|---|---|---|
|
||
| `AccountAlreadyExists` | 尝试创建已存在的 account(account ID 或 email 已被占用时会发生) | 409 Conflict |
|
||
|
||
### 7.8 Modify Account
|
||
|
||
> versionadded:: Squid — `:caps: accounts=write`。**必须提供 `id`、`name` 或 `email` 之一。**
|
||
|
||
```http
|
||
PUT /{admin}/account?format=json HTTP/1.1
|
||
Host: {fqdn}
|
||
```
|
||
|
||
**Request Parameters**:
|
||
|
||
| 参数 | 描述 | 类型 | 示例 | 必填 |
|
||
|---|---|---|---|---|
|
||
| `id` | 待修改 account 的 ID | String | `RGW00000000000000001` | No |
|
||
| `name` | 待修改 account 的名称 | String | `account_name` | No |
|
||
| `email` | 待修改 account 的 email | String | `foo@bar.com` | No |
|
||
| `max-users` | 最大用户数,默认 1000 | Integer | 500 [1000] | No |
|
||
| `max-roles` | 最大 role 数,默认 1000 | Integer | 500 [1000] | No |
|
||
| `max-groups` | 最大 group 数,默认 1000 | Integer | 500 [1000] | No |
|
||
| `max-access-keys` | 最大 access key 数,默认 4 | Integer | 1 [4] | No |
|
||
| `max-buckets` | 最大 bucket 数,默认 1000 | Integer | 500 [1000] | No |
|
||
|
||
**Response Entities**:与 7.7 Create Account 的响应实体**完全相同**(`account` 容器 + `id`/`tenant`/`name`/`email`/`max_users`/`max_roles`/`max_groups`/`max_buckets`/`max_access_keys`/`quota`/`bucket_quota` 及其子字段)。
|
||
|
||
**Special Error Responses**:None.
|
||
|
||
### 7.9 Get Account Info
|
||
|
||
> versionadded:: Squid — `:caps: accounts=write`。**必须提供 `id` 或 `name` 之一。**
|
||
|
||
```http
|
||
GET /{admin}/account?format=json HTTP/1.1
|
||
Host: {fqdn}
|
||
```
|
||
|
||
**Request Parameters**:
|
||
|
||
| 参数 | 描述 | 类型 | 示例 | 必填 |
|
||
|---|---|---|---|---|
|
||
| `id` | 要获取信息的 account ID | String | `RGW00000000000000001` | No |
|
||
| `name` | 要获取信息的 account 名称 | String | `account_name` | No |
|
||
|
||
**Response Entities**:与 7.7 相同(`account` 及其全部子字段)。
|
||
|
||
**Special Error Responses**:None.
|
||
|
||
### 7.10 Remove Account
|
||
|
||
> versionadded:: Squid — `:caps: accounts=write`。**必须提供 `id`、`name` 或 `email` 之一。**
|
||
|
||
```http
|
||
DELETE /{admin}/account?format=json HTTP/1.1
|
||
Host: {fqdn}
|
||
```
|
||
|
||
**Request Parameters**:
|
||
|
||
| 参数 | 描述 | 类型 | 示例 | 必填 |
|
||
|---|---|---|---|---|
|
||
| `id` | 待移除 account 的 ID | String | `RGW00000000000000001` | No |
|
||
| `tenant` | account 所属的 Tenant | String | `tenant` | No |
|
||
| `name` | 待移除 account 的名称 | String | `account_name` | No |
|
||
| `email` | 待移除 account 的 email | String | `foo@bar.com` | No |
|
||
|
||
**Response Entities**:None. **Special Error Responses**:None.
|
||
|
||
### 7.11 Create User
|
||
|
||
`:caps: users=write`
|
||
|
||
> 默认会自动创建一对 S3 key 并在响应中返回。若只提供 `access-key` 或 `secret-key` 之一,则省略的那个会自动生成。默认情况下,生成的 key 会被**加入 keyring 而不替换**已有 key 对。若指定了 `access-key` 且其指向该用户已拥有的某个 key,则该 key 会被**修改**。
|
||
|
||
```http
|
||
PUT /{admin}/user?format=json HTTP/1.1
|
||
Host: {fqdn}
|
||
```
|
||
|
||
**Request Parameters**:
|
||
|
||
| 参数 | 描述 | 类型 | 示例 | 必填 |
|
||
|---|---|---|---|---|
|
||
| `uid` | 待创建的用户 ID | String | `foo_user` | Yes |
|
||
| `display-name` | 待创建用户的显示名 | String | `foo user` | Yes |
|
||
| `email` | 与用户关联的 email 地址 | String | `foo@bar.com` | No |
|
||
| `key-type` | 要生成的 key 类型,选项 `swift`、`s3`(默认) | String | `s3` [`s3`] | No |
|
||
| `access-key` | 指定 access key | String | `ABCD0EF12GHIJ2K34LMN` | No |
|
||
| `secret-key` | 指定 secret key | String | `0AbCDEFg1h2i34JklM5nop6QrSTUV+WxyzaBC7D8` | No |
|
||
| `user-caps` | 用户能力 | String | `usage=read, write; users=read` | No |
|
||
| `generate-key` | 生成新 key 对并加入已有 keyring | Boolean | True [True] | No |
|
||
| `max-buckets` | 指定用户可拥有的最大 bucket 数 | Integer | 500 [1000] | No |
|
||
| `suspended` | 指定用户是否被暂停 | Boolean | False [False] | No |
|
||
| `tenant` | (versionadded:: Jewel)用户所属的 Tenant | string | `tenant1` | No |
|
||
| `default-placement` | 用户的默认 placement | string | `default-placement` | No |
|
||
| `default-storage-class` | 用户的默认 storage class;**设置此项时必须同时定义 `default-placement`** | string | `STANDARD-1A` | No |
|
||
| `account-id` | (versionadded:: Squid)用户所属的 account | string | `RGW00000000000000001` | No |
|
||
|
||
> 自 Luminous 起,tenant 既可以作为 uid 的一部分(`tenant$user` 语法)指定,也可以作为额外的请求参数指定。
|
||
|
||
**Response Entities**:
|
||
|
||
| 实体 | 描述 | 类型 | Parent |
|
||
|---|---|---|---|
|
||
| `user` | 用户数据信息的容器 | Container | — |
|
||
| `tenant` | 用户所属的 tenant | String | `user` |
|
||
| `user_id` | 用户 id | String | `user` |
|
||
| `display_name` | 显示名 | String | `user` |
|
||
| `suspended` | 是否被暂停 | Boolean | `user` |
|
||
| `max_buckets` | 可拥有的最大 bucket 数 | Integer | `user` |
|
||
| `subusers` | 关联的 subuser | Container | `user` |
|
||
| `keys` | 关联的 S3 key | Container | `user` |
|
||
| `swift_keys` | 关联的 Swift key | Container | `user` |
|
||
| `caps` | 用户能力 | Container | `user` |
|
||
|
||
**Special Error Responses**:
|
||
|
||
| 错误 | 描述 | Code |
|
||
|---|---|---|
|
||
| `UserExists` | 尝试创建已存在的用户 | 409 Conflict |
|
||
| `InvalidAccessKey` | 指定了无效的 access key | 400 Bad Request |
|
||
| `InvalidKeyType` | 指定了无效的 key 类型 | 400 Bad Request |
|
||
| `InvalidSecretKey` | 指定了无效的 secret key | 400 Bad Request |
|
||
| `KeyExists` | 提供的 access key 已存在且属于另一个用户 | 409 Conflict |
|
||
| `EmailExists` | 提供的 email 地址已存在 | 409 Conflict |
|
||
| `InvalidCapability` | 尝试授予无效的管理能力 | 400 Bad Request |
|
||
|
||
### 7.12 Modify User
|
||
|
||
`:caps: users=write`
|
||
|
||
```http
|
||
POST /{admin}/user?format=json HTTP/1.1
|
||
Host: {fqdn}
|
||
```
|
||
|
||
**Request Parameters**:
|
||
|
||
| 参数 | 描述 | 类型 | 示例 | 必填 |
|
||
|---|---|---|---|---|
|
||
| `uid` | 待修改的用户 ID | String | `foo_user` | Yes |
|
||
| `display-name` | 待修改的显示名 | String | `foo user` | No |
|
||
| `email` | 关联的 email 地址 | String | `foo@bar.com` | No |
|
||
| `generate-key` | 生成新 key 对并加入已有 keyring | Boolean | True [False] | No |
|
||
| `access-key` | 指定 access key | String | `ABCD0EF12GHIJ2K34LMN` | No |
|
||
| `secret-key` | 指定 secret key | String | `0AbCDEFg1h2i34JklM5nop6QrSTUV+WxyzaBC7D8` | No |
|
||
| `key-type` | key 类型,选项 `swift`、`s3`(默认) | String | `s3` | No |
|
||
| `max-buckets` | 最大 bucket 数 | Integer | 500 [1000] | No |
|
||
| `suspended` | 是否暂停 | Boolean | False [False] | No |
|
||
| `op-mask` | 待修改的 op-mask | String | `read, write, delete, *` | No |
|
||
| `default-placement` | 用户的默认 placement | string | `default-placement` | No |
|
||
| `default-storage-class` | 用户的默认 storage class;设置此项时必须定义 `default-placement` | string | `STANDARD-1A` | No |
|
||
|
||
**Response Entities**:`user` 容器 + `user_id`、`display_name`、`suspended`、`max_buckets`、`subusers`、`keys`、`swift_keys`、`caps`(Parent 均为 `user`)。
|
||
|
||
**Special Error Responses**:`InvalidAccessKey`(400)、`InvalidKeyType`(400)、`InvalidSecretKey`(400)、`KeyExists`(409)、`EmailExists`(409)、`InvalidCapability`(400)。
|
||
|
||
### 7.13 Remove User
|
||
|
||
`:caps: users=write`
|
||
|
||
```http
|
||
DELETE /{admin}/user?format=json HTTP/1.1
|
||
Host: {fqdn}
|
||
```
|
||
|
||
**Request Parameters**:
|
||
|
||
| 参数 | 描述 | 类型 | 示例 | 必填 |
|
||
|---|---|---|---|---|
|
||
| `uid` | 待移除的用户 ID | String | `foo_user` | Yes |
|
||
| `purge-data` | 指定时,属于该用户的 bucket 与对象也会被移除 | Boolean | True | No |
|
||
|
||
**Response Entities**:None. **Special Error Responses**:None.
|
||
|
||
### 7.14 Create Subuser
|
||
|
||
`:caps: users=write`
|
||
|
||
> 创建一个新的 subuser(主要用于使用 Swift API 的客户端)。注意:**一般来说,要使 subuser 有用,必须通过 `access` 授予权限。** 与创建用户一样,如果指定了 `subuser` 而没有指定 `secret`,则会自动生成 secret key。
|
||
|
||
```http
|
||
PUT /{admin}/user?subuser&format=json HTTP/1.1
|
||
Host: {fqdn}
|
||
```
|
||
|
||
**Request Parameters**:
|
||
|
||
| 参数 | 描述 | 类型 | 示例 | 必填 |
|
||
|---|---|---|---|---|
|
||
| `uid` | 在其下创建 subuser 的用户 ID | String | `foo_user` | Yes |
|
||
| `subuser` | 待创建的 subuser ID | String | `sub_foo` | Yes |
|
||
| `secret-key` | 指定 secret key | String | `0AbCDEFg1h2i34JklM5nop6QrSTUV+WxyzaBC7D8` | No |
|
||
| `key-type` | 要生成的 key 类型,选项 `swift`(默认)、`s3` | String | `swift` [`swift`] | No |
|
||
| `access` | 设置 sub-user 的访问权限,应为 `read, write, readwrite, full` 之一 | String | `read` | No |
|
||
| `generate-secret` | 生成 secret key | Boolean | True [False] | No |
|
||
|
||
**Response Entities**:
|
||
|
||
| 实体 | 描述 | 类型 | Parent |
|
||
|---|---|---|---|
|
||
| `subusers` | 与用户账号关联的 subuser | Container | — |
|
||
| `id` | subuser id | String | `subusers` |
|
||
| `permissions` | subuser 对用户账号的访问权限 | String | `subusers` |
|
||
|
||
**Special Error Responses**:`SubuserExists`(409)、`InvalidKeyType`(400)、`InvalidSecretKey`(400)、`InvalidAccess`(400)。
|
||
|
||
### 7.15 Modify Subuser
|
||
|
||
`:caps: users=write`
|
||
|
||
```http
|
||
POST /{admin}/user?subuser&format=json HTTP/1.1
|
||
Host: {fqdn}
|
||
```
|
||
|
||
**Request Parameters**:
|
||
|
||
| 参数 | 描述 | 类型 | 示例 | 必填 |
|
||
|---|---|---|---|---|
|
||
| `uid` | 其下 subuser 待修改的用户 ID | String | `foo_user` | Yes |
|
||
| `subuser` | 待修改的 subuser ID | String | `sub_foo` | Yes |
|
||
| `generate-secret` | 为 subuser 生成新 secret key,**替换**已有 key | Boolean | True [False] | No |
|
||
| `secret` | 指定 secret key | String | `0AbCDEFg1h2i34JklM5nop6QrSTUV+WxyzaBC7D8` | No |
|
||
| `key-type` | key 类型,选项 `swift`(默认)、`s3` | String | `swift` [`swift`] | No |
|
||
| `access` | 访问权限,应为 `read, write, readwrite, full` 之一 | String | `read` | No |
|
||
|
||
**Response Entities**:同 7.14(`subusers` → `id`、`permissions`)。
|
||
|
||
**Special Error Responses**:`InvalidKeyType`(400)、`InvalidSecretKey`(400)、`InvalidAccess`(400)。
|
||
|
||
### 7.16 Remove Subuser
|
||
|
||
`:caps: users=write`
|
||
|
||
```http
|
||
DELETE /{admin}/user?subuser&format=json HTTP/1.1
|
||
Host: {fqdn}
|
||
```
|
||
|
||
**Request Parameters**:
|
||
|
||
| 参数 | 描述 | 类型 | 示例 | 必填 |
|
||
|---|---|---|---|---|
|
||
| `uid` | 其下 subuser 待移除的用户 ID | String | `foo_user` | Yes |
|
||
| `subuser` | 待移除的 subuser ID | String | `sub_foo` | Yes |
|
||
| `purge-keys` | 移除属于该 subuser 的 key | Boolean | True [True] | No |
|
||
|
||
**Response Entities**:None. **Special Error Responses**:None.
|
||
|
||
### 7.17 Create Key
|
||
|
||
`:caps: users=write`
|
||
|
||
> 创建新 key。若指定了 `subuser`,则默认创建的 key 为 swift 类型。若只提供 `access-key` 或 `secret-key` 之一,则省略的那个会自动生成。默认情况下,生成的 key 被加入 keyring 而不替换已有 key 对。若指定了 `access-key` 且指向该用户已拥有的 key,则该 key 会被修改。**响应是一个容器,列出与所创建 key 同类型的所有 key。** 注意:**创建 swift key 时指定 `access-key` 选项无效**。此外,**每个 user 或 subuser 只能持有一个 swift key**。
|
||
|
||
```http
|
||
PUT /{admin}/user?key&format=json HTTP/1.1
|
||
Host: {fqdn}
|
||
```
|
||
|
||
**Request Parameters**:
|
||
|
||
| 参数 | 描述 | 类型 | 示例 | 必填 |
|
||
|---|---|---|---|---|
|
||
| `uid` | 接收新 key 的用户 ID | String | `foo_user` | Yes |
|
||
| `subuser` | 接收新 key 的 subuser ID | String | `sub_foo` | No |
|
||
| `key-type` | 要生成的 key 类型,选项 `swift`、`s3`(默认) | String | `s3` [`s3`] | No |
|
||
| `access-key` | 指定 access key | String | `AB01C2D3EF45G6H7IJ8K` | No |
|
||
| `secret-key` | 指定 secret key | String | `0ab/CdeFGhij1klmnopqRSTUv1WxyZabcDEFgHij` | No |
|
||
| `generate-key` | 生成新 key 对并加入已有 keyring | Boolean | True [True] | No |
|
||
| `active` | 激活或停用某个 key | Boolean | True [True] | No |
|
||
|
||
**Response Entities**:
|
||
|
||
| 实体 | 描述 | 类型 | Parent |
|
||
|---|---|---|---|
|
||
| `keys` | 与该用户账号关联的、所创建类型的 key | Container | — |
|
||
| `user` | 与 key 关联的用户账号 | String | `keys` |
|
||
| `access-key` | access key | String | `keys` |
|
||
| `secret-key` | secret key | String | `keys` |
|
||
|
||
**Special Error Responses**:`InvalidAccessKey`(400)、`InvalidKeyType`(400)、`InvalidSecretKey`(400)、`KeyExists`(409)。
|
||
|
||
### 7.18 Remove Key
|
||
|
||
`:caps: users=write`
|
||
|
||
```http
|
||
DELETE /{admin}/user?key&format=json HTTP/1.1
|
||
Host: {fqdn}
|
||
```
|
||
|
||
**Request Parameters**:
|
||
|
||
| 参数 | 描述 | 类型 | 示例 | 必填 |
|
||
|---|---|---|---|---|
|
||
| `access-key` | 待移除的 S3 key 对的 access key | String | `AB01C2D3EF45G6H7IJ8K` | Yes |
|
||
| `uid` | 要从其移除 key 的用户 | String | `foo_user` | No |
|
||
| `subuser` | 要从其移除 key 的 subuser | String | `sub_foo` | No |
|
||
| `key-type` | 待移除的 key 类型,选项 `swift`、`s3`。**注意:移除 swift key 时必需** | String | `swift` | No |
|
||
|
||
**Special Error Responses**:None. **Response Entities**:None.
|
||
|
||
### 7.19 Get Bucket Info
|
||
|
||
`:caps: buckets=read`
|
||
|
||
> 获取已有 bucket 子集的信息。若指定了 `uid` 而未指定 `bucket`,则返回该用户拥有的**所有** bucket。若只指定 `bucket`,则检索该特定 bucket 的信息。
|
||
> 若指定 `max-entries` 限制返回 bucket 数,**响应体结构会变化**,包含 `buckets`、`count` 和 `truncated` 三个 key;若 `truncated` 为 true 还会加入 `marker` key。
|
||
|
||
```http
|
||
GET /{admin}/bucket?format=json HTTP/1.1
|
||
Host: {fqdn}
|
||
```
|
||
|
||
**Request Parameters**:
|
||
|
||
| 参数 | 描述 | 类型 | 示例 | 必填 |
|
||
|---|---|---|---|---|
|
||
| `bucket` | 要返回信息的 bucket | String | `foo_bucket` | No |
|
||
| `uid` | 要检索 bucket 信息的用户 | String | `foo_user` | No |
|
||
| `stats` | 返回 bucket 统计信息 | Boolean | True [False] | No |
|
||
| `max-entries` | 要返回的 bucket 列表条目数 | Integer | 100 | No |
|
||
| `marker` | 列举 bucket 时使用的 marker | String (bucket name) | `my-bucket` | No |
|
||
|
||
**Response Entities**:
|
||
|
||
| 实体 | 描述 | 类型 | Parent |
|
||
|---|---|---|---|
|
||
| `stats` | 每 bucket 信息 | Container | — |
|
||
| `buckets` | 包含一个或多个 bucket 容器的列表 | Container | — |
|
||
| `bucket` | 单个 bucket 信息的容器 | Container | `buckets` |
|
||
| `name` | bucket 名 | String | `bucket` |
|
||
| `pool` | bucket 存储所在的 pool | String | `bucket` |
|
||
| `id` | 唯一的 bucket id | String | `bucket` |
|
||
| `marker` | 内部 bucket tag | String | `bucket` |
|
||
| `owner` | bucket owner 的用户 id | String | `bucket` |
|
||
| `usage` | 存储用量信息 | Container | `bucket` |
|
||
| `index` | bucket index 的状态 | String | `bucket` |
|
||
| `count` | 返回的 bucket 数,仅在指定 `max-entries` 时出现 | Integer | — |
|
||
| `truncated` | 仅在指定 `max-entries` 时,若响应被截断则为 true | Boolean | — |
|
||
| `marker` | 若 `truncated` 为 true,返回用于继续分页的 marker(bucket 名) | String | — |
|
||
|
||
**Special Error Responses**:`IndexRepairFailed`(Bucket index repair failed,409 Conflict)。
|
||
|
||
### 7.20 Check Bucket Index
|
||
|
||
`:caps: buckets=write`
|
||
|
||
> 检查已有 bucket 的 index。**注意:要用 `check-objects` 检查 multipart 对象计数,必须把 `fix` 设为 True。**
|
||
|
||
```http
|
||
GET /{admin}/bucket?index&format=json HTTP/1.1
|
||
Host: {fqdn}
|
||
```
|
||
|
||
**Request Parameters**:
|
||
|
||
| 参数 | 描述 | 类型 | 示例 | 必填 |
|
||
|---|---|---|---|---|
|
||
| `bucket` | 要返回信息的 bucket | String | `foo_bucket` | Yes |
|
||
| `check-objects` | 检查 multipart 对象计数 | Boolean | True [False] | No |
|
||
| `fix` | 检查时同时修复 bucket index | Boolean | False [False] | No |
|
||
|
||
**Response Entities**:`index`(Status of bucket index,String)。
|
||
|
||
**Special Error Responses**:`IndexRepairFailed`(409)。
|
||
|
||
### 7.21 Remove Bucket
|
||
|
||
`:caps: buckets=write`
|
||
|
||
```http
|
||
DELETE /{admin}/bucket?format=json HTTP/1.1
|
||
Host: {fqdn}
|
||
```
|
||
|
||
**Request Parameters**:
|
||
|
||
| 参数 | 描述 | 类型 | 示例 | 必填 |
|
||
|---|---|---|---|---|
|
||
| `bucket` | 待移除的 bucket | String | `foo_bucket` | Yes |
|
||
| `tenant` | bucket 所属的 tenant | String | `tenant1` | No |
|
||
| `purge-objects` | 删除前先移除 bucket 的对象 | Boolean | True [False] | No |
|
||
| `bypass-gc` | 绕过垃圾回收 | Boolean | True [False] | No |
|
||
|
||
**Response Entities**:None.
|
||
|
||
**Special Error Responses**:`BucketNotEmpty`(尝试删除非空 bucket,409)、`ObjectRemovalFailed`(无法移除对象,409)。
|
||
|
||
### 7.22 Unlink Bucket
|
||
|
||
`:caps: buckets=write` — 把 bucket 从指定用户**解绑**(主要用于变更 bucket 归属)。
|
||
|
||
```http
|
||
POST /{admin}/bucket?format=json HTTP/1.1
|
||
Host: {fqdn}
|
||
```
|
||
|
||
**Request Parameters**:
|
||
|
||
| 参数 | 描述 | 类型 | 示例 | 必填 |
|
||
|---|---|---|---|---|
|
||
| `bucket` | 待解绑的 bucket | String | `foo_bucket` | Yes |
|
||
| `uid` | 要从其解绑 bucket 的用户 ID | String | `foo_user` | Yes |
|
||
|
||
**Response Entities**:None. **Special Error Responses**:`BucketUnlinkFailed`(409)。
|
||
|
||
### 7.23 Link Bucket
|
||
|
||
`:caps: buckets=write` — 把 bucket 链接到指定用户,并**从任何之前的用户解绑**。
|
||
|
||
```http
|
||
PUT /{admin}/bucket?format=json HTTP/1.1
|
||
Host: {fqdn}
|
||
```
|
||
|
||
**Request Parameters**:
|
||
|
||
| 参数 | 描述 | 类型 | 示例 | 必填 |
|
||
|---|---|---|---|---|
|
||
| `bucket` | 待(重新)链接的 bucket 名 | String | `foo_bucket` | Yes |
|
||
| `bucket-id` | 待(重新)链接的 bucket id | String | `dev.6607669.420` | No |
|
||
| `uid` | 要链接到的用户 ID | String | `foo_user` | Yes |
|
||
|
||
**Response Entities**:`bucket` 容器 → `name`、`pool`、`id`、`marker`、`owner`、`usage`、`index`(Parent 均为 `bucket`)。
|
||
|
||
**Special Error Responses**:`BucketUnlinkFailed`(409)、`BucketLinkFailed`(409)。
|
||
|
||
### 7.24 Remove Object
|
||
|
||
`:caps: buckets=write` — **注意:不要求 owner 处于非 suspended 状态。**
|
||
|
||
```http
|
||
DELETE /{admin}/bucket?object&format=json HTTP/1.1
|
||
Host: {fqdn}
|
||
```
|
||
|
||
**Request Parameters**:
|
||
|
||
| 参数 | 描述 | 类型 | 示例 | 必填 |
|
||
|---|---|---|---|---|
|
||
| `bucket` | 包含待移除对象的 bucket | String | `foo_bucket` | Yes |
|
||
| `object` | 待移除的对象 | String | `foo.txt` | Yes |
|
||
|
||
**Response Entities**:None. **Special Error Responses**:`NoSuchObject`(404)、`ObjectRemovalFailed`(409)。
|
||
|
||
### 7.25 Get Bucket or Object Policy
|
||
|
||
`:caps: buckets=read`
|
||
|
||
```http
|
||
GET /{admin}/bucket?policy&format=json HTTP/1.1
|
||
Host: {fqdn}
|
||
```
|
||
|
||
**Request Parameters**:
|
||
|
||
| 参数 | 描述 | 类型 | 示例 | 必填 |
|
||
|---|---|---|---|---|
|
||
| `bucket` | 要读取 policy 的 bucket | String | `foo_bucket` | Yes |
|
||
| `object` | 要读取 policy 的对象 | String | `foo.txt` | No |
|
||
|
||
**Response Entities**:`policy`(Access control policy,Container)。
|
||
|
||
**Special Error Responses**:`IncompleteBody`(bucket policy 请求未指定 bucket,或 object policy 请求未指定 bucket 与 object,400)。
|
||
|
||
### 7.26 Add A User Capability
|
||
|
||
`:caps: users=write`
|
||
|
||
```http
|
||
PUT /{admin}/user?caps&format=json HTTP/1.1
|
||
Host: {fqdn}
|
||
```
|
||
|
||
**Request Parameters**:
|
||
|
||
| 参数 | 描述 | 类型 | 示例 | 必填 |
|
||
|---|---|---|---|---|
|
||
| `uid` | 要添加管理能力的用户 ID | String | `foo_user` | Yes |
|
||
| `user-caps` | 要添加到该用户的管理能力 | String | `usage=read,write;user=write` | Yes |
|
||
|
||
**Response Entities**:`user` 容器 → `user_id`、`caps`。
|
||
|
||
**Special Error Responses**:`InvalidCapability`(400)。
|
||
|
||
**Example Request**:
|
||
|
||
```http
|
||
PUT /{admin}/user?caps&user-caps=usage=read,write;user=write&format=json HTTP/1.1
|
||
Host: {fqdn}
|
||
Content-Type: text/plain
|
||
Authorization: {your-authorization-token}
|
||
```
|
||
|
||
### 7.27 Remove A User Capability
|
||
|
||
`:caps: users=write`
|
||
|
||
```http
|
||
DELETE /{admin}/user?caps&format=json HTTP/1.1
|
||
Host: {fqdn}
|
||
```
|
||
|
||
**Request Parameters**:
|
||
|
||
| 参数 | 描述 | 类型 | 示例 | 必填 |
|
||
|---|---|---|---|---|
|
||
| `uid` | 要移除管理能力的用户 ID | String | `foo_user` | Yes |
|
||
| `user-caps` | 要从该用户移除的管理能力 | String | `usage=read, write` | Yes |
|
||
|
||
**Response Entities**:`user` 容器 → `user_id`、`caps`。
|
||
|
||
**Special Error Responses**:`InvalidCapability`(400)、`NoSuchCap`(用户不具备指定的能力,404)。
|
||
|
||
### 7.28 Quotas(配额)
|
||
|
||
Admin Operations API 允许在 **user**、user 拥有的 **bucket**、**account**、以及 account 拥有的 **bucket** 上设置配额。配额包括 bucket 中的最大对象数与最大存储大小(MB)。
|
||
|
||
**能力要求**:
|
||
|
||
| 对象 | 查看 | 设置/修改/禁用 |
|
||
|---|---|---|
|
||
| user / user 的 bucket | `users=read` | `users=write` |
|
||
| account / account 的 bucket | `accounts=read` | `accounts=write` |
|
||
|
||
**合法参数**:
|
||
|
||
| 参数 | 说明 |
|
||
|---|---|
|
||
| `bucket` | 为某用户拥有的 bucket 指定配额 |
|
||
| `max-objects` | 最大对象数。**负值禁用**该设置 |
|
||
| `max-size` | 最大字节数配额;`max-size-kb` 以 KiB 指定。**负值禁用** |
|
||
| `quota-type` | 配额作用域。user 级配额可选 `bucket`、`user`;account 级配额可选 `bucket`、`account` |
|
||
| `enabled` | 是否启用配额,值为 `'True'` 或 `'False'` |
|
||
|
||
**各操作**:
|
||
|
||
| 操作 | 方法与路径 | 说明 |
|
||
|---|---|---|
|
||
| Get User Quota | `GET /admin/user?quota&uid=<uid>"a-type=user` | 需要 `users=read` |
|
||
| Set User Quota | `PUT /admin/user?quota&uid=<uid>"a-type=user` | 需要 `users=write`。**请求体内容必须包含对应读操作所编码的配额设置的 JSON 表示** |
|
||
| Get Bucket Quota | `GET /admin/user?quota&uid=<uid>"a-type=bucket` | 需要 `users=read` |
|
||
| Set Bucket Quota | `PUT /admin/user?quota&uid=<uid>"a-type=bucket` | 需要 `users=write`。请求体同上 |
|
||
| Set Quota for an Individual Bucket | `PUT /admin/bucket?quota&uid=<uid>&bucket=<bucket-name>` | 需要 `buckets=write`。请求体同上 |
|
||
| Set Account Quota | `PUT /admin/account?quota&id=<account_id>"a-type=account` | 需要 `accounts=write` |
|
||
| Set Bucket Quota under an Account | `PUT /admin/account?quota&id=<account_id>"a-type=bucket` | 需要 `accounts=write` |
|
||
|
||
### 7.29 Rate Limit(限流)
|
||
|
||
Admin Operations API 允许在 user、bucket 上设置/获取限流配置,以及全局限流配置。限流包括:每分钟的最大操作数和/或字节数(区分读/写),作用于 bucket 和/或 user,以及最大存储大小(MB)。
|
||
|
||
**能力要求**:查看需 `ratelimit=read`;设置/修改/禁用需 `ratelimit=write`。
|
||
|
||
**合法参数**:
|
||
|
||
| 参数 | 说明 |
|
||
|---|---|
|
||
| `bucket` | 为某 bucket 指定限流 |
|
||
| `uid` | 为某 user 指定限流 |
|
||
| `max-read-bytes` | 每分钟最大读字节数。`0` 禁用 |
|
||
| `max-write-bytes` | 每分钟最大写字节数。`0` 禁用 |
|
||
| `max-read-ops` | 每分钟最大读操作次数。`0` 禁用 |
|
||
| `max-write-ops` | 每分钟最大写操作次数。`0` 禁用 |
|
||
| `global` | 是否指定全局限流,值为 `'True'` 或 `'False'` |
|
||
| `ratelimit-scope` | 限流作用域,可选 `bucket`、`user`、`anonymous`。**`anonymous` 仅对设置 global 配置有效** |
|
||
| `enabled` | 是否启用限流,值为 `'True'` 或 `'False'` |
|
||
|
||
**各操作(源文原文语法)**:
|
||
|
||
| 操作 | 语法 | 所需 caps |
|
||
|---|---|---|
|
||
| Get User Rate Limit | `GET /{admin}/ratelimit?ratelimit-scope=user&uid=<uid>` | `ratelimit=read` |
|
||
| Set User Rate Limit | `POST /{admin}/ratelimit?ratelimit-scope=user&uid=<uid><[&max-read-bytes=<bytes>][&max-write-bytes=<bytes>][&max-read-ops=<ops>][&max-write-ops=<ops>][enabled=<True\|False>]>` | `ratelimit=write` |
|
||
| Get Bucket Rate Limit | `GET /{admin}/ratelimit?bucket=<bucket>&ratelimit-scope=bucket` | `users=read`(源文如此表述) |
|
||
| Set Rate Limit for an Individual Bucket | `POST /{admin}/ratelimit?bucket=<bucket-name>&ratelimit-scope=bucket<[&max-read-bytes=<bytes>][&max-write-bytes=<bytes>][&max-read-ops=<ops>][&max-write-ops=<ops>]>` | `ratelimit=write` |
|
||
| Get Global Rate Limit | `GET /{admin}/ratelimit?global=<True\|False>` | `ratelimit=read` |
|
||
| Set Global User Rate Limit | `POST /{admin}/ratelimit?ratelimit-scope=user&global=<True\|False><[&max-read-bytes=<bytes>][&max-write-bytes=<bytes>][&max-read-ops=<ops>][&max-write-ops=<ops>][enabled=<True\|False>]>` | `ratelimit=write` |
|
||
| Set Global Rate Limit Bucket | `POST /{admin}/ratelimit?ratelimit-scope=bucket&global=<True\|False><[&max-read-bytes=<bytes>][&max-write-bytes=<bytes>][&max-read-ops=<ops>][&max-write-ops=<ops>]>` | `ratelimit=write` |
|
||
| Set Global Anonymous User Rate Limit | `POST /{admin}/ratelimit?ratelimit-scope=anon&global=<True\|False><[&max-read-bytes=<bytes>][&max-write-bytes=<bytes>][&max-read-ops=<ops>][&max-write-ops=<ops>][enabled=<True\|False>]>` | `ratelimit=write` |
|
||
|
||
### 7.30 Standard Error Responses
|
||
|
||
| 错误 | 描述 | Code |
|
||
|---|---|---|
|
||
| `AccessDenied` | Access denied | 403 Forbidden |
|
||
| `InternalError` | Internal server error | 500 Internal Server Error |
|
||
| `NoSuchUser` | User does not exist | 404 Not Found |
|
||
| `NoSuchBucket` | Bucket does not exist | 404 Not Found |
|
||
| `NoSuchKey` | No such access key | 404 Not Found |
|
||
|
||
### 7.31 绑定库(Binding libraries)
|
||
|
||
官方在 `adminops.rst` 末尾列出的第三方 Admin Ops API 绑定库:
|
||
|
||
| 语言 | 项目 |
|
||
|---|---|
|
||
| Golang | `ceph/go-ceph`、`IrekFasikhov/go-rgwadmin`、`QuentinPerez/go-radosgw` |
|
||
| Java | `twonote/radosgw-admin4j` |
|
||
| PHP | `lbausch/php-ceph-radosgw-admin`、`myENA/php-rgw-api` |
|
||
| Python | `UMIACS/rgwadmin`、`valerytschopp/python-radosgw-admin` |
|
||
|
||
> 引自:[Admin Ops API](https://docs.ceph.com/en/tentacle/radosgw/adminops/)
|
||
|
||
---
|
||
|
||
## 八、账号(User Accounts)
|
||
|
||
来源:`account.rst` 全文(11KB)。`versionadded:: Squid`
|
||
|
||
### 8.1 account 是什么
|
||
|
||
Ceph 对象网关支持 **user accounts** 作为**可选特性**,用于实现类似 **AWS IAM** 的 Users、Groups、Roles 的自助管理。
|
||
|
||
**Account Root User(账号根用户)**:
|
||
|
||
- 每个 account 由一个 **account root user** 管理。
|
||
- 与普通 user、role 一样,**account 与 account root user 必须由管理员使用 `radosgw-admin` 或 Admin Ops API 创建**。
|
||
- account root user 对 account 拥有的所有资源有默认权限。
|
||
- root user 的凭据(access/secret key)可用于 **IAM API** 创建额外的 IAM user 与 role,以配合 S3 API 使用,并管理其 access key 与 policy。
|
||
- 官方建议:**account owner 应把 root user 只用于管理**,并为具体应用创建具有细粒度权限的 user 与 role。
|
||
- ⚠️ 警告:虽然 account root user 访问 account 内资源**不需要** IAM policy,但**可以**添加显示 Deny 的策略阻止其访问。使用 Deny 语句要谨慎。
|
||
|
||
### 8.2 account 与 user 的区别(核心差异表)
|
||
|
||
| 维度 | 普通(非 account)user | account 下的 user / role |
|
||
|---|---|---|
|
||
| 资源归属 | 该 user 自己拥有其创建的 bucket 与上传的对象 | 资源由 **account 本身**拥有 |
|
||
| S3 ACL 中的 owner/grantee | 该 user | **account id** |
|
||
| `s3:ListBuckets` 可见性 | 只有该 owner user 能看到 | **该 account 下的任何 user 或 role** 都能看到 |
|
||
| 用量统计与配额执行 | 作用于单个 user | 作用于 **account 整体**,而非其各个 user |
|
||
| 默认权限 | 允许创建 bucket 与上传对象 | **默认无任何权限**(start with no permissions at all) |
|
||
|
||
**IAM Policy 的必要性**:在 account user 能执行 API 操作之前,**必须**添加某些 policy 允许之。account root user 可以通过以下几种方式为其 user 添加 identity policy:
|
||
|
||
| 方式 | 使用的 action |
|
||
|---|---|
|
||
| 直接给用户加 policy | `iam:PutUserPolicy`、`iam:AttachUserPolicy` |
|
||
| 创建 IAM group 并加组策略,再把用户加入组 | `iam:PutGroupPolicy`、`iam:AttachGroupPolicy` + `iam:AddUserToGroup`;加入组的用户继承组的全部 policy |
|
||
| 创建 IAM role 并加角色策略,用户 assume 该 role | `iam:PutRolePolicy`、`iam:AttachRolePolicy` + `sts:AssumeRole` / `sts:AssumeRoleWithWebIdentity`;assume 该 role 的用户继承 role 的全部 policy |
|
||
|
||
这些 identity policy 的求值遵循 AWS 的 `Evaluating policies within a single account` 与 `Cross-account policy evaluation logic` 规则。
|
||
|
||
### 8.3 Account IDs
|
||
|
||
- 为避免歧义,Account ID 采用特殊格式:**字符串 `RGW` + 17 位数字**,例如 `RGW33567154695143645`。
|
||
- 创建 account 时若未指定 ID,会**随机生成**一个符合该格式的 ID。
|
||
- Account ID 常见于 IAM policy 文档的 **ARN** 中。例如 `arn:aws:iam::RGW33567154695143645:user/A` 指该 account 中名为 A 的 IAM 用户。**Ceph 对象网关在该位置也支持 tenant 名。**
|
||
- Account ID 也可以用在 ACL 中类型为 **`CanonicalUser`** 的 `Grantee` 上(此处同样支持 User ID)。
|
||
|
||
**Principals 的差异**:
|
||
|
||
| 场景 | Principal ARN 形式 | 对应 radosgw-admin 参数 |
|
||
|---|---|---|
|
||
| account 之外 | `arn:aws:iam:::user/uid` 或 `arn:aws:iam::tenantname:user/uid` | `uid` 对应 `--uid` |
|
||
| account 之内(account user) | `arn:aws:iam::RGW33567154695143645:user/name`,用**用户名** | `name` 对应 `--display-name` |
|
||
|
||
> Account user **继续匹配 tenant 形式**,这样当用户被迁入 account 时已有 policy 仍能工作。
|
||
|
||
### 8.4 租户隔离(Tenant Isolation)
|
||
|
||
- 与 user 一样,account 可以**可选地**属于某个 tenant,以实现 bucket 的命名空间隔离。例如 tenant "a" 下可以有一个名为 "acct" 的 account,tenant "b" 下也可以有一个名为 "acct" 的不同 account。
|
||
- **一个带 tenant 的 account 只能包含同名的 tenant 下的 user。**
|
||
- **无论 tenant 如何,account ID 与 email 地址必须全局唯一。**
|
||
|
||
### 8.5 账号操作命令
|
||
|
||
| 操作 | 命令 |
|
||
|---|---|
|
||
| 创建 account | `radosgw-admin account create [--account-name={name}] [--account-id={id}] [--email={email}]` |
|
||
| 创建 account root user | `radosgw-admin user create --uid={userid} --display-name={name} --account-id={accountid} --account-root --gen-secret --gen-access-key` |
|
||
| 删除 account | `radosgw-admin account rm --account-id={accountid}` |
|
||
| 查看 account 统计 | `radosgw-admin account stats --account-id={accountid} --sync-stats` |
|
||
| 启用 account 配额 | `radosgw-admin quota set --quota-scope=account --account-id={accountid} --max-size=10G` + `radosgw-admin quota enable --quota-scope=account --account-id={accountid}` |
|
||
| 启用 account 的 bucket 配额 | `radosgw-admin quota set --quota-scope=bucket --account-id={accountid} --max-objects=1000000` + `radosgw-admin quota enable --quota-scope=bucket --account-id={accountid}` |
|
||
| 把已有 user 迁入 account | `radosgw-admin user modify --uid={userid} --account-id={accountid}` |
|
||
|
||
完整示例:
|
||
|
||
```bash
|
||
# 1) 创建账号
|
||
radosgw-admin account create --account-name=acct1 --email=acct1@example.com
|
||
|
||
# 2) 创建该账号的 root user
|
||
radosgw-admin user create --uid=acct1root --display-name="Acct1 Root" \
|
||
--account-id=RGW00000000000000001 --account-root --gen-secret --gen-access-key
|
||
|
||
# 3) 查看账号统计
|
||
radosgw-admin account stats --account-id=RGW00000000000000001 --sync-stats
|
||
|
||
# 4) 设置账号配额并启用
|
||
radosgw-admin quota set --quota-scope=account --account-id=RGW00000000000000001 --max-size=10G
|
||
radosgw-admin quota enable --quota-scope=account --account-id=RGW00000000000000001
|
||
|
||
# 5) 设置账号的 bucket 级配额并启用
|
||
radosgw-admin quota set --quota-scope=bucket --account-id=RGW00000000000000001 --max-objects=1000000
|
||
radosgw-admin quota enable --quota-scope=bucket --account-id=RGW00000000000000001
|
||
|
||
# 6) 删除账号
|
||
radosgw-admin account rm --account-id=RGW00000000000000001
|
||
```
|
||
|
||
### 8.6 迁移已有用户到 account
|
||
|
||
```bash
|
||
radosgw-admin user modify --uid={userid} --account-id={accountid}
|
||
```
|
||
|
||
**迁移注意事项(官方 note / warning 原文要点)**:
|
||
|
||
1. **该用户的所有 bucket 的所有权将转移给 account。**
|
||
2. **account 成员身份是永久的。一旦加入,用户无法从其 account 中移除。**
|
||
3. **IAM User API 对 `UserName` 的格式有额外要求**,在把用户迁入 account 时会被强制检查。若迁移失败并报 "UserName contains invalid characters",应把 `--display-name` 修改为匹配 `[\w+=,.@-]+`。
|
||
4. ⚠️ **该用户的 notification topics 的所有权不会转移给 account。** 通知仍然工作,但这些 topic 对 SNS Topic API 不再可见。topic 及其关联的 bucket notification 需要另行迁移(见下)。
|
||
5. 因为 account user 默认无任何权限,**必须**添加某些 identity policy 以恢复用户原有权限。
|
||
6. 另一种做法:为每个已有用户创建一个新的 account,此时可以加 `--account-root` 选项让每个用户成为其 account 的 root user。
|
||
|
||
#### 迁移 Notification Topics 的步骤
|
||
|
||
Account topics **仅在启用 `notification_v2` feature 时**才受支持(详见 `radosgw-notifications` 与 `Supported Zone Features`,属第 12 册/第 10 册范畴)。
|
||
|
||
1. **迁移影响**:非 account user 迁入 account 后,其已有 notification topics 仍可通过 **RADOS Gateway admin API** 访问,但用户**无法通过 SNS Topic API 访问**它们。尽管如此,topic 仍可用,bucket notification 仍会按预期投递。
|
||
2. **重建 topics**:account user 应使用**相同的名字**重新创建 topic。旧 topic(现已不可访问)与新的 account-owned topic 可以共存且互不干扰。
|
||
3. **更新 bucket notification 配置**:订阅了旧 user-owned topic 的 bucket 应更新为使用新的 account-owned topic。**为避免重复通知,应保持相同的 notification ID。**
|
||
|
||
旧配置:
|
||
|
||
```json
|
||
{"TopicConfigurations": [{ "Id": "ID1", "TopicArn": "arn:aws:sns:default::topic1", "Events": ["s3:ObjectCreated:*"]}]}
|
||
```
|
||
|
||
新配置(其中 `RGW00000000000000001` 是 account ID,`topic1` 是 topic 名,`ID1` 是 notification ID):
|
||
|
||
```json
|
||
{"TopicConfigurations": [{ "Id": "ID1", "TopicArn": "arn:aws:sns:default:RGW00000000000000001:topic1", "Events": ["s3:ObjectCreated:*"]}]}
|
||
```
|
||
|
||
4. **移除旧 topics**:一旦没有 bucket 订阅旧 user-owned topic,可由 admin 移除:
|
||
|
||
```bash
|
||
radosgw-admin topic rm --topic topic1
|
||
```
|
||
|
||
### 8.7 Account Root User 实操示例(awscli)
|
||
|
||
官方给出的完整流程(源文原文):
|
||
|
||
```bash
|
||
# 1) 为 account root user 创建 profile
|
||
$ aws --profile rgwroot configure set endpoint_url http://localhost:8000
|
||
$ aws --profile rgwroot configure
|
||
AWS Access Key ID [None]: {root access key}
|
||
AWS Secret Access Key [None]: {root secret key}
|
||
Default region name [None]: default
|
||
Default output format [None]:
|
||
|
||
# 2) 创建 IAM user、添加凭据、附加 S3 访问策略
|
||
$ aws --profile rgwroot iam create-user --user-name Alice
|
||
{
|
||
"User": {
|
||
"Path": "/",
|
||
"UserName": "Alice",
|
||
"UserId": "b580aa8e-14c7-4b6a-9dac-a30c640244b6",
|
||
"Arn": "arn:aws:iam::RGW63136524507535818:user/Alice",
|
||
"CreateDate": "2024-02-07T00:15:45.162786+00:00"
|
||
}
|
||
}
|
||
$ aws --profile rgwroot iam create-access-key --user-name Alice
|
||
{
|
||
"AccessKey": {
|
||
"UserName": "Alice",
|
||
"AccessKeyId": "JBNLYD5BDNRVV64J02E8",
|
||
"Status": "Active",
|
||
"SecretAccessKey": "SnHoE700kdNuT22K8Bhy2iL3DwZU0sUSDI1gUXHr",
|
||
"CreateDate": "2024-02-07T00:16:34.679316+00:00"
|
||
}
|
||
}
|
||
$ aws --profile rgwroot iam attach-user-policy --user-name Alice \
|
||
--policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess
|
||
|
||
# 3) 为 S3 user 创建 profile
|
||
$ aws --profile rgws3 configure set endpoint_url http://localhost:8000
|
||
$ aws --profile rgws3 configure
|
||
AWS Access Key ID [None]: JBNLYD5BDNRVV64J02E8
|
||
AWS Secret Access Key [None]: SnHoE700kdNuT22K8Bhy2iL3DwZU0sUSDI1gUXHr
|
||
Default region name [None]: default
|
||
Default output format [None]:
|
||
|
||
# 4) 用 S3 user profile 创建 bucket
|
||
$ aws --profile rgws3 s3 mb s3://testbucket
|
||
make_bucket: testbucket
|
||
```
|
||
|
||
> 引自:[User Accounts](https://docs.ceph.com/en/tentacle/radosgw/account/)
|
||
|
||
---
|
||
|
||
## 九、多租户(Multi-tenancy)
|
||
|
||
来源:`multitenancy.rst` 全文。`versionadded:: Jewel`
|
||
|
||
### 9.1 概念
|
||
|
||
多租户特性允许**同名**的 bucket 与 user 同时存在,方法是把它们隔离在所谓的 **`tenants`** 之下。举例用途:允许 Swift API 用户创建容易冲突的名字(如 "test" 或 "trove")的 bucket。
|
||
|
||
关键规则(源文原文):
|
||
|
||
- 自 Jewel 起,**每个 user 和 bucket 都位于某个 tenant 之下**。
|
||
- 为兼容起见,提供了一个名为**空**的 "legacy" tenant。
|
||
- 每当引用 bucket 而没有显式 tenant 时,会使用**隐式 tenant**,取自执行操作的用户。
|
||
- 由于**已有用户位于 legacy tenant 之下**,他们继续像以前一样创建和访问 bucket。
|
||
- RADOS 中的对象布局以**兼容方式**扩展,确保平滑升级到 Jewel。
|
||
|
||
### 9.2 管理带显式 tenant 的用户
|
||
|
||
**Tenant 本身没有任何操作(Tenants as such do not have any operations on them)。** 它们随着用户的管理而按需出现和消失。
|
||
|
||
创建、修改、删除带显式 tenant 的用户有两种方式:
|
||
|
||
| 方式 | 说明 |
|
||
|---|---|
|
||
| `--tenant` 选项 | 额外的命令行选项 |
|
||
| `'<tenant>$<user>'` 语法 | 在 `radosgw-admin` 命令的参数中使用 |
|
||
|
||
**示例**:
|
||
|
||
```bash
|
||
# 创建一个用 S3 访问的 user testx$tester
|
||
# radosgw-admin --tenant testx --uid tester --display-name "Test User" --access_key TESTER --secret test123 user create
|
||
|
||
# 创建一个用 Swift 访问的 user testx$tester
|
||
# radosgw-admin --tenant testx --uid tester --display-name "Test User" --subuser tester:test --key-type swift --access full user create
|
||
# radosgw-admin --subuser 'testx$tester:test' --key-type swift --secret test123
|
||
```
|
||
|
||
> **注意**:带显式 tenant 的 subuser 在 shell 中**必须加引号**。
|
||
> **Tenant 名只能包含字母数字字符和下划线。**
|
||
|
||
### 9.3 访问带显式 tenant 的 bucket
|
||
|
||
客户端应用访问 bucket 时,总是使用某个特定用户的凭据。每个用户属于一个 tenant。因此**每个操作在其上下文中都有一个隐式 tenant**,在未显式指定 tenant 时使用它。只要被引用的 bucket 与引用它的用户属于同一个 tenant,就**完全保持与之前版本的兼容**——只有在访问**另一个** tenant 的 bucket 时才会出现异常。
|
||
|
||
#### 9.3.1 S3
|
||
|
||
S3 中用**冒号**分隔 tenant 与 bucket:
|
||
|
||
```text
|
||
https://ep.host.dom/tenant:bucket
|
||
```
|
||
|
||
Python 示例(源文原文):
|
||
|
||
```python
|
||
from boto.s3.connection import S3Connection, OrdinaryCallingFormat
|
||
c = S3Connection(
|
||
aws_access_key_id="TESTER",
|
||
aws_secret_access_key="test123",
|
||
host="ep.host.dom",
|
||
calling_format = OrdinaryCallingFormat())
|
||
bucket = c.get_bucket("test5b:testbucket")
|
||
```
|
||
|
||
**重要限制(源文原文)**:
|
||
|
||
- **无法通过 hostname 提供显式 tenant**。Hostname 不能包含冒号,也不能包含任何在 bucket 名中尚未合法的分隔符;用句点会产生歧义语法。因此**必须使用 bucket-in-URL-path 格式**。
|
||
- 由于**原生 S3 API 不处理多租户而 radosgw 的实现处理**,在签名 URL 与 public read ACL 场景下会有点复杂:
|
||
|
||
| 场景 | 规则 |
|
||
|---|---|
|
||
| **签名 URL(signed URL)** | 签名 URL 包含 `AWSAccessKeyId` 查询参数,radosgw 能据此判断拥有该 bucket 的正确 user 和 tenant。因此生成签名 URL 的应用**可以只使用不带前缀的 bucket 名**(也可以选择包含前缀)。 |
|
||
| **public read ACL 的 bucket** | 这种对象是被**不带任何查询参数**的 HTTP 客户端读取的,radosgw 无从判断 tenant。因此**可公开读的对象必须始终使用带 tenant 前缀的 bucket 名访问**。 |
|
||
|
||
具体例子(源文原文):
|
||
|
||
- 签名 URL(对象 `bar` 在 container `foo`,tenant `7188e165c0ae4424ac68ae2e89a05c50`)——两种形式都可以:
|
||
|
||
```text
|
||
http://<host>:<port>/foo/bar?AWSAccessKeyId=b200fb6634c547199e436a0f93c0c46e&Expires=1542890806&Signature=eok6CYQC%2FDwmQQmqvY5jTg6ehXU%3D
|
||
http://<host>:<port>/7188e165c0ae4424ac68ae2e89a05c50:foo/bar?AWSAccessKeyId=b200fb6634c547199e436a0f93c0c46e&Expires=1542890806&Signature=eok6CYQC%2FDwmQQmqvY5jTg6ehXU%3D
|
||
```
|
||
|
||
取决于签名生成时是否传入了 tenant 前缀。
|
||
|
||
- public read ACL(同上对象)——**必须**带前缀:
|
||
|
||
```text
|
||
http://<host>:<port>/7188e165c0ae4424ac68ae2e89a05c50:foo/bar
|
||
```
|
||
|
||
#### 9.3.2 Swift with built-in authenticator
|
||
|
||
**TBD** —— 源文原文即为 `TBD -- not in test_multen.py yet`。
|
||
|
||
#### 9.3.3 Swift with Keystone
|
||
|
||
默认配置下,**虽然原生 Swift 天然具有多租户能力,radosgw 不会为 Swift API 启用多租户**。这样做是为了确保带有 legacy bucket(即在 radosgw 支持多租户之前创建的 bucket)的环境,这些 bucket 仍保留其**双 API 能力**——既可以用 S3 也可以用 Swift 查询和修改。
|
||
|
||
若想为 Swift 启用多租户(尤其是用户只通过 OpenStack Keystone 认证的场景),应在 `ceph.conf` 中配置:
|
||
|
||
```ini
|
||
rgw keystone implicit tenants = true
|
||
```
|
||
|
||
官方文档中该选项写作 `rgw keystone implicit tenants`;其对应的实际配置项为 `rgw_keystone_implicit_tenants`(默认值取自 src/common/options/rgw.yaml.in @ v20.2.4):
|
||
|
||
| 配置项 | 类型 | 默认值 | 说明 | 枚举值 |
|
||
|---|---|---|---|---|
|
||
| `rgw_keystone_implicit_tenants` | str | `'false'` | RGW Keystone implicit tenants creation。通过 Keystone 认证时,隐式地在与其同名的 tenant 中创建新用户。可限定为只对 S3 或 SWIFT 生效 | `false`、`true`、`swift`、`s3`、`both`、`0`、`1`、`none` |
|
||
|
||
启用后的行为(源文原文):
|
||
|
||
- 任何新连接的用户(无论使用 Swift API 还是 Keystone 认证的 S3)都会促使 radosgw 创建一个名为 **`<tenant_id>$<tenant_id`** 的用户,`<tenant_id>` 是 Keystone tenant(project)UUID,例如 `7188e165c0ae4424ac68ae2e89a05c50$7188e165c0ae4424ac68ae2e89a05c50`。
|
||
- 该用户创建 Swift container 时,radosgw 内部把给定的 container 名翻译为 **`<tenant_id>/<container_name>`**,例如 `7188e165c0ae4424ac68ae2e89a05c50/foo`。这确保两个或更多不同 tenant 都创建名为 `foo` 的 container 时,radosgw 能通过 tenant 前缀透明地区分它们。
|
||
- 也可以把 `rgw keystone implicit tenants` 设为 `s3` 或 `swift`,把隐式 tenant 的效果**限定**为只对 swift 或只对 s3 生效。这主要面向以前在旧版 ceph 中使用过 implicit tenants 的用户——旧版中 implicit tenants 只作用于 swift 协议。
|
||
|
||
### 9.4 已知限制
|
||
|
||
> 明确说明:**目前无法在其它 tenant 中创建 bucket。新建 bucket 的 owner 是从认证信息中提取的。**
|
||
|
||
> 引自:[Multi-tenancy](https://docs.ceph.com/en/tentacle/radosgw/multitenancy/)
|
||
|
||
---
|
||
|
||
## 十、NFS 导出
|
||
|
||
来源:`nfs.rst` 全文(12KB)。`versionadded:: Jewel`
|
||
|
||
> **注意**:使用 cephadm 或 Rook 部署时,**仅支持 NFSv4 协议**。
|
||
|
||
Ceph 对象网关的命名空间可以**通过 NFSv4 导出**,与传统的 HTTP 访问协议(S3 和 Swift)并存。具体做法是:把 Ceph 对象网关**嵌入 NFS-Ganesha NFS 服务器**中,从而提供基于文件的访问。
|
||
|
||
**管理 nfs-ganesha 集群与 rgw export 最简单也最推荐的方式是使用 `ceph nfs ...` 命令**(详见 `/mgr/nfs`,本册不展开)。
|
||
|
||
### 10.1 librgw 与 rgw_file
|
||
|
||
| 组件 | 说明 |
|
||
|---|---|
|
||
| `librgw` | 提供到 Ceph 对象网关服务的可加载接口,并在初始化时**实例化一个完整的 Ceph 对象网关实例** |
|
||
| `rgw_file` | `librgw` 导出的、用于对 RGW bucket 与 object 进行**面向文件**访问的**有状态 API**。该 API 是通用的,但其设计**深受 NFS-Ganesha 的 FSAL(File System Abstraction Layer)API 影响**,主要就是为它设计的 |
|
||
| Python bindings | 也提供了一组 Python 绑定 |
|
||
|
||
### 10.2 命名空间约定
|
||
|
||
实现遵循 **AWS 层次化命名空间约定**,把 UNIX 风格路径名映射到 S3 bucket 与 object。
|
||
|
||
| 规则 | 说明 |
|
||
|---|---|
|
||
| 顶层 | 由 S3 bucket 组成,表现为 **NFS 目录** |
|
||
| 下级 | bucket 下的文件和目录各表现为 object,遵循 S3 的 prefix 与 delimiter 约定,**`/` 是唯一支持的路径分隔符** |
|
||
| 映射示例 | NFS 客户端把 RGW 命名空间挂载在 `/nfs`,那么 NFS 命名空间中的 `/nfs/mybucket/www/index.html` 对应 bucket/container `mybucket` 中的 RGW object `www/index.html` |
|
||
| 叶对象 | 无论文件还是目录,**总是**会以对应 key 名的 RGW object 物化:文件为 `<name>`,目录为 `<name>/` |
|
||
| 非叶目录 | (如上例的 `www`)可能只由出现在一个或多个叶对象名中而**隐含存在** |
|
||
| 在 NFS 内创建的目录 / 被 NFS 客户端直接操作的目录 | **总是**有叶对象表示,用于存放物化属性(如 Unix 属主和权限) |
|
||
|
||
### 10.3 支持的操作与限制
|
||
|
||
RGW NFS 接口支持对文件和目录的**大多数**操作,但有以下限制:
|
||
|
||
| 限制 | 说明 |
|
||
|---|---|
|
||
| 不支持链接 | 包括 symlink 在内的链接都不支持 |
|
||
| 不支持 NFS ACL | 但 **Unix 用户/组属主与权限是支持的** |
|
||
| 目录不可移动/重命名 | 但**文件可以在目录之间移动** |
|
||
| 只支持**完整、顺序**的写 I/O | 即写操作被约束为**上传(uploads)** |
|
||
|
||
**顺序写的进一步说明(源文原文)**:
|
||
|
||
- 许多典型的 I/O 操作(如**原地编辑文件**)必然失败,因为它们执行的是非顺序存储。
|
||
- 某些**表面上**顺序写的文件工具(如某些版本的 GNU tar)可能因为偶尔的非顺序存储而失败。
|
||
- 通过 NFS 挂载时,一般可以通过**同步挂载选项**(如 Linux 上的 `-osync`)把应用的顺序 I/O 约束为顺序写入 NFS 服务器。
|
||
- **无法同步挂载的 NFS 客户端(如 MS Windows)将无法上传文件。**
|
||
|
||
### 10.4 安全模型
|
||
|
||
RGW NFS 接口提供**混合安全模型**:
|
||
|
||
| 层面 | 说明 |
|
||
|---|---|
|
||
| **NFS 协议安全** | 由 NFS-Ganesha 服务器提供,由 NFS 服务器与客户端协商。例如:客户端可被信任(AUTH_SYS),或被要求提供 Kerberos 用户凭据(RPCSEC_GSS)。RPCSEC_GSS 的线路安全可以是仅完整性(`krb5i`)或完整性+隐私/加密(`krb5p`)。还有各种 NFS 特有的安全与权限规则可用,例如 **root-squashing** |
|
||
| **RGW/S3 凭据** | 每个 RGW NFS 挂载(即 NFS-Ganesha EXPORT)关联一组 RGW/S3 安全凭据(**NFS 不知道这些凭据**)。通过 NFS 服务器执行的所有 RGW object 操作,都将由**被访问 export 中所存凭据对应的那个 RGW 用户**执行。**目前只支持 RGW 与 RGW LDAP 凭据** |
|
||
|
||
> ⚠️ 其它 RGW 认证类型(如 **Keystone**)**目前不支持**。
|
||
|
||
### 10.5 手动配置 NFS-Ganesha 实例
|
||
|
||
每个 NFS RGW 实例都是一个**嵌入了完整 Ceph RGW 实例的 NFS-Ganesha 服务器实例**。因此 RGW NFS 的配置包含两部分:
|
||
|
||
- **Ceph 与 Ceph 对象网关相关配置** → 本地 `ceph.conf`
|
||
- **NFS-Ganesha 相关配置** → `ganesha.conf`
|
||
|
||
#### 10.5.1 ceph.conf
|
||
|
||
必需项:
|
||
|
||
- 一个合法的 `[client.rgw.{instance-name}]` 段
|
||
- 最小实例配置的合法取值,特别是**已安装且正确的 `keyring`**
|
||
|
||
其它配置变量(如 `rgw data`、`rgw backend store`)是**可选**的。
|
||
|
||
少量配置变量是 **RGW NFS 独有**的,例如 `rgw_nfs_namespace_expire_secs`。
|
||
|
||
**前端选择的特殊处理(源文原文)**:前端选择由 `librgw.so` 运行时特殊处理。**默认只启动 `rgw-nfs` 前端。** 其它前端(如 `beast`)通过 `rgw nfs frontends` 配置项启用,其语法与普通的 `rgw frontends` 选项相同。非默认前端的默认选项照常通过 `rgw frontend defaults` 指定。
|
||
|
||
| 配置项 | 类型 | 默认值(默认值取自 src/common/options/rgw.yaml.in @ v20.2.4) | 说明 |
|
||
|---|---|---|---|
|
||
| `rgw_nfs_frontends` | str | `rgw-nfs` | 以 librgw/nfs 方式运行时的前端配置 |
|
||
| `rgw_nfs_namespace_expire_secs` | int | `5_min`(=300 秒) | RGW NFS 命名空间刷新周期。`nfs.rst` 原文:在 NFS 之外新增的对象与 bucket 会在该时间之后出现在 NFS 命名空间中,**默认 300 秒(5 分钟)**;在 Ceph 配置文件中覆盖该默认值可改变刷新速率 |
|
||
| `rgw_nfs_write_completion_interval_s` | int | `10` | NFSv3 写完成判定间隔(见 10.8) |
|
||
|
||
#### 10.5.2 ganesha.conf
|
||
|
||
与 RGW NFS 配合使用的**严格最小** `ganesha.conf` 包含一个 EXPORT 块,其中嵌入类型为 RGW 的 FSAL 块:
|
||
|
||
```text
|
||
EXPORT
|
||
{
|
||
Export_ID={numeric-id};
|
||
Path = "/";
|
||
Pseudo = "/";
|
||
Access_Type = RW;
|
||
SecType = "sys";
|
||
NFS_Protocols = 4;
|
||
Transport_Protocols = TCP;
|
||
|
||
# optional, permit unsquashed access by client "root" user
|
||
#Squash = No_Root_Squash;
|
||
|
||
FSAL {
|
||
Name = RGW;
|
||
User_Id = {s3-user-id};
|
||
Access_Key_Id ="{s3-access-key}";
|
||
Secret_Access_Key = "{s3-secret}";
|
||
}
|
||
}
|
||
```
|
||
|
||
**EXPORT 块参数说明**:
|
||
|
||
| 参数 | 说明 |
|
||
|---|---|
|
||
| `Export_ID` | 必须是整数值,例如 `"77"` |
|
||
| `Path` | 对 RGW 而言应为 `"/"` |
|
||
| `Pseudo` | 定义 NFSv4 pseudo root 名(**仅 NFSv4**) |
|
||
| `SecType = sys;` | 允许客户端无需 Kerberos 认证即可挂载 |
|
||
| `Squash = No_Root_Squash;` | 允许客户端 root 用户覆盖权限(Unix 约定)。**启用 root-squashing 时,root 用户尝试的操作会像由 NFS-Ganesha 服务器上的本地 "nobody"(和 "nogroup")用户执行一样** |
|
||
|
||
**RGW FSAL 支持的 RGW 专有配置变量**(在 RGW config section 中):
|
||
|
||
```text
|
||
RGW {
|
||
cluster = "{cluster name, default 'ceph'}";
|
||
name = "client.rgw.{instance-name}";
|
||
ceph_conf = "/opt/ceph-rgw/etc/ceph/ceph.conf";
|
||
init_args = "-d --debug-rgw=16";
|
||
}
|
||
```
|
||
|
||
| 变量 | 说明 |
|
||
|---|---|
|
||
| `cluster` | 设置 Ceph 集群名(**必须与被导出的集群匹配**) |
|
||
| `name` | 设置 RGW 实例名(**必须与被导出的集群匹配**) |
|
||
| `ceph_conf` | 指向要使用的非默认 `ceph.conf` 文件路径 |
|
||
|
||
#### 10.5.3 其它有用的 NFS-Ganesha 配置
|
||
|
||
**启用 NFSv3 与 UDP**:
|
||
|
||
```text
|
||
EXPORT {
|
||
...
|
||
NFS_Protocols = 3,4;
|
||
Transport_Protocols = UDP,TCP;
|
||
...
|
||
}
|
||
```
|
||
|
||
> 任何需要支持 NFSv3 的 EXPORT 块都应在 `NFS_Protocols` 中包含版本 3。此外,**NFSv3 是最后一个支持 UDP 传输的主要版本**;要启用 UDP,把它加入 `Transport_Protocols` 设置。
|
||
|
||
**idmapper 集成**:有一族重要选项涉及与 Linux idmapping 服务(用于跨系统规范化用户与组名)的交互,源文未提供集成细节("Details of idmapper integration are not provided here")。
|
||
|
||
**接受客户端提供的数字 UID/GID(NFSv4 默认会字符串化这些值)**——在小规模环境与试验中可能有用:
|
||
|
||
```text
|
||
NFSV4 {
|
||
Allow_Numeric_Owners = true;
|
||
Only_Numeric_Owners = true;
|
||
}
|
||
```
|
||
|
||
#### 10.5.4 排障(NFS-Ganesha 日志)
|
||
|
||
NFS-Ganesha 配置问题通常通过带调试选项运行服务器来排查,由 LOG config section 控制。
|
||
|
||
日志消息按组件分组,可分别为每个组件启用日志。**组件日志的合法取值**:
|
||
|
||
| 值 | 含义 |
|
||
|---|---|
|
||
| `FATAL` | critical errors only |
|
||
| `WARN` | unusual condition |
|
||
| `DEBUG` | mildly verbose trace output |
|
||
| `FULL_DEBUG` | verbose trace output |
|
||
|
||
完整 LOG 配置示例(源文原文,含全部组件):
|
||
|
||
```text
|
||
LOG {
|
||
Components {
|
||
MEMLEAKS = FATAL;
|
||
FSAL = FATAL;
|
||
NFSPROTO = FATAL;
|
||
NFS_V4 = FATAL;
|
||
EXPORT = FATAL;
|
||
FILEHANDLE = FATAL;
|
||
DISPATCH = FATAL;
|
||
CACHE_INODE = FATAL;
|
||
CACHE_INODE_LRU = FATAL;
|
||
HASHTABLE = FATAL;
|
||
HASHTABLE_CACHE = FATAL;
|
||
DUPREQ = FATAL;
|
||
INIT = DEBUG;
|
||
MAIN = DEBUG;
|
||
IDMAPPER = FATAL;
|
||
NFS_READDIR = FATAL;
|
||
NFS_V4_LOCK = FATAL;
|
||
CONFIG = FATAL;
|
||
CLIENTID = FATAL;
|
||
SESSIONS = FATAL;
|
||
PNFS = FATAL;
|
||
RW_LOCK = FATAL;
|
||
NLM = FATAL;
|
||
RPC = FATAL;
|
||
NFS_CB = FATAL;
|
||
THREAD = FATAL;
|
||
NFS_V4_ACL = FATAL;
|
||
STATE = FATAL;
|
||
FSAL_UP = FATAL;
|
||
DBUS = FATAL;
|
||
}
|
||
# optional: redirect log output
|
||
# Facility {
|
||
# name = FILE;
|
||
# destination = "/tmp/ganesha-rgw.log";
|
||
# enable = active;
|
||
}
|
||
}
|
||
```
|
||
|
||
### 10.6 运行多个 NFS 网关
|
||
|
||
- 每个 NFS-Ganesha 实例作为一个完整的网关端点,限制是**目前一个 NFS-Ganesha 实例不能被配置为导出 HTTP 服务**。
|
||
- 与普通网关实例一样,**可以启动任意数量的 NFS-Ganesha 实例**,从集群导出相同或不同的资源。这使得 NFS-Ganesha 实例可以**集群化**。**但这并不意味着高可用(HA)。**
|
||
- 当常规网关实例与 NFS-Ganesha 实例**覆盖相同的数据资源**时,这些资源既可通过标准 S3 API 访问,也可通过 NFS-Ganesha 实例导出访问。
|
||
- 可以**把 NFS-Ganesha 实例与 Ceph 对象网关实例放在同一主机上**(co-locate)。
|
||
|
||
### 10.7 RGW vs RGW NFS
|
||
|
||
| 事项 | 说明 |
|
||
|---|---|
|
||
| 同实例混导 | 从**同一个程序实例**同时导出 NFS 命名空间和其它 RGW 命名空间(如通过 Civetweb HTTP 前端的 S3 或 Swift)**目前不支持** |
|
||
| NFS 外新增对象的可见延迟 | 在 NFS 之外添加 object 和 bucket 时,它们会在 `rgw_nfs_namespace_expire_secs` 设定的时间之后出现在 NFS 命名空间中,**默认 300 秒(5 分钟)**。在 Ceph 配置文件中覆盖该默认值可改变刷新速率 |
|
||
| 导出不合规的 Swift container | 若导出的 Swift container 名不符合有效的 S3 bucket 命名要求,应在 Ceph 配置文件的 `[client.rgw]` 段把 `rgw_relaxed_s3_bucket_names` 设为 `true`。例如 Swift container 名含下划线就不是合法的 S3 bucket 名,会被拒绝,除非设置了该选项 |
|
||
|
||
### 10.8 配置 NFS 客户端
|
||
|
||
#### NFSv4 客户端
|
||
|
||
要访问该命名空间,把配置好的 NFS-Ganesha export 挂载到本地 POSIX 命名空间的期望位置。此实现有几点独特限制:
|
||
|
||
- **推荐 NFS 4.1 及更高协议版本**:NFSv4 的 OPEN 与 CLOSE 操作被用于跟踪上传事务。
|
||
- **为成功上传数据,客户端必须保持写顺序**:在 Linux 与许多 Unix NFS 客户端上使用 `-osync` 挂载选项。
|
||
|
||
Linux 与部分 Unix 平台的挂载约定:
|
||
|
||
```bash
|
||
# 命令行
|
||
mount -t nfs -o nfsvers=4.1,noauto,soft,sync,proto=tcp <ganesha-host-name>:/ <mount-point>
|
||
```
|
||
|
||
```text
|
||
# /etc/fstab
|
||
<ganesha-host-name>:/ <mount-point> nfs noauto,soft,nfsvers=4.1,sync,proto=tcp 0 0
|
||
```
|
||
|
||
#### NFSv3 客户端
|
||
|
||
Linux 客户端可通过提供 `nfsvers=3` 与 `noacl` 挂载选项以 NFSv3 挂载。要使用 UDP 作为传输,加入 `proto=udp`;但**首选 TCP**:
|
||
|
||
```text
|
||
<ganesha-host-name>:/ <mount-point> nfs noauto,noacl,soft,nfsvers=3,sync,proto=tcp 0 0
|
||
```
|
||
|
||
相应地,NFS Ganesha 的 EXPORT 块中,若挂载将使用 v3 + UDP,则 Protocols 设置要包含版本 3、Transports 设置要包含 UDP。
|
||
|
||
#### NFSv3 语义
|
||
|
||
由于 **NFSv3 不向文件服务器传达客户端的 OPEN 与 CLOSE 操作**,RGW NFS 无法用这些操作标记文件上传事务的开始与结束。取而代之:
|
||
|
||
- **当向某文件 offset 0 发送第一次写时,开始一次新的上传**;
|
||
- **当一段时间内(默认 10 秒)没有看到对该文件的新写时,结束(finalize)该上传**。
|
||
|
||
要改变这个超时,在 Ceph 配置文件的 RGW 段中为 `rgw_nfs_write_completion_interval_s` 设置一个替代值(默认 `10`,默认值取自 src/common/options/rgw.yaml.in @ v20.2.4)。
|
||
|
||
> 引自:[Export over NFS](https://docs.ceph.com/en/tentacle/radosgw/nfs/)
|
||
|
||
---
|
||
|
||
## 十一、监控指标(Metrics)
|
||
|
||
来源:`metrics.rst` 全文(8KB)。
|
||
|
||
### 11.1 总览
|
||
|
||
Ceph 对象网关使用 **Perf Counters** 跟踪指标。这些计数器可以是**带标签的(Labeled Perf Counters)**;带标签时,它们存放在 Ceph 对象网关特有的缓存中。
|
||
|
||
这些指标可以发送到时序数据库 **Prometheus**,以可视化集群范围的用量数据随时间的变化(例如:某个特定 bucket 上的 S3 put 操作数量)。
|
||
|
||
### 11.2 Op Metrics(操作指标)——完整列表
|
||
|
||
以下指标与 S3 或 Swift 操作相关,**按每个 Ceph 对象网关**跟踪。
|
||
|
||
| Name | Type | Description |
|
||
|---|---|---|
|
||
| `put_obj_ops` | Counter | Number of put operations |
|
||
| `put_obj_bytes` | Counter | Number of bytes put |
|
||
| `put_obj_lat` | Gauge | Total latency of put operations |
|
||
| `get_obj_ops` | Counter | Number of get operations |
|
||
| `get_obj_bytes` | Counter | Number of bytes from get requests |
|
||
| `get_obj_lat` | Gauge | Total latency of get operations |
|
||
| `del_obj_ops` | Counter | Number of delete object operations |
|
||
| `del_obj_bytes` | Counter | Number of bytes deleted |
|
||
| `del_obj_lat` | Gauge | Total latency of delete object operations |
|
||
| `del_bucket_ops` | Counter | Number of delete bucket operations |
|
||
| `del_bucket_lat` | Gauge | Total latency of delete bucket operations |
|
||
| `copy_obj_ops` | Counter | Number of copy object operations |
|
||
| `copy_obj_bytes` | Counter | Number of bytes copied |
|
||
| `copy_obj_lat` | Gauge | Total latency of copy object operations |
|
||
| `list_object_ops` | Counter | Number of list object operations |
|
||
| `list_object_lat` | Gauge | Total latency of list object operations |
|
||
| `list_bucket_ops` | Counter | Number of list bucket operations |
|
||
| `list_bucket_lat` | Gauge | Total latency of list bucket operations |
|
||
|
||
### 11.3 counter dump / counter schema 的三个 section
|
||
|
||
`counter dump` 与 `counter schema` 命令的输出中,有三个不同的 section 展示 op metrics 及其信息:
|
||
|
||
| Section | 含义 |
|
||
|---|---|
|
||
| `rgw_op` | 反映给定 Ceph 对象网关上**每个 op metric 的总计** |
|
||
| `rgw_op_per_user` | **带标签**的 op metric 计数器,按 **user** 统计 |
|
||
| `rgw_op_per_bucket` | **带标签**的 op metric 计数器,按 **bucket** 统计 |
|
||
|
||
查看方式:
|
||
|
||
- op metric 的**信息**(schema)在 `counter schema` 输出的 `rgw_op` 段中;
|
||
- op metric 的**数值**在 `counter dump` 输出的 `rgw_op` 段中。
|
||
|
||
`rgw_op` 段输出示例(源文原文):
|
||
|
||
```json
|
||
"rgw_op": [
|
||
{
|
||
"labels": {},
|
||
"counters": {
|
||
"put_obj_ops": 2,
|
||
"put_obj_bytes": 5327,
|
||
"put_obj_lat": {
|
||
"avgcount": 2,
|
||
"sum": 2.818064835,
|
||
"avgtime": 1.409032417
|
||
},
|
||
"get_obj_ops": 5,
|
||
"get_obj_bytes": 5325,
|
||
"get_obj_lat": {
|
||
"avgcount": 2,
|
||
"sum": 0.003000069,
|
||
"avgtime": 0.001500034
|
||
},
|
||
...
|
||
"list_buckets_ops": 1,
|
||
"list_buckets_lat": {
|
||
"avgcount": 1,
|
||
"sum": 0.002300000,
|
||
"avgtime": 0.002300000
|
||
}
|
||
}
|
||
},
|
||
]
|
||
```
|
||
|
||
### 11.4 Op Metrics Labels(标签)
|
||
|
||
Op metrics 也可以按 **user** 或按 **bucket** 跟踪。导出到 Prometheus 时带类似 `Bucket = {name}` 或 `User = {userid}` 的标签:
|
||
|
||
```json
|
||
"rgw_op_per_bucket": [
|
||
...
|
||
{
|
||
"labels": {
|
||
"Bucket": "bucket1"
|
||
},
|
||
"counters": {
|
||
"put_obj_ops": 2,
|
||
"put_obj_bytes": 5327,
|
||
"put_obj_lat": {
|
||
"avgcount": 2,
|
||
"sum": 2.818064835,
|
||
"avgtime": 1.409032417
|
||
},
|
||
"get_obj_ops": 5,
|
||
"get_obj_bytes": 5325,
|
||
"get_obj_lat": {
|
||
"avgcount": 2,
|
||
"sum": 0.003000069,
|
||
"avgtime": 0.001500034
|
||
},
|
||
...
|
||
"list_buckets_ops": 1,
|
||
"list_buckets_lat": {
|
||
"avgcount": 1,
|
||
"sum": 0.002300000,
|
||
"avgtime": 0.002300000
|
||
}
|
||
}
|
||
},
|
||
...
|
||
]
|
||
```
|
||
|
||
**多租户的标签**:多租户允许在不同 tenant 下创建同名的 bucket 与 user。**若 user 或 bucket 位于某个 tenant 之下,会额外加上形如 `Tenant = {tenantid}` 的标签。**
|
||
|
||
**默认关闭(源文原文要点)**:
|
||
|
||
> 在拥有大量 user 和 bucket 的大型系统中,把**所有**指标导出到 Prometheus 可能不可行。**因此,这些带标签指标的收集默认是禁用的。**
|
||
>
|
||
> 一旦启用,被跟踪的 user 与 bucket 的工作集会被加以限制,以控制内存与数据库使用。**其结果是,这些带标签指标的收集并不总是可靠的。**
|
||
|
||
### 11.5 User & Bucket Counter Caches
|
||
|
||
| 目的 | 必须启用的配置项 |
|
||
|---|---|
|
||
| 跟踪 **by user** 的 op metrics | `rgw_user_counters_cache = true` |
|
||
| 跟踪 **by bucket** 的 op metrics | `rgw_bucket_counters_cache = true` |
|
||
|
||
设置方式:
|
||
|
||
```bash
|
||
ceph config set client.rgw rgw_user_counters_cache true
|
||
ceph config set client.rgw rgw_bucket_counters_cache true
|
||
```
|
||
|
||
> ⚠️ **重要**:由于 op metrics 是 labeled perf counters,它们**存活在内存中**。若 Ceph 对象网关**重启或崩溃**,该网关中的所有计数器——无论在缓存中与否——**都会丢失**。
|
||
|
||
### 11.6 缓存大小与淘汰(Eviction)
|
||
|
||
- `rgw_user_counters_cache_size` 与 `rgw_bucket_counters_cache_size` 分别设置每个缓存中的条目数。
|
||
- **一旦缓存中的计数器数量大于缓存大小配置值,计数器就会被淘汰;被淘汰的是最近最少使用(LRU)的计数器。**
|
||
- 举例:若 bucket 数量超出 `rgw_bucket_counters_cache_size` 达到 1,且标签为 `bucket1` 的计数器是最后被更新的,则 `bucket1` 的计数器会被淘汰。若淘汰后又对 `bucket1` 执行了被 op metrics 跟踪的 S3 操作,则缓存中 `bucket1` 的**所有指标都会从 0 重新开始**。
|
||
|
||
**缓存 sizing 的依赖因素**:
|
||
|
||
1. 集群中的 user 数量
|
||
2. 集群中的 bucket 数量
|
||
3. Ceph 对象网关的内存占用
|
||
4. Prometheus 的磁盘与内存占用
|
||
|
||
> **内存估算**:为帮助计算 Ceph 对象网关某个缓存的内存占用,需注意**每个缓存条目(包含全部 op metrics)为 1360 字节**。这是一个估算值,**如果 op metrics 列表增加或删除指标,该值会变化**。
|
||
|
||
### 11.7 把指标发送到 Prometheus
|
||
|
||
- 要把指标从 Ceph 对象网关送入时序数据库 Prometheus,**必须运行 ceph-exporter 守护进程,并配置它去 scrape Radosgw 的 admin socket**。
|
||
- ceph-exporter 守护进程以固定间隔 scrape Ceph 对象网关的 admin socket,该间隔由配置变量 **`exporter_stats_period`** 定义。
|
||
- Prometheus 自身也有可配置的 scrape 间隔(见 Prometheus 官方文档)。
|
||
|
||
### 11.8 配置参考(Metrics)
|
||
|
||
通过 `ceph config set client.rgw CONFIG_VARIABLE VALUE` 设置:
|
||
|
||
| 配置项 | 类型 | 默认值(默认值取自 src/common/options/*.yaml.in @ v20.2.4) | 含义 |
|
||
|---|---|---|---|
|
||
| `rgw_user_counters_cache` | bool | `false` | 启用一个 rgw perf counters 缓存,存放带 user 标签的计数器。该缓存只包含以 user 为标签的 perf counters |
|
||
| `rgw_user_counters_cache_size` | uint | `10000` | user perf counters 缓存可存放的带标签 perf counters 数量 |
|
||
| `rgw_bucket_counters_cache` | bool | `false` | 启用一个 rgw perf counters 缓存,存放带 bucket 标签的计数器。该缓存只包含以 bucket 为标签的 perf counters |
|
||
| `rgw_bucket_counters_cache_size` | uint | `10000` | bucket perf counters 缓存可存放的带标签 perf counters 数量 |
|
||
|
||
通过 `ceph config set global CONFIG_VARIABLE VALUE` 设置(ceph-exporter 相关):
|
||
|
||
| 配置项 | 类型 | 默认值(默认值取自 src/common/options/ceph-exporter.yaml.in @ v20.2.4) | 含义 |
|
||
|---|---|---|---|
|
||
| `exporter_stats_period` | int | `5` | 再次向 exporter server 发送请求前的等待时间(秒) |
|
||
|
||
> 引自:[Metrics](https://docs.ceph.com/en/tentacle/radosgw/metrics/)
|
||
|
||
---
|
||
## 十二、配置参考(Config Reference)
|
||
|
||
来源:`config-ref.rst` 全文(13KB)+ `metrics.rst` + `nfs.rst` 中出现的配置项。
|
||
|
||
### 12.1 使用约定(源文原文要点)
|
||
|
||
1. 以下设置可添加到 Ceph 配置文件(通常是 `ceph.conf`)的 **`[client.radosgw.{instance-name}]`** 段下。这些设置可能包含默认值;若你未在其中显式指定每个设置,则会自动采用默认值。
|
||
2. **写在 `[client.radosgw.{instance-name}]` 段下的配置变量,对未指定 instance-name 的 `rgw` 或 `radosgw-admin` 命令不生效。** 因此,希望对所有 RGW 实例或所有 `radosgw-admin` 选项生效的变量,应放到 **`[global]`** 或 **`[client]`** 段,以避免指定 instance-name。
|
||
|
||
**默认值来源说明**:下表中所有 `默认值` 列的数据均取自 `src/common/options/*.yaml.in @ v20.2.4`(本机路径 `handbook-src/options/rgw.yaml.in`、`global.yaml.in`、`ceph-exporter.yaml.in`),因为 rst 源文中的 `.. confval::` 默认值是构建期生成的占位符。凡这些 yaml.in 中也不存在的,标注「文档未明确」。
|
||
|
||
**Lifecycle 调优建议(源文原文)**:
|
||
|
||
- 这两个值可根据具体工作负载调整,以进一步提高 lifecycle 处理的激进程度。
|
||
- 对于 **bucket 数量很多(数千个)** 的工作负载:**调大 `rgw_lc_max_worker`**(默认 3)。
|
||
- 对于 **单 bucket 内对象数很多(数十万个)** 的工作负载:**调大 `rgw_lc_max_wp_worker`**(默认 3)。
|
||
- ⚠️ **在调大任何一个值之前,先验证当前集群性能与 Ceph 对象网关利用率。**
|
||
- ⚠️ **每个 zone 至少需有一个 RGW 守护进程启用 lifecycle 维护线程(`rgw_enable_lc_threads`)。**
|
||
|
||
**Garbage Collection 说明与调优(源文原文)**:
|
||
|
||
- Ceph 对象网关**立即**为新对象分配存储空间,但**在**网关把已删除/被覆盖的对象从 **bucket index** 中删除**之后的某个时刻**,才清除它们在 Ceph 存储集群中占用的空间。这个清除过程称为 **Garbage Collection(GC)**。
|
||
- 查看等待 GC 的对象队列:
|
||
|
||
```bash
|
||
radosgw-admin gc list
|
||
```
|
||
|
||
> 指定 `--include-all` 可列出所有条目,包括未过期的 GC 对象。
|
||
|
||
- GC 是后台活动,可连续执行,也可在低负载时段执行,取决于管理员如何配置。**默认情况下 Ceph 对象网关连续执行 GC 操作。**
|
||
- 由于 GC 操作是 Ceph 对象网关的正常运行的一部分(尤其是对象删除操作),**大多数时候都存在符合 GC 条件的对象**。
|
||
- **删除密集型工作负载**可能临时或永久超过 GC 的速率。管理员可通过以下配置参数**提高 GC 操作相对于其它操作的优先级**。
|
||
- **删除密集负载的初始调优建议**:
|
||
|
||
```ini
|
||
rgw_gc_max_concurrent_io = 20
|
||
rgw_gc_max_trim_chunk = 64
|
||
```
|
||
|
||
> ⚠️ **修改这些值需要重启 RGW 服务。** 调大后请监控集群在 GC 期间的性能,确认没有因调大而导致的不良性能问题。
|
||
> ⚠️ **每个 zone 至少需有一个 RGW 运行垃圾回收维护线程(`rgw_enable_gc_threads`)。**
|
||
|
||
**Multisite 重要提示(源文原文)**:`rgw_data_log_num_shards` 与 `rgw_md_log_max_shards` 的值**在同步开始之后不应再修改**。
|
||
|
||
**QoS 说明(源文原文)**:较旧且现已非默认的 `civetweb` 前端采用**每连接一个线程**的线程模型,因此在接受连接时**自动**受 `rgw_thread_pool_size` 节流。较新且默认的 `beast` 前端在接受新连接时**不受**线程池大小限制,因此在 Nautilus 引入了 scheduler 抽象,以支持额外的请求调度方式。当前 scheduler 默认为一个 throttler,把活跃连接数限制在一个配置上限。**基于 mClock 的 QoS 限流目前处于实验阶段,不建议用于生产。** 当前 *dmclock_client* op queue 的实现把 RGW op 分为 admin、auth(swift auth、sts)、metadata、data 请求。
|
||
|
||
**D4N 说明(源文原文)**:D4N 是一种缓存架构,利用 **Redis** 通过**在 Ceph 对象网关(RGW)守护进程之间建立共享数据库**来加速 S3 对象存储操作。**D4N 架构一次只能作用于一个 Redis 实例。** 地址可配置,可通过下面的参数更改。
|
||
|
||
**Topic persistency 说明(源文原文)**:Topic persistency 会**反复推送通知直到成功**。默认行为是**无限期、尽可能频繁地推送**。通过这些设置可以控制一次不成功通知的重试时长和/或最大重试次数;两次推送重试之间的间隔通过 sleep duration 参数配置。**所有这些选项默认值为 `0`,意味着持久化保留是无限期的,通知会尽可能频繁地重试。**
|
||
|
||
**Cloud Restore 说明(源文原文)**:Cloud Restore 特性目前支持把已 transition 到 S3 兼容云服务上的对象恢复到 Ceph 对象网关(RGW)。restore 请求由后台的 Restore worker thread **异步**处理。
|
||
|
||
### 12.2 核心设置(Core Settings)
|
||
|
||
| 配置项 | 类型 | 默认值 | 含义 |
|
||
|---|---|---|---|
|
||
| `rgw_frontends` | str | `beast port=7480` | RGW 前端(frontend)配置 |
|
||
| `rgw_data` | str | `/var/lib/ceph/radosgw/$cluster-$id` | RGW 配置的备用目录路径 |
|
||
| `rgw_enable_apis` | str | `s3, s3website, swift, swift_auth, admin, sts, iam, notifications` | RGW 要启用的 RESTful API 列表 |
|
||
| `rgw_cache_enabled` | bool | `true` | 是否启用 RGW 元数据缓存 |
|
||
| `rgw_cache_lru_size` | int | `25000` | RGW 元数据缓存中的最大条目数 |
|
||
| `rgw_dns_name` | str | `(无默认值)` | RGW 使用的主机名。逗号分隔的 DNS 名列表;除非通过 zonegroup 配置,否则 bucket 虚拟主机(virtual hosting)要正常工作需要它;另见 zonegroup 内的 hostnames 设置 |
|
||
| `rgw_script_uri` | str | `(无默认值)` | 请求中未设置 ``SCRIPT_URI`` 时使用的替代值 |
|
||
| `rgw_request_uri` | str | `(无默认值)` | 请求中未设置 ``REQUEST_URI`` 时使用的替代值 |
|
||
| `rgw_print_continue` | bool | `true` | RGW 是否支持 100-continue |
|
||
| `rgw_remote_addr_param` | str | `REMOTE_ADDR` | 入站请求中携带远端地址的 HTTP header 名 |
|
||
| `rgw_op_thread_timeout` | int | `10_min` | 异步 rados 协程操作的超时时间 |
|
||
| `rgw_op_thread_suicide_timeout` | int | `0` | Ceph 对象网关进程自行退出前的 timeout 秒数;设为 ``0`` 表示禁用 |
|
||
| `rgw_thread_pool_size` | int | `512` | RGW 请求处理线程池大小。决定使用 civetweb 或 fastcgi 前端时 RGW 能处理的并发请求数;数值越大并发能力越强,代价是资源占用更高 |
|
||
| `rgw_num_control_oids` | int | `8` | 用于跨 RGW 通信的控制对象数量 |
|
||
| `rgw_init_timeout` | int | `5_min` | 初始化超时 |
|
||
| `rgw_mime_types_file` | str | `/etc/mime.types` | 本地 mime types 文件路径 |
|
||
| `rgw_s3_success_create_obj_status` | int | `0` | 对象创建时的 HTTP 返回码覆盖值 |
|
||
| `rgw_resolve_cname` | bool | `false` | 是否通过 CNAME 支持 vanity domain name |
|
||
| `rgw_obj_stripe_size` | size | `4_M` | RGW 对象条带(stripe)大小 |
|
||
| `rgw_extended_http_attrs` | str | `(无默认值)` | RGW 支持扩展 HTTP attrs |
|
||
| `rgw_exit_timeout_secs` | int | `2_min` | RGW 关闭(shutdown)超时 |
|
||
| `rgw_get_obj_window_size` | size | `16_M` | RGW 对象读取窗口大小 |
|
||
| `rgw_get_obj_max_req_size` | size | `4_M` | RGW 对象读取 chunk 大小 |
|
||
| `rgw_multipart_min_part_size` | size | `5_M` | S3 multipart-upload 的最小 part 大小 |
|
||
| `rgw_relaxed_s3_bucket_names` | bool | `false` | 是否启用放宽的 S3 bucket 命名规则 |
|
||
| `rgw_list_buckets_max_chunk` | int | `1000` | 单次列举操作中可获取的 bucket 最大数量 |
|
||
| `rgw_override_bucket_index_max_shards` | uint | `0` | 新建 bucket 的默认 bucket index 分片数。该值会覆盖 zone 中保存的 ``bucket_index_max_shards``。**官方建议在 zone 中设置**,因为它对该 zone 内所有 radosgw 守护进程全局生效 |
|
||
| `rgw_curl_wait_timeout_ms` | int | `1000` | 某些 ``curl`` 调用的超时时间(毫秒) |
|
||
| `rgw_copy_obj_progress` | bool | `true` | copy 操作过程中是否发送进度报告 |
|
||
| `rgw_copy_obj_progress_every_bytes` | size | `1_M` | 每传输多少字节后发送一次 copy-object 进度信息 |
|
||
| `rgw_max_copy_obj_concurrent_io` | int | `10` | 执行 copy_obj 时并发处理的 refcount 操作数量 |
|
||
| `rgw_admin_entry` | str | `admin` | 访问 RGW RESTful admin API 的路径前缀 |
|
||
| `rgw_content_length_compat` | bool | `false` | 多个 content length header 的兼容性处理 |
|
||
| `rgw_bucket_quota_ttl` | int | `10_min` | Bucket quota 统计的缓存 TTL |
|
||
| `rgw_user_quota_bucket_sync_interval` | int | `3_min` | User quota 的 bucket 同步间隔 |
|
||
| `rgw_user_quota_sync_interval` | int | `1_day` | User quota 同步间隔 |
|
||
| `rgw_bucket_default_quota_max_objects` | int | `-1` | Bucket 中最大对象数的默认配额 |
|
||
| `rgw_bucket_default_quota_max_size` | int | `-1` | Bucket 总大小的默认配额 |
|
||
| `rgw_user_default_quota_max_objects` | int | `-1` | User 的最大对象数配额 |
|
||
| `rgw_user_default_quota_max_size` | int | `-1` | User 的最大容量配额 |
|
||
| `rgw_account_default_quota_max_objects` | int | `-1` | Account 的最大对象数配额 |
|
||
| `rgw_account_default_quota_max_size` | int | `-1` | Account 的最大容量配额 |
|
||
| `rgw_verify_ssl` | bool | `true` | RGW 连接远端 HTTP 服务器时是否校验 SSL |
|
||
| `rgw_max_chunk_size` | size | `4_M` | RGW 最大 chunk 大小。chunk size 是 RGW 访问 RADOS 对象时发给 OSD 的请求大小;读写单请求永不超过此值;**它也定义了 RGW HEAD 对象的大小**(head 操作需原子)。写入默认 storage class 时最多有这么多载荷数据与元数据一起存在 head 对象;写入**非默认** storage class 时 HEAD RADOS 对象仍在默认 storage class 的 pool 中,但**不内联**载荷数据 |
|
||
|
||
### 12.3 Lifecycle Settings(生命周期)
|
||
|
||
| 配置项 | 类型 | 默认值 | 含义 |
|
||
|---|---|---|---|
|
||
| `rgw_lc_max_worker` | int | `3` | 并行运行的 LCWorker 任务数量(大量 bucket 场景可调大) |
|
||
| `rgw_lc_max_wp_worker` | int | `3` | 每个 LCWorker 的 workpool 线程数(单 bucket 内对象极多可调大) |
|
||
| `rgw_enable_lc_threads` | bool | `true` | 是否启用 lifecycle 维护线程。**每个 zone 至少需要一个 RGW 守护进程开启此项** |
|
||
|
||
### 12.4 Garbage Collection Settings(垃圾回收)
|
||
|
||
| 配置项 | 类型 | 默认值 | 含义 |
|
||
|---|---|---|---|
|
||
| `rgw_gc_max_objs` | int | `32` | 垃圾回收数据的分片(shard)数量 |
|
||
| `rgw_gc_obj_min_wait` | int | `2_hr` | 垃圾回收对象的过期时间 |
|
||
| `rgw_gc_processor_max_time` | int | `1_hr` | GC processor 可以 lease 某个 shard 的时长 |
|
||
| `rgw_gc_processor_period` | int | `1_hr` | 垃圾回收周期运行时长 |
|
||
| `rgw_gc_max_concurrent_io` | int | `10` | 垃圾回收的最大并发 RADOS IO 操作数 |
|
||
| `rgw_gc_max_trim_chunk` | int | `16` | 单次操作中从 garbage collector log 移除的最大 key 数(**删除密集负载调优建议值:64**) |
|
||
| `rgw_enable_gc_threads` | bool | `true` | 是否启用垃圾回收维护线程。**每个 zone 至少需要一个 RGW 开启** |
|
||
|
||
### 12.5 Multisite Settings(多站点)
|
||
|
||
| 配置项 | 类型 | 默认值 | 含义 |
|
||
|---|---|---|---|
|
||
| `rgw_zone` | str | `(无默认值)` | Zone 名称 |
|
||
| `rgw_zonegroup` | str | `(无默认值)` | Zonegroup 名称 |
|
||
| `rgw_realm` | str | `(无默认值)` | 网关实例所属 realm 名。若未设置 realm,可用 ``radosgw-admin realm default`` 命令配置集群级默认值 |
|
||
| `rgw_run_sync_thread` | bool | `true` | 是否运行 sync 线程 |
|
||
| `rgw_data_log_window` | int | `30` | Data log 时间窗口 |
|
||
| `rgw_data_log_changes_size` | int | `1000` | Data log 中待处理变更的最大条数 |
|
||
| `rgw_data_log_num_shards` | int | `128` | Data log 分片数(**同步开始后不应再修改**) |
|
||
| `rgw_md_log_max_shards` | int | `64` | RGW metadata log 分片数(**同步开始后不应再修改**) |
|
||
| `rgw_data_sync_poll_interval` | int | `20` | 多站点增量同步追平某个 datalog shard 后,等待多少秒再轮询更多变更 |
|
||
| `rgw_meta_sync_poll_interval` | int | `20` | 多站点增量同步追平某个 mdlog shard 后,等待多少秒再轮询更多变更 |
|
||
| `rgw_bucket_sync_spawn_window` | int | `20` | bucket sync 愿意并行处理的最大条目数(每个远端 bilog shard) |
|
||
| `rgw_data_sync_spawn_window` | int | `20` | data sync 愿意并行处理的最大条目数(每个远端 datalog shard) |
|
||
| `rgw_meta_sync_spawn_window` | int | `20` | metadata sync 愿意并行处理的最大条目数(每个远端 mdlog shard) |
|
||
|
||
### 12.6 S3 Settings
|
||
|
||
| 配置项 | 类型 | 默认值 | 含义 |
|
||
|---|---|---|---|
|
||
| `rgw_s3_auth_use_ldap` | bool | `false` | S3 认证是否使用 LDAP |
|
||
|
||
### 12.7 Swift Settings
|
||
|
||
| 配置项 | 类型 | 默认值 | 含义 |
|
||
|---|---|---|---|
|
||
| `rgw_enforce_swift_acls` | bool | `true` | RGW 是否强制实施 swift acls |
|
||
| `rgw_swift_tenant_name` | str | `(无默认值)` | Swift tenant 名 |
|
||
| `rgw_swift_token_expiration` | int | `1_day` | 通过 RGW Swift auth 生成的 token 的过期时间(秒) |
|
||
| `rgw_swift_url` | str | `(无默认值)` | Swift-auth storage URL |
|
||
| `rgw_swift_url_prefix` | str | `swift` | Swift URL 前缀 |
|
||
| `rgw_swift_auth_url` | str | `(无默认值)` | Swift auth URL |
|
||
| `rgw_swift_auth_entry` | str | `auth` | Swift auth URL 前缀 |
|
||
| `rgw_swift_account_in_url` | bool | `false` | Swift account 是否编码在 URL 中 |
|
||
| `rgw_swift_versioning_enabled` | bool | `false` | 是否启用 Swift versioning |
|
||
| `rgw_trust_forwarded_https` | bool | `false` | 是否信任 Forwarded 与 X-Forwarded-Proto header |
|
||
|
||
### 12.8 Logging Settings(日志)
|
||
|
||
| 配置项 | 类型 | 默认值 | 含义 |
|
||
|---|---|---|---|
|
||
| `rgw_log_nonexistent_bucket` | bool | `false` | RGW 是否记录对不存在 bucket 的操作 |
|
||
| `rgw_log_object_name` | str | `'%Y-%m-%d-%H-%i-%n'` | Ops log 对象名格式 |
|
||
| `rgw_log_object_name_utc` | bool | `false` | Ops log 对象名是否基于 UTC |
|
||
| `rgw_usage_max_shards` | int | `32` | Usage log 的分片数 |
|
||
| `rgw_usage_max_user_shards` | int | `1` | Usage log 中单个用户的分片数 |
|
||
| `rgw_enable_ops_log` | bool | `false` | 是否启用 ops log |
|
||
| `rgw_enable_usage_log` | bool | `false` | 是否启用 usage log |
|
||
| `rgw_ops_log_rados` | bool | `false` | Ops log 是否使用 RADOS |
|
||
| `rgw_ops_log_socket_path` | str | `(无默认值)` | Ops log 的 Unix domain socket 路径 |
|
||
| `rgw_ops_log_data_backlog` | size | `5_M` | Ops log socket 的 backlog 大小 |
|
||
| `rgw_usage_log_flush_threshold` | int | `1024` | Usage log 刷盘前累积的条目数 |
|
||
| `rgw_usage_log_tick_interval` | int | `30` | Usage log 刷盘周期间的秒数 |
|
||
| `rgw_log_http_headers` | str | `(无默认值)` | 要记录的 HTTP header 列表 |
|
||
|
||
### 12.9 Keystone Settings
|
||
|
||
| 配置项 | 类型 | 默认值 | 含义 |
|
||
|---|---|---|---|
|
||
| `rgw_keystone_url` | str | `(无默认值)` | Keystone 服务器的 URL |
|
||
| `rgw_keystone_admin_domain` | str | `(无默认值)` | Keystone admin 用户 domain(Keystone v3) |
|
||
| `rgw_keystone_admin_project` | str | `(无默认值)` | Keystone admin 用户 project(Keystone v3) |
|
||
| `rgw_keystone_admin_token` | str | `(无默认值)` | **已废弃**:用于 Keystone 请求的 admin token(共享密钥) |
|
||
| `rgw_keystone_admin_token_path` | str | `(无默认值)` | 包含 admin token(共享密钥)的文件路径 |
|
||
| `rgw_keystone_admin_tenant` | str | `(无默认值)` | Keystone admin 用户 tenant |
|
||
| `rgw_keystone_admin_user` | str | `(无默认值)` | Keystone admin 用户 |
|
||
| `rgw_keystone_admin_password` | str | `(无默认值)` | **已废弃**:Keystone admin 密码 |
|
||
| `rgw_keystone_admin_password_path` | str | `(无默认值)` | 包含 Keystone admin 密码的文件路径 |
|
||
| `rgw_keystone_accepted_roles` | str | `Member, admin` | 只有具备这些角色之一的用户在 Keystone 认证时才会被服务 |
|
||
| `rgw_keystone_token_cache_size` | int | `10000` | Keystone token 缓存大小 |
|
||
| `rgw_keystone_verify_ssl` | bool | `true` | RGW 是否校验 Keystone 服务器的 SSL 证书 |
|
||
| `rgw_keystone_service_token_enabled` | bool | `false` | 是否允许 service token 使用已过期的 Keystone auth token |
|
||
| `rgw_keystone_service_token_accepted_roles` | str | `admin` | 只有具备这些角色之一的用户才是合法的 service user |
|
||
| `rgw_keystone_expired_token_cache_expiration` | int | `3600` | 过期 token 的过期时间上,在当前时间基础上增加的秒数 |
|
||
| `rgw_keystone_implicit_tenants` | str | `'false'` | RGW Keystone 隐式 tenant 创建。通过 Keystone 认证时,在其同名 tenant 中隐式创建新用户;可限定只对 S3 或 SWIFT 生效 |
|
||
|
||
### 12.10 Server-side encryption Settings(服务端加密)
|
||
|
||
| 配置项 | 类型 | 默认值 | 含义 |
|
||
|---|---|---|---|
|
||
| `rgw_crypt_s3_kms_backend` | str | `barbican` | SSE-KMS 加密密钥存放在哪里。支持的 KMS 系统有 OpenStack Barbican(``barbican``,默认)与 HashiCorp Vault(``vault``) |
|
||
|
||
### 12.11 Barbican Settings
|
||
|
||
| 配置项 | 类型 | 默认值 | 含义 |
|
||
|---|---|---|---|
|
||
| `rgw_barbican_url` | str | `(无默认值)` | Barbican 服务器的 URL |
|
||
| `rgw_keystone_barbican_user` | str | `(无默认值)` | 访问 barbican secret 的 Keystone 用户 |
|
||
| `rgw_keystone_barbican_password` | str | `(无默认值)` | barbican 用户的 Keystone 密码 |
|
||
| `rgw_keystone_barbican_tenant` | str | `(无默认值)` | Keystone barbican 用户 tenant(Keystone v2.0) |
|
||
| `rgw_keystone_barbican_project` | str | `(无默认值)` | Keystone barbican 用户 project(Keystone v3) |
|
||
| `rgw_keystone_barbican_domain` | str | `(无默认值)` | Keystone barbican 用户 domain |
|
||
|
||
### 12.12 HashiCorp Vault Settings
|
||
|
||
| 配置项 | 类型 | 默认值 | 含义 |
|
||
|---|---|---|---|
|
||
| `rgw_crypt_vault_auth` | str | `token` | 与 Vault 配合使用的认证方式类型 |
|
||
| `rgw_crypt_vault_token_file` | str | `(无默认值)` | 若认证方式为 ``token``,则提供 token 文件路径(出于安全考虑,该文件应只对 Rados Gateway 可读) |
|
||
| `rgw_crypt_vault_addr` | str | `(无默认值)` | Vault 服务器基地址 |
|
||
| `rgw_crypt_vault_prefix` | str | `(无默认值)` | Vault secret URL 前缀,可用于把访问限制在 Vault secret 空间的某个子集 |
|
||
| `rgw_crypt_vault_secret_engine` | str | `transit` | 用于获取加密密钥的 Vault Secret Engine |
|
||
| `rgw_crypt_vault_namespace` | str | `(无默认值)` | 用于选择租户的 Vault Namespace |
|
||
|
||
### 12.13 SSE-S3 Settings
|
||
|
||
| 配置项 | 类型 | 默认值 | 含义 |
|
||
|---|---|---|---|
|
||
| `rgw_crypt_sse_s3_backend` | str | `vault` | SSE-S3 加密密钥存放在哪里。唯一合法选择是 HashiCorp Vault(``vault``) |
|
||
| `rgw_crypt_sse_s3_vault_secret_engine` | str | `transit` | 用于获取加密密钥的 Vault Secret Engine |
|
||
| `rgw_crypt_sse_s3_key_template` | str | `"%bucket_id"` | Vault 中 per-bucket SSE-S3 key 的模板 |
|
||
| `rgw_crypt_sse_s3_vault_auth` | str | `token` | SSE-S3 与 Vault 配合使用的认证方式类型 |
|
||
| `rgw_crypt_sse_s3_vault_token_file` | str | `(无默认值)` | 若认证方式为 ``token``,则提供 token 文件路径(出于安全考虑,该文件应只对 Rados Gateway 可读) |
|
||
| `rgw_crypt_sse_s3_vault_addr` | str | `(无默认值)` | SSE-S3 Vault 服务器基地址 |
|
||
| `rgw_crypt_sse_s3_vault_prefix` | str | `(无默认值)` | SSE-S3 Vault secret URL 前缀,可把访问限制在 Vault secret 空间的某个子集 |
|
||
| `rgw_crypt_sse_s3_vault_namespace` | str | `(无默认值)` | 用于选择租户的 Vault Namespace |
|
||
| `rgw_crypt_sse_s3_vault_verify_ssl` | bool | `true` | RGW 是否校验 vault 服务器的 SSL 证书 |
|
||
| `rgw_crypt_sse_s3_vault_ssl_cacert` | str | `(无默认值)` | 访问 vault 服务器的自定义 CA 证书路径 |
|
||
| `rgw_crypt_sse_s3_vault_ssl_clientcert` | str | `(无默认值)` | 访问 vault 服务器的自定义客户端证书路径 |
|
||
| `rgw_crypt_sse_s3_vault_ssl_clientkey` | str | `(无默认值)` | 客户端证书所需私钥的路径 |
|
||
|
||
### 12.14 QoS settings(服务质量/调度)
|
||
|
||
| 配置项 | 类型 | 默认值 | 含义 |
|
||
|---|---|---|---|
|
||
| `rgw_max_concurrent_requests` | int | `1024` | 最大并发 HTTP 请求数 |
|
||
| `rgw_scheduler_type` | str | `throttler` | dmclock scheduler 类型,默认 ``throttler``;另一个合法值 ``dmclock`` 是实验性的 |
|
||
| `rgw_dmclock_auth_res` | float | `200` | auth 请求的 mclock reservation(保留值) |
|
||
| `rgw_dmclock_auth_wgt` | float | `100` | auth 请求的 mclock weight(权重) |
|
||
| `rgw_dmclock_auth_lim` | float | `0` | auth 请求的 mclock limit(上限) |
|
||
| `rgw_dmclock_admin_res` | float | `100` | admin 请求的 mclock reservation |
|
||
| `rgw_dmclock_admin_wgt` | float | `100` | admin 请求的 mclock weight |
|
||
| `rgw_dmclock_admin_lim` | float | `0` | admin 请求的 mclock limit |
|
||
| `rgw_dmclock_data_res` | float | `500` | object data 请求的 mclock reservation |
|
||
| `rgw_dmclock_data_wgt` | float | `500` | object data 请求的 mclock weight |
|
||
| `rgw_dmclock_data_lim` | float | `0` | object data 请求的 mclock limit |
|
||
| `rgw_dmclock_metadata_res` | float | `500` | metadata 请求的 mclock reservation |
|
||
| `rgw_dmclock_metadata_wgt` | float | `500` | metadata 请求的 mclock weight |
|
||
| `rgw_dmclock_metadata_lim` | float | `0` | metadata 请求的 mclock limit |
|
||
|
||
### 12.15 D4N Settings(分布式缓存)
|
||
|
||
| 配置项 | 类型 | 默认值 | 含义 |
|
||
|---|---|---|---|
|
||
| `rgw_d4n_address` | str | `127.0.0.1:6379` | D4N Redis 连接的地址 |
|
||
| `rgw_d4n_l1_datacache_persistent_path` | str | `/tmp/rgw_d4n_datacache/` | 本地缓存对象数据的存放路径 |
|
||
| `rgw_d4n_l1_datacache_size` | size | `1_G` | datacache 在磁盘上的最大容量 |
|
||
| `rgw_d4n_l1_evict_cache_on_start` | bool | `true` | 启动时是否清空持久化 datacache 的内容 |
|
||
| `rgw_d4n_l1_fadvise` | int | `4` | 缓存文件访问模式的 ``posix_fadvise()`` flag |
|
||
| `rgw_d4n_libaio_aio_threads` | int | `20` | libaio 可使用的最大工作线程数 |
|
||
| `rgw_d4n_libaio_aio_num` | int | `64` | libaio 预期入队的最大并发 I/O 请求数 |
|
||
| `rgw_lfuda_sync_frequency` | int | `60` | LFUDA 变量的同步频率(秒) |
|
||
| `rgw_d4n_l1_datacache_address` | str | `127.0.0.1:6379` | 本地 Redis 缓存地址 |
|
||
|
||
### 12.16 Topic persistency settings(通知持久化)
|
||
|
||
| 配置项 | 类型 | 默认值 | 含义 |
|
||
|---|---|---|---|
|
||
| `rgw_topic_persistency_time_to_live` | uint | `0` | 持久化 topic 的按时间保留时长(秒) |
|
||
| `rgw_topic_persistency_max_retries` | uint | `0` | 持久化通知的最大尝试发送次数。**值为 1 表示不重试,值为 0 表示无限重试** |
|
||
| `rgw_topic_persistency_sleep_duration` | uint | `0` | 同一条持久化通知两次尝试之间的最小时间间隔(秒)。**实际间隔可能更长** |
|
||
|
||
### 12.17 Cloud Restore settings(云回调)
|
||
|
||
| 配置项 | 类型 | 默认值 | 含义 |
|
||
|---|---|---|---|
|
||
| `rgw_restore_max_objs` | int | `32` | restore 处理的分片数 |
|
||
| `rgw_restore_lock_max_time` | int | `90` | restore 处理持锁的最长时间(秒)。**官方文档未提供 desc,含义由上下文推断** |
|
||
| `rgw_restore_processor_period` | int | `15_min` | Restore 周期运行时长 |
|
||
|
||
### 12.18 Metrics(监控指标,来自 metrics.rst)
|
||
|
||
| 配置项 | 类型 | 默认值 | 含义 |
|
||
|---|---|---|---|
|
||
| `rgw_user_counters_cache` | bool | `false` | 是否启用 rgw perf counters 缓存,用于带 user 标签的计数器。该缓存只包含以 user 为标签的 perf counters |
|
||
| `rgw_user_counters_cache_size` | uint | `10000` | user perf counters 缓存可存放的带标签 perf counters 数量 |
|
||
| `rgw_bucket_counters_cache` | bool | `false` | 是否启用 rgw perf counters 缓存,用于带 bucket 标签的计数器。该缓存只包含以 bucket 为标签的 perf counters |
|
||
| `rgw_bucket_counters_cache_size` | uint | `10000` | bucket perf counters 缓存可存放的带标签 perf counters 数量 |
|
||
| `exporter_stats_period` | 文档未明确 | `文档未明确` | 再次向 exporter server 发送请求前的等待时间(秒) |
|
||
|
||
### 12.19 NFS Settings(来自 nfs.rst)
|
||
|
||
| 配置项 | 类型 | 默认值 | 含义 |
|
||
|---|---|---|---|
|
||
| `rgw_nfs_frontends` | str | `rgw-nfs` | 以 librgw/nfs 方式运行时的前端配置。逗号分隔的前端配置列表;默认只启动 ``rgw-nfs`` 前端 |
|
||
| `rgw_nfs_namespace_expire_secs` | int | `5_min` | NFS 命名空间中缓存条目的过期时间。`nfs.rst` 说明:在 NFS 之外新增的 object/bucket 会在该时间后出现在 NFS 命名空间中,**默认 300 秒(5 分钟)** |
|
||
| `rgw_nfs_write_completion_interval_s` | int | `10` | NFSv3 下判定一次上传完成的静默间隔(秒),默认 10 秒 |
|
||
|
||
|
||
> 引自:[Ceph Object Gateway Config Reference](https://docs.ceph.com/en/tentacle/radosgw/config-ref/)
|
||
|
||
---
|
||
|
||
## 十三、排障(Troubleshooting)
|
||
|
||
来源:`troubleshooting.rst` 全文(7KB)。按「现象 → 原因 → 解决」逐场景列出。
|
||
|
||
### 13.1 场景一:网关无法启动(The Gateway Won't Start)
|
||
|
||
| 项目 | 内容 |
|
||
|---|---|
|
||
| **现象** | 无法启动网关(即**不存在**已有的 `pid`) |
|
||
| **原因** | 存在**另一个用户**留下的 `.asok` 文件。这可能发生在:你以 `root` 用户启动进程,而启动脚本试图以 `www-data` 或 `apache` 用户启动进程,此时已存在的 `.asok` 阻止了脚本启动守护进程 |
|
||
| **解决** | 若存在其它用户的 `.asok` 文件且**没有正在运行的 `pid`**,则**删除该 `.asok` 文件**并重试启动进程 |
|
||
|
||
**辅助诊断**:`radosgw` init 脚本(`/etc/init.d/radosgw`)提供了 verbose 参数,可提供一些线索:
|
||
|
||
```bash
|
||
/etc/init.d/radosgw start -v
|
||
```
|
||
|
||
或:
|
||
|
||
```bash
|
||
/etc/init.d radosgw start --verbose
|
||
```
|
||
|
||
### 13.2 场景二:HTTP 请求错误(HTTP Request Errors)
|
||
|
||
| 项目 | 内容 |
|
||
|---|---|
|
||
| **现象** | 出现 HTTP 请求错误,尤其是 **500 错误** |
|
||
| **原因** | 500 错误通常表明**与 `radosgw` 守护进程通信有问题** |
|
||
| **排查/解决** | 1) 检查 Web 服务器自身的 access log 与 error log(这通常是定位问题的第一步);2) 确保守护进程**正在运行**;3) 确保其 **socket 路径已配置**;4) 确保 Web 服务器在**正确的位置**寻找它 |
|
||
|
||
### 13.3 场景三:`radosgw` 进程崩溃(Crashed radosgw process)
|
||
|
||
| 项目 | 内容 |
|
||
|---|---|
|
||
| **现象** | 从 Web 服务器(apache、nginx 等)看到 **500 错误** |
|
||
| **原因** | `radosgw` 进程已死 |
|
||
| **恢复** | **简单地重启 `radosgw` 即可恢复服务** |
|
||
| **定位根因** | 检查 `/var/log/ceph` 中的日志,和/或 core file(如果有生成) |
|
||
|
||
### 13.4 场景四:`radosgw` 请求被阻塞(Blocked radosgw Requests)
|
||
|
||
| 项目 | 内容 |
|
||
|---|---|
|
||
| **现象** | 部分(或全部)`radosgw` 请求看起来被阻塞 |
|
||
| **排查手段** | 通过 `radosgw` 守护进程的 **admin socket** 查看其内部状态。默认会有一个 socket 配置在 `/var/run/ceph` 下,可用如下方式查询守护进程 |
|
||
|
||
```bash
|
||
ceph daemon /var/run/ceph/client.rgw help
|
||
```
|
||
|
||
可用命令:
|
||
|
||
```text
|
||
help list available commands
|
||
objecter_requests show in-progress osd requests
|
||
perfcounters_dump dump perfcounters value
|
||
perfcounters_schema dump perfcounters schema
|
||
version get protocol version
|
||
```
|
||
|
||
**特别值得关注的是**:
|
||
|
||
```bash
|
||
ceph daemon /var/run/ceph/client.rgw objecter_requests
|
||
```
|
||
|
||
该命令会 dump 当前与 RADOS 集群之间**进行中**的请求信息,从而判断是否有请求被**无响应的 OSD** 阻塞。示例输出:
|
||
|
||
```json
|
||
{ "ops": [
|
||
{ "tid": 1858,
|
||
"pg": "2.d2041a48",
|
||
"osd": 1,
|
||
"last_sent": "2012-03-08 14:56:37.949872",
|
||
"attempts": 1,
|
||
"object_id": "fatty_25647_object1857",
|
||
"object_locator": "@2",
|
||
"snapid": "head",
|
||
"snap_context": "0=[]",
|
||
"mtime": "2012-03-08 14:56:37.949813",
|
||
"osd_ops": [
|
||
"write 0~4096"]},
|
||
{ "tid": 1873,
|
||
"pg": "2.695e9f8e",
|
||
"osd": 1,
|
||
"last_sent": "2012-03-08 14:56:37.970615",
|
||
"attempts": 1,
|
||
"object_id": "fatty_25647_object1872",
|
||
"object_locator": "@2",
|
||
"snapid": "head",
|
||
"snap_context": "0=[]",
|
||
"mtime": "2012-03-08 14:56:37.970555",
|
||
"osd_ops": [
|
||
"write 0~4096"]}],
|
||
"linger_ops": [],
|
||
"pool_ops": [],
|
||
"pool_stat_ops": [],
|
||
"statfs_ops": []}
|
||
```
|
||
|
||
**诊断方法**:
|
||
|
||
1. 在这个 dump 中有两个进行中的请求。**`last_sent` 字段是 RADOS 请求发出的时间。如果该时间已经过去很久,说明 OSD 没有响应。**
|
||
2. 例如对请求 1858,可以检查 OSD 状态:
|
||
|
||
```bash
|
||
ceph pg map 2.d2041a48
|
||
```
|
||
|
||
```text
|
||
osdmap e9 pg 2.d2041a48 (2.0) -> up [1,0] acting [1,0]
|
||
```
|
||
|
||
3. 这告诉我们要看 **`osd.1`**——该 PG 的 primary copy:
|
||
|
||
```bash
|
||
ceph daemon osd.1 ops
|
||
```
|
||
|
||
```json
|
||
{ "num_ops": 651,
|
||
"ops": [
|
||
{ "description": "osd_op(client.4124.0:1858 fatty_25647_object1857 [write 0~4096] 2.d2041a48)",
|
||
"received_at": "1331247573.344650",
|
||
"age": "25.606449",
|
||
"flag_point": "waiting for sub ops",
|
||
"client_info": { "client": "client.4124",
|
||
"tid": 1858}},
|
||
...
|
||
```
|
||
|
||
4. **`flag_point` 字段表明该 OSD 当前正在等待副本响应**,在本例中是 `osd.0`。
|
||
|
||
### 13.5 场景五:Java S3 API — Peer Not Authenticated
|
||
|
||
| 项目 | 内容 |
|
||
|---|---|
|
||
| **现象** | `[java] INFO: Unable to execute HTTP request: peer not authenticated` |
|
||
| **原因** | **S3 的 Java SDK 默认使用 HTTPS**,因此要求来自**受信任证书颁发机构**的有效证书。仅测试 Ceph 对象存储服务时不需要这么严格 |
|
||
| **解决方法 1** | 在 IP 或主机名前加上 `http://`。把 `conn.setEndpoint("myserver");` 改成 `conn.setEndpoint("http://myserver")` |
|
||
| **解决方法 2** | 设置凭据之后,添加一个 client configuration 并把协议设为 `Protocol.HTTP`: |
|
||
|
||
```java
|
||
AWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
|
||
|
||
ClientConfiguration clientConfig = new ClientConfiguration();
|
||
clientConfig.setProtocol(Protocol.HTTP);
|
||
|
||
AmazonS3 conn = new AmazonS3Client(credentials, clientConfig);
|
||
```
|
||
|
||
### 13.6 场景六:405 MethodNotAllowed
|
||
|
||
| 项目 | 内容 |
|
||
|---|---|
|
||
| **现象** | 收到 405 错误,例如 `[java] Exception in thread "main" Status Code: 405, AWS Service: Amazon S3, AWS Request ID: null, AWS Error Code: MethodNotAllowed, AWS Error Message: null, S3 Extended Request ID: null` |
|
||
| **原因 1** | S3 subdomain 未正确设置。**需要**在 DNS 记录中有一条**通配(wild card)**设置,subdomain 功能才能正常工作 |
|
||
| **原因 2 / 解决 2** | 确保**默认站点已被禁用**(check to ensure that the default site is disabled) |
|
||
|
||
### 13.7 场景七:`default.rgw.meta` pool 中存在大量对象
|
||
|
||
| 项目 | 内容 |
|
||
|---|---|
|
||
| **现象** | `default.rgw.meta` pool 中存在**大量对象** |
|
||
| **原因** | 在 **jewel 之前**创建的集群**默认启用了一个元数据归档(metadata archival)特性**,使用 `default.rgw.meta` pool。该归档保存了**所有旧版本的 user 与 bucket 元数据**,导致 `default.rgw.meta` pool 中对象数量巨大 |
|
||
|
||
#### 解决步骤 1:禁用 Metadata Heap(停止新增)
|
||
|
||
希望**从今往后**禁用该特性的用户,应把 `metadata_heap` 字段设为空字符串 `""`:
|
||
|
||
```bash
|
||
$ radosgw-admin zone get --rgw-zone=default > zone.json
|
||
# 编辑 zone.json,设置 "metadata_heap": ""
|
||
$ radosgw-admin zone set --rgw-zone=default --infile=zone.json
|
||
$ radosgw-admin period update --commit
|
||
```
|
||
|
||
> **效果**:这会停止把新元数据写入 `default.rgw.meta` pool,但**不会移除任何已有对象或该 pool 本身**。
|
||
|
||
#### 解决步骤 2:清理 Metadata Heap Pool(清理存量)
|
||
|
||
> **前置检查(重要)**:从 **luminous** 起,radosgw 在 `default.rgw.meta` 中使用 **Pool Namespaces** 服务于**完全不同的目的**——即存储 `user_keys` 和其它**关键元数据**。因此:
|
||
|
||
```bash
|
||
$ radosgw-admin zone get --rgw-zone=default | grep default.rgw.meta
|
||
# 应该不匹配任何字符串(should not match any strings)
|
||
```
|
||
|
||
**在确认该 pool 没有被用于任何用途之后**,用户可以安全地删除 `default.rgw.meta` pool 中的所有对象,或可选地删除整个 pool。
|
||
|
||
> ⚠️ jewel 之前创建的集群通常只把 `default.rgw.meta` 用于元数据归档特性;但 luminous 之后该 pool 承担了新的关键用途,**务必先做上面的 grep 检查再清理**。
|
||
|
||
> 引自:[troubleshooting](https://docs.ceph.com/en/tentacle/radosgw/troubleshooting/)
|
||
|
||
---
|
||
|
||
## 十四、命令速查表(radosgw-admin 常用命令)
|
||
|
||
| 分类 | 命令 | 说明 |
|
||
|---|---|---|
|
||
| 用户 | `radosgw-admin user create --uid=<uid> --display-name="<name>" [--email=<e>]` | 创建 S3 用户 |
|
||
| 用户 | `radosgw-admin user info --uid=<uid>` | 查看用户信息(含配额设置) |
|
||
| 用户 | `radosgw-admin user modify --uid=<uid> --display-name="<name>"` | 修改用户信息 |
|
||
| 用户 | `radosgw-admin user modify --uid=<uid> --admin` / `--admin=0` | 添加 / 移除 admin 标志 |
|
||
| 用户 | `radosgw-admin user modify --uid=<uid> --placement-id=<p> --storage-class=<s> --tags=<t1,t2>` | 修改用户的 placement / storage class / tags |
|
||
| 用户 | `radosgw-admin user suspend --uid=<uid>` | 暂停用户(同时禁用其 subuser) |
|
||
| 用户 | `radosgw-admin user enable --uid=<uid>` | 恢复用户 |
|
||
| 用户 | `radosgw-admin user rm --uid=<uid> [--purge-data] [--purge-keys]` | 删除用户及其 subuser |
|
||
| 用户 | `radosgw-admin user stats --uid=<uid> [--sync-stats]` | 查看/同步用户用量与配额统计 |
|
||
| 子用户 | `radosgw-admin subuser create --uid=<uid> --subuser=<uid:sub> --access=[read\|write\|readwrite\|full]` | 创建 Swift 子用户 |
|
||
| 子用户 | `radosgw-admin subuser modify --uid=<uid> --subuser=<uid:sub> --access=full` | 修改子用户权限 |
|
||
| 子用户 | `radosgw-admin subuser rm --subuser=<uid:sub> [--purge-keys]` | 删除子用户 |
|
||
| 密钥 | `radosgw-admin key create --uid=<uid> --key-type=s3 --access-key=<ak> --secret-key=<sk>` | 添加 S3 key 对 |
|
||
| 密钥 | `radosgw-admin key create --subuser=<uid:sub> --key-type=swift --secret-key=<sk>` | 添加 Swift secret key |
|
||
| 密钥 | `radosgw-admin key create --subuser=<uid:sub> --key-type=s3 --access-key=<ak> --secret-key=<sk>` | 为子用户关联 S3 key 对 |
|
||
| 密钥 | `radosgw-admin key rm --uid=<uid> --key-type=s3 --access-key=<ak>` | 删除 S3 key 对 |
|
||
| 密钥 | `radosgw-admin key rm --subuser=<uid:sub> --key-type=swift` | 删除 Swift secret key |
|
||
| 能力 | `radosgw-admin caps add --uid=<uid> --caps="users=*;buckets=*"` | 添加管理能力 |
|
||
| 能力 | `radosgw-admin caps rm --uid=<uid> --caps="users=*"` | 移除管理能力 |
|
||
| 配额 | `radosgw-admin quota set --quota-scope=user --uid=<uid> [--max-objects=N] [--max-size=S]` | 设置用户配额 |
|
||
| 配额 | `radosgw-admin quota enable --quota-scope=user --uid=<uid>` | 启用用户配额 |
|
||
| 配额 | `radosgw-admin quota disable --quota-scope=user --uid=<uid>` | 禁用用户配额 |
|
||
| 配额 | `radosgw-admin quota set --quota-scope=bucket {--bucket=<b>\|--uid=<uid>} [--max-objects=N] [--max-size=S]` | 设置 bucket 配额 |
|
||
| 配额 | `radosgw-admin quota enable --quota-scope=bucket --uid=<uid>` | 启用 bucket 配额 |
|
||
| 配额 | `radosgw-admin quota set --quota-scope=account --account-id=<id> --max-size=10G` | 设置 account 配额 |
|
||
| 配额 | `radosgw-admin quota enable --quota-scope=account --account-id=<id>` | 启用 account 配额 |
|
||
| 配额 | `radosgw-admin global quota get` | 查看全局配额 |
|
||
| 配额 | `radosgw-admin global quota set --quota-scope bucket --max-objects 1024` | 设置全局配额 |
|
||
| 配额 | `radosgw-admin global quota enable --quota-scope bucket` | 启用全局配额 |
|
||
| 限流 | `radosgw-admin ratelimit set --ratelimit-scope=user --uid=<uid> [--max-read-ops=N] [--max-read-bytes=N] [--max-write-ops=N] [--max-write-bytes=N]` | 设置用户限流 |
|
||
| 限流 | `radosgw-admin ratelimit get --ratelimit-scope=user --uid=<uid>` | 查看用户限流 |
|
||
| 限流 | `radosgw-admin ratelimit enable --ratelimit-scope=user --uid=<uid>` | 启用用户限流 |
|
||
| 限流 | `radosgw-admin ratelimit disable --ratelimit-scope=user --uid=<uid>` | 禁用用户限流 |
|
||
| 限流 | `radosgw-admin ratelimit set --ratelimit-scope=bucket --bucket=<b> [--max-read-ops=N] ...` | 设置 bucket 限流 |
|
||
| 限流 | `radosgw-admin ratelimit get --ratelimit-scope=bucket --bucket=<b>` | 查看 bucket 限流 |
|
||
| 限流 | `radosgw-admin ratelimit enable --ratelimit-scope=bucket --bucket=<b>` | 启用 bucket 限流 |
|
||
| 限流 | `radosgw-admin ratelimit disable --ratelimit-scope=bucket --uid=<b>` | 禁用 bucket 限流 |
|
||
| 限流 | `radosgw-admin global ratelimit get` | 查看全局限流 |
|
||
| 限流 | `radosgw-admin global ratelimit set --ratelimit-scope {bucket\|user\|anonymous} --max-read-ops=1024` | 设置全局限流 |
|
||
| 限流 | `radosgw-admin global ratelimit enable --ratelimit-scope {bucket\|user\|anonymous}` | 启用全局限流 |
|
||
| 用量 | `radosgw-admin usage show --uid=<uid> --start-date=<d> --end-date=<d>` | 查看用量(需 `rgw_enable_usage_log = true`) |
|
||
| 用量 | `radosgw-admin usage show --show-log-entries=false` | 查看所有用户的用量汇总 |
|
||
| 用量 | `radosgw-admin usage trim --uid=<uid> --end-date=<d>` | 裁剪用量日志 |
|
||
| 账号 | `radosgw-admin account create [--account-name=<n>] [--account-id=<id>] [--email=<e>]` | 创建 account |
|
||
| 账号 | `radosgw-admin user create --uid=<u> --display-name=<n> --account-id=<id> --account-root --gen-secret --gen-access-key` | 创建 account root user |
|
||
| 账号 | `radosgw-admin account rm --account-id=<id>` | 删除 account |
|
||
| 账号 | `radosgw-admin account stats --account-id=<id> --sync-stats` | 查看 account 统计 |
|
||
| 账号 | `radosgw-admin user modify --uid=<u> --account-id=<id>` | 把已有用户迁入 account(不可逆) |
|
||
| 租户 | `radosgw-admin --tenant <t> --uid <u> --display-name "<n>" user create` | 创建带显式 tenant 的用户 |
|
||
| 租户 | `radosgw-admin --subuser '<tenant>$<user>:<sub>' --key-type swift --secret <s>` | 操作带显式 tenant 的子用户(shell 中需加引号) |
|
||
| 区域 | `radosgw-admin zonegroup get` | 查看 zonegroup(含 placement_targets) |
|
||
| 区域 | `radosgw-admin zone get [--rgw-zone=<z>]` | 查看 zone(含 placement_pools) |
|
||
| 区域 | `radosgw-admin zone set --rgw-zone=<z> --infile=<f>` | 应用 zone 配置 |
|
||
| 区域 | `radosgw-admin zonegroup placement add --rgw-zonegroup <zg> --placement-id <p> [--storage-class <sc>]` | 添加 placement target / storage class(zonegroup 侧) |
|
||
| 区域 | `radosgw-admin zone placement add --rgw-zone <z> --placement-id <p> [--storage-class <sc>] --data-pool <dp> --index-pool <ip> --data-extra-pool <xp> [--compression <c>] [--placement-inline-data=false]` | 添加 placement 的 zone 侧 pool 映射 |
|
||
| 区域 | `radosgw-admin zonegroup placement default --rgw-zonegroup <zg> --placement-id <p>` | 修改默认 placement target |
|
||
| 区域 | `radosgw-admin period update --commit` | 提交 period 变更(realm 场景必做) |
|
||
| Bucket | `radosgw-admin bucket stats --bucket=<b>` | 查看 bucket 统计(含 `placement_rule`) |
|
||
| 元数据 | `radosgw-admin metadata list [bucket\|bucket.instance\|user\|...]` | 列举元数据类型/条目 |
|
||
| 元数据 | `radosgw-admin metadata get user:<user>` | 获取元数据条目 |
|
||
| 元数据 | `radosgw-admin metadata get bucket:<bucket>` | 获取 bucket 元数据 |
|
||
| 元数据 | `radosgw-admin metadata get bucket.instance:<bucket>:<bucket_id>` | 获取 bucket instance 元数据 |
|
||
| GC | `radosgw-admin gc list` | 查看等待 GC 的对象队列(`--include-all` 含未过期条目) |
|
||
| 通知 | `radosgw-admin topic rm --topic <name>` | 删除通知 topic |
|
||
| 配置 | `ceph config set client.rgw <CONFIG_VARIABLE> <VALUE>` | 运行时设置 RGW 配置项 |
|
||
| 配置 | `ceph config set client.rgw rgw_user_counters_cache true` | 启用 user 级 op metrics |
|
||
| 配置 | `ceph config set client.rgw rgw_bucket_counters_cache true` | 启用 bucket 级 op metrics |
|
||
| 配置 | `ceph config set global exporter_stats_period <seconds>` | 设置 exporter scrape 间隔 |
|
||
| 诊断 | `ceph daemon /var/run/ceph/client.rgw help` | 查看 RGW admin socket 可用命令 |
|
||
| 诊断 | `ceph daemon /var/run/ceph/client.rgw objecter_requests` | 查看进行中的 OSD 请求(排查阻塞) |
|
||
| 诊断 | `ceph pg map <pgid>` | 查看 PG 映射到哪些 OSD |
|
||
| 诊断 | `ceph daemon osd.<N> ops` | 查看某 OSD 的进行中 op |
|
||
|
||
---
|
||
|
||
## 文档未明确项
|
||
|
||
本册以下内容在 Ceph Tentacle v20.2.4 官方文档的本册范围内**未明确说明**,未作臆测,留待后续补充或参考其它分册:
|
||
|
||
1. **各 RGW pool 的建议 PG 数量**:`pools.rst` 只说明 pool 首次被操作时由 `osd pool default pg num` / `osd pool default pgp num` 创建,并提示 `placement_pools` 中列出的 bucket index 与 data 池「需要额外调优」,但**未给出任何具体 PG 数值建议**。
|
||
2. **zone 定义中的完整 pool 清单**:`pools.rst` 明确说「The zone definitions list several more pools than that」,但本册范围内(不含 `multisite.rst`)**未逐一列出**这些 pool 的名字与用途。
|
||
3. **`realm` 与 `period` 的完整语义**:本册源文仅在 `placement.rst` 的 note 中提及 realm 与 `period update --commit`,其完整定义、层级与操作属第 10 册(`multisite.rst`)范畴。
|
||
4. **RGW 与原生 AWS S3 的完整差异清单**:官方只说明「compatible with a *large subset*」,本册源文只散落地给出 storage class 命名、`GLACIER` 前缀、bucket 命名规则、多租户、NFS 语义等具体差异点,**没有系统性清单**。
|
||
5. **RGW 的适用/不适用场景清单**:官方未提供,本册第一章中的归纳为💡补充内容。
|
||
6. **multipart 在 RADOS 中的完整布局**:`layout.rst` 未系统讲述 `shadow` 对象的切分规则、`rgw_obj_stripe_size` 与 tail 对象的关系等,只给出了零散事实点(示例对象名、`data_extra_pool` 用途、`check-objects` 检查项)。
|
||
7. **`default.rgw.log` pool 的具体用途**:`pools.rst` 与 `layout.rst` 附录只列出名字,未展开说明其存的是什么。
|
||
8. **civetweb 前端的引入版本与选项**:`frontends.rst` 只详述 `beast`;`config-ref.rst` 提到 civetweb 是「older and now non-default」,但**未说明其引入版本,也未列出其选项**。
|
||
9. **Swift with built-in authenticator 的多租户方式**:`multitenancy.rst` 原文即为 `TBD -- not in test_multen.py yet`。
|
||
10. **NFS-Ganesha idmapper 集成细节**:`nfs.rst` 原文说明「Details of idmapper integration are not provided here」。
|
||
11. **`rgw_restore_lock_max_time` 的含义**:`rgw.yaml.in` 中该配置项**没有 `desc`/`long_desc`/`fmt_desc` 字段**,只有默认值 `90`;本册按上下文推断为「restore 处理持锁的最长时间(秒)」,已标注。
|
||
12. **`rgw_nfs_namespace_expire_secs` 的语义描述**:`rgw.yaml.in` 中同样无 desc 字段;本册以 `nfs.rst` 正文(默认 300 秒 / 5 分钟)为准。
|
||
13. **Admin Ops API 中 `Get Usage` 与 `Trim Usage` 的 Special Error Responses**:源文原文即为 `TBD.`
|
||
14. **Admin Ops API 中 `Get Bucket Rate Limit` 所需 caps**:源文写的是「`users` capability set with `read` permission」,与其余限流操作的 `ratelimit=read` 不一致,**源文本身如此,未作修正**。
|
||
15. **`zone placement modify` 的独立示例**:`placement.rst` 只提到该命令支持 `--placement-inline-data=false`,未给出独立示例。
|
||
16. **`exporter_stats_period` 的 Prometheus 侧 scrape 配置**:`metrics.rst` 只给出 Prometheus 官方文档链接,未在本册展开。
|