存档

文章标签 ‘Ceph’

RadosGW 初体验

2015年8月3日 没有评论

介绍

Ceph 的最底层模块是对象存储,本质上就是一个 Rados, 如果不考虑用户体验,利用 rados 就可以使用 Ceph 对象存储. 例如:

$ rados -p test_pool get SI7W1FUI43H3I3ED9CWX test.data
  • test_pool: pool 名
  • SI7W1FUI43H3I3ED9CWX: object 名
  • test.data 保存到这里

和 RBD 以及 CephMDS 一样,RadosGW 提供了对 Radow 对象存储访问的更友好支持. 它允许用户通过 Restful API 的方式进行使用 RadowGW 。

从技术架构上讲, 和 RBD 一样, 它位于 Librados 之上, 而且正如它的名字所暗示的, 它是 Rados 的一个网关,通过 HTTP RestFul API, 对外提供对象存储的服务. 为了用户使用的方便性和兼容性,还提供了兼容 S3 和 Swfit 的接口.

以上,使得可以基于 RadosGW 构建云存储.

环境描述

假设已经有一个安装好的 Ceph 集群. 在一台新的节点上配置 RadowGW

节点信息如下:

主机名字
ceph.test.com
IP 地址
192.168.3.140

NOTE: 所有节点的操作系统都是 centos 7.

安装部署

安装配置 Apache

  1. 安装
$ sudo yum install -y httpd
  1. 配置: 编辑 /etc/httpd/conf/httpd.conf
# 设置 ServerName
ServerName ceph.test.com
 
# 添加下面内容
<IfModule !proxy_fcgi_module>
    LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so
</IfModule>
 
# 修改监听参数: 192.168.3.140 为本机 IP
Listen 192.168.3.140:80
  1. 重启 Apache
$ sudo systemctl restart httpd

安装配置 RadosGW

  1. 安装 RadosGW
$ sudo yum install -y radosgw-agent
  1. 创建用于 RadosGW 的用户等信息(在 ceph admin 节点执行)
$ sudo ceph-authtool --create-keyring /etc/ceph/ceph.client.radosgw.keyring
$ sudo chmod +r /etc/ceph/ceph.client.radosgw.keyring
$ sudo ceph-authtool /etc/ceph/ceph.client.radosgw.keyring -n client.radosgw.gateway --gen-key
$ sudo ceph-authtool -n client.radosgw.gateway --cap osd 'allow rwx' --cap mon 'allow rwx' /etc/ceph/ceph.client.radosgw.keyring
$ sudo ceph -k /etc/ceph/ceph.client.admin.keyring auth add client.radosgw.gateway -i /etc/ceph/ceph.client.radosgw.keyring

将这个 keyring 和 admin.keyring 复制到 ceph.test.com

$ scp /etc/ceph/ceph.client.radosgw.keyring root@ceph.test.com:/etc/ceph
$ scp /etc/ceph/ceph.client.admin.keyring root@ceph.test.com:/etc/ceph
  1. 创建 RadosGW 需要的 pool(在 ceph admin 节点)
$ ceph osd pool create .rgw 64 64
$ ceph osd pool create .rgw.root 64 64 
$ ceph osd pool create .rgw.control 64 64 
$ ceph osd pool create .rgw.gc 64 64
$ ceph osd pool create .rgw.buckets 64 64 
$ ceph osd pool create .rgw.buckets.index 64 64 
$ ceph osd pool create .log 64 64 
$ ceph osd pool create .intent-log 64 64 
$ ceph osd pool create .usage 64 64 
$ ceph osd pool create .users 64 64 
$ ceph osd pool create .users.email 64 64
$ ceph osd pool create .users.swift 64 64
$ ceph osd pool create .users.uid 64 64
  1. 修改并 gateway.client 的配置到各个节点.

将下列内容添加到 ceph 节点的各个配置文件(包括 RadosGW 节点)

[client.radosgw.gateway]
host = ceph
keyring = /etc/ceph/ceph.client.radosgw.keyring
rgw socket path = /var/run/ceph/ceph.radosgw.gateway.fastcgi.sock
log file = /var/log/radosgw/client.radosgw.gateway.log
rgw print continue = false
  1. 创建 RadosGW 运行目录
$ sudo mkdir -p /var/lib/ceph/radosgw/ceph-radosgw.gateway
$ sudo chown apache:apache /var/log/radosgw/client.radosgw.gateway.log
  1. 启动 RadosGW
$ /etc/init.d/ceph-radosgw start
  1. 将 RadosGW 的配置写入 Apache 中 a) 创建文件 /etc/httpd/conf.d/rgw.conf, 内容为:
<VirtualHost *:80>
ServerName localhost
DocumentRoot /var/www/html
 
ErrorLog /var/log/httpd/rgw_error.log
CustomLog /var/log/httpd/rgw_access.log combined
 
# LogLevel debug
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]
SetEnv proxy-nokeepalive 1
ProxyPass / unix:///var/run/ceph/ceph.radosgw.gateway.fastcgi.sock|fcgi://localhost:9000/
</VirtualHost>

b) 重启 Apache

$ sudo systemctl restart httpd

测试

创建用户

为了完成测试,分别创建一个用于 S3 和 Swift 的用户:

  1. 创建 S3 用户:
$ sudo radosgw-admin user create --uid="testuser" --display-name="First User"
{ "user_id": "testuser",
  ... ...
  "keys": [
        { "user": "testuser",
          "access_key": "EZU2MX4CJCIZILATWQSK",
          "secret_key": "4z18K+f7MZQop2Z99PxN2KKGSX9rb6KBd9ioW0D\/"},
  ... ...
  "temp_url_keys": []}
  1. 创建 Swift 用户: a) 创建 Swift 用户
$ sudo radosgw-admin subuser create --uid=testuser --subuser=testuser:swift
{ "user_id": "testuser",
  ... ...
  "keys": [
        { "user": "testuser",
          "access_key": "EZU2MX4CJCIZILATWQSK",
          "secret_key": "4z18K+f7MZQop2Z99PxN2KKGSX9rb6KBd9ioW0D\/"},
        { "user": "testuser:swift",
          "access_key": "SI7W1FUI43H3I3ED9CWX",
          "secret_key": ""}],
  ... ...
  "temp_url_keys": []}

b) 设置 Swift 用户的密钥:

$ sudo radosgw-admin subuser create --uid=testuser --subuser=testuser:swift
{ "user_id": "testuser",
  ... ...
  "keys": [
        { "user": "testuser",
          "access_key": "EZU2MX4CJCIZILATWQSK",
          "secret_key": "4z18K+f7MZQop2Z99PxN2KKGSX9rb6KBd9ioW0D\/"},
        { "user": "testuser:swift",
          "access_key": "SI7W1FUI43H3I3ED9CWX",
          "secret_key": ""}],
  "swift_keys": [
        { "user": "testuser:swift",
          "secret_key": "yTXiN+2y1Uf6j+CXioZwhqzwCPhOgqVblm2iShj+"}],
  ... ...
  "temp_url_keys": []}

测试

下面的例子使用 s3cmd 测试用 S3 接口连接使用 RadosGW:

NOTE: s3cmd的安装配置请参考 s3cmd 的相关文档

$ s3cmd mb s3://my-bucket # 创建一个 bucket
Bucket 's3://my-bucket/' created
$ s3cmd ls
2015-08-03 10:11  s3://my-bucket
$ cat test.sh 
source openrc
python foo.py $@
$ s3cmd put test.sh s3://my-bucket/my-dir/test.sh # 将 test.sh 上传到 my-bucket/my-dir 下
test.sh -> s3://my-bucket/my-dir/test.sh  [1 of 1]
 31 of 31   100% in    0s   196.90 B/s  done
$ s3cmd ls s3://my-bucket # 查看目录
                       DIR   s3://my-bucket/my-dir/
$ s3cmd get s3://my-bucket/my-dir/test.sh test1.sh # 下载 test.sh 这个对象
s3://my-bucket/my-dir/test.sh -> test1.sh  [1 of 1]
s3://my-bucket/my-dir/test.sh -> test1.sh  [1 of 1]
 31 of 31   100% in    0s     5.83 kB/s  done
$ cat test1.sh
source openrc
python foo.py $@

分类: Storage 标签: ,

Ceph 中的网络配置

2014年4月3日 没有评论

Ceph 是分布式的文件系统, 由于它是网络文件系统, 它的性能不仅仅受限于物理磁盘的
读写带宽(IOPS), 好的网络架构对发挥 Ceph 的性能也至关重要.

在这里, 我不去详细探讨 Ceph 内部的架构细节(在另外文章我会详细分析), 仅仅通过

Ceph 的配置文件和一些测试来简单研究一下 Ceph 的网络配置.

Ceph 里的数据同步

Ceph 里面的数据同步包括 Monitor 之间的增量同步配置(CRUSH啊这些), osd 之间
的数据冗余. 为了让 Ceph 的性能发挥到最好, 对于数据的传输, Ceph 定义了
public network 和 cluster network, public network 是外部访问用到的
网络(fuse client, rbd client), cluster network 为了 Ceph 内部组件的
数据同步(monitor, osd).

Ceph 的网络配置

前面说过, Ceph 区分外部访问的数据和内部集群使用的数据, 用两个不同的网络配置来
区分: public addrcluster addr.

一般来说, 生产环境中的服务器都有两块以上的网卡, 配置的时候, 一块网卡主要来跑
Ceph 的 对外的数据传输服务(保证足够的 IOPS), 另一块网卡来做集群内部的数据同步.

简单测试

这里的测试仅仅是为了测试上面说过的理论, 不涉及其它 Ceph 的内容. 为了方便计,
只用了一台机器同时跑 monitor 和 osd(这在生产环境中是非常不推荐的).

你可以用我之前的文章讲到的 Ceph 初体验 来搭建测试环境.

附上我的配置文件(注意我的 osd.0 的配置):

root@ceph1:~# cat /etc/ceph/ceph.conf 
[global]
fsid = 382f9965-75ad-403a-b063-4d1fa3e9fb52
mon_initial_members = ceph1
mon_host = 192.168.3.30
auth_supported = cephx
osd_journal_size = 1024
filestore_xattr_use_omap = true
 
[osd.0]
public_addr = 192.168.3.30
cluster_addr = 192.168.3.33

下面的图是该配置在 client 下用 iftop 截到的图, 可以看到数据的传输
走的是 192.168.3.33 这个网络.

ceph-iftop1

改变上面的 osd.0 配置为下面的内容

[osd.0]
public_addr = 192.168.3.33
cluster_addr = 192.168.3.30

用 iftop 可以看到, 数据传输的接口果然变了.

ceph-iftop2

总结

Ceph 的网络配置大体就这么两个参数, 当然使用上要比上面讲的灵活一点. 灵活配置
Ceph 的网络参数可以满足性能上的要求, 甚至在网络带宽远远小于磁盘的 I/O 带宽的
时候(在生产环境中比较少见), 可以给每一个 osd 配置一个网络出口达到最好的性能.

更多具体详细的讨论请参考 Ceph 官网上 网络配置文档.

分类: Storage 标签: ,

用 Puppet 部署 CEPH

2014年2月23日 没有评论

相比其他分布式系统(e.g. glusterfs), Ceph 的复杂毋庸置疑, 甚至在部署上也稍显
麻烦, 目前主流的部署方式主要有以下几种:

  • ceph-deploy: 取代之前的 mkcephfs, 不推荐在生产环节使用
  • chef: 官方推荐的部署工具
  • puppet: 大家部署这些服务最喜欢的方式
  • XXX: 自己从底层定制, 比如我这里写的 ceph-aio

本文主要介绍用 puppet 部署 ceph.

基本配置

三台机器, 每台机器都分别作为 monitor 和 osd, 并且每台机器都有两个磁盘,
把第二个磁盘(/dev/vdb)作为 osd. 我这里使用 这个 puppet 模块, 但是这个模块
官方没有对同时把一台节点变为 monitor 和 osd的测试, 我这里测试中也出了一点问题,
我用了一些 work around 的方法, 需要注意, 下面的 Troubleshoot 中会提到.

我部署的基本环境如下:

Hostname Ip Address Roles osd
ceph1.test 192.168.176.30 master + mon + osd /dev/vdb
ceph2.test 192.168.176.31 agent + mon + osd /dev/vdb
ceph3.test 192.168.176.32 agent + mon + osd /dev/vdb

修改每台节点的 hosts 文件, 使得可以互相用主机名 ping 通

# cat /etc/hosts
... ...
192.168.176.30  ceph1.test
192.168.176.31  ceph2.test
192.168.176.32  ceph3.test

puppet master 配置

1 安装 puppet 软件包

# apt-get install -y ruby1.8 puppetmaster sqlite3 libsqlite3-ruby \
  libactiverecord-ruby git augeas-tools puppet ruby1.8-dev libruby1.8
# update-alternatives --set ruby /usr/bin/ruby1.8

2 配置 puppet

修改 /etc/puppet/puppet.conf 的相应配置项为:

[master]
storeconfigs = true
dbadapter = sqlite3
 
[agent]
pluginsync = true
server = ceph1.test

设置我们的节点不需要认证:

# echo "*.test" > /etc/puppet/autosign.conf

3 puppet 的模块设置

安装需要的 puppet 模块:

# puppet module install ripienaar/concat
# puppet module install puppetlabs/apt

安装 puppet 的 ceph 模块:

# cd /etc/puppet/modules
# git clone git://github.com/enovance/puppet-ceph.git ceph

4 配置 site.pp 文件

我照着文档写了对应上面三个节点的 site.pp 文件, 可以从发 这里 下载, 然后拷贝到
/etc/puppet/manifests 目录下

5 重启 puppetmaster

# service puppetmaster restart

puppet agent 配置

注意: 此操作要在三个节点上同时执行.

1 安装 puppet 软件包

# apt-get -y install puppet

2 修改 /etc/puppet/puppet.conf 的相应配置项为:

[agent]
pluginsync = true
server = ceph1.test

3 大功告成, 开始利用 puppet 部署 ceph

# puppet agent --enable
# export AGENT_OPTIONS="--onetime --verbose --ignorecache --no-daemonize --no-usecacheonfailure --no-splay --show_diff --debug"
# puppet agent $AGENT_OPTIONS # 运行五步这步操作, 分别可以获取 keyring, 配置磁盘等等

4 依次登陆每个节点同步 ceph 的配置文件

# ssh cephx.test
# puppet agent -vt

Troubleshoot

在配置 osd 的时候会发现初始化 osd 的时候失败, 官方对同时把节点当做 monitor
和 osd 没有进行详细的测试, 我这里手动初始化 osd 来 work around 这个问题, 我这里
以 ceph1.test, 也就是 osd.0 为例来说明

# rm -rf /var/lib/ceph/osd/ceph-0/* # 先清空之前初始化失败的数据
# ceph auth add osd.0 osd 'allow *' mon 'allow rwx' -i /var/lib/ceph/osd/ceph-0/keyring # 初始化 osd 的目录
# service ceph start osd.0 # 启动 osd 服务

可以看到现在 osd 正常了

# ceph osd tree
# id    weight  type name   up/down reweight
-1  0.04999 root default
-2  0.04999     host ceph1
0   0.04999         osd.0   up  1

分类: Storage 标签: ,

Rados API 的使用

2014年1月4日 没有评论

Rados 介绍

Rados 是 Ceph 最底层的组件, 基于对象存储模型, 向上提供 object, file system, block 的存储方式. 这里我主要关注 rados block storage: rbd

rbd 用两种方式提供的客户端访问, 一种方式是是把客户端操作集成在内核中, 用户 只需要像使用其他文件系统一样挂载就可以直接使用了, 我在 CEPH 初体验 里面有 简单的提及.

另一种方式是通过 librados 来访问, 这个库有各种语言支持, e.g. C, python, java 等. QEMU 中对 Ceph 的支持即是通过这种方式来实现的.

本文主要讨论 librados(librbd) 的使用.

API 说明

为了使用 rbd, 需要使用以下几个 API:

/** 
 * 创建一个 rados_t 句柄, 该句柄存储了rados 客户端的数据结构, 用来和
 * rados 通信, 第二个参数是连接 rados 的客户端 ID
 * 
 * @param cluster 存储句柄的指针
 * @param id 连接 rados 的用户名
 * @return 
 */
int rados_create(rados_t *cluster, const char * const id);
 
/** 
 * 设置 rados 参数, 包括认证信息, monitor 地址等, 如果设置了 cephx 认证,
 * 那么之前创建 rados 句柄的时候, 必须设置客户端 ID, 并且必须设置 key 的密码
 * 
 * @param cluster 上面创建的 rados 句柄
 * @param option 
 * @param value 
 * @return 
 */
int rados_conf_set(rados_t cluster, const char *option, const char *value);
 
/** 
 * 完成了上面的设置之后, 使用 rados 句柄连接 rados 服务器
 * 
 * @param cluster 
 * 
 * @return 
 */
int rados_connect(rados_t cluster);
 
/** 
 * 成功连接上 rados 服务器之后, 就可以用 rados_ioctx_create() 打开 rados
 * 上的 pool, 该函数需要传递一个 rados_ioctx_t, 用来保存 IO 句柄
 * 
 * @param cluster rados 句柄
 * @param pool_name 需要打开的 pool
 * @param ioctx 保存 IO 句柄
 * 
 * @return 
 */
int rados_ioctx_create(rados_t cluster, const char *pool_name, rados_ioctx_t *ioctx);
 
/** 
 * 利用上面创建的关联到 pool 上的 IO 句柄打开具体的镜像
 * 
 * @param io IO 句柄
 * @param name 镜像名称
 * @param image 存储 image 句柄, 以后需要这个指针读写镜像
 * @param snap_name 打开镜像上的快照, 如果不是, 传递 null
 * @return 
 */
int rbd_open(rados_ioctx_t io, const char *name, rbd_image_t *image, const char *snap_name);
 
/** 
 * rados 支持异步操作, 当执行大量 I/O 的时候, 不需要等待每一个操作完成,
 * 只需要传递一个回调函数给读写函数, 当操作完成后, librados 会自动条用
 * 我们的回调函数. 下面的函数创建一个 rados 的异步句柄
 * 
 * @param cb_arg 传递给回调函数的参数
 * @param complete_cb 回调函数
 * @param c 存储异步句柄
 * 
 * @return 
 */
int rbd_aio_create_completion(void *cb_arg, rbd_callback_t complete_cb, rbd_completion_t *c);
 
/** 
 * 异步读的 API
 * 
 * @param image 上面谈到的 image 句柄
 * @param off 读写的文件位置
 * @param len 读写大小
 * @param buf 存储读写的数据
 * @param c 异步句柄
 * 
 * @return 
 */
int rbd_aio_read(rbd_image_t image, uint64_t off, size_t len, char *buf, rbd_completion_t c);

测试

完整的测试代码可以到 这里 下载, 我已经详细的写了程序注释.

首先, 我们创建一个测试的镜像, 写入一些数据, 看看我们的程序能不能读到:

# 1. 创建一个名为 test 的 pool
# rados mkpool test
# 2. 在 test 中创建镜像 hello
# rbd create -p test --size 10 hello
# 3. 在 hello 中写一些数据(为了使用这个 rbd, 先 map 到我们的文件系统, 写入数据, 再 unmap)
rbd map test/hello
echo "hello, you are reading image hello which is in test pool, have fun" > hello.txt
dd if=hello.txt of=/dev/rbd/test/hello
rbd unmap /dev/rbd/test/hello

然后用我们的测试程序来读取上面写入的数据

# ./rados test hello admin AQBhjqlSKBBTCxAAwchc9GauJ4+MPHz9hkV9Iw== 192.168.176.30:6789
open rados as following setting:
poolname: test
imagename: hello
username: admin
password: AQBhjqlSKBBTCxAAwchc9GauJ4+MPHz9hkV9Iw==
monitor: 192.168.176.30:6789
buffer read:
========================================
hello, you are reading image hello which is in test pool, have fun
 
========================================

分类: Storage 标签: ,

整合 Openstack 和 Ceph

2013年12月18日 没有评论

环境

Hostname IP Address Roles
ceph1 192.168.176.30 ceph-monitor/admin
ceph2 192.168.176.31 ceph-osd
ceph3 192.168.176.32 ceph-osd
os-control 192.168.176.152 controller/compute/cinder-scheduler
os-compute 192.168.176.156 compute
cinder1 192.168.176.156 cinder-node

为 openstack 创建 osd pool

在 ceph-admin 节点上:

root@ceph1:~# ceph osd pool create volumes 128
root@ceph1:~# ceph osd pool create images 128
root@ceph1:~# ceph osd pool stats
pool data id 0
  nothing is going on
 
pool metadata id 1
  nothing is going on
 
pool rbd id 2
  nothing is going on
 
pool volumes id 3
  nothing is going on
 
pool images id 4
  nothing is going on

为 openstack 节点配置 ceph

安装软件包

在 glance-node(os-control) 上:

root@os-control:~# apt-get install -y python-ceph

在 cinder-node(cinder1) 上:

root@os-compute:~# apt-get install -y python-ceph ceph-common

配置

配置文件

在 ceph-admin 节点把 ceph 的配置文件复制到 {glance,cinder-node}:/etc/ceph, 如果这两个节点不存在该文件夹, 先创建

root@ceph1:~# ceph-deploy config push os-control
root@ceph1:~# ceph-deploy config push cinder1

设置认证

1 因为我们之前的 Ceph 配置开启了 cephx 认证, 创建相应的用户来使用 Ceph 服务.

root@ceph1:~# ceph auth get-or-create client.volumes mon 'allow r' \
osd 'allow class-read object_prefix rbd_children, allow rwx pool=volumes, allow rx pool=images'
 
root@ceph1:~# ceph auth get-or-create client.images mon 'allow r' \ 
osd 'allow class-read object_prefix rbd_children, allow rwx pool=images'

2 然后把 client.{volumes/images} 的 keyring 复制到相应的节点(glance-node/cinder-node)

root@ceph1:~# ceph auth get-or-create client.images | ssh os-control tee /etc/ceph/ceph.client.images.keyring
root@ceph1:~# ssh os-control sudo chown glance:glance /etc/ceph/ceph.client.images.keyring
 
root@ceph1:~# ceph auth get-or-create client.volumes | ssh cinder1 tee /etc/ceph/ceph.client.volumes.keyring
root@ceph1:~# ssh cinder1 chown cinder:cinder /etc/ceph/ceph.client.volumes.keyring

3 配置 compute-node(os-control), 在 compute 节点上, 认证是由 libvirt 来完成的.

# 1) 把 client.volumes 的 keyring 复制到 compute-node
root@ceph1:~# ceph auth get-key client.volumes | ssh os-control tee client.volumes.key
 
# 2) 在 compute-node 中, 创建 secret.xml 文件, 内容如下
<secret ephemeral='no' private='no'>
  <usage type='ceph'>
    <name>client.volumes secret</name>
  </usage>
</secret>
 
# 3) 把这个文件导入到 libvirt 中
# virsh secret-define --file secret.xml
3888d137-bcda-45fe-93e3-4fdd0112d0df
 
# 4) 把 client.volumes 的密钥导入 libvirt 中
# virsh secret-set-value --secret 3888d137-bcda-45fe-93e3-4fdd0112d0df \
--base64 $(cat client.volumes.key) && rm client.volumes.key secret.xml

设置 openstack

1 在 glance-node(os-control) 中, 修改配置文件 /etc/glance/glance-api.conf 的以下值

default_store=rbd
rbd_store_user=images
rbd_store_pool=images
show_image_direct_url=True

2 在 cinder-node(cinder1) 中, 修改 /etc/cinder/cinder.conf 的以下值

volume_driver=cinder.volume.drivers.rbd.RBDDriver
rbd_pool=volumes
glance_api_version=2
rbd_user=volumes
rbd_secret_uuid=3888d137-bcda-45fe-93e3-4fdd0112d0df

3 在各自节点重启 openstack 相关服务

# service glance-api restart
# service nova-compute restart
# service cinder-volume restart

使用

创建 images

# 1) 用 glance 上传一个镜像, 命令和普通 glance 操作一样 ==>
# du -h /mnt/Images/ubuntu-13.10-server-cloudimg-amd64-disk1.img 
232M    /mnt/Images/ubuntu-13.10-server-cloudimg-amd64-disk1.img
# glance image-create \
--name="ubuntu-ceph-image" \
--is-public True \
--container-format bare \
--disk-format qcow2 \
--file /mnt/Images/ubuntu-13.10-server-cloudimg-amd64-disk1.img \
--progress
 
# 2) 查看上传的镜像
# nova image-list
+--------------------------------------+-----------------------+--------+--------+
| ID                                   | Name                  | Status | Server |
+--------------------------------------+-----------------------+--------+--------+
| 8aa5b765-1a4d-4b98-b5ad-9b6c7b58d57b | Ubuntu 13.10 cloudimg | ACTIVE |        |
| 7849c15e-9c28-49c6-97ab-d278bc27b525 | ubuntu-ceph-image     | ACTIVE |        |
+--------------------------------------+-----------------------+--------+--------+
 
# 3) 在 ceph 节点上查看 rados 的情况
# rbd ls images
7849c15e-9c28-49c6-97ab-d278bc27b525
# rbd info images/7849c15e-9c28-49c6-97ab-d278bc27b525
rbd image '7849c15e-9c28-49c6-97ab-d278bc27b525':
    size 231 MB in 29 objects                         <== 注意这个大小
    order 23 (8192 kB objects)
    block_name_prefix: rbd_data.10c2375b6
    format: 2
    features: layering

创建可启动 volumes

# 1) 创建一个 10G 的可启动盘
# cinder create --image-id 7849c15e-9c28-49c6-97ab-d278bc27b525 --display-name boot-vol-on-ceph 10
 
# 2) 查看创建的磁盘信息
# cinder list
+--------------------------------------+-----------+------------------+------+-------------+----------+--------------------------------------+
|                  ID                  |   Status  |   Display Name   | Size | Volume Type | Bootable |             Attached to              |
+--------------------------------------+-----------+------------------+------+-------------+----------+--------------------------------------+
| 6f01529e-1d42-4c53-b4c7-e50d466571cc |   in-use  |     volume1      |  1   |     None    |  false   | 015ac60a-1902-4d39-b4ea-11376838872b |
| 7604e894-231b-4d86-b613-9659c7583936 |   in-use  |     volume2      |  1   |     None    |  false   | 015ac60a-1902-4d39-b4ea-11376838872b |
| bd3a9b3a-64c8-4865-8f55-32dfc683ff67 | available | boot-vol-on-ceph |  10  |     None    |   true   |                                      |
+--------------------------------------+-----------+------------------+------+-------------+----------+--------------------------------------+
 
# 3) 查看 rbd 的信息
# rbd ls volumes
volume-bd3a9b3a-64c8-4865-8f55-32dfc683ff67
# rbd info volumes/volume-bd3a9b3a-64c8-4865-8f55-32dfc683ff67
rbd image 'volume-bd3a9b3a-64c8-4865-8f55-32dfc683ff67':
    size 10240 MB in 2560 objects                           <== 创建的大小 10G
    order 22 (4096 kB objects)
    block_name_prefix: rbd_data.10e02ae8944a
    format: 2
    features: layering

启动

# nova boot --flavor 2 --key_name mykey --block_device_mapping vda=bd3a9b3a-64c8-4865-8f55-32dfc683ff67:::0 myvm-on-ceph
# nova list
+--------------------------------------+--------------+--------+--------------+-------------+-----------------------+
| ID                                   | Name         | Status | Task State   | Power State | Networks              |
+--------------------------------------+--------------+--------+--------------+-------------+-----------------------+
| 015ac60a-1902-4d39-b4ea-11376838872b | myvm         | ACTIVE | None         | Running     | private=192.168.22.34 |
| 10309940-f56a-4c64-9910-561e29fb7b81 | myvm-on-ceph | ACTIVE | None         | Running     | private=192.168.22.36 |
+--------------------------------------+--------------+--------+--------------+-------------+-----------------------+

查看 QEMU 的命令行信息, 在 compute-node 节点

# ps aux | grep '[1]9537' | awk -F " -" '{ i=1;while(i<NF) {print NF,$i;i++}}' | grep 'drive file'
32 drive file=rbd:volumes/volume-bd3a9b3a-64c8-4865-8f55-32dfc683ff67:id=volumes:key=AQBkJK9SOA1UDBAAUqjfU6SvWzEv/w7ZH8nBmg==:auth_supported=cephx\;none:mon_host=192.168.176.30\:6789\;192.168.176.31\:6789\;192.168.176.32\:6789,if=none,id=drive-virtio-disk0,format=raw,serial=bd3a9b3a-64c8-4865-8f55-32dfc683ff67,cache=none

可以看到, QEMU 已经使用了 rbd 的 url 来读写虚拟机镜像了.

其它

如果配置多个 {compute,cinder}-node, 按照上面各自节点的配置做相应的配置即可.

分类: OpenStack, Storage 标签: , ,

CEPH 初体验

2013年12月12日 2 条评论

介绍

Ceph 是新一代的分布式文件系统, 具有高扩展, 高可靠性, 高性能的特点. 它采用多个 多个元数据 + 多个存储节点 + 多个监控节点的架构, 解决单点故障的问题.

架构简介

如图, ceph 的后端是 RADOS, 一个对象存储系统. 通过 rados, 提供了以下接口:

  • 类似于 amazon S3 的对象存储系统
  • Block 设备接口
  • 文件系统接口, 兼容 POSIX

ceph architecture

组件简介

ceph 主要由以下组件:

  • osd: Object Storage Device, 负责提供存储资源
  • monitor: 维护整个 ceph 集群的状态
  • mds: 保存 cephfs 的元数据, 非必须, 只有 cephfs 接口需要此模块
  • rados gateway: 提供 REST 接口, 兼容 S3 和 Swift 的 API

搭建环境准备

准备了三台机器, 每台机器有两个磁盘(vda, vdb), 初始搭建用 ceph1 作为 mon, ceph2, ceph3 作为 osd, osd mon, osd 的扩展之后完成

  | Hostname |     IP Address | Role       |
  |----------+----------------+------------|
  | ceph1    | 192.168.176.30 | mon, admin |
  | ceph2    | 192.168.176.31 | osd        |
  | ceph3    | 192.168.176.32 | osd        |

1 修改三台节点的 hosts 文件, 使得彼此可见, 在每一个节点 的/etc/hosts 中, 加入

192.168.176.30  ceph1
192.168.176.31  ceph2
192.168.176.32  ceph3

2 把 admin 节点(ceph1) 的 ssh 密钥拷贝到其他节点, 使得 ceph1 可以无密码访问其他节点

 # ssh-keygen
 # ssh-copy-id ceph1
 # ssh-copy-id ceph2
 # ssh-copy-id ceph3

3 在 admin node(ceph1) 上, 设置 ceph 的软件源仓库

 # wget -q -O- 'https://ceph.com/git/?p=ceph.git;a=blob_plain;f=keys/release.asc' | \
apt-key add -
 # echo deb http://ceph.com/packages/ceph-extras/debian $(lsb_release -sc) main | \
tee /etc/apt/sources.list.d/ceph-extras.list
 # CODENAME 是 lsb_release -sc 得到的值
 # apt-add-repository 'deb http://ceph.com/debian-emperor/ {CODENAME} main'
 # apt-get update && apt-get install ceph-deploy

部署

部署工作是在 admin node 上完成的.

 # 1. 创建一个工作目录
 # mkdir -p ~/my-cluster && cd ~/my-cluster
 
 # 2. 创建一个集群, 默认集群名为 ceph, 默认 monitor 为 ceph1
 # ceph-deploy new ceph1
 
 # 3. 在所有节点上安装 ceph 软件包, 此操作将在所有节点上执行以下操作, 1) 添加 ceph
 #    的软件源, 2) 更新软件源数据库, 安装 ceph ceph-mds ceph-common ceph-fs-common
 #    和 gdisk 软件包
 # ceph-deploy install ceph1 ceph2 ceph3
 
 # 4. 创建 mon, 这里选择 ceph1 作为 monitor 节点, 大概的流程如下:
 #    1) 把 ceph.conf 文件复制到 ceph1:/etc/ceph
 #    2) 在 ceph1 中创建 ceph1:/var/lib/ceph/mon/ceph-ceph1 并把 ceph.mon.keyring 
 #       复制到 ceph1:/var/lib/ceph/tmp/ceph-ceph1.mon.keyring
 #    3) 在 ceph1 中使用以下命令初始化 monitor data: 
 #       ceph-mon --cluster ceph --mkfs -i ceph1 --keyring /var/lib/ceph/tmp/ceph-ceph1.mon.keyring
 #    4) 在 ceph1 中运行 initctl emit ceph-mon cluster=ceph id=ceph1 启动 ceph-mon
 #       或者使用 service ceph -c /etc/ceph/ceph.conf start mon.ceph1
 #    5) 在 ceph1 中用 ceph --cluster=ceph --admin-daemon /var/run/ceph/ceph-mon.ceph1.asok mon_status
 #        检查 ceph1 的 mon 状态, 如果有错误, 报告之
 # ceph-deploy mon create ceph1
 
 # 5. 复制远程 node 上的密钥复制到当前文件夹, 包括:
 #    ceph.client.admin.keyring ==> ceph.client.admin.keyring
 #    /var/lib/ceph/mon/ceph-ceph1/keyring ==> ceph.mon.keyring
 #    /var/lib/ceph/bootstrap-osd/ceph.keyring ==> ceph.bootstrap-osd.keyring
 #    /var/lib/ceph/bootstrap-mds/ceph.keyring ==> ceph.bootstrap-mds.keyring
 # ceph-deploy gatherkeys ceph1
 
 # 6. 增加 osd
 #    prepare 主要步骤:
 #    1) push 配置文件 到 ceph{2,3}:/etc/ceph/ceph.conf
 #    2) push ceph.bootstrap-osd.keyring 复制到 ceph{2,3}:/var/lib/ceph/bootstrap-osd/ceph.keyring
 #    3) udevadm trigger --subsystem-match=block --action=add
 #    4) ceph-disk-prepare --fs-type xfs --cluster ceph -- /dev/vdb ==> 创建分区, 格式化 等
 #    activate 步骤:
 #    ceph-disk-activate --mark-init upstart --mount /dev/vdb ==> 挂载 ceph 分区, 使用以下命令启动
 #    initctl emit --no-wait -- ceph-osd cluster=ceph id=0
 # ceph-deploy osd prepare ceph2:/dev/vdb ceph3:/dev/vdb
 # ceph-deploy osd activate ceph2:/dev/vdb ceph3:/dev/vdb
 # ceph osd tree # 查看 osd 的状态
 # id   weight  type name   up/down reweight
-1  0.3 root default
-2  0.09999     host ceph2
0   0.09999         osd.0   up  1   
-3  0.09999     host ceph3
1   0.09999         osd.1   up  1   
 
 # 7. 复制 admin 密钥到其他节点
 #    复制 ceph.conf, ceph.client.admin.keyring 到 ceph{1,2,3}:/etc/ceph
 # ceph-deploy admin ceph1 ceph2 ceph3
 
 # 8. 查看部署状态
 # ceph health
HEALTH_OK ==> that's all

添加新的 osd

这里准备把 ceph1 变为 一个新的 osd

 # 根据上面的介绍, 新增一个 osd 很简单
 # ceph-deploy osd prepare ceph1:/dev/vdb
 # ceph-deploy osd activate ceph1:/dev/vdb
 # ceph osd tree # 查看状态
 # id   weight  type name   up/down reweight
-1  0.3 root default
-2  0.09999     host ceph2
0   0.09999         osd.0   up  1   
-3  0.09999     host ceph3
1   0.09999         osd.1   up  1   
-4  0.09999     host ceph1
2   0.09999         osd.2   up  1

添加新的 mon

为了 monitor 的高可用, 一般部署的时候推荐设置多个 monitor, 这里把 ceph2 和 ceph3 也变为 monitor.

 # 1. ceph2, ceph3 不在 mon_initial_members 中, 这里把 ceph{2,3} 也加入配置文件中
 #    顺便把 public 网络也设置一下
 # emacsclient ceph.conf
 # cat ceph.conf
root@ceph1:~/my-cluster# cat ceph.conf 
[global]
...
mon_initial_members = ceph1 ceph2 ceph3
public_network = 192.168.176.0/24
...
 
 # 2. 把配置文件同步到其它节点
 # ceph-deploy --overwrite-conf config push ceph1 ceph2 ceph3
 
 # 3. 创建 monitor
 # ceph-deploy mon create ceph2 ceph3

添加新 mds

mds 是 metadata service, 目前官方只推荐在生产环境中使用一个 mds. 因为 object 和 block storage 没有文件的概念, 不需要元数据, 所以 mds 只有在部署 CephFS 才有 意义.

 # 1. 细节解释:
 #    1) 把 ceph.conf 和 ceph.bootstrap-mds.keyring 复制到 ceph1:/etc/ceph 和
 #       /var/lib/ceph/bootstrap-mds/ceph.keyring
 #    2) 创建 ceph1:/var/lib/ceph/mds/ceph-ceph1
 #    3) ceph --cluster ceph --name client.bootstrap-mds \
 #       --keyring /var/lib/ceph/bootstrap-mds/ceph.keyring \
 #       auth get-or-create mds.ceph1 osd allow rwx mds allow mon allow profile mds \
 #       -o /var/lib/ceph/mds/ceph-ceph1/keyring
 #    4) 启动 initctl emit ceph-mds cluster=ceph id=ceph1, 或者
 #       service ceph start mds.ceph1
 # ceph-deploy mds create ceph1

作为文件系统使用

在一台安装了 ceph 客户端的机器上, 直接挂在

 # mount -t ceph ceph1:6789:/ /mnt -o name=admin,secret=AQBhjqlSKBBTCxAAwchc9GauJ4+MPHz9hkV9Iw==
 # df -h | grep mnt
192.168.176.30:6789:/        297G  108M  297G   1% /mnt

作为块设备使用

在一台安装了 ceph 的机器上(或者可以用 ceph-deploy install machine-name 安装), 执行以下命令:

 # modprobe rbd # 挂载 rbd 的内核模块
 # rbd create --size 4096 test1 # 创建一个 4G 的 rbd 镜像
 # 把 上面创建的 rbd 镜像映射到块设备 /dev/rbd/{poolname}/imagename , 这里为 /dev/rbd/rbd/test
 # rbd map test1 --pool rbd
 # 然后, 就可以像使用普通快设备一样使用这个块设备了(格式化,分区,直接给虚拟机使用), 例如
 # mkfs.ext4 /dev/rbd/rbd/test1 # 格式化
 # mount /dev/rbd/rbd/test1 /rbd
 # df -h | grep rbd
/dev/rbd1                    3.9G  8.0M  3.6G   1% /rbd

参考

分类: Storage 标签: ,