7.Ceph 分布式存储 对象存储管理
7.Ceph 分布式存储 对象存储管理
对象存储介绍
对象存储简介
对象存储是一个基于对象的存储服务, 提供海量、 安全、 高可靠、 低成本的数据存储能力。
对象存储将数据存储为离散项,每一项也是一个对象。每个对象都具有唯一的对象ID(也称对象密钥),用户可在不了解对象位置的情况下,通过对象ID进行存储或检索。
对象存储中的对象实际是一个文件数据与其相关属性信息的集合体, 包括三个部分:
- Key:键值,即对象的名称,为经过 UTF-8 编码的长度大于0且不超过1024的字符序列。一个桶里的每个对象必须拥有唯一的对象键值。
- Metadata:元数据,即对象的描述信息,包括系统元数据和用户元数据,这些元数据以键值对(Key-Value)的形式被上传到对象存储中。元数据由对象存储产生,在处理对象数据时使用,包括Date, Content-length,Last-modify, ETag等。
- Data:数据,即文件的数据内容。
对象存储在扁平的命名空间中,称为桶,是对象存储存储对象的容器。 桶中的所有对象都处于同一逻辑层级, 去除了文件系统中的多层级树形目录结构。每个桶都有自己的存储类别、 访问权限、 所属区域等属性, 用户可以在不同区域创建不同存储类别和访问权限的桶, 并配置更多高级属性来满足不同场景的存储诉求。
对象存储特征
- 接入灵活:支持多种形态客户端,如通过用对象存储接口、 RESTful接口、 SDK等。
- 访问协议简单:使用http或https协议访问。
- 访问网络不受限:通过互联网或局域网都进行访问。
- 结构扁平化:对象直接存放在桶中,无目录结构。
RADOS 网关介绍
RADOS 网关简介
-
RADOS GateWay,也称对象网关 (RGW),**为客户端提供标准对象存储 API 来访问 Ceph 集群。**Ceph 存储支持 Amazon S3(简单存储服务)和 OpenStack Swift(OpenStack 对象存储)两种常用的对象 API。Amazon S3 将对象存储的扁平命名空间称为存储桶,而 OpenStack Swift 则将其称为容器。
-
守护进程 radosgw 在 librados 库的基础上构建,提供基于 Beast HTTP、WebSocket 和网络协议库的 Web 服务接口,作为处理 API 请求的前端。
-
radosgw 是Ceph 存储的客户端,用于访问对象存储中对象。
RADOS 网关中用户只能访问网关,不能像cephx 用户一样直接访问存储集群。提交 Amazon S3 或 OpenStack Swift API 请求时,RADOS 网关客户端会使用这些网关用户帐户进行身份验证。网关用户通过 RADOS 网关完成身份验证后,网关会使用 cephx 凭据向存储集群进行身份验证,以处理对象请求。也可通过集成基于 LDAP 的外部身份验证服务来管理网关用户。
RADOS 网关会为默认区域创建多个池:
- .rgw.root,存储信息记录。
- .default.rgw.control,控制池。
- .default.rgw.meta,存储 user_keys 和其他关键元数据。
- .default.rgw.log,包含所有存储桶/容器和对象操作(如创建、读取和删除)的日志。
- .default.rgw.buckets.index,存储存储桶的索引。
- .default.rgw.buckets.data,存储存储桶数据。
- .default.rgw.buckets.non-ec,用于对象元数据上传。
用户也可以手动创建这些池。建议这些池名称以区域名称为前缀,例如区域名称是 us-east-1,则池名称可以是 .us-east-1.rgw.buckets.data。
RADOS 网关架构
Ceph RADOS 网关支持多站点部署:在多个 Ceph 存储集群之间自动复制对象数据。常见的用例是在地理上分隔的集群之间进行主动/主动复制,以便于灾难恢复。
-
区域(zone),每个区域会关联一个或多个 RADOS 网关,这些网关关联Ceph 存储。
-
区域组(zone group ),区域组是由一个或多个区域的集合。存储在区域组中某个区域中的数据会被复制到该区域组中的所有其他区域。每个区域组中会有一个区域为该组的主区域,该组中的其他区域为次要区域。
-
域 (realm) ,代表所有对象和存储桶的全局命名空间。域中含有一个或多个区域组,各自包含一个或多个区域。域中会指定一个区域组为主区域组,其他都是次要区域组。域 (realm) 中的所有 RADOS 网关都从位于主区域组中主区域中的 RADOS 网关拉取配置。因为主区域组中的主区域负责处理所有元数据更新,所以创建用户等操作都必须在主区域进行。
每个域有关联的期间 (period),每个期间有关联的时期 (epoch)。
- 期间 (period),用于跟踪特定时间域、区域组和区域的配置状态。每个期间有一个唯一 ID,包含域配置,并且知道前一个期间的 ID。
- 时期 (epoch),用于跟踪特定域期间的配置版本号。
更新规则:
- 更新主区域的配置时,RADOS 网关服务使用当前时间更新期间。这个新期间会变成域的当前期间,该期间的时期值会增加一。
- 至于其他配置更改,只有时期会递增,期间不会变化。
RADOS 网关用例
Ceph 对象存储因其高扩展性、高可靠性和灵活性,适用于多种场景,包括大规模数据存储、云服务、备份归档、大数据分析、多媒体存储、容器存储、灾难恢复、混合云、科学计算和物联网数据存储等。
以下是常见的使用场景及原因:
- 大规模数据存储
- 场景: 适用于需要存储海量非结构化数据的场景,如视频、图片、日志等。
- 原因: Ceph 对象存储能轻松扩展到 PB 甚至 EB 级别,适合处理大规模数据。
- 云存储服务
- 场景: 用于公有云或私有云中的对象存储服务。
- 原因: Ceph 兼容 S3 和 Swift API,便于与现有云平台集成,提供高可用性和持久性。
- 备份和归档
- 场景: 用于长期数据备份和归档。
- 原因: Ceph 提供高可靠性和低成本存储,支持数据压缩和加密,适合长期保存。
- 大数据分析
- 场景: 存储大数据分析中的原始数据或中间结果。
- 原因: Ceph 的高吞吐量和低延迟特性,适合大数据应用的读写需求。
- 多媒体内容存储与分发
- 场景: 用于存储和分发视频、音频等多媒体内容。
- 原因: Ceph 的高并发读写能力,适合内容分发网络(CDN)的需求。
- 容器存储
- 场景: 为 Kubernetes 等容器平台提供持久化存储。
- 原因: Ceph 支持 RBD 和 CephFS,适合容器环境中的动态存储需求。
- 灾难恢复
- 场景: 用于跨地域的数据复制和灾难恢复。
- 原因: Ceph 支持多站点复制,确保数据在灾难发生时的高可用性。
- 混合云存储
- 场景: 在混合云环境中统一管理数据。
- 原因: Ceph 可在私有云和公有云之间无缝迁移数据,提供一致的存储体验。
- 科学计算与高性能计算(HPC)
- 场景: 存储科学计算和 HPC 中的大量数据。
- 原因: Ceph 的高吞吐量和并行访问能力,适合科学计算中的大规模数据处理。
- 物联网(IoT)数据存储
- 场景: 存储物联网设备生成的海量数据。
- 原因: Ceph 的高扩展性和高可靠性,适合处理物联网设备产生的大量数据。
RADOS 网关部署
Ceph 使用 Ceph 编排器来部署(或删除) RADOS 网关服务,用于管理单个集群或多个集群。使用集中式配置数据库中的 client.rgw.* 部分来定义新 RADOS 网关守护进程的参数和特征。
对象存储网关部署流程:
- 创建对象存储域
- 创建对象网关
创建对象存储域
示例:
# 创建 realm
[root@ceph1 ~]# radosgw-admin realm create --rgw-realm=webapp --default
[root@ceph1 ~]# radosgw-admin realm list
{
"default_info": "527e3bea-d51d-462e-92d7-79aaf422a89c",
"realms": [
"webapp"
]
}
# 创建 zonegroup,并将其设置为 master
[root@ceph1 ~]# radosgw-admin zonegroup create --rgw-realm=webapp --rgw-zonegroup=video --master --default
[root@ceph1 ~]# radosgw-admin zonegroup list
{
"default_info": "0fdaf584-33ee-4be7-978c-fb2771181aee",
"zonegroups": [
"video"
]
}
# 创建 zone,并将其设置为 master
[root@ceph1 ~]# radosgw-admin zone create --rgw-realm=webapp --rgw-zonegroup=video --rgw-zone=storage --master --default
[root@ceph1 ~]# radosgw-admin zone list
{
"default_info": "76366a48-2ab8-4830-9cf7-f9b2fe432c5a",
"zones": [
"storage"
]
}
# 提交配置
[root@ceph1 ~]# radosgw-admin period update --rgw-realm=webapp --commit
RADOS 网关部署
RADOS 网关部署-命令行
# 创建 rgw,并和已创建的 realm webapp 进行关联,数量为 3
[root@ceph1 ~]# ceph orch apply rgw webapp --placement="3 ceph1.bq.cloud ceph2.bq.cloud ceph3.bq.cloud" --realm=webapp --zone=storage --port=8080
# 查看服务
[root@ceph1 ~]# ceph orch ls rgw
NAME PORTS RUNNING REFRESHED AGE PLACEMENT
rgw.webapp ?:8080 3/3 40s ago 45s ceph1.bq.cloud;ceph2.bq.cloud;ceph3.bq.cloud;count:3
# 查看进程
[root@ceph1 ~]# ceph orch ps --daemon-type rgw| awk '{print $1,$4}'
NAME STATUS
rgw.webapp.ceph1.luxaau running
rgw.webapp.ceph2.hrdzlb running
rgw.webapp.ceph3.pyfond running
验证对象存储是否可以访问
[root@ceph1 ~]# curl http://ceph1.bq.cloud:8080
<?xml version="1.0" encoding="UTF-8"?><ListAllMyBucketsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Owner><ID>anonymous</ID><DisplayName></DisplayName></Owner><Buckets></Buckets></ListAllMyBucketsResult>
[root@ceph1 ~]# curl http://ceph2.bq.cloud:8080
<?xml version="1.0" encoding="UTF-8"?><ListAllMyBucketsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Owner><ID>anonymous</ID><DisplayName></DisplayName></Owner><Buckets></Buckets></ListAllMyBucketsResult>
[root@ceph1 ~]# curl http://ceph3.bq.cloud:8080
<?xml version="1.0" encoding="UTF-8"?><ListAllMyBucketsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Owner><ID>anonymous</ID><DisplayName></DisplayName></Owner><Buckets></Buckets></ListAllMyBucketsResult>
# RADOS 网关部署-服务文件#跳过
RADOS 网关-部署
以下示例 YAML 文件中,Ceph 编排器会将 rgw.webapp RADOS 网关服务和3个守护进程部署到单个集群中,并会通过端口 8080 提供该服务。
[root@ceph1 ~]# vim rgw_service.yaml
service_type: rgw
service_id: webapp
service_name: rgw.webapp
placement:
count: 3
hosts:
- ceph1.bq.cloud
- ceph2.bq.cloud
- ceph3.bq.cloud
spec:
rgw_frontend_port: 8080
服务规范文件说明:
- **count 参数用于设定创建的 RGW 实例数量。**如果在一个主机上创建多个实例,Ceph 编排器会将第一个实例的端口设置为指定的 rgw_frontend_port 或 port 值。对于每个后续实例,端口值加 1。例如:ceph1.bq.cloud 服务器运行两个 RGW 实例,一个使用端口 8080,另一个使用端口 8081。
- 每个实例都启用自己的唯一端口进行访问,并对请求创建相同的响应。通过部署提供单一服务 IP 地址和端口的负载平衡器服务,为 RADOS 网关配置高可用性。
应用部署:
[root@ceph1 ~]# ceph orch apply -i rgw_service.yaml
Scheduled rgw.webapp update...
**有些参数(如 RGW 实例使用的网络或 ssl 证书内容)只能使用服务规格文件来定义。**在服务规范文件中,域、区域和端口的参数名称与 CLI 使用的参数名称不同。
#RADOS 网关-实例删除
# 更改 rgw.webapp 服务实例为2
[root@ceph1 ~]# vim rgw_service.yaml
service_type: rgw
service_id: webapp
service_name: rgw.webapp
placement:
count: 2
hosts:
- ceph1.bq.cloud
- ceph2.bq.cloud
spec:
rgw_frontend_port: 8080
[root@ceph1 ~]# ceph orch apply -i rgw_service.yaml
#RADOS 网关-实例添加
# 更改 rgw.webapp 服务实例为3
[root@ceph1 ~]# vim rgw_service.yaml
service_type: rgw
service_id: webapp
service_name: rgw.webapp
placement:
count: 3
hosts:
- ceph1.bq.cloud
- ceph2.bq.cloud
- ceph3.bq.cloud
spec:
rgw_frontend_port: 8080
[root@ceph1 ~]# ceph orch apply -i rgw_service.yaml
#RADOS 网关-配置备份
# 查看当前 RADOS 网关配置
[root@ceph1 ~]# ceph orch ls rgw --format yaml
service_type: rgw
service_id: webapp
service_name: rgw.webapp
placement:
count: 3
hosts:
- ceph1.bq.cloud
- ceph2.bq.cloud
- ceph3.bq.cloud
spec:
rgw_frontend_port: 8080
status:
created: '2023-09-20T03:07:39.524771Z'
running: 0
size: 3
events:
- 2023-09-20T03:01:03.668554Z service:rgw.webapp [INFO] "service was created"
# 备份生成的文件
[root@ceph1 ~]# ceph orch ls rgw --format yaml -o rgw_service.yaml
#RADOS 网关-配置恢复
# 删除status之后所有行记录
[root@ceph1 ~]# sed '/^status/,$d' rgw_service.yaml
service_type: rgw
service_id: webapp
service_name: rgw.webapp
placement:
count: 3
hosts:
- ceph1.bq.cloud
- ceph2.bq.cloud
- ceph3.bq.cloud
spec:
rgw_frontend_port: 8080
[root@ceph1 ~]# ceph orch apply -i rgw_service.yaml
RADOS 网关删除-跳过
删除 RADOS 网关服务,将删除 RADOS 网关对应所有进程。
[root@ceph1 ~]# ceph orch rm rgw.webapp
注意:删除RADOS 网关,并不会删除池中数据。
删除对象存储域-跳过
# 删除 zone
[root@ceph1 ~]# radosgw-admin zone delete --rgw-zone=storage
# 删除 zonegroup
[root@ceph1 ~]# radosgw-admin zonegroup delete --rgw-zonegroup=video
# 删除 realm
[root@ceph1 ~]# radosgw-admin realm delete --rgw-realm=webapp
管理对象网关用户
创建用户
使用 radosgw-admin user create 命令来创建 RADOS 网关用户。
- 必选选项 --uid 和 --display-name ,指定唯一的帐户名和人性化显示名。
- 可选选项 --access-key 和 --secret,指定自定义 AWS 帐户和机密密钥。
示例:
[root@ceph1 ~]# radosgw-admin user create --uid="operator" --display-name="S3 Operator" --email="operator@example.com" --access_key="12345" --secret="67890"
{
"user_id": "operator",
"display_name": "S3 Operator",
"email": "operator@example.com",
"suspended": 0,
"max_buckets": 1000,
"subusers": [],
"keys": [
{
"user": "operator",
"access_key": "12345",
"secret_key": "67890"
}
],
......
[root@ceph1 ~]# radosgw-admin user list
[
"operator"
]
[root@ceph1 ~]# radosgw-admin user info --uid=operator
{
"user_id": "operator",
"display_name": "S3 Operator",
"email": "operator@example.com",
"suspended": 0,
"max_buckets": 1000,
"subusers": [],
"keys": [
{
"user": "operator",
"access_key": "12345",
"secret_key": "67890"
}
],
......
如果未指定访问密钥和机密密钥,则自动生成,并显示在输出中。
[root@ceph1 ~]# radosgw-admin user create --uid=s3user --display-name="Amazon S3 API user"
{
"user_id": "s3user",
"display_name": "Amazon S3 API user",
"email": "",
"suspended": 0,
"max_buckets": 1000,
"subusers": [],
"keys": [
{
"user": "s3user",
"access_key": "ZQI72JZZDTA8BRCQOLGK",
"secret_key": "BN6lMGhqacV61Fx2iEHww9N0ySI3Vvo6jMwCJnxX"
}
],
......
**注意:**radosgw-admin 命令自动生成的访问密钥和机密密钥可能包含 JSON 转义字符(\)。客户端可能无法正确处理此字符。建议重新生成或手动指定密钥以避免此问题。
重新生成密钥
仅重新生成现有用户的机密密钥。
[root@ceph1 ~]# radosgw-admin key create --uid=s3user --access-key="ZQI72JZZDTA8BRCQOLGK" --gen-secret
{
"user_id": "s3user",
"display_name": "Amazon S3 API user",
"email": "",
"suspended": 0,
"max_buckets": 1000,
"subusers": [],
"keys": [
{
"user": "s3user",
"access_key": "ZQI72JZZDTA8BRCQOLGK",
"secret_key": "TJCcwo8rspE4xYyLAZHz4vapWA42YGB8hhrlPUnl"
}
],
......
添加用户访问密钥
若要为现有用户添加访问密钥,请使用 –gen-access-key 选项。创建额外的密钥可以方便地授予同一用户对需要不同或唯一密钥的多个应用的访问权限。
[root@ceph1 ~]# radosgw-admin key create --uid=s3user --gen-access-key
{
"user_id": "s3user",
"display_name": "Amazon S3 API user",
"email": "",
"suspended": 0,
"max_buckets": 1000,
"subusers": [],
"keys": [
{
"user": "s3user",
"access_key": "6WBR1FL8CBFX26KVRPPA",
"secret_key": "UsytqYCeSudSqHKWwVVYZGFDdcS24lPpkXBrD42G"
},
{
"user": "s3user",
"access_key": "ZQI72JZZDTA8BRCQOLGK",
"secret_key": "TJCcwo8rspE4xYyLAZHz4vapWA42YGB8hhrlPUnl"
}
],
......
删除用户密钥
要从用户删除访问密钥和相关的机密密钥,请使用 radosgw-admin key rm --access-key 命令。此操作非常适用于删除单个应用访问权限,并且不会影响使用其他密钥的访问权限。
[root@ceph1 ~]# radosgw-admin key rm --uid=s3user --access-key=6WBR1FL8CBFX26KVRPPA
{
"user_id": "s3user",
"display_name": "Amazon S3 API user",
"email": "",
"suspended": 0,
"max_buckets": 1000,
"subusers": [],
"keys": [
{
"user": "s3user",
"access_key": "ZQI72JZZDTA8BRCQOLGK",
"secret_key": "TJCcwo8rspE4xYyLAZHz4vapWA42YGB8hhrlPUnl"
}
],
......
临时禁用对象网关用户
使用 radosgw-admin user suspend 命令可临时禁用 RADOS 网关用户,用户的子用户也会暂停,无法与 RADOS 网关服务交互。
root@ceph1 ~]# radosgw-admin user suspend --uid=s3user
{
"user_id": "s3user",
"display_name": "Amazon S3 API user",
"email": "",
"suspended": 1, <----看着变成了1
....
注意:suspended的值为1。
临时启用对象网关用户
使用 radosgw-admin user enable 命令可启用 RADOS 网关用户。
root@ceph1 ~]# radosgw-admin user enable --uid=s3user
{
"user_id": "s3user",
"display_name": "Amazon S3 API user",
"email": "",
"suspended": 0,
....
注意:suspended的值为0。
修改用户信息
用户可修改用户信息,如电子邮件、显示名、密钥和访问控制级别。
[root@ceph1 ~]# radosgw-admin user modify --uid=s3user --access=full
–access 选项用于控制子用户访问权限,控制级别有:read、write、 readwrite 和 full。full 访问级别包括 readwrite 级别和访问控制管理功能。
删除用户
若要移除用户,同时删除其对象和存储桶,需使用 --purge-data 选项。
[root@ceph1 ~]# radosgw-admin user list
[
"operator",
"s3user"
]
[root@ceph1 ~]# radosgw-admin user rm --uid=s3user --purge-data
[root@ceph1 ~]# radosgw-admin user list
[
"operator"
]
使用 Amazon S3 API 访问对象存储
Amazon S3 API 介绍
在混合云环境中,用户希望应用可以通过相同的 API 无缝混用私有企业、公共云资源和存储位置。Ceph 存储支持使用 Amazon S3 API 接口管理对象存储资源。
Amazon S3 API 称命名空间为存储桶,用于存储对象。要使用 Amazon S3 API 管理对象和存储桶,应用需通过 RADOS 网关用户进行身份验证。每个用户都有一个识别用户的 access key 和一个对用户进行身份验证的 secret key。
使用 Amazon S3 API 时,需考虑对象和元数据的大小限制:
- 对象大小介于 0B 和 5 TB 之间。
- 单次上传操作的最大大小为 5GB。
- 使用分段上传功能可上传 100MB 以上的对象。
- 单个 HTTP 请求中的元数据大小最大为 16,000 字节。
安装 Amazon S3 API 客户端
Amazon S3 API 客户端有多个,例如 awscli、cloudberry、cyberduck 和 curl。
**这里我们讲解 aws 工具。**aws工具由awscli 软件包提供。
以下演示通过pip方式安装。
# 准备 aliyun 源 pip 仓库
[root@client ~]# mkdir .pip
[root@client ~]# cat > .pip/pip.conf << 'EOF'
[global]
index-url = http://mirrors.aliyun.com/pypi/simple/
[install]
trusted-host=mirrors.aliyun.com
EOF
# 安装软件包
[root@client ~]# pip3 install awscli
使用 Amazon S3 API 客户端
aws 命令帮助信息
[root@client ~]# aws
Note: AWS CLI version 2, the latest major version of the AWS CLI, is now stable and recommended for general use. For more information, see the AWS CLI version 2 installation instructions at: https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html
usage: aws [options] <command> <subcommand> [<subcommand> ...] [parameters]
To see help text, you can run:
aws help
aws <command> help
aws <command> <subcommand> help
aws: error: the following arguments are required: command
配置 AWS CLI 凭据
配置 AWS CLI 工具默认凭据:使用 operator 用户,输入 12345 作为访问密钥,67890 作为机密密钥。
[root@client ~]# aws configure
AWS Access Key ID [None]: 12345
AWS Secret Access Key [None]: 67890
Default region name [None]: `回车`
Default output format [None]: `回车`
配置信息保存在~/.aws目录。
[root@client ~]# ls .aws
config credentials
[root@client ~]# cat .aws/config
[default]
[root@client ~]# cat .aws/credentials
[default]
aws_access_key_id = 12345
aws_secret_access_key = 67890
注意:aws 命令默认使用 default 中凭据。
如果想配置多个凭据,配置如下:#跳过
[root@client ~]# aws configure --profile=ceph
AWS Access Key ID [None]: 12345
AWS Secret Access Key [None]: 67890
Default region name [None]:
Default output format [None]:
[root@client ~]# cat .aws/config
[default]
[profile ceph]
[root@client ~]# cat .aws/credentials
[default]
aws_access_key_id = 12345
aws_secret_access_key = 67890
[ceph]
aws_access_key_id = 12345
aws_secret_access_key = 67890
配置参考:https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html
使用参数 endpoint_url配置服务器位置。
示例:
创建存储桶
可以通过选项 –profile 指定凭据,–endpoint 指定服务器位置。
[root@client ~]# aws --endpoint=http://ceph1.bq.cloud:8080 s3 mb s3://webapp
make_bucket: webapp
查看存储桶清单
示例:
[root@client ~]# aws --endpoint=http://ceph1.bq.cloud:8080 s3 ls
2025-08-25 17:14:05 webapp
radosgw-admin 命令也支持存储桶操作,例如使用 radosgw-admin bucket list 或 radosgw-admin bucket rm 命令。
[root@client ~]# radosgw-admin buckets list
[
"webapp"
]
上传对象到存储桶
cp 子命令支持三种复制方向:
<LocalPath> <S3Uri>,将本地文件上传到对象存储中。<S3Uri> <LocalPath>,下载对象存储中对象到本地。<S3Uri> <S3Uri>,将对象存储中对象复制到对象存储中。
示例:
[root@client ~]# echo Hello World > Welcome-pub.html
[root@client ~]# echo Hello bq > Welcome-pri.html
[root@client ~]# aws --endpoint=http://ceph1.bq.cloud:8080 s3 cp Welcome-pub.html s3://webapp/ --acl=public-read-write
upload: ./Welcome-pub.html to s3://webapp/Welcome-pub.html
[root@client ~]# aws s3 cp Welcome-pri.html s3://webapp --endpoint=http://ceph1.bq.cloud:8080
upload: ./Welcome-pri.html to s3://webapp/Welcome-pri.html
查看存储桶中对象
[root@client ~]# aws s3 ls s3://webapp --endpoint=http://ceph1.bq.cloud:8080
2025-08-25 17:23:35 13 Welcome-pri.html
2025-08-25 17:22:18 12 Welcome-pub.html
下载存储桶中对象
# 下载单个
[root@client ~]# aws s3 cp s3://webapp/Welcome-pri.html /tmp --endpoint=http://ceph1.bq.cloud:8080
download: s3://webapp/Welcome-pri.html to ../tmp/Welcome-pri.html
[root@client ~]# ls /tmp/Welcome-pri.html
/tmp/Welcome-pri.html
# 使用选项 --recursive 递归下载bucket中所有对象
[root@client ~]# aws s3 cp s3://webapp /tmp --recursive --endpoint=http://ceph1.bq.cloud:8080
download: s3://webapp/Welcome-pri.html to ../tmp/Welcome-pri.html
download: s3://webapp/Welcome-pub.html to ../tmp/Welcome-pub.html
# 使用wget或者curl下载
[root@client ~]# wget http://ceph1.bq.cloud:8080/webapp/Welcome-pub.html # Welcome-pub.html可以正常下载
[root@client ~]# wget http://ceph1.bq.cloud:8080/webapp/Welcome-pri.html # Welcome-pri.html不可以下载,因为权限不允许
--2025-08-25 17:36:59-- http://ceph1.bq.cloud:8080/webapp/Welcome-pri.html
Resolving ceph1.bq.cloud (ceph1.bq.cloud)... 192.168.108.11
Connecting to ceph1.bq.cloud (ceph1.bq.cloud)|192.168.108.11|:8080... connected.
HTTP request sent, awaiting response... 403 Forbidden
2025-08-25 17:36:59 ERROR 403: Forbidden.
删除存储桶中对象
[root@client ~]# aws s3 rm s3://webapp/Welcome-pri.html --endpoint=http://ceph1.bq.cloud:8080
delete: s3://webapp/Welcome-pri.html
[root@client ~]# aws s3 ls s3://webapp --endpoint=http://ceph1.bq.cloud:8080
2025-08-25 17:22:18 12 Welcome-pub.html
删除存储桶
# 非空的存储桶不能删除
[root@client ~]# aws s3 rb s3://webapp --endpoint=http://ceph1.bq.cloud:8080
remove_bucket failed: s3://webapp argument of type 'NoneType' is not iterable
# 清空存储桶,再次删除
[root@client ~]# aws s3 rm s3://webapp --recursive --include "Welcome-*" --endpoint=http://ceph1.bq.cloud:8080
delete: s3://webapp/Welcome-pub.html
[root@client ~]# aws s3 rb s3://webapp --endpoint=http://ceph1.bq.cloud:8080
remove_bucket: webapp
用户配额管理
设置配额可限制用户或存储桶可消耗的存储量。
user 级别
–quota-scope 选项设置为 user 来应用用户配额。
启用用户配额
示例:operator用户的配额设置为最多 1024 个对象。
[root@ceph1 ~]# radosgw-admin quota enable --quota-scope=user --uid=operator
[root@ceph1 ~]# radosgw-admin quota set --quota-scope=user --uid=operator --max-objects=1024
# 查看用户配额
[root@ceph1 ~]# radosgw-admin user info --uid=operator
{
"user_id": "operator",
"display_name": "S3 Operator",
"email": "operator@example.com",
"suspended": 0,
"max_buckets": 1000,
"subusers": [],
"keys": [
{
"user": "operator",
"access_key": "12345",
"secret_key": "67890"
}
],
"swift_keys": [],
"caps": [],
"op_mask": "read, write, delete",
"default_placement": "",
"default_storage_class": "",
"placement_tags": [],
"bucket_quota": {
"enabled": false,
"check_on_raw": false,
"max_size": -1,
"max_size_kb": 0,
"max_objects": -1
},
"user_quota": {
"enabled": true,
"check_on_raw": false,
"max_size": -1,
"max_size_kb": 0,
"max_objects": 1024
},
"temp_url_keys": [],
"type": "rgw",
"mfa_ids": []
}
# 查看空间使用情况
[root@ceph1 ~]# radosgw-admin user stats --uid=operator
{
"stats": {
"size": 0,
"size_actual": 0,
"size_kb": 0,
"size_kb_actual": 0,
"num_objects": 0
},
"last_stats_sync": "0.000000",
"last_stats_update": "2025-08-25T09:44:36.609841Z"
}
禁用用户配额
示例:禁用operator用户配额。
[root@ceph1 ~]# radosgw-admin quota set --quota-scope=user --uid=operator --max-objects=-1
[root@ceph1 ~]# radosgw-admin quota disable --quota-scope=user --uid=operator
[root@ceph1 ~]# radosgw-admin user info --uid=operator
{
"user_id": "operator",
"display_name": "S3 Operator",
"email": "operator@example.com",
"suspended": 0,
"max_buckets": 1000,
"subusers": [],
"keys": [
{
"user": "operator",
"access_key": "12345",
"secret_key": "67890"
}
],
"swift_keys": [],
"caps": [],
"op_mask": "read, write, delete",
"default_placement": "",
"default_storage_class": "",
"placement_tags": [],
"bucket_quota": {
"enabled": false,
"check_on_raw": false,
"max_size": -1,
"max_size_kb": 0,
"max_objects": -1
},
"user_quota": {
"enabled": false,
"check_on_raw": false,
"max_size": -1,
"max_size_kb": 0,
"max_objects": -1
},
"temp_url_keys": [],
"type": "rgw",
"mfa_ids": []
}
bucket 级别
–quota-scope 选项设置为 bucket 来应用存储桶配额。
启用 bucket 配额
示例:webapp 存储桶被设置为最多 1024 个对象。
[root@client ~]# aws --endpoint=http://ceph1.bq.cloud:8080 s3 mb s3://webapp
make_bucket: webapp
[root@ceph1 ~]# radosgw-admin quota enable --quota-scope=bucket --bucket=webapp
[root@ceph1 ~]# radosgw-admin quota set --quota-scope=bucket --bucket=webapp --max-objects=1024
# 查看 bucket 配额
[root@ceph1 ~]# radosgw-admin bucket stats --bucket=webapp
{
"bucket": "webapp",
"num_shards": 11,
"tenant": "",
"zonegroup": "0fdaf584-33ee-4be7-978c-fb2771181aee",
"placement_rule": "default-placement",
"explicit_placement": {
"data_pool": "",
"data_extra_pool": "",
"index_pool": ""
},
"id": "76366a48-2ab8-4830-9cf7-f9b2fe432c5a.44325.2",
"marker": "76366a48-2ab8-4830-9cf7-f9b2fe432c5a.44325.2",
"index_type": "Normal",
"owner": "operator",
"ver": "0#1,1#1,2#1,3#1,4#1,5#1,6#1,7#1,8#1,9#1,10#1",
"master_ver": "0#0,1#0,2#0,3#0,4#0,5#0,6#0,7#0,8#0,9#0,10#0",
"mtime": "2025-08-25T10:12:11.164221Z",
"creation_time": "2025-08-25T10:09:12.571418Z",
"max_marker": "0#,1#,2#,3#,4#,5#,6#,7#,8#,9#,10#",
"usage": {},
"bucket_quota": {
"enabled": true,
"check_on_raw": false,
"max_size": -1,
"max_size_kb": 0,
"max_objects": 1024 #webapp 存储桶被设置为最多 1024 个对象。
}
}
禁用 bucket 配额
示例:
[root@ceph1 ~]# radosgw-admin quota set --quota-scope=bucket --bucket=webapp --max-objects=-1
[root@ceph1 ~]# radosgw-admin quota disable --quota-scope=bucket --bucket=webapp
# 查看配额和使用情况
[root@ceph1 ~]# radosgw-admin bucket stats --bucket=webapp
[root@ceph1 ~]# radosgw-admin bucket stats --bucket=webapp
{
"bucket": "webapp",
"num_shards": 11,
"tenant": "",
"zonegroup": "0fdaf584-33ee-4be7-978c-fb2771181aee",
"placement_rule": "default-placement",
"explicit_placement": {
"data_pool": "",
"data_extra_pool": "",
"index_pool": ""
},
"id": "76366a48-2ab8-4830-9cf7-f9b2fe432c5a.44325.2",
"marker": "76366a48-2ab8-4830-9cf7-f9b2fe432c5a.44325.2",
"index_type": "Normal",
"owner": "operator",
"ver": "0#1,1#1,2#1,3#1,4#1,5#1,6#1,7#1,8#1,9#1,10#1",
"master_ver": "0#0,1#0,2#0,3#0,4#0,5#0,6#0,7#0,8#0,9#0,10#0",
"mtime": "2025-08-25T10:13:42.983364Z",
"creation_time": "2025-08-25T10:09:12.571418Z",
"max_marker": "0#,1#,2#,3#,4#,5#,6#,7#,8#,9#,10#",
"usage": {},
"bucket_quota": {
"enabled": false,
"check_on_raw": false,
"max_size": -1,
"max_size_kb": 0,
"max_objects": -1 #取消了配额
}
}
global 级别
全局配额会影响集群中的所有存储桶和所有用户。
针对所有用户的配额:
[root@ceph1 ~]# radosgw-admin global quota set --quota-scope user --max-objects 2048
Global quota changes saved. Use 'period update' to apply them to the staging period, and 'period commit' to commit the new period.
{
"user quota": {
"enabled": false,
"check_on_raw": false,
"max_size": -1,
"max_size_kb": 0,
"max_objects": 2048
}
}
[root@ceph1 ~]# radosgw-admin global quota enable --quota-scope user
Global quota changes saved. Use 'period update' to apply them to the staging period, and 'period commit' to commit the new period.
{
"user quota": {
"enabled": true,
"check_on_raw": false,
"max_size": -1,
"max_size_kb": 0,
"max_objects": 2048
}
}
# 查看配额
[root@ceph1 ~]# radosgw-admin global quota get --quota-scope user
{
"user quota": {
"enabled": true,
"check_on_raw": false,
"max_size": -1,
"max_size_kb": 0,
"max_objects": 2048
}
}
针对所有bucket配额:
[root@ceph1 ~]# radosgw-admin global quota set --quota-scope bucket --max-objects 2048
Global quota changes saved. Use 'period update' to apply them to the staging period, and 'period commit' to commit the new period.
{
"bucket quota": {
"enabled": false,
"check_on_raw": false,
"max_size": -1,
"max_size_kb": 0,
"max_objects": 2048
}
}
[root@ceph1 ~]# radosgw-admin global quota enable --quota-scope bucket
Global quota changes saved. Use 'period update' to apply them to the staging period, and 'period commit' to commit the new period.
{
"bucket quota": {
"enabled": true,
"check_on_raw": false,
"max_size": -1,
"max_size_kb": 0,
"max_objects": 2048
}
}
# 查看配额
[root@ceph1 ~]# radosgw-admin global quota get --quota-scope bucket
{
"bucket quota": {
"enabled": true,
"check_on_raw": false,
"max_size": -1,
"max_size_kb": 0,
"max_objects": 2048
}
}
要在区域和期间配置中实施全局配额:
- 使用 radosgw-admin period update --commit 命令来提交更改来实施配额。
- 重启 RGW 实例来实施配额。
查看配额使用情况
存储管理员通过监控使用情况统计信息来确定存储消耗或用户带宽使用情况。监控还有助于查找不活动的应用或不当的用户配额。
显示用户在特定日期之间的使用情况统计信息。
[root@ceph1 ~]# radosgw-admin usage show --uid=operator --start-date='2023-09-21T07:01:52' --end-date='2023-09-21T07:01:53'
{
"entries": [],
"summary": []
}
查看所有用户的统计信息。这些总体统计数据有助于了解对象存储模式,并规划新实例的部署以扩展 RADOS 网关服务。
[root@ceph1 ~]# radosgw-admin usage show --show-log-entries=false
{
"summary": []
}
使用 Swift API 访问对象存储
Swift API 介绍
用户还可以通过 OpenStack Swift API 访问 Ceph 存储集群中对象。
OpenStack Swift API 的用户模型与 Amazon S3 API 的不同。
- **Amazon S3 API 授权和身份验证模型是单层设计。**一个用户帐户可能有多个访问密钥和机密,供该用户提供不同类型的访问。
- **OpenStack Swift API 是多层级设计,专为容纳租户和指定用户而构建。**Swift 租户拥有由服务使用的存储及其容器。Swift 用户分配给服务,配置不同的访问权限级别访问存储。
为了容纳 OpenStack Swift API 身份验证和授权模型,RADOS 网关使用子用户。Swift API tenant:user 模型以 user:subuser 形式映射到 RADOS 网关的身份验证系统。
- Swift API 租户作为 RADOS 网关用户进行处理。
- Swift API 用户作为 RADOS 网关子用户进行处理。
若要访问Swift API ,需要创建一个 Swift 用户,然后为该 Swift 用户创建一个子用户,该子用户与 RADOS 网关用户和访问密钥相关联。
如果还原快照做如下操作:
radosgw-admin realm create --rgw-realm=webapp --default
radosgw-admin zonegroup create --rgw-realm=webapp --rgw-zonegroup=video --master --default
radosgw-admin zone create --rgw-realm=webapp --rgw-zonegroup=video --rgw-zone=storage --master --default
ceph orch apply rgw webapp --placement="3 ceph1.bq.cloud ceph2.bq.cloud ceph3.bq.cloud" --realm=webapp --zone=storage --port=8080
radosgw-admin user create --uid="operator" --display-name="S3 Operator" --email="operator@example.com" --access_key="12345" --secret="67890"
管理对象网关子用户
创建子用户
# 这里创建 operator 子用户 operator:swift
[root@ceph1 ~]# radosgw-admin subuser create --uid=operator --subuser=operator:swift --access=full --secret=opswift
{
"user_id": "operator",
"display_name": "S3 Operator",
"email": "operator@example.com",
"suspended": 0,
"max_buckets": 1000,
"subusers": [
{
"id": "operator:swift",
"permissions": "full-control"
}
],
"keys": [
{
"user": "operator",
"access_key": "12345",
"secret_key": "67890"
}
],
"swift_keys": [
{
"user": "operator:swift",
"secret_key": "opswift"
}
],
"caps": [],
"op_mask": "read, write, delete",
"default_placement": "",
"default_storage_class": "",
"placement_tags": [],
"bucket_quota": {
"enabled": false,
"check_on_raw": false,
"max_size": -1,
"max_size_kb": 0,
"max_objects": -1
},
"user_quota": {
"enabled": false,
"check_on_raw": false,
"max_size": -1,
"max_size_kb": 0,
"max_objects": -1
},
"temp_url_keys": [],
"type": "rgw",
"mfa_ids": []
}
- –access 选项,指定用户的权限(读取、写入、读写、完全)。
- –uid 选项,指定现有的已关联 RADOS 网关用户。
- –subuser=username:swift 选项,指定现有的已关联 RADOS 网关用户的子用户。
创建子用户 key
[root@ceph1 ~]# radosgw-admin key create --uid=operator --subuser=operator:swift --key-type=swift --gen-secret
–key-type 选项接受 swift 或 s3 值。如果要手动指定访问密钥,请使用 --access-key 选项;如果要手动指定机密密钥,请使用 --secret-key 选项。也可以使用 --gen-accesskey 选项仅生成随机访问密钥,或使用 --gen-secret 选项仅生成随机机密。
修改子用户
使用 radosgw-admin subuser modify 命令可修改子用户,例如访问级别、secret等。
[root@ceph1 ~]# radosgw-admin subuser modify --uid=operator --subuser=operator:swift --secret=opswift --access=full
删除子用户key
要删除子用户密钥,请使用 radosgw-admin key rm 命令。
[root@ceph1 ~]# radosgw-admin key rm --subuser=operator:swift
删除子用户
使用 radosgw-admin subuser rm 命令删除子用户。–purge-data 选项可清除与子用户关联的所有数据,–purge-keys 选项可清除所有子用户密钥。
[root@ceph1 ~]# radosgw-admin subuser rm --subuser=operator:swift
准备实验子用户
# 创建用户 swift
[root@ceph1 ~]# radosgw-admin user create --uid=swift --display-name=swift
# 创建子账号 swift_rgw
[root@ceph1 ~]# radosgw-admin subuser create --uid=swift --subuser=swift:swift_rgw --access=full
# 创建的子账号 swift 类型 key
[root@ceph1 ~]# radosgw-admin key create --subuser=swift:swift_rgw --key-type=swift --gen-secret
{
"user_id": "swift",
"display_name": "swift",
"email": "",
"suspended": 0,
"max_buckets": 1000,
"subusers": [
{
"id": "swift:swift_rgw",
"permissions": "full-control"
}
],
"keys": [
{
"user": "swift",
"access_key": "BXK4ZTZLO2A5W2380V8Y",
"secret_key": "ygZS3CTL1x3ja4UJMlY4M6Zb8abOQFZ3A9FOgQcM"
}
],
"swift_keys": [
{
"user": "swift:swift_rgw",
"secret_key": "9KPxNkJSvGP1i5LDs9QV4elDCoHTAjdsPJoszDWj"
}
],
"caps": [],
"op_mask": "read, write, delete",
"default_placement": "",
"default_storage_class": "",
"placement_tags": [],
"bucket_quota": {
"enabled": false,
"check_on_raw": false,
"max_size": -1,
"max_size_kb": 0,
"max_objects": -1
},
"user_quota": {
"enabled": false,
"check_on_raw": false,
"max_size": -1,
"max_size_kb": 0,
"max_objects": -1
},
"temp_url_keys": [],
"type": "rgw",
"mfa_ids": []
}
# 配置完成后,记录下生成的 Key,后续会使用该值进行认证。
# "user": "swift:swift_rgw",
# "secret_key": "9KPxNkJSvGP1i5LDs9QV4elDCoHTAjdsPJoszDWj"
安装 swift 客户端
# 准备 aliyun 源 pip 仓库
[root@client ~]# mkdir .pip
[root@client ~]# cat > .pip/pip.conf << 'EOF'
[global]
index-url = http://mirrors.aliyun.com/pypi/simple/
[install]
trusted-host=mirrors.aliyun.com
EOF
# 安装软件包
[root@client ~]# pip3 install python-swiftclient
# 确认swift版本
[root@client ~]# swift --version
python-swiftclient 4.7.0
配置用户凭据
Swift 客户端与 RADOS 网关通信时,RADOS 网关同时充当数据服务器和 Swift 身份验证守护进程(使用 /auth URL 路径)。
使用环境变量提供凭据
RADOS 网关支持 Internal Swift(版本 1.0)和 OpenStack Keystone(版本2.0)身份验证:
- 如果使用的是 Auth 版本 1.0,则请使用 ST_AUTH、ST_USER 和 ST_KEY 环境变量。
- 如果使用的是 Auth 版本 2.0,则请使用OS_AUTH_URL、OS_USERNAME、OS_PASSWORD、OS_TENANT_NAME 和OS_TENANT_ID 环境变量。
[root@client ~]# vim swift.rc
export ST_AUTH=http://ceph1.bq.cloud:8080/auth/1.0
export ST_USER=swift:swift_rgw
export ST_KEY=9KPxNkJSvGP1i5LDs9QV4elDCoHTAjdsPJoszDWj #用前面的值替代
[root@client ~]# source swift.rc
[root@client ~]# swift list
使用选项提供凭据
用户认证选项:
- -A 选项,指定Swift 认证 URL。
- -U 选项,指定Swift 子用户。
- -K 选项,指定Swift 子用户对应的机密。
示例:
[root@client ~]# swift -A http://ceph1.bq.cloud:8080/auth/1.0 -U "swift:swift_rgw" -K 9KPxNkJSvGP1i5LDs9QV4elDCoHTAjdsPJoszDWj list
管理对象
swift 命令帮助信息
[root@client ~]# swift --help
usage: swift [--version] [--help] [--os-help] [--snet] [--verbose]
[--debug] [--info] [--quiet] [--auth <auth_url>]
[--auth-version <auth_version> |
--os-identity-api-version <auth_version> ]
[--user <username>]
[--key <api_key>] [--retries <num_retries>]
[--os-username <auth-user-name>]
[--os-password <auth-password>]
[--os-user-id <auth-user-id>]
[--os-user-domain-id <auth-user-domain-id>]
[--os-user-domain-name <auth-user-domain-name>]
[--os-tenant-id <auth-tenant-id>]
[--os-tenant-name <auth-tenant-name>]
[--os-project-id <auth-project-id>]
[--os-project-name <auth-project-name>]
[--os-project-domain-id <auth-project-domain-id>]
[--os-project-domain-name <auth-project-domain-name>]
[--os-auth-url <auth-url>]
[--os-auth-token <auth-token>]
[--os-auth-type <os-auth-type>]
[--os-application-credential-id
<auth-application-credential-id>]
[--os-application-credential-secret
<auth-application-credential-secret>]
[--os-storage-url <storage-url>]
[--os-region-name <region-name>]
[--os-service-type <service-type>]
[--os-endpoint-type <endpoint-type>]
[--os-cacert <ca-certificate>]
[--insecure]
[--os-cert <client-certificate-file>]
[--os-key <client-certificate-key-file>]
[--no-ssl-compression]
[--force-auth-retry]
<subcommand> [--help] [<subcommand options>]
Command-line interface to the OpenStack Swift API.
Positional arguments:
<subcommand>
delete Delete a container or objects within a container.
download Download objects from containers.
list Lists the containers for the account or the objects
for a container.
post Updates meta information for the account, container,
or object; creates containers if not present.
copy Copies object, optionally adds meta
stat Displays information for the account, container,
or object.
upload Uploads files or directories to the given container.
capabilities List cluster capabilities.
tempurl Create a temporary URL.
auth Display auth related environment variables.
bash_completion Outputs option and flag cli data ready for
bash_completion.
Examples:
swift download --help
swift -A https://api.example.com/v1.0 \
-U user -K api_key stat -v
swift --os-auth-url https://api.example.com/v2.0 \
--os-tenant-name tenant \
--os-username user --os-password password list
swift --os-auth-url https://api.example.com/v3 --auth-version 3\
--os-project-name project1 --os-project-domain-name domain1 \
--os-username user --os-user-domain-name domain1 \
--os-password password list
swift --os-auth-url https://api.example.com/v3 --auth-version 3\
--os-project-id 0123456789abcdef0123456789abcdef \
--os-user-id abcdef0123456789abcdef0123456789 \
--os-password password list
swift --os-auth-url https://api.example.com/v3 --auth-version 3\
--os-application-credential-id d78683c92f0e4f9b9b02a2e208039412 \
--os-application-credential-secret APPLICATION_CREDENTIAL_SECRET \
--os-auth-type v3applicationcredential list
swift --os-auth-token 6ee5eb33efad4e45ab46806eac010566 \
--os-storage-url https://10.1.5.2:8080/v1/AUTH_ced809b6a4baea7aeab61a \
list
swift list --lh
optional arguments:
--version show program's version number and exit
-h, --help
--os-help Show OpenStack authentication options.
-s, --snet Use SERVICENET internal network.
-v, --verbose Print more info.
--debug Show the curl commands and results of all http queries
regardless of result status.
--info Show the curl commands and results of all http queries
which return an error.
-q, --quiet Suppress status output.
-A=AUTH, --auth=AUTH URL for obtaining an auth token.
-V=AUTH_VERSION, --auth-version=AUTH_VERSION, --os-identity-api-version=AUTH_VERSION
Specify a version for authentication. Defaults to
env[ST_AUTH_VERSION], env[OS_AUTH_VERSION],
env[OS_IDENTITY_API_VERSION] or 1.0.
-U=USER, --user=USER User name for obtaining an auth token.
-K=KEY, --key=KEY Key for obtaining an auth token.
-T=TIMEOUT, --timeout=TIMEOUT
Timeout in seconds to wait for response.
-R=RETRIES, --retries=RETRIES
The number of times to retry a failed connection.
--insecure Allow swiftclient to access servers without having to
verify the SSL certificate. Defaults to
env[SWIFTCLIENT_INSECURE] (set to 'true' to enable).
--no-ssl-compression This option is deprecated and not used anymore. SSL
compression should be disabled by default by the
system SSL library.
--force-auth-retry Force a re-auth attempt on any error other than 401
unauthorized
--prompt Prompt user to enter a password which overrides any
password supplied via --key, --os-password or
environment variables.
子命令帮助信息
[root@client ~]# swift upload --help
Usage: swift upload [--changed] [--skip-identical] [--segment-size <size>]
[--segment-container <container>] [--leave-segments]
[--object-threads <thread>] [--segment-threads <threads>]
[--meta <name:value>] [--header <header>] [--use-slo]
[--use-dlo] [--ignore-checksum] [--skip-container-put]
[--object-name <object-name>]
<container> <file_or_directory> [<file_or_directory>] [...]
Uploads specified files and directories to the given container.
Positional arguments:
<container> Name of container to upload to.
<file_or_directory> Name of file or directory to upload. Specify multiple
times for multiple uploads. If "-" is specified, reads
content from standard input (--object-name is required
in this case).
Optional arguments:
-c, --changed Only upload files that have changed since the last
upload.
--skip-identical Skip uploading files that are identical on both sides.
-S, --segment-size <size>
Upload files in segments no larger than <size> (in
Bytes) and then create a "manifest" file that will
download all the segments as if it were the original
file.
--segment-container <container>
Upload the segments into the specified container. If
not specified, the segments will be uploaded to a
<container>_segments container to not pollute the
main <container> listings.
--leave-segments Indicates that you want the older segments of manifest
objects left alone (in the case of overwrites).
--object-threads <threads>
Number of threads to use for uploading full objects.
Default is 10.
--segment-threads <threads>
Number of threads to use for uploading object segments.
Default is 10.
-m, --meta <name:value>
Sets a meta data item. This option may be repeated.
Example: -m Color:Blue -m Size:Large
-H, --header <header:value>
Adds a customized request header. This option may be
repeated. Example: -H "content-type:text/plain"
-H "Content-Length: 4000".
--use-slo When used in conjunction with --segment-size it will
create a Static Large Object. Deprecated; this is now
the default behavior when the cluster supports it.
--use-dlo When used in conjunction with --segment-size it will
create a Dynamic Large Object. May be useful with old
swift clusters.
--ignore-checksum Turn off checksum validation for uploads.
--skip-container-put Assume all necessary containers already exist; don't
automatically try to create them.
--object-name <object-name>
Upload file and name object to <object-name> or upload
dir and use <object-name> as object prefix instead of
folder name.
查看存储状态
[root@client ~]# swift stat
Account: v1
Containers: 0
Objects: 0
Bytes: 0
Objects in policy "default-placement-bytes": 0
Bytes in policy "default-placement-bytes": 0
Containers in policy "default-placement": 0
Objects in policy "default-placement": 0
Bytes in policy "default-placement": 0
X-Timestamp: 1756120916.52301
X-Account-Bytes-Used-Actual: 0
X-Trans-Id: tx000000bdae1b6eec631b5-0068ac4754-ad01-storage
X-Openstack-Request-Id: tx000000bdae1b6eec631b5-0068ac4754-ad01-storage
Accept-Ranges: bytes
Content-Type: text/plain; charset=utf-8
Connection: Keep-Alive
查看认证信息
[root@client ~]# swift auth
export OS_STORAGE_URL=http://ceph1.bq.cloud:8080/swift/v1
export OS_AUTH_TOKEN=AUTH_rgwtk0f00000073776966743a73776966745f7267771c03132ca7ff9f23e498ad685aaedc2332323e8a316edd865b5d15be670fb35bf3a00a8c
创建容器
[root@client ~]# swift post --help
Usage: swift post [--read-acl <acl>] [--write-acl <acl>] [--sync-to <sync-to>]
[--sync-key <sync-key>] [--meta <name:value>]
[--header <header>]
[<container> [<object>]]
Updates meta information for the account, container, or object.
If the container is not found, it will be created automatically.
Positional arguments:
[<container>] Name of container to post to.
[<object>] Name of object to post.
Optional arguments:
-r, --read-acl <acl> Read ACL for containers. Quick summary of ACL syntax:
.r:*, .r:-.example.com, .r:www.example.com,
account1 (v1.0 identity API only),
account1:*, account2:user2 (v2.0+ identity API).
-w, --write-acl <acl> Write ACL for containers. Quick summary of ACL syntax:
account1 (v1.0 identity API only),
account1:*, account2:user2 (v2.0+ identity API).
-t, --sync-to <sync-to>
Sync To for containers, for multi-cluster replication.
-k, --sync-key <sync-key>
Sync Key for containers, for multi-cluster replication.
-m, --meta <name:value>
Sets a meta data item. This option may be repeated.
Example: -m Color:Blue -m Size:Large
-H, --header <header:value>
Adds a customized request header.
This option may be repeated. Example
-H "content-type:text/plain" -H "Content-Length: 4000"
[root@client ~]# swift post webapp
查看容器清单
[root@client ~]# swift list --help
Usage: swift list [--long] [--lh] [--totals] [--prefix <prefix>]
[--delimiter <delimiter>] [--header <header:value>]
[--versions] [<container>]
Lists the containers for the account or the objects for a container.
Positional arguments:
[<container>] Name of container to list object in.
[root@client ~]# swift list
webapp
上传对象到容器
[root@client ~]# swift upload --help
Usage: swift upload [--changed] [--skip-identical] [--segment-size <size>]
[--segment-container <container>] [--leave-segments]
[--object-threads <thread>] [--segment-threads <threads>]
[--meta <name:value>] [--header <header>] [--use-slo]
[--use-dlo] [--ignore-checksum] [--skip-container-put]
[--object-name <object-name>]
<container> <file_or_directory> [<file_or_directory>] [...]
Uploads specified files and directories to the given container.
Positional arguments:
<container> Name of container to upload to.
<file_or_directory> Name of file or directory to upload. Specify multiple
times for multiple uploads. If "-" is specified, reads
content from standard input (--object-name is required
in this case).
[root@client ~]# echo Hello World > Welcome.html
[root@client ~]# echo Test> test.html
[root@client ~]# swift upload webapp Welcome.html
Welcome.html
用户可使用 –object-name 选项来定义对象名称。
如果使用绝对路径来定义文件位置,对象名称将包含文件路径,包括斜杠字符 /。例如,以下命令将会上传 /etc/hosts 文件到 services 存储桶。
[root@client ~]# swift upload webapp /etc/hostname
etc/hostname
查看容器中对象清单
[root@client ~]# swift list webapp
Welcome.html
etc/hostname
下载容器中对象
[root@client ~]# swift download --help
Usage: swift download [--all] [--marker <marker>] [--prefix <prefix>]
[--output <out_file>] [--output-dir <out_directory>]
[--object-threads <threads>] [--ignore-checksum]
[--container-threads <threads>] [--no-download]
[--skip-identical] [--remove-prefix]
[--version-id <version_id>]
[--header <header:value>] [--no-shuffle]
[<container> [<object>] [...]]
# 下载容器中所有对象
[root@client ~]# swift download webapp
etc/hostname [auth 0.005s, headers 0.009s, total 0.010s, 0.004 MB/s]
Welcome.html [auth 0.005s, headers 0.010s, total 0.010s, 0.002 MB/s]
# 下载容器中单个对象
[root@client ~]# swift download webapp Welcome.html
Welcome.html [auth 0.004s, headers 0.008s, total 0.009s, 0.003 MB/s]
删除容器中对象
[root@client ~]# swift delete --help
Usage: swift delete [--all] [--leave-segments]
[--object-threads <threads>]
[--container-threads <threads>]
[--header <header:value>]
[--prefix <prefix>]
[--versions]
[<container> [<object>] [--version-id <version_id>] [...]]
Delete a container or objects within a container.
Positional arguments:
[<container>] Name of container to delete from.
[<object>] Name of object to delete. Specify multiple times
for multiple objects.
[root@client ~]# swift delete webapp etc/hostname
etc/hostname
删除容器
删除容器,将删除容器中所有对象和容器本身。
[root@client ~]# swift delete webapp
Welcome.html
webapp
桶配额限制
环境准备
[root@client ~]# swift post dbapp
[root@client ~]# swift upload --object-name hosts-1 dbapp /etc/hosts
针对用户进行配额限制
# 对用户 swift 的配额限制
[root@ceph1 ~]# radosgw-admin quota enable --quota-scope=user --uid=swift
# 将用户 swift 可上传的对象数量设置为不超过 3
[root@ceph1 ~]# radosgw-admin quota set --quota-scope=user --uid=swift --max-objects=3
# 查看用户配额信息
[root@ceph1 ~]# radosgw-admin user info --uid=swift
......
"user_quota": {
"enabled": true,
"check_on_raw": false,
"max_size": -1,
"max_size_kb": 0,
"max_objects": 3
},
......
# 上传对象测试:当上传第4个对象时,客户端会收到报错。
[root@client ~]# swift upload --object-name hosts-2 dbapp /etc/hosts
[root@client ~]# swift upload --object-name hosts-3 dbapp /etc/hosts
[root@client ~]# swift upload --object-name hosts-4 dbapp /etc/hosts
Object PUT failed: http://ceph1.bq.cloud:8080/swift/v1/dbapp/hosts-4 413 Request Entity Too Large b'QuotaExceeded' (txn: tx00000f89584465dec20ff-006603ab85-acdb-webapp)
Consider using the --segment-size option to chunk the object
# 将“ --max-objects”设置为-1,取消对象数量配额的限制
[root@ceph1 ~]# radosgw-admin quota set --quota-scope=user --uid=swift --max-objects=-1
# 在客户端重新上传对象,则会顺利上传完成
[root@client ~]# swift upload --object-name hosts-4 dbapp /etc/hosts
思考:除了设置对象数量外,是否还有其他的配额限制方式?
回答:有,除了对象数量,还可以最大上传的容量进行限制。
针对桶进行配额限制
# 启用对桶 dbapp 的配额限制
[root@ceph1 ~]# radosgw-admin quota enable --quota-scope=bucket --bucket=dbapp
# 将桶 dbapp 的最大容量设置为 10M:
[root@ceph1 ~]# radosgw-admin quota set --quota-scope=bucket --bucket=dbapp --max-size=10M
# 查看配额信息
[root@ceph1 ~]# radosgw-admin bucket stats
......
"bucket_quota": {
"enabled": true,
"check_on_raw": true,
"max_size": 10485760,
"max_size_kb": 10240,
"max_objects": -1
}
......
# 在客户端创建一个 6M 的文件 file,进行测试,具体命令为:
[root@client ~]# dd if=/dev/zero of=file bs=1M count=6
# 将文件 file 上传到容器(桶) dbapp 中,当上传第二个时,系统会返回报错
[root@client ~]# swift upload --object-name file-1 dbapp file
file-1
[root@client ~]# swift upload --object-name file-2 dbapp file
Object PUT failed: http://ceph1.bq.cloud:8080/swift/v1/dbapp/file-2 413 Request Entity Too Large b'QuotaExceeded' (txn: tx000008b826fc312e77202-006603acbd-acdb-webapp)
Consider using the --segment-size option to chunk the object
# 将“--max-size”设置为-1,取消对象容量配额的限制
[root@ceph1 ~]# radosgw-admin quota set --quota-scope=bucket --bucket=dbapp --max-size=-1
# 在客户端重新上传对象,则会顺利上传完成
[root@client ~]# swift upload --object-name file-2 dbapp file
管理多站点对象存储网关
Ceph RADOS 网关支持多站点部署,实现在多个Ceph 存储集群之间自动复制对象数据。常见的用例是在地理上分隔的集群之间进行主动/主动复制,以便于灾难恢复。
多站点架构选择
- multi zone,域(realm)中具有一个区域组(zonegroup)和多个区域(zone)。每个区域由一个或多个 RADOS 网关以及关联一个独立的Ceph 存储集群。一个区域中存储的数据复制到该区域组中所有区域。如果有一个 zone 遭遇到灾难性故障,这可用于进行灾难恢复。
- multi zonegroup,域(realm)中有多个区域组,每个区域组具有一个或多个区域。用户可使用多区域组来管理一个地区中一个或多个区域内 RADOS 网关的地理位置。
- multi realm,配置使得同一硬件可用于支持不同区域组和区域之间通用的多个对象命名空间。
最小的 RADOS 网关多站点部署:
- 需要两个Ceph 存储集群,每个集群具有一个 RADOS 网关。
- 它们存在于同一域中,分配到相同的主区域组。
- 一个 RADOS 网关与该区域组中的主区域关联。另一个与该区域组中的独立次要区域关联。
多站点网关同步流程
RADOS 网关在所有主要区域组和次要区域组集合之间同步元数据和数据操作。
- **元数据操作与存储桶相关:**创建、删除、启用和禁用版本控制,以及管理用户。元主 (meta master) 位于主区域组中的主区域,负责管理元数据更新。
- 数据操作与对象相关。
多站点之间数据同步流程:
- 多站点初始配置后,RADOS 网关会在主区域和次要区域之间执行一次初始的完整同步。随后的更新是增量更新。
- **当 RADOS 网关将数据写入区域组中任何区域时,它会在其他区域组的所有区域之间同步这一数据。**当 RADOS 网关同步数据时,所有活跃的网关会更新数据日志并通知其他网关。
- 当 RADOS 网关因为存储桶或用户操作而同步元数据时,主网关会更新元数据日志并通知其他RADOS 网关。
多站点架构配置流程
部署多站点 RGW-实践
多站点架构如下图所示:
环境准备
部署好主集群和备集群。
配置主集群
# 创建存储域
[root@ceph1 ~]# radosgw-admin realm create --rgw-realm=webapp --default
[root@ceph1 ~]# radosgw-admin zonegroup create --rgw-realm=webapp --rgw-zonegroup=video --master --default
[root@ceph1 ~]# radosgw-admin zone create --rgw-realm=webapp --rgw-zonegroup=video --rgw-zone=storage1 --master --default
[root@ceph1 ~]# radosgw-admin period update --rgw-realm=webapp --commit
# 创建 rgw 服务,这里创建3个(创建一个也够了)
[root@ceph1 ~]# ceph orch apply rgw webapp --placement="3 ceph1.bq.cloud ceph2.bq.cloud ceph3.bq.cloud" --realm=webapp --zone=storage1 --port=8080
# 创建用于同步数据的系统用户:
[root@ceph1 ~]# radosgw-admin user create --uid=system-user --display-name=system-user --access-key=bq@123 --secret=Huawei12#$ --system
# 将创建好的系统用户绑定给 master zone
[root@ceph1 ~]# radosgw-admin zone modify --rgw-realm=webapp --rgw-zonegroup=video --rgw-zone=storage1 --endpoints 'http://ceph1.bq.cloud:8080,http://ceph2.bq.cloud:8080,http://ceph3.bq.cloud:8080' --access-key=bq@123 --secret=Huawei12#$ --master --default
# 配置 RGW
[root@ceph1 ~]# ceph auth ls 2>/dev/null |grep 'rgw.*ceph'
client.rgw.webapp.ceph1.qqepfc
client.rgw.webapp.ceph2.iculct
client.rgw.webapp.ceph3.xbrkun
[root@ceph1 ~]# ceph config set client.rgw.webapp.ceph1.qqepfc rgw_realm webapp
[root@ceph1 ~]# ceph config set client.rgw.webapp.ceph1.qqepfc rgw_zonegroup video
[root@ceph1 ~]# ceph config set client.rgw.webapp.ceph1.qqepfc rgw_zone storage1
[root@ceph1 ~]# ceph config set client.rgw.webapp.ceph2.iculct rgw_realm webapp
[root@ceph1 ~]# ceph config set client.rgw.webapp.ceph2.iculct rgw_zonegroup video
[root@ceph1 ~]# ceph config set client.rgw.webapp.ceph2.iculct rgw_zone storage1
[root@ceph1 ~]# ceph config set client.rgw.webapp.ceph3.xbrkun rgw_realm webapp
[root@ceph1 ~]# ceph config set client.rgw.webapp.ceph3.xbrkun rgw_zonegroup video
[root@ceph1 ~]# ceph config set client.rgw.webapp.ceph3.xbrkun rgw_zone storage1
# 提交配置
[root@ceph1 ~]# radosgw-admin period update --commit
# 重启 RGW 服务
[root@ceph1 ~]# ceph orch restart rgw.webapp
配置备集群
# 拉取主分区 realm 的配置信息:
[root@ceph4 ~]# radosgw-admin realm pull --url=http://ceph1.bq.cloud:8080 --access-key=bq@123 --secret=Huawei12#$
# 查看是否获取到 realm 和 zonegroup 的信息:
[root@ceph4 ~]# radosgw-admin realm list
[root@ceph4 ~]# radosgw-admin zonegroup list
# 获取 period 信息
[root@ceph4 ~]# radosgw-admin period pull --url=http://ceph1.bq.cloud:8080 --access-key=bq@123 --secret=Huawei12#$
# 检查是否获取
[root@ceph4 ~]# radosgw-admin period list
{
"periods": [
"df0d2416-7ee9-465c-a1e5-cebd19b7b468"
]
}
# 创建非 master zone
[root@ceph4 ~]# radosgw-admin zone create --rgw-zonegroup=video --rgw-zone=storage2 --endpoints "http://ceph4.bq.cloud:8080, http://ceph5.bq.cloud:8080, http://ceph6.bq.cloud:8080" --access-key=bq@123 --secret=Huawei12#$
# 创建 RGW
[root@ceph4 ~]# ceph orch apply rgw webapp --placement="3 ceph4.bq.cloud ceph5.bq.cloud ceph6.bq.cloud" --realm=webapp --zone=storage2 --port=8080
# 设置 RGW 信息
[root@ceph4 ~]# ceph auth ls 2>/dev/null|grep 'rgw.*ceph'
client.rgw.webapp.ceph4.quzfrg
client.rgw.webapp.ceph5.catzsj
client.rgw.webapp.ceph6.aszklt
[root@ceph4 ~]# ceph config set client.rgw.webapp.ceph4.quzfrg rgw_realm webapp
[root@ceph4 ~]# ceph config set client.rgw.webapp.ceph4.quzfrg rgw_zonegroup video
[root@ceph4 ~]# ceph config set client.rgw.webapp.ceph4.quzfrg rgw_zone storage2
[root@ceph4 ~]# ceph config set client.rgw.webapp.ceph5.catzsj rgw_realm webapp
[root@ceph4 ~]# ceph config set client.rgw.webapp.ceph5.catzsj rgw_zonegroup video
[root@ceph4 ~]# ceph config set client.rgw.webapp.ceph5.catzsj rgw_zone storage2
[root@ceph4 ~]# ceph config set client.rgw.webapp.ceph6.aszklt rgw_realm webapp
[root@ceph4 ~]# ceph config set client.rgw.webapp.ceph6.aszklt rgw_zonegroup video
[root@ceph4 ~]# ceph config set client.rgw.webapp.ceph6.aszklt rgw_zone storage2
# 更新 realm
[root@ceph4 ~]# radosgw-admin period update --rgw-realm=webapp --commit
# 重启 RGW 服务
[root@ceph4 ~]# ceph orch restart rgw.webapp
测试
# 查看同步状态
[root@ceph4 ~]# radosgw-admin sync status
realm f1ea35c6-c4b5-46b4-9e4b-62e2c6301217 (webapp)
zonegroup c4f0f536-6651-43f0-b1f3-a1fbaf55775d (video)
zone 9d1339a8-6570-4ad6-88de-172cf3899332 (storage2)
metadata sync syncing
full sync: 0/64 shards
incremental sync: 64/64 shards
metadata is caught up with master
data sync source: 9366405a-6d9b-4897-97d0-9e139304fe64 (storage1)
syncing
full sync: 0/128 shards
incremental sync: 128/128 shards
data is caught up with source
# 对象同步测试---有问题
[root@client ~]# source swift.rc
[root@client ~]# swift post dbapp
[root@client ~]# swift upload --object-name hosts-from-primary dbapp /etc/hosts
# 查看备集群对象(需要稍微等待几秒)
[root@client ~]# source swift-slave.rc
[root@client ~]# swift list dbapp
hosts-from-primary
管理区域故障转移
在多站点部署中,主区域不可用时,次要区域可以继续为读取和写入请求服务。
不过,因为主区域不可用,所以用户无法创建新的存储桶和用户。如果主区域没有立即恢复,则需要对其中一个次要区域升级,以替代主区域。
具体过程如下:
-
将主区域指定为次要区域。
[root@ceph4 ~]# radosgw-admin zone modify --master --rgw-zone=storage2 -
更新主区域组端点。
[root@ceph4 ~]# radosgw-admin zonegroup modify --rgw-zonegroup=video \ --endpoints=http://ceph4.bq.cloud:8080 -
提交更改。
[root@ceph4 ~]# radosgw-admin period update --commit [root@ceph4 ~]# radosgw-admin sync status realm f1ea35c6-c4b5-46b4-9e4b-62e2c6301217 (webapp) zonegroup c4f0f536-6651-43f0-b1f3-a1fbaf55775d (video) zone 9d1339a8-6570-4ad6-88de-172cf3899332 (storage2) metadata sync no sync (zone is master) data sync source: 9366405a-6d9b-4897-97d0-9e139304fe64 (storage1) syncing full sync: 0/128 shards incremental sync: 128/128 shards data is caught up with source
radosgw-admin 命令
realm 子命令
realm create create a new realm
realm rm remove a realm
realm get show realm info
realm get-default get default realm name
realm list list realms
realm list-periods list all realm periods
realm rename rename a realm
realm set set realm info (requires infile)
realm default set realm as default
realm pull pull a realm and its current period
zonegroup 子命令
zonegroup add add a zone to a zonegroup
zonegroup create create a new zone group info
zonegroup default set default zone group
zonegroup delete delete a zone group info
zonegroup get show zone group info
zonegroup modify modify an existing zonegroup
zonegroup set set zone group info (requires infile)
zonegroup rm remove a zone from a zonegroup
zonegroup rename rename a zone group
zonegroup list list all zone groups set on this cluster
zonegroup placement list list zonegroup's placement targets
zonegroup placement get get a placement target of a specific zonegroup
zonegroup placement add add a placement target id to a zonegroup
zonegroup placement modify modify a placement target of a specific zonegroup
zonegroup placement rm remove a placement target from a zonegroup
zonegroup placement default set a zonegroup's default placement target
zone 子命令
zone create create a new zone
zone rm remove a zone
zone get show zone cluster params
zone modify modify an existing zone
zone set set zone cluster params (requires infile)
zone list list all zones set on this cluster
zone rename rename a zone
zone placement list list zone's placement targets
zone placement get get a zone placement target
zone placement add add a zone placement target
zone placement modify modify a zone placement target
zone placement rm remove a zone placement target
period 子命令
period rm remove a period
period get get period info
period get-current get current period info
period pull pull a period
period push push a period
period list list all periods
period update update the staging period
period commit commit the staging period
常用选项
--uid=<id> user id
--new-uid=<id> new user id
--subuser=<name> subuser name
--email=<email> user's email address
--display-name=<name> user's display name
--system set the system flag on the user
--access-key=<key> S3 access key
--secret/--secret-key=<key> specify secret key
--gen-access-key generate random access key (for S3)
--gen-secret generate random secret key
--key-type=<type> key type, options are: swift, s3
--bucket=<bucket> Specify the bucket name.
--bucket-id=<bucket-id> bucket id
--bucket-new-name=<bucket>
for bucket link: optional new name
--pool=<pool> Specify the pool name.
--object=<object> object name
--period=<id> period id
--url=<url> url for pushing/pulling period/realm
--epoch=<number> period epoch
--commit commit the period during 'period update'
--default set entity (realm, zonegroup, zone) as default
--master set as master
--master-zone=<id> master zone id
--rgw-realm=<name> realm name
--realm-id=<id> realm id
--realm-new-name=<name> realm new name
--rgw-zonegroup=<name> zonegroup name
--zonegroup-id=<id> zonegroup id
--zonegroup-new-name=<name>
zonegroup new name
--endpoints=<list> zone endpoints
--rgw-zone=<name> name of zone in which radosgw is running
--zone-id=<id> zone id
--zone-new-name=<name> zone new name
--source-zone specify the source zone (for data sync)
更多推荐

所有评论(0)