ljzsdut
GitHubToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeBack to homepage

07 Rados Gw

块存储、文件存储与对象存储

image-20211008103112636

对象存储系统(OSS)

对象存储(Object Storage System) 是无层次结构的数据存储方法,通常用于云计算环境中。

  • 不同于其他数据存储方法,基于对象的存储不使用目录树;数据作为单独的对象进行存储。数据并不放置在目录层次结构中,而是存在于平面地址空间内的同一级别;

  • 应用通过唯一地址来识别每个单独的数据对象

  • 每个对象可包含有助于检索的元数据

  • 专为使用API在应用级别(而非用户级别)进行访问而设计(RestFull风格API)

  • 适应于创建后不再频繁变动的文件对象。

  • 适应于非结构化数据(无schema)。

  • 使用bucket的概念作为存储空间的隔离,用户的权限、配额也是在bucket上实现,可以理解为是一个目录。(也支持对象级别的权限限制)

对象与对象存储

对象是对象存储系统中数据存储的基本单位,每个Object是数据数据属性集的综合体,数据属性可以根据应用的需求进行设置,包括数据分布、服务质量等

  • 每个对象自我维护其属性,从而简化了存储系统的管理任务
  • 对象的大小可以不同,甚至可以包含整个数据结构,如文件、数据库表项等

对象存储系统一般是一类智能设备,它具有自己的存储介质、处理器、内存以及网 络系统等,负责管理本地的对象,是对象存储系统的核心

image-20211008102908249

User、bucket、object

一般说来,一个对象存储系统的核心资源类型应该包括用户(User)、存储桶(bucket)和对象(object)。

三者的关系是:用户将对象存储于对象存储系统上的存储桶中,存储桶隶属于用户并能够容纳对象,一个用户可以拥有一到多个存储桶,而一个存储桶常用于存储多个对象。

image-20211008112047645

虽然在设计与实现上有所区别,但大多数对象存储系统对外呈现的核心资源类型大同小异:

  • 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两种权限

RadosGW

为了支持通用的云存储功能,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

多站点(Mutli-Sites)

  • zonegroup负责定义其下的各个zone之间的合作模式(active/passive或 active/active)、调用的数据存储策略和同步机制等,并且能够为一个更大级别的应用通过多个zonegroup完成跨地域的协作,实现提升客户端接入的服务质量等功能,这也通常称为多站点(Mutli-Sites)
  • 为Ceph存储集群启用radosgw服务之后,它会默认生成一个名为default的 zonegroup,其内含一个名为default的zone,管理员可按需扩展使用更多的zone或 zonegroup
  • 更进一步地,zongroup还有其父级组件realm,用于界定跨地理位置进行复制时的 边界

安装ceph对象存储网关

Ceph的对象网关是一个http server,默认监听端口为7480。

1、安装rgw软件包(可选)

该步骤在创建的时候已经执行过,如果某个node上缺少ceph-radosgw包,可以再次执行一下。

ceph-deploy install --no-adjust-repos stor01 stor02 stor03

2、创建rgw实例

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

配置Citeweb

自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>

配置https

添加证书文件路径、监听端口相关的配置:

[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 API接口

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:使用s3cmd命令之前需要事先配置其工作环境,包括指定Access Key和Secret Key,以及 S3服务的访问端点和默认的Region(Ceph的新版本中称作zonegroup)等

s3cmd --configure

配置的结果将保存于~/.s3cmd.cfg配置文件中,用户随后可通过编辑此文件修改配置参数,或者再次运行此配置命令为其指定新的配置信息。

s3cmd有众多的子命令。

S3 API(sdk)使用

参考链接

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 API接口

创建用户

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,但二者在功 用上类同,都是对象数据的容器。

swift命令行

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

Swift API

参考链接