07 Rados Gw

对象存储(Object Storage System) 是无层次结构的数据存储方法,通常用于云计算环境中。
不同于其他数据存储方法,基于对象的存储不使用目录树;数据作为单独的对象进行存储。数据并不放置在目录层次结构中,而是存在于平面地址空间内的同一级别;
应用通过唯一地址来识别每个单独的数据对象
每个对象可包含有助于检索的元数据
专为使用API在应用级别(而非用户级别)进行访问而设计(RestFull风格API)
适应于创建后不再频繁变动的文件对象。
适应于非结构化数据(无schema)。
使用bucket的概念作为存储空间的隔离,用户的权限、配额也是在bucket上实现,可以理解为是一个目录。(也支持对象级别的权限限制)
对象是对象存储系统中数据存储的基本单位,每个Object是数据和数据属性集的综合体,数据属性可以根据应用的需求进行设置,包括数据分布、服务质量等
- 每个对象自我维护其属性,从而简化了存储系统的管理任务
- 对象的大小可以不同,甚至可以包含整个数据结构,如文件、数据库表项等
对象存储系统一般是一类智能设备,它具有自己的存储介质、处理器、内存以及网 络系统等,负责管理本地的对象,是对象存储系统的核心

一般说来,一个对象存储系统的核心资源类型应该包括用户(User)、存储桶(bucket)和对象(object)。
三者的关系是:用户将对象存储于对象存储系统上的存储桶中,存储桶隶属于用户并能够容纳对象,一个用户可以拥有一到多个存储桶,而一个存储桶常用于存储多个对象。

虽然在设计与实现上有所区别,但大多数对象存储系统对外呈现的核心资源类型大同小异:
- Amazon S3:提供了user、bucket和object分别表示用户、存储桶和对象,其中bucket隶 属于user,因此user名称即可做为bucket的名称空间,不同用户允许使用相同名称的 bucket
- OpenStack Swift:提供了user、container和object分别对应于用户、存储桶和对象,不过它还额外为user提供了父级组件account,用于表示一个项目或租户,因此一个account中可包含一到多个user,它们可共享使用同一组container,并为container提供名称空间
- RadosGW:提供了user、subuser、bucket和object,其中的user对应于S3的user,而subuser则对应于Swift的user,不过user和subuser都不支持为bucket提供名称空间,因此 ,不同用户的存储桶也不允许同名;不过,自Jewel版本起,RadosGW引入了tenant(租户)用于为user和bucket提供名称空间,但它是个可选组件。Jewel版本之前,radosgw的所有user位于同一名称空间,它要求所有user的ID必须惟一,并且即便是不同user的bucket也不允许使用相同的bucket ID
用户账号是认证(Authentication)、授权(Authorization)及存储配额(Quota )功能的载体,RGW依赖它对RESTful API进行请求认证、控制资源(存储桶和对 象等)的访问权限并设定可用存储空间上限。
S3和Swift使用了不同的认证机制:
- S3主要采用的是基于访问密钥(access key)和私有密钥(secret key)进行认证,RGW兼容其V2和V4两种认证机制,其中V2认证机制支持本地认证、LDAP认证和kerberos认证三种方式,所有未能通过认证的用户统统被视为匿名用户
- Swift结合Swift私有密钥(swift key)使用令牌(token)认证方式,它支持临时URL认 证、本地认证、OpenStack Keystone认证、第三方认证和匿名认证等方式
通过身份认证后,RGW针对用户的每次资源操作请求都会进行授权检查,仅那些 能够满足授权定义(ACL)的请求会被允许执行
- S3使用bucket acl和object acl分别来控制bucket和object的访问控制权限,一般用于向 bucket或object属主之外的其它用户进行授权
- Swift API中的权限控制则分为user访问控制列表和bucket访问控制列表两种,前一种针 对user进行设定,而后一定则专用于bucket及内部的object,且只有read和write两种权限
为了支持通用的云存储功能,Ceph在RADOS集群的基础上提供了RGW(RADOS GateWay)数据抽象和管理层,它是原生兼容S3和Swift API的对象存储服务,支持数据压缩和多站点(Multi-Site)多活机制,并支持NFS协议访问接口等特性
- S3和Swift是RESTful风格的API,它们基于http/https协议完成通信和数据交换
- radosgw的http/https服务由内建的Civeweb提供,它同时也能支持多种主流的Web服务程序以代理的形式接收用户请求并转发至ceph-radosgw进程,这些Web服务程序包括nginx和haproxy等
RGW的功能依赖于Ceph对象网关守护进程(ceph-radosgw)实现,它负责向客户端提供REST API接口,并将数据操作请求转换为底层RADOS存储集群的相关操作
- 出于冗余及负载均衡的需要,一个Ceph集群上的ceph-radosgw守护进程通常不止一个, 这些支撑同一对象存储服务的守护进程联合起来构成一个zone(区域)用于代表一个独立的存储服务和存储空间。Ceph RGW是一个无状态的http服务,可以使用http反向代理实现高可用。
- 在容灾设计的架构中,管理员会基于两个或以上的Ceph集群定义出多个zone,这些zone之间通过同步机制实现冗余功能,并组成一个新的父级逻辑组件zonegroup
- zonegroup负责定义其下的各个zone之间的合作模式(active/passive或 active/active)、调用的数据存储策略和同步机制等,并且能够为一个更大级别的应用通过多个zonegroup完成跨地域的协作,实现提升客户端接入的服务质量等功能,这也通常称为多站点(Mutli-Sites)
- 为Ceph存储集群启用radosgw服务之后,它会默认生成一个名为default的 zonegroup,其内含一个名为default的zone,管理员可按需扩展使用更多的zone或 zonegroup
- 更进一步地,zongroup还有其父级组件realm,用于界定跨地理位置进行复制时的 边界
Ceph的对象网关是一个http server,默认监听端口为7480。
该步骤在创建的时候已经执行过,如果某个node上缺少ceph-radosgw包,可以再次执行一下。
ceph-deploy install --no-adjust-repos stor01 stor02 stor03
ceph-deploy rgw create stor01
rgw实例创建完成后,我们可以向7480端口发送一个未认证请求来确认是否部署成功(此时为认证)。
[cephadm@stor01 ceph-cluster]$ curl http://stor01:7480
<?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>
创建rgw实例后,会默认在rados集群中创建几个与rgw相关的pool用于存储相关信息:
[cephadm@stor01 ceph-cluster]$ ceph osd pool ls
.rgw.root
default.rgw.control
default.rgw.meta
default.rgw.log
自0.80版本起,Ceph放弃了基于apache和fastcgi提供radosgw服务的传统而代之以 默认嵌入在ceph-radosgw进程中的Citeweb,这种新的实现方式更加轻便和简洁, 但直到Ceph 11.0.1版本,Citeweb才开始支持SSL协议。
Citeweb默认监听于TCP协议的7480端口提供http服务,修改配置需要编辑 ceph.conf配置文件,以如下格式进行定义
[client.rgw.<gateway-node>]
rgw_host = <hostname OR ipaddr> #可选
rgw_frontends = "civetweb port=80"
配置完成后需要重启ceph-radosgw进程以生效新配置:
systemctl restart ceph-radosgw@rgw.<gateway-node>
添加证书文件路径、监听端口相关的配置:
[client.rgw.<gateway-node>]
rgw_frontends = "civetweb port=80+443s ssl_certificate=/etc/ceph/private/keyandcert.pem" # "port=443s"表示只监听https协议的443端口
注意,civetweb的使用的证书中必须包含证书和私钥,也就是说,证书和私钥在一个文件中。
openssl genrsa -out civetweb.key 2048
openssl req -new -x509 -key civetweb.key -out civetweb.crt -days 365 -subj “/CN=*.ljzsdut.com”
cat civetweb.key civetweb.crt >/etc/ceph/private/keyandcert.pem
- num_threads:Citeweb以线程模型处理客户端请求,它为每个连接请求分配一个专用线程,因而此参数定义了其支持的最大并发连接数,默认值为50
- request_timeout_ms:网络发送与接收操作的超时时长,以ms为单位,默认值为30000;可以在必要时通过增大此值实现长连接的效果.
- access_log_file:访问日志的文件路径,默认为空
- error_log_file:错误日志的文件路径,默认为空
[client.rgw.<gateway-node>]
rgw_frontends = "civetweb port=80+443s ssl_certificate=/etc/ceph/private/keyandcert.pem num_threads=200"
S3的存储桶是用于存储对象的容器,每个对象都必须储存在一个特定的存储桶中, 且每个对象都要直接通过RESTful API基于URL进行访问,URL格式为 http(s)://bucket-name.radowgw-host[:port]/key。例如,对于存储在stor01.ljzsdut.com上的S3 API对象存储系统上eshop存储桶中的名为 images/commodity1.jpg 的对象,可通过http://eshop.stor01.ljzsdut.com/images/commodity1.jpg对其进行寻址。因此,radosgw的S3 API接口的功能强依赖于DNS的泛域名解析服务,它必须能够 正常解析任何“<bucket-name>.<radowgw-host>”格式的名称至radosgw主机。
下面是一个在bind中用于泛域名解析的配置示例:
IN NS ns
ns IN A 172.29.1.199
stor01 IN A 172.29.1.11
stor02 IN A 172.29.1.22
*.stor01 IN CNAME stor01
*.stor02 IN CNAME stor02
另外,还需要配置每个radowgw守护进程的rgw_dns_name为其DNS名称:
[client.rgw.stor01]
rgw_dns_name = stor01.ljzsdut.com
S3服务的REST API使用用户账号(user)、存储桶(bucket)和对象(object)三个组件来组织存储的数据对象,对象保存于存储桶中,而存储桶则支持授权给特定账号进行读写及创建/删除等操作。
radosgw-admin是用于管理radowgw服务的命令行管理接口,它有着众多的分别用于不同管理功能的命令,例如user、subuser、key、bucket和object等
radosgw-admin user create --uid="s3user" --display-name="S3 Testing User"
而后即可通过其API接口进行访问测试,或者使用s3cmd命令进行。
查看用户列表
[cephadm@stor01 ceph-cluster]$ radosgw-admin user list
[
"s3user"
]
查看用户详情信息
[cephadm@stor01 ceph-cluster]$ radosgw-admin user info --uid s3user
{
"user_id": "testuser",
"display_name": "First User",
"email": "",
"suspended": 0,
"max_buckets": 1000,
"subusers": [],
"keys": [
{
"user": "testuser",
"access_key": "1LTAUGZ65G2EYROZE8BQ",
"secret_key": "Q9TrDQCPFKrRVFBsDEkTGN0bWKcGSnctpNRBIMCV"
}
],
"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": []
}
配置s3cmd:使用s3cmd命令之前需要事先配置其工作环境,包括指定Access Key和Secret Key,以及 S3服务的访问端点和默认的Region(Ceph的新版本中称作zonegroup)等
s3cmd --configure
配置的结果将保存于~/.s3cmd.cfg配置文件中,用户随后可通过编辑此文件修改配置参数,或者再次运行此配置命令为其指定新的配置信息。
s3cmd有众多的子命令。
import boto
import boto.s3.connection
access_key = 'put your access key here!'
secret_key = 'put your secret key here!'
#创建连接
conn = boto.connect_s3(
aws_access_key_id = access_key,
aws_secret_access_key = secret_key,
host = 'objects.dreamhost.com',
#is_secure=False, # uncomment if you are not using ssl
calling_format = boto.s3.connection.OrdinaryCallingFormat(),
)
# 打印自己拥有的bucket
for bucket in conn.get_all_buckets():
print "{name}\t{created}".format(
name = bucket.name,
created = bucket.creation_date,
)
Swift的用户账号对应于radosgw中的subuser(子用户),它隶属于某个事先存在的user(用户账号),即swift api使用的认证用户需要在s3 api用户的基础上做进一步的配置:
radosgw-admin user create --uid="swiftuser" --display-name="Swift Testing User"
radosgw-admin subuser create --uid=swiftuser --subuser=swiftuser:swift --access=full
或:
sudo radosgw-admin user create --subuser="{username}:{subusername}" --uid="{username}"
--display-name="{Display Name}" --key-type=swift --secret="{password}" --access=full
Swift API的上下文中,存储桶以container表示,而非S3中的bucket,但二者在功 用上类同,都是对象数据的容器。
Python Swiftclient是一个用于与Swift API交互的Python客户端程序,它包含了 Python API(swift 模块)和一个命令行工具swift。可以使用pip instal --upgrade python-swiftclient 进行安装。
swift命令可以通过Swift API完成容器和对象数据的管理操作,其基础语法格式为:
swift [-A Auth URL] [-U username] [-K password] subcommand