Ceph是一个高性能的PB级分布式文件系统。它能够在一个系统中提供对象存储、块存储和文件存储。对如何加载使用这些存储感兴趣的话可以参考《用容器轻松搭建ceph实验环境》。它还可以通过RADOSGW来实现S3和OpenStack Swift存储接口。不管RADOSGW还是块存储或文件存储都是基于对象存储来提供服务。本文的主要内容是如何通过RADOSGW来暴露S3和SWIFT接口。由于Docker Registry在2.4版本移除了对rados的支持,所以如果使用ceph作为后端存储就需要利用RADOSGW了。
准备工作
我们需要先安装virtualBox和vagrant。通过vagrant来驱动virtualBox搭建一个虚拟测试环境。首先在本地任意路径新建一个空文件夹比如test
,运行以下命令:
virtual box host1 2 3 4
| mkdir test cd test vagrant init minimum/ubuntu-trusty64-docker vi Vagrantfile
|
里面应该有一句config.vm.box = "minimum/ubuntu-trusty64-docker"
,在它的下面添加如下几行代码,相当于给它分配一台IP为192.168.33.111,内存为1G的虚拟机。
Vagrantfile1 2 3 4
| config.vm.network "private_network", ip: "192.168.33.111" config.vm.provider "virtualbox" do |v| v.memory = 1024 end
|
这个vagrant镜像已经在ubuntu的基础上帮我们安装了docker,用起来很方便。然后终端运行以下命令启动并连接虚拟机。
搭建环境
首先需要安装一些ceph、radosgw的依赖包,还有python-boto、swift客户端等工具可以用于测试。
1 2 3 4
| sudo apt-get update sudo apt-get -y --force-yes install ceph-common radosgw python-boto sudo pip install --upgrade setuptools sudo pip install --upgrade python-swiftclient
|
然后就可以启动ceph/demo这个容器来轻松提供ceph服务了:
1
| docker run -d --net=host -v /etc/ceph:/etc/ceph -e MON_IP=192.168.33.111 -e CEPH_NETWORK=192.168.33.111/24 --name=ceph ceph/demo
|
接下来的步骤主要参考的是有一点坑的官方教程。需要为radosgw生成一个名为gateway
的用户:
1 2
| sudo ceph auth del client.radosgw.gateway sudo ceph auth get-or-create client.radosgw.gateway osd 'allow rwx' mon 'allow rwx' -o /etc/ceph/ceph.client.radosgw.keyring
|
然后需要把这个用户加到ceph.conf
配置里,提供端口为9000的FastCGI服务:
1 2 3 4 5 6 7 8
| sudo sed -i $'$a \\\n' /etc/ceph/ceph.conf sudo sed -i '$a [client.radosgw.gateway]' /etc/ceph/ceph.conf sudo sed -i '$a host = vagrant-ubuntu-trusty-64' /etc/ceph/ceph.conf sudo sed -i '$a keyring = /etc/ceph/ceph.client.radosgw.keyring' /etc/ceph/ceph.conf sudo sed -i '$a rgw socket path = ""' /etc/ceph/ceph.conf sudo sed -i '$a log file = /var/log/radosgw/client.radosgw.gateway.log' /etc/ceph/ceph.conf sudo sed -i '$a rgw frontends = fastcgi socket_port=9000 socket_host=0.0.0.0' /etc/ceph/ceph.conf sudo sed -i '$a rgw print continue = false' /etc/ceph/ceph.conf
|
其中第二行的vagrant-ubuntu-trusty-64
,必须使用hostname -s
得出的结果。如果是按照准备工作的做法,是不需要变的。另外这里的第一个回答非常清晰地解释了CGI和FastCGI。
配置完成后就可以重启ceph容器并启动radosgw:
1 2
| docker restart ceph sudo /etc/init.d/radosgw start
|
为了提供HTTP服务,需要安装apache2(Red Hat系是httpd):
1
| sudo apt-get -y --force-yes install apache2
|
接下来创建一个apache2的配置文件,监听80端口并把请求转发到radosgw提供的FastCGI 9000端口上:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| cat << EOF > rgw.conf <VirtualHost *:80> ServerName localhost DocumentRoot /var/www/html ErrorLog /var/log/apache2/rgw_error.log CustomLog /var/log/apache2/rgw_access.log combined RewriteEngine On RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L] SetEnv proxy-nokeepalive 1 ProxyPass / fcgi://localhost:9000/ </VirtualHost> EOF sudo mv rgw.conf /etc/apache2/conf-enabled/rgw.conf
|
由于上述配置需要用到一些apache2默认未加载的模块,所以需要加载并重新启动apache2:
1 2 3 4
| sudo a2enmod rewrite sudo a2enmod proxy_http sudo a2enmod proxy_fcgi sudo service apache2 restart
|
测试服务
S3
RADOSGW的基本配置已经完成,现在我们测试一下s3接口。它的存储模型是这样的:用户可以创建和管理多个存储桶(bucket),每个存储桶里可以存放无限多个对象(object),每个对象是一个键值对。存储桶的名称与区域无关,全球唯一。
接下来先创建一个s3用户:
1 2 3
| docker exec ceph radosgw-admin user create --uid="testuser" --display-name="First User" | tee user.txt export ACCESS_KEY=`sed -n 's/ *"access_key": "\(.*\)",/\1/p' user.txt` export SECRET_KEY=`sed -n 's/ *"secret_key": "\(.*\)"/\1/p' user.txt`
|
使用以下python代码来测试我们的s3接口是否已经可用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| cat << EOF > s3test.py import boto import boto.s3.connection import os access_key = os.environ["ACCESS_KEY"] secret_key = os.environ["SECRET_KEY"] conn = boto.connect_s3( aws_access_key_id = access_key, aws_secret_access_key = secret_key, host = '192.168.33.111', is_secure=False, calling_format = boto.s3.connection.OrdinaryCallingFormat(), ) bucket = conn.create_bucket('my-new-bucket') for bucket in conn.get_all_buckets(): print "{name}\t{created}".format( name = bucket.name, created = bucket.creation_date, ) EOF python s3test.py
|
如果显示了my-new-bucket
,那就说明测试成功地通过s3接口创建了一个存储桶。可以使用以下命令来获取这个存储桶和实例的信息:
1 2 3 4
| docker exec ceph radosgw-admin metadata bucket list docker exec ceph radosgw-admin metadata get bucket:my-new-bucket | tee bucket.txt export BUCKET_ID=`cat bucket.txt | sed -n 's/ *"bucket_id": "\(.*\)"/\1/p'` docker exec ceph radosgw-admin metadata get bucket.instance:my-new-bucket:$BUCKET_ID
|
还可以修改实例的信息并PUT回去,具体做法可参见《Changing the region of a RGW bucket》。
Swift
接下来测试swift。对于swift来说,它的存储模型是这样的:一个账号(account)里可以有多个容器(container),容器里可以有许多个键值对,字典里的值称为对象(object)。账号和容器被存储在SQLite数据库里,而对象是以文件方式存储的。
首先需要创建swift用户并生成secret:
1 2 3
| docker exec ceph radosgw-admin subuser create --uid=testuser --subuser=testuser:swift --access=full docker exec ceph radosgw-admin key create --subuser=testuser:swift --key-type=swift --gen-secret | tee subuser.txt export PASSWORD=`sed -n '/testuser:swift/{N;p;}' subuser.txt | sed -n 's/ *"secret_key": "\(.*\)"/\1/p'`
|
然后就可以用以下命令查看swift里所有的容器:
1
| swift -A http://192.168.33.111/auth/v1.0 -U testuser:swift -K $PASSWORD list
|
应该能看到刚才测试s3接口时创建的my-new-bucket
,在这里s3的存储桶和swift的容器是同一个概念。接下来我们自己创建容器:
1 2
| swift -A http://192.168.33.111/auth/v1.0 -U testuser:swift -K $PASSWORD post qinghua swift -A http://192.168.33.111/auth/v1.0 -U testuser:swift -K $PASSWORD list qinghua
|
创建成功,里面没有文件。现在可以上传、下载文件试试:
1 2 3 4 5 6
| echo Hello World > hw.txt swift -A http://192.168.33.111/auth/v1.0 -U testuser:swift -K $PASSWORD upload qinghua hw.txt swift -A http://192.168.33.111/auth/v1.0 -U testuser:swift -K $PASSWORD list qinghua mv hw.txt hw.bak swift -A http://192.168.33.111/auth/v1.0 -U testuser:swift -K $PASSWORD download qinghua hw.txt cat hw.txt
|
搞定!