侧边栏壁纸
博主头像
张种恩的技术小栈博主等级

行动起来,活在当下

  • 累计撰写 748 篇文章
  • 累计创建 65 个标签
  • 累计收到 39 条评论

目 录CONTENT

文章目录

Ceph 对象存储网关的使用

zze
zze
2021-10-22 / 0 评论 / 1 点赞 / 403 阅读 / 13012 字

RGW 特点:

  • 数据不需要放置在目录层次结构中,而是存在于平面地址空间内的同一级别。
  • 应用通过唯一地址来识别每个单独的数据对象。
  • 每个对象可包含有助于检索的元数据。
  • 通过 RESTful API 在应用级别进行访问。

RadosGW 对象存储简介

RadosGW 是对象存储(OSS,Object Storage Service)的一种实现方式,RADOS 网关也称为 Ceph 对象网关,RadosGW、RGW,是一种服务,使客户端能够利用标准对象存储 API 来访问 Ceph 集群,它支持 AWS S3 和 Swift API,在 Ceph 0.8 版本之后使用 Civetweb(https:/github.com/civetweb/civetweb)的 Web 服务器来响应 api 请求,客户端使用 http/https 协议通过 RESTful API 与 RGW 通信,而 RGW 则通过 librados 与 Ceph 集群通信,RGW 客户端通过 S3 或者 Swift API 使用 RGW 用户进行身份验证,然后 RGW 网关代表用户利用 Cephx 与 Ceph 存储进行身份验证。

S3 由 Amazon 于 2006 年推出,全称为 Simple Storage Service,S3 定义了对象存储,是对象存储事实上的标准,从某种意义上说,S3 就是对象存储,对象存储就是 S3,它是对象存储市场的霸主,后续的对象存储都是对 S3 的模仿。

对象存储特点

通过对象存储将数据存储为对象,每个对象除了包含数据,还包含数据自身的元数据。
对象通过 Object ID 来检索,无法通过普通文件系统的方式通过文件路径及文件名称操作来直接访问对象,只能通过 API 来访问,或者第三方客户端(实际上也是对 API 的封装)。
对象存储中的对象不整理到目录树中,而是存储在扁平的命名空间中,Amazon S3 将这个扁平命名空间称为 bucket,而 swift 则将其称为容器。
无论是 bucket 还是容器,都不能嵌套。
bucket 需要被授权才能访问到,一个帐户可以对多个 bucket 授权,而权限可以不同。
方便横向扩展、快速检索数据。
不支持客户端挂载,且需要客户端在访问的时候指定文件名称。
不是很适用于文件过于频繁修改及删除的场景。
Ceph 使用 bucket 作为存储桶(存储空间),实现对象数据的存储和多用户隔离,数据存储在 bucket 中,用户的权限也是针对 bucket 进行授权,可以设置用户对不同的 bucket 拥有不同的权限,以实现权限管理。

bucket 特性

存储空间(bucket)是用于存储对象(Object)的容器,所有的对象都必须隶属于某个存储空间,可以设置和修改存储空间属性用来控制地城、访问权限、生命周期等,这些属性设置直接作用于该存储空间内所有对象,因此可以通过灵活创建不同的存储空间来完成不同的管理功能。
同一个存储空间的内部是扁平的,没有文件系统的目录等概念,所有的对象都直接隶属于其对应的存储空间。
每个用户可以拥有多个存储空间,存储空间的名称在 OSS 范围内必须是全局唯一的,一旦创建之后无法修改名称。
存储空间内部的对象数目没有限制。

bucket 命名规范

  • 只能包括小写字母,数字和短横线
  • 必须以小写字母或者数字开头和结尾
  • 长度必须在 3-63 字节之间
  • 存储桶名称不能使用 IP 地址格式
  • Bucket 名必须全局唯一

对象存储对比

  • Amazon S3:提供了 user、bucket 和 object 分别表示用户、存储桶和对象,其中 bucket 隶属于 user,可以针对 user 设置不同 bucket 的名称空间的访问权限,而且不同用户允许访问相同的 bucket。
  • OpenStack Swift:提供了 user、container 和 object 分别对应于用户、存储桶和对象,不过它还额外为 user 提供了父级组件 account,account 用于表示一个项目或租户(OpenStack 用户),因此一个 account 中可包含一到多个 user,它们可共享使用同一组 container,并为 container 提供名称空间。
  • RadosGW:提供了 user、subuser、bucket 和 object,其中的 user 对应于 S3 的 user,而 subuser 则对应于 Swift 的 user,不过 user 和 subuser 都不支持为 bucket 提供名称空间,因此,不同用户的存储桶也不允许同名;不过,自 Jewel 版本起,RadosGW 引入了 tenant(租户)用于为 user 和 bucket 提供名称空间,但它是个可选组件,RadosGW 基于 ACL 为不同的用户设置不同的权限控制,如:Read 读权限、Write 写权限、Readwrite 读写权限、full-control 全部控制权限。

RGW 部署

参考【Ceph RBD、RGW 与 CephFS 的基础应用 - 对象存储 RGW】。

存储池

RGW 部署成功后 Ceph 集群会默认创建几个专门用于 RGW 的存储池,如下:

$ ceph osd pool ls | grep rgw
.rgw.root
default.rgw.log # 存储日志信息
default.rgw.control # 系统控制池,在有数据更新时,通知其它 RGW 更新缓存
default.rgw.meta # 元数据存储池,通过不同的名称空间分别存储不同的 rados 对象,这些名称空间包括用户 UID 及其 bucket 映射信息的名称空间 users.uid、用户的密钥名称空间 users.key、用户的 email 名称空间 users.email、用户的 subuser 的名称空间 users.swift,以及 bucket 的名称空间 root 等
# 下面三个存储池在创建了 bucket 并向 bucket 存入数据了才会创建
default.rgw.buckets.index # 存放 bucket 到 object 的索引信息
default.rgw.buckets.data # 存放对象的数据
default.rgw.buckets.non-ec # 数据的额外信息存储池
$ ceph osd pool get default.rgw.buckets.data crush_rule
crush_rule: replicated_rule # 默认是副本池
$ ceph osd pool get default.rgw.buckets.data size
size: 3 # 默认的副本数
$ ceph osd pool get default.rgw.buckets.data pgp_num
pgp_num: 32
$ ceph osd pool get default.rgw.buckets.data pg_num
pg_num: 32

验证 ZONE 信息

$ radosgw-admin zone get --rgw-zone=default
{
    "id": "ee395401-ecb7-4618-a68f-a19bb9d32a28",
    "name": "default",
    "domain_root": "default.rgw.meta:root",
    "control_pool": "default.rgw.control",
    "gc_pool": "default.rgw.log:gc",
    "lc_pool": "default.rgw.log:lc",
    "log_pool": "default.rgw.log",
    "intent_log_pool": "default.rgw.log:intent",
    "usage_log_pool": "default.rgw.log:usage",
    "roles_pool": "default.rgw.meta:roles",
    "reshard_pool": "default.rgw.log:reshard",
    "user_keys_pool": "default.rgw.meta:users.keys",
    "user_email_pool": "default.rgw.meta:users.email",
    "user_swift_pool": "default.rgw.meta:users.swift",
    "user_uid_pool": "default.rgw.meta:users.uid",
    "otp_pool": "default.rgw.otp",
    "system_key": {
        "access_key": "",
        "secret_key": ""
    },
    "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
            }
        }
    ],
    "realm_id": "",
    "notif_pool": "default.rgw.log:notif"
}

自定义 HTTP 端口

配置文件可以在 ceph-deploy 服务器修改然后统一推送,或者单独修改每个 radosgw 服务器的配置为统一配置,然后重启 RGW 服务。

RGW 服务默认监听 HTTP 端口为 7480,下面以修改 ceph-node1ceph-node2 上的 RGW 服务监听的端口为 9000 为例:

$ vim ceph.conf
...
[client.rgw.ceph-node1]
rgw_host=ceph-node1
rgw_frontends=civetweb port=9000
# 配置节名称可以通过查看进程启动命令确认 ps -ef | grep rgw
[client.rgw.ceph-node2]
rgw_host=ceph-node2
rgw_frontends=civetweb port=9000

# 推送配置
$ ceph-deploy --overwrite-conf config push ceph-node1 ceph-node2 ceph-node3
# ceph-node1 重启 RGW 服务
$ systemctl restart ceph-radosgw@rgw.ceph-node1.service
# ceph-node2 重启 RGW 服务
$ systemctl restart ceph-radosgw@rgw.ceph-node2.service
# 检查 ceph-node1 和 ceph-node2 上的 RGW 服务监听的端口
$ ss -tanlp | grep rados
LISTEN   0         128                 0.0.0.0:9000             0.0.0.0:*        users:(("radosgw",pid=16943,fd=59)) 

启用 HTTPS

RGW 服务是无状态的 HTTP 服务,所以我们可以在集群边缘添加一个代理服务器来代理到 RGW 服务,比如使用 Nginx、HAProxy 等反向代理服务,所以 HTTPS 就可以在边缘代理服务器来进行配置。而 RGW 服务本身也支持 HTTPS 配置(此方式不常用),下面就演示一下此种方式启用 HTTPS。

自签证书:

$ cd /etc/ceph && mkdir certs && cd certs
# 生成私钥
$ openssl genrsa -out civetweb.key 2048
# 签发证书
$ cd /root && openssl rand -writerand .rnd && cd -
$ openssl req -new -x509 -key civetweb.key -out civetweb.crt -subj "/CN=rgw.zze.xyz"
$ cat civetweb.crt civetweb.key > civetweb.pem
$ ls
civetweb.crt  civetweb.key  civetweb.pem
# 同步证书到 RGW 服务所在主机的 /etc/ceph/certs 目录
$ scp -r /etc/ceph/certs ceph-node1:/etc/ceph/
$ scp -r /etc/ceph/certs ceph-node2:/etc/ceph/

配置 RGW 服务启用 SSL:

$ vim ceph.conf
...
[client.rgw.ceph-node1]
rgw_host=ceph-node1
rgw_frontends="civetweb port=9000+9443s ssl_certificate=/etc/ceph/certs/civetweb.pem"

[client.rgw.ceph-node2]
rgw_host=ceph-node2
rgw_frontends="civetweb port=9000+9443s ssl_certificate=/etc/ceph/certs/civetweb.pem"

# 推送配置
$ ceph-deploy --overwrite-conf config push ceph-node1 ceph-node2 ceph-node3

重启 RGW 服务生效:

# ceph-node1 重启 RGW 服务
$ systemctl restart ceph-radosgw@rgw.ceph-node1.service
# ceph-node2 重启 RGW 服务
$ systemctl restart ceph-radosgw@rgw.ceph-node2.service
# 此时 RGW 服务会同时监听 9000 和 9443 端口
$ ss -tanlp | egrep '9000|9443'
LISTEN   0         128                 0.0.0.0:9443             0.0.0.0:*        users:(("radosgw",pid=18097,fd=62))
LISTEN   0         128                 0.0.0.0:9000             0.0.0.0:*        users:(("radosgw",pid=18097,fd=61))

此时就可以在浏览器通过 https://rgw.zze.xyz:9443/ 以 HTTPS 方式来访问 RGW 服务了,当然浏览器所在 PC 要添加对应的 HOSTS 解析将 rgw.zze.xyz 解析到 RGW 节点。

日志及优化配置

可以为 RGW 服务配置指定的日志存储目录:

# 创建日志目录并授权
$ mkdir /var/log/radosgw && chown ceph.ceph /var/log/radosgw
# 修改配置
$ vim /etc/ceph/ceph.conf
...
[client.rgw.ceph-node1]
...
# 错误日志
error_log_file=/var/log/radosgw/civetweb.error.log
# 访问日志
access_log_file=/var/log/radosgw/civetweb.access.log
# 请求超时时间配置,此处为 30 秒,num_threads 指定处理请求的线程数,默认为 100
request_timeout_ms=30000 num_threads=200

重启生效。

测试读写数据

创建用户并授权

$ radosgw-admin user create --uid="zze" --display-name="zhongen.zhang"
{
    "user_id": "zze",
    "display_name": "zhongen.zhang",
    "email": "",
    "suspended": 0,
    "max_buckets": 1000,
    "subusers": [],
    "keys": [
        {
            "user": "zze",
            "access_key": "UH996E0MNY3VT2W8RHP2",
            "secret_key": "sbDgbN3EDSYi1qfDDDfnDSUfDpJDC8BxtYKhYkLr"
        }
    ],
    "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 是一个支持通过命令行访问 Ceph RGW 实现创建存储同桶、上传、下载以及管理数据到对象存储的命令行客户端工具。

安装并生成认证配置:

$ apt install s3cmd -y
$ s3cmd --configure

Enter new values or accept defaults in brackets with Enter.
Refer to user manual for detailed description of all options.

Access key and Secret key are your identifiers for Amazon S3. Leave them empty for using the env variables.
Access Key: UH996E0MNY3VT2W8RHP2
Secret Key: sbDgbN3EDSYi1qfDDDfnDSUfDpJDC8BxtYKhYkLr
Default Region [US]: 

Use "s3.amazonaws.com" for S3 Endpoint and not modify it to the target Amazon S3.
S3 Endpoint [s3.amazonaws.com]: 172.20.0.21:9000

Use "%(bucket)s.s3.amazonaws.com" to the target Amazon S3. "%(bucket)s" and "%(location)s" vars can be used
if the target S3 system supports dns based buckets.
DNS-style bucket+hostname:port template for accessing a bucket [%(bucket)s.s3.amazonaws.com]: 172.20.0.21:9000/%(bucket)

Encryption password is used to protect your files from reading
by unauthorized persons while in transfer to S3
Encryption password: 
Path to GPG program [/usr/bin/gpg]: 

When using secure HTTPS protocol all communication with Amazon S3
servers is protected from 3rd party eavesdropping. This method is
slower than plain HTTP, and can only be proxied with Python 2.7 or newer
Use HTTPS protocol [Yes]: no

On some networks all internet access must go through a HTTP proxy.
Try setting it here if you can't connect to S3 directly
HTTP Proxy server name: 

New settings:
  Access Key: UH996E0MNY3VT2W8RHP2
  Secret Key: sbDgbN3EDSYi1qfDDDfnDSUfDpJDC8BxtYKhYkLr
  Default Region: US
  S3 Endpoint: 172.20.0.21:9000
  DNS-style bucket+hostname:port template for accessing a bucket: 172.20.0.21:9000/%(bucket)
  Encryption password: 
  Path to GPG program: /usr/bin/gpg
  Use HTTPS protocol: False
  HTTP Proxy server name: 
  HTTP Proxy server port: 0

Test access with supplied credentials? [Y/n] Y
Please wait, attempting to list all buckets...
Success. Your access key and secret key worked fine :-)

Now verifying that encryption works...
Not configured. Never mind.

Save settings? [y/N] y
Configuration saved to '/root/.s3cfg'

测试使用:

# 创建 bucket 
$ s3cmd mb s3://zze
Bucket 's3://zze/' created
# 查看 bucket 列表
$ s3cmd ls
2021-10-22 09:46  s3://zze
# 上传 ceph.conf 到 zze bucket
$ s3cmd put ceph.conf s3://zze/
upload: 'ceph.conf' -> 's3://zze/ceph.conf'  [1 of 1]
 777 of 777   100% in    2s   383.70 B/s  done
# 查看 zze bucket 中的文件,s3cmd la 可以查看所有 bucket 中的所有文件
$ s3cmd ls s3://zze
2021-10-22 09:54       777   s3://zze/ceph.conf
# 下载 ceph.conf 到 /root 目录
$ s3cmd get s3://zze/ceph.conf /root/
1

评论区