centos7 yum 安装jewel版本ceph

删除默认的源,国外的比较慢

yum clean all
rm -rf /etc/yum.repos.d/*.repo

下载阿里云的base源

wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo

下载阿里云的epel源

wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo

修改里面的系统版本为7.3.1611,当前用的centos的版本的的yum源可能已经清空了

sed -i '/aliyuncs/d' /etc/yum.repos.d/CentOS-Base.repo
sed -i '/aliyuncs/d' /etc/yum.repos.d/epel.repo
sed -i 's/$releasever/7.3.1611/g' /etc/yum.repos.d/CentOS-Base.repo

添加ceph源

vim /etc/yum.repos.d/ceph.repo

添加

[ceph]
name=ceph
baseurl=http://mirrors.aliyun.com/ceph/rpm-jewel/el7/x86_64/
gpgcheck=0
[ceph-noarch]
name=cephnoarch
baseurl=http://mirrors.aliyun.com/ceph/rpm-jewel/el7/noarch/
gpgcheck=0
[ceph-source]
name=cephsource
baseurl=http://mirrors.aliyun.com/ceph/rpm-infernalis/el7/SRPMS
gpgcheck=0
[ceph-radosgw]
name=cephradosgw
baseurl=http://mirrors.aliyun.com/ceph/rpm-jewel/el7/x86_64/
gpgcheck=0

进行yum的makecache

yum makecache

安装软件

yum install ceph ceph-deploy

然后我们可以顺利按照官网来安装ceph cluster了

利用docker部署ceph集群

背景

Ceph官方现在提供两类镜像来创建集群,一种是常规的,每一种Ceph组件是单独的一个镜像,如ceph/daemon、ceph/radosgw、ceph/mon、ceph/osd等;另外一种是最新的方式,所有的Ceph组件都集成在一个镜像ceph/daemon中,如果要创建对应的Ceph组件容器,只需要指定类型即可。这里,我们使用第一种方式来创建Ceph集群。
  
另外,这里所有的容器,都是在同一个Docker host上创建的。

重新开始

在搭建过程中,如果遇到了任何问题,想删除之前的环境,并重新开始搭建时,可以运行如下命令:

#  rm -rf /etc/ceph /var/lib/ceph/  /opt/osd/; mkdir -p /etc/ceph /var/lib/ceph/osd /opt/osd/;chown -R 64045:64045 /var/lib/ceph/osd/;chown -R 64045:64045 /opt/osd/; docker rm -f $(docker ps -a | grep "ceph" | awk '{print $1}');

  
这里,分别删除了ceph配置、osd目录。并重新创建目录并更改所属用户(这一步非常重要),再删除所有有ceph关键字的容器。

搭建集群

创建monitor节点

这里,假设monitor节点的ip为192.168.1.111。

# docker run -itd --name mymon --network my-bridge --ip 192.168.1.111 -e MON_NAME=mymon -e MON_IP=192.168.1.111 -v /etc/ceph:/etc/ceph ceph/mon

在monitor节点上标识osd

# docker exec mymon ceph osd create
0
# docker exec mymon ceph osd create
1
# docker exec mymon ceph osd create
2

创建osd节点

# docker run -itd --name osd0 --network my-bridge -e CLUSTER=ceph -e WEIGHT=1.0 -e MON_NAME=mymon -e MON_IP=192.168.1.111 -v /etc/ceph:/etc/ceph -v /opt/osd/0:/var/lib/ceph/osd/ceph-0 ceph/osd 
# docker run -itd --name osd1 --network my-bridge -e CLUSTER=ceph -e WEIGHT=1.0 -e MON_NAME=mymon -e MON_IP=192.168.1.111 -v /etc/ceph:/etc/ceph -v /opt/osd/1:/var/lib/ceph/osd/ceph-1 ceph/osd 
# docker run -itd --name osd2 --network my-bridge -e CLUSTER=ceph -e WEIGHT=1.0 -e MON_NAME=mymon -e MON_IP=192.168.1.111 -v /etc/ceph:/etc/ceph -v /opt/osd/2:/var/lib/ceph/osd/ceph-2 ceph/osd 

再创建两个monitor节点组成集群

# docker run -itd --name mymon_1 --network my-bridge --ip 192.168.1.112 -e MON_NAME=mymon_1 -e MON_IP=192.168.1.112 -v /etc/ceph:/etc/ceph ceph/mon
# docker run -itd --name mymon_2 --network my-bridge --ip 192.168.1.113 -e MON_NAME=mymon_2 -e MON_IP=192.168.1.113 -v /etc/ceph:/etc/ceph ceph/mon

创建Ceph网关节点

#  docker run -itd --name myrgw --network my-bridge --ip 192.168.1.100 -p 9080:80 -e RGW_NAME=myrgw -v /etc/ceph:/etc/ceph ceph/radosgw

验证

执行ceph命令来查看ceph集群状态。

# docker exec mymon ceph -s

缺点

这种搭建方法,所有容器共享了/etc/ceph中的配置,因此,仅限于在一个docker host中搭建集群。在最新的Ceph镜像ceph/daemon中,提供了一种共享kv存储etcd的实现方式,可以实现多host情况下的Ceph集群搭建,适用于swarm、k8s或者Marathon的环境下搭建Ceph,有兴趣的朋友可以试一试。

CentOS7下部署ceph-12 (luminous)多机集群

一、准备

前一篇点击打开链接只部署了一个单机集群。在这一篇里,手动部署一个多机集群:mycluster。我们有三台机器nod1,node2和node3;其中node1可以免密ssh/scp任意其他两台机器。我们的所有工作都在node1上完成。

准备工作包括在各个机器上安装ceph rpm包(见前一篇第1节点击打开链接),并在各个机器上修改下列文件:

/usr/lib/systemd/system/[email protected]
/usr/lib/systemd/system/[email protected]
/usr/lib/systemd/system/[email protected]
/usr/lib/systemd/system/[email protected]
/usr/lib/systemd/system/[email protected]

修改:

Environment=CLUSTER=ceph                                                  <---  改成CLUSTER=mycluster
ExecStart=/usr/bin/... --id %i --setuser ceph --setgroup ceph    <--- 删掉--setuser ceph --setgroup ceph

二、创建工作目录

在node1创建一个工作目录,后续所有工作都在node1上的这个工作目录中完成;

mkdir /tmp/mk-ceph-cluster  
cd /tmp/mk-ceph-cluster  

三、创建配置文件

vim mycluster.conf  
[global]  
    cluster                     = mycluster  
    fsid                        = 116d4de8-fd14-491f-811f-c1bdd8fac141  

    public network              = 192.168.100.0/24  
    cluster network             = 192.168.73.0/24  

    auth cluster required       = cephx  
    auth service required       = cephx  
    auth client required        = cephx  

    osd pool default size       = 3  
    osd pool default min size   = 2  

    osd pool default pg num     = 128  
    osd pool default pgp num    = 128  

    osd pool default crush rule = 0  
    osd crush chooseleaf type   = 1  

    admin socket                = /var/run/ceph/$cluster-$name.asock  
    pid file                    = /var/run/ceph/$cluster-$name.pid  
    log file                    = /var/log/ceph/$cluster-$name.log  
    log to syslog               = false  

    max open files              = 131072  
    ms bind ipv6                = false  

[mon]  
    mon initial members = node1,node2,node3  
    mon host = 192.168.100.131:6789,192.168.100.132:6789,192.168.100.133:6789  

    ;Yuanguo: the default value of {mon data} is /var/lib/ceph/mon/$cluster-$id,  
    ;         we overwrite it.  
    mon data                     = /var/lib/ceph/mon/$cluster-$name  
    mon clock drift allowed      = 10  
    mon clock drift warn backoff = 30  

    mon osd full ratio           = .95  
    mon osd nearfull ratio       = .85  

    mon osd down out interval    = 600  
    mon osd report timeout       = 300  

    debug ms                     = 20  
    debug mon                    = 20  
    debug paxos                  = 20  
    debug auth                   = 20  

[mon.node1]  
    host                         = node1  
    mon addr                     = 192.168.100.131:6789  
[mon.node2]  
    host                         = node2  
    mon addr                     = 192.168.100.132:6789  
[mon.node3]  
    host                         = node3  
    mon addr                     = 192.168.100.133:6789  

[mgr]  
    ;Yuanguo: the default value of {mgr data} is /var/lib/ceph/mgr/$cluster-$id,  
    ;         we overwrite it.  
    mgr data                     = /var/lib/ceph/mgr/$cluster-$name  

[osd]  
    ;Yuanguo: we wish to overwrite {osd data}, but it seems that 'ceph-disk' forces  
    ;     to use the default value, so keep the default now; maybe in later versions  
    ;     of ceph the limitation will be eliminated.  
    osd data                     = /var/lib/ceph/osd/$cluster-$id  
    osd recovery max active      = 3  
    osd max backfills            = 5  
    osd max scrubs               = 2  

    osd mkfs type = xfs  
    osd mkfs options xfs = -f -i size=1024  
    osd mount options xfs = rw,noatime,inode64,logbsize=256k,delaylog  

    filestore max sync interval  = 5  
    osd op threads               = 2  

    debug ms                     = 100  
    debug osd                    = 100

需要说明的是,在这个配置文件中,我们覆盖了一些默认值,比如:{mon data}和{mgr data},但是没有覆盖{osd data},因为ceph-disk貌似强制使用默认值。另外,pid, sock文件被放置在/var/run/ceph/中,以$cluster-$name命名;log文件放置在/var/log/ceph/中,也是以$cluster-$name命名。这些都可以覆盖。

四、生成keyring

在单机部署中点击打开链接,我们说过,有两种操作集群中user及其权限的方式,这里我们使用第一种:先生成keyring文件,然后在创建集群时带入使之生效。

ceph-authtool --create-keyring mycluster.keyring --gen-key -n mon. --cap mon 'allow *'  

ceph-authtool --create-keyring mycluster.client.admin.keyring --gen-key -n client.admin --set-uid=0 --cap mon 'allow *' --cap osd 'allow *' --cap mds 'allow *' --cap mgr 'allow *'  
ceph-authtool --create-keyring mycluster.client.bootstrap-osd.keyring --gen-key -n client.bootstrap-osd --cap mon 'allow profile bootstrap-osd'  
ceph-authtool --create-keyring mycluster.mgr.node1.keyring --gen-key -n mgr.node1 --cap mon 'allow profile mgr' --cap osd 'allow *' --cap mds 'allow *'  
ceph-authtool --create-keyring mycluster.mgr.node2.keyring --gen-key -n mgr.node2 --cap mon 'allow profile mgr' --cap osd 'allow *' --cap mds 'allow *'  
ceph-authtool --create-keyring mycluster.mgr.node3.keyring --gen-key -n mgr.node3 --cap mon 'allow profile mgr' --cap osd 'allow *' --cap mds 'allow *'  

ceph-authtool mycluster.keyring  --import-keyring mycluster.client.admin.keyring  
ceph-authtool mycluster.keyring  --import-keyring mycluster.client.bootstrap-osd.keyring  
ceph-authtool mycluster.keyring  --import-keyring mycluster.mgr.node1.keyring  
ceph-authtool mycluster.keyring  --import-keyring mycluster.mgr.node2.keyring  
ceph-authtool mycluster.keyring  --import-keyring mycluster.mgr.node3.keyring  
cat mycluster.keyring  
[mon.]  
        key = AQA525NZsY73ERAAIM1J6wSxglBNma3XAdEcVg==  
        caps mon = "allow *"  
[client.admin]  
        key = AQBJ25NZznIpEBAAlCdCy+OyUIvxtNq+1DSLqg==  
        auid = 0  
        caps mds = "allow *"  
        caps mgr = "allow *"  
        caps mon = "allow *"  
        caps osd = "allow *"  
[client.bootstrap-osd]  
        key = AQBW25NZtl/RBxAACGWafYy1gPWEmx9geCLi6w==  
        caps mon = "allow profile bootstrap-osd"  
[mgr.node1]  
        key = AQBb25NZ1mIeFhAA/PmRHFY6OgnAMXL1/8pSxw==  
        caps mds = "allow *"  
        caps mon = "allow profile mgr"  
        caps osd = "allow *"  
[mgr.node2]  
        key = AQBg25NZJ6jyHxAAf2GfBAG5tuNwf9YjkhhEWA==  
        caps mds = "allow *"  
        caps mon = "allow profile mgr"  
        caps osd = "allow *"  
[mgr.node3]  
        key = AQBl25NZ7h6CJRAAaFiea7hiTrQNVoZysA7n/g==  
        caps mds = "allow *"  
        caps mon = "allow profile mgr"  
        caps osd = "allow *"  

五、生成monmap

生成monmap并添加3个monitor

monmaptool --create --add node1 192.168.100.131:6789 --add node2 192.168.100.132:6789 --add node3 192.168.100.133:6789  --fsid 116d4de8-fd14-491f-811f-c1bdd8fac141 monmap  
[plain] view plain copy
monmaptool --print monmap  
monmaptool: monmap file monmap  
epoch 0  
fsid 116d4de8-fd14-491f-811f-c1bdd8fac141  
last_changed 2017-08-16 05:45:37.851899  
created 2017-08-16 05:45:37.851899  
0: 192.168.100.131:6789/0 mon.node1  
1: 192.168.100.132:6789/0 mon.node2  
2: 192.168.100.133:6789/0 mon.node3  

六、分发配置文件

keyring和monmap

把第2、3和4步中生成的配置文件,keyring,monmap分发到各个机器。由于mycluster.mgr.nodeX.keyring暂时使用不到,先不分发它们(见第8节)。

cp mycluster.client.admin.keyring mycluster.client.bootstrap-osd.keyring mycluster.keyring  mycluster.conf monmap /etc/ceph  
scp mycluster.client.admin.keyring mycluster.client.bootstrap-osd.keyring mycluster.keyring  mycluster.conf monmap node2:/etc/ceph  
scp mycluster.client.admin.keyring mycluster.client.bootstrap-osd.keyring mycluster.keyring  mycluster.conf monmap node3:/etc/ceph  

七、创建集群

1、创建{mon data}目录

mkdir /var/lib/ceph/mon/mycluster-mon.node1      
ssh node2 mkdir /var/lib/ceph/mon/mycluster-mon.node2  
ssh node3 mkdir /var/lib/ceph/mon/mycluster-mon.node3  

注意,在配置文件mycluster.conf中,我们把{mon data}设置为/var/lib/ceph/mon/$cluster-$name,而不是默认的/var/lib/ceph/mon/$cluster-$id;
$cluster-$name展开为mycluster-mon.node1(23);
默认的$cluster-$id展开为mycluster-node1(23);

2、初始化monitor

ceph-mon --cluster mycluster --mkfs -i node1 --monmap /etc/ceph/monmap --keyring /etc/ceph/mycluster.keyring  
ssh node2 ceph-mon --cluster mycluster --mkfs -i node2 --monmap /etc/ceph/monmap --keyring /etc/ceph/mycluster.keyring  
ssh node3 ceph-mon --cluster mycluster --mkfs -i node3 --monmap /etc/ceph/monmap --keyring /etc/ceph/mycluster.keyring  

注意,在配置文件mycluster.conf,我们把{mon data}设置为/var/lib/ceph/mon/$cluster-$name,展开为/var/lib/ceph/mon/mycluster-mon.node1(23)。ceph-mon会
根据–cluster mycluster找到配置文件mycluster.conf,并解析出{mon data},然后在那个目录下进行初始化。

3、touch done

touch /var/lib/ceph/mon/mycluster-mon.node1/done  
ssh node2 touch /var/lib/ceph/mon/mycluster-mon.node2/done  
ssh node3 touch /var/lib/ceph/mon/mycluster-mon.node3/done  

4、启动monitors

systemctl start ceph-mon@node1  
ssh node2 systemctl start ceph-mon@node2  
ssh node3 systemctl start ceph-mon@node3  

5、检查机器状态

ceph --cluster mycluster -s  
  cluster:  
    id:     116d4de8-fd14-491f-811f-c1bdd8fac141  
    health: HEALTH_OK  

  services:  
    mon: 3 daemons, quorum node1,node2,node3  
    mgr: no daemons active  
    osd: 0 osds: 0 up, 0 in  

  data:  
    pools:   0 pools, 0 pgs  
    objects: 0 objects, 0 bytes  
    usage:   0 kB used, 0 kB / 0 kB avail  
    pgs:  

八、添加osd

每台集群都有一个/dev/sdb,我们把它们作为osd。

1、删除它们的分区

2、prepare

ceph-disk prepare --cluster mycluster --cluster-uuid 116d4de8-fd14-491f-811f-c1bdd8fac141 --bluestore --block.db /dev/sdb  --block.wal /dev/sdb /dev/sdb  
ssh node2 ceph-disk prepare --cluster mycluster --cluster-uuid 116d4de8-fd14-491f-811f-c1bdd8fac141 --bluestore --block.db /dev/sdb  --block.wal /dev/sdb /dev/sdb  
ssh node3 ceph-disk prepare --cluster mycluster --cluster-uuid 116d4de8-fd14-491f-811f-c1bdd8fac141 /dev/sdb  
注意:prepare node3:/dev/sdb时,我们没有加选项:--bluestore --block.db /dev/sdb  --block.wal /dev/sdb;后面我们会看它和其他两个有什么不同。

3、activate

ceph-disk activate /dev/sdb1 --activate-key /etc/ceph/mycluster.client.bootstrap-osd.keyring  
ssh node2 ceph-disk activate /dev/sdb1 --activate-key /etc/ceph/mycluster.client.bootstrap-osd.keyring  
ssh node3 ceph-disk activate /dev/sdb1 --activate-key /etc/ceph/mycluster.client.bootstrap-osd.keyring  

注意:ceph-disk好像有两个问题:

  • 前面说过,它不使用自定义的{osd data},而强制使用默认值 /var/lib/ceph/osd/$cluster-$id

  • 好像不能为一个磁盘指定osd id,而只能依赖它自动生成。虽然ceph-disk prepare有一个选项–osd-id,但是ceph-disk activate并不使用它而是自己生成。当不匹配时,会出现 如下错误:

# ceph-disk activate /dev/sdb1 --activate-key /etc/ceph/mycluster.client.bootstrap-osd.keyring  
command_with_stdin: Error EEXIST: entity osd.0 exists but key does not match  

mount_activate: Failed to activate  
'['ceph', '--cluster', 'mycluster', '--name', 'client.bootstrap-osd', '--keyring', '/etc/ceph/mycluster.client.bootstrap-osd.keyring', '-i', '-', 'osd', 'new', u'ca8aac6a-b442-4b07-8fa6-62ac93b7cd29']' failed with status code 17  

从 ‘-i’, ‘-‘可以看出,它只能自动生成osd id;

4、检查osd

在ceph-disk prepare时,node1:/dev/sdb和node2:/dev/sdb一样,都有–bluestore –block.db /dev/sdb –block.wal选项;node3:/dev/sdb不同,没有加这些选项。我们看看有什么不同。

4.1 node1

mount | grep sdb  
/dev/sdb1 on /var/lib/ceph/osd/mycluster-0 type xfs (rw,noatime,seclabel,attr2,inode64,noquota)  

ls /var/lib/ceph/osd/mycluster-0/  
activate.monmap  block     block.db_uuid  block.wal       bluefs     fsid     kv_backend  mkfs_done  systemd  whoami  
active           block.db  block_uuid     block.wal_uuid  ceph_fsid  keyring  magic       ready      type  

ls -l /var/lib/ceph/osd/mycluster-0/block  
lrwxrwxrwx. 1 ceph ceph 58 Aug 16 05:52 /var/lib/ceph/osd/mycluster-0/block -> /dev/disk/by-partuuid/a12dd642-b64c-4fef-b9e6-0b45cff40fa9  

ls -l /dev/disk/by-partuuid/a12dd642-b64c-4fef-b9e6-0b45cff40fa9  
lrwxrwxrwx. 1 root root 10 Aug 16 05:55 /dev/disk/by-partuuid/a12dd642-b64c-4fef-b9e6-0b45cff40fa9 -> ../../sdb2  

blkid /dev/sdb2  
/dev/sdb2: PARTLABEL="ceph block" PARTUUID="a12dd642-b64c-4fef-b9e6-0b45cff40fa9"  

cat /var/lib/ceph/osd/mycluster-0/block_uuid  
a12dd642-b64c-4fef-b9e6-0b45cff40fa9  



ls -l /var/lib/ceph/osd/mycluster-0/block.db  
lrwxrwxrwx. 1 ceph ceph 58 Aug 16 05:52 /var/lib/ceph/osd/mycluster-0/block.db -> /dev/disk/by-partuuid/1c107775-45e6-4b79-8a2f-1592f5cb03f2  

ls -l /dev/disk/by-partuuid/1c107775-45e6-4b79-8a2f-1592f5cb03f2  
lrwxrwxrwx. 1 root root 10 Aug 16 05:55 /dev/disk/by-partuuid/1c107775-45e6-4b79-8a2f-1592f5cb03f2 -> ../../sdb3  

blkid /dev/sdb3  
/dev/sdb3: PARTLABEL="ceph block.db" PARTUUID="1c107775-45e6-4b79-8a2f-1592f5cb03f2"  

cat /var/lib/ceph/osd/mycluster-0/block.db_uuid  
1c107775-45e6-4b79-8a2f-1592f5cb03f2  



ls -l /var/lib/ceph/osd/mycluster-0/block.wal  
lrwxrwxrwx. 1 ceph ceph 58 Aug 16 05:52 /var/lib/ceph/osd/mycluster-0/block.wal -> /dev/disk/by-partuuid/76055101-b892-4da9-b80a-c1920f24183f  

ls -l /dev/disk/by-partuuid/76055101-b892-4da9-b80a-c1920f24183f  
lrwxrwxrwx. 1 root root 10 Aug 16 05:55 /dev/disk/by-partuuid/76055101-b892-4da9-b80a-c1920f24183f -> ../../sdb4  

blkid /dev/sdb4  
/dev/sdb4: PARTLABEL="ceph block.wal" PARTUUID="76055101-b892-4da9-b80a-c1920f24183f"  

cat /var/lib/ceph/osd/mycluster-0/block.wal_uuid  
76055101-b892-4da9-b80a-c1920f24183f  

可见,node1(node2)上,/dev/sdb被分为4个分区:

  • /dev/sdb1: metadata
  • /dev/sdb2:the main block device
  • /dev/sdb3: db
  • /dev/sdb4: wal

具体见:ceph-disk prepare –help

4.2 node3

mount | grep sdb  
/dev/sdb1 on /var/lib/ceph/osd/mycluster-2 type xfs (rw,noatime,seclabel,attr2,inode64,noquota)  

ls /var/lib/ceph/osd/mycluster-2  
activate.monmap  active  block  block_uuid  bluefs  ceph_fsid  fsid  keyring  kv_backend  magic  mkfs_done  ready  systemd  type  whoami  

ls -l /var/lib/ceph/osd/mycluster-2/block  
lrwxrwxrwx. 1 ceph ceph 58 Aug 16 05:54 /var/lib/ceph/osd/mycluster-2/block -> /dev/disk/by-partuuid/0a70b661-43f5-4562-83e0-cbe6bdbd31fb  

ls -l /dev/disk/by-partuuid/0a70b661-43f5-4562-83e0-cbe6bdbd31fb  
lrwxrwxrwx. 1 root root 10 Aug 16 05:56 /dev/disk/by-partuuid/0a70b661-43f5-4562-83e0-cbe6bdbd31fb -> ../../sdb2  

blkid /dev/sdb2  
/dev/sdb2: PARTLABEL="ceph block" PARTUUID="0a70b661-43f5-4562-83e0-cbe6bdbd31fb"  

cat /var/lib/ceph/osd/mycluster-2/block_uuid  
0a70b661-43f5-4562-83e0-cbe6bdbd31fb  

可见,在node3上,/dev/sdb被分为2个分区:

  • /dev/sdb1:metadata
  • /dev/sdb2:the main block device;db和wal也在这个分区上。

具体见:ceph-disk prepare –help

5、检查集群状态

ceph --cluster mycluster -s  
  cluster:  
    id:     116d4de8-fd14-491f-811f-c1bdd8fac141  
    health: HEALTH_WARN  
            no active mgr  

  services:  
    mon: 3 daemons, quorum node1,node2,node3  
    mgr: no daemons active  
    osd: 3 osds: 3 up, 3 in  

  data:  
    pools:   0 pools, 0 pgs  
    objects: 0 objects, 0 bytes  
    usage:   0 kB used, 0 kB / 0 kB avail  
    pgs:  

由于没有添加mgr,集群处于WARN状态。

九、添加mgr

1、创建{mgr data}目录

mkdir /var/lib/ceph/mgr/mycluster-mgr.node1  
ssh node2 mkdir /var/lib/ceph/mgr/mycluster-mgr.node2  
ssh node3 mkdir /var/lib/ceph/mgr/mycluster-mgr.node3  

注意,和{mon data}类似,在配置文件mycluster.conf中,我们把{mgr data}设置为/var/lib/ceph/mgr/$cluster-$name,而不是默认的/var/lib/ceph/mgr/$cluster-$id。

2、分发mgr的keyring

cp mycluster.mgr.node1.keyring /var/lib/ceph/mgr/mycluster-mgr.node1/keyring  
scp mycluster.mgr.node2.keyring node2:/var/lib/ceph/mgr/mycluster-mgr.node2/keyring  
scp mycluster.mgr.node3.keyring node3:/var/lib/ceph/mgr/mycluster-mgr.node3/keyring  

3、启动mgr

systemctl start ceph-mgr@node1  
ssh node2 systemctl start ceph-mgr@node2  
ssh node3 systemctl start ceph-mgr@node3  

4、检查集群状态

ceph --cluster mycluster -s  
  cluster:  
    id:     116d4de8-fd14-491f-811f-c1bdd8fac141  
    health: HEALTH_OK  

  services:  
    mon: 3 daemons, quorum node1,node2,node3  
    mgr: node1(active), standbys: node3, node2  
    osd: 3 osds: 3 up, 3 in  

  data:  
    pools:   0 pools, 0 pgs  
    objects: 0 objects, 0 bytes  
    usage:   5158 MB used, 113 GB / 118 GB avail  
    pgs:  

可见,添加mgr之后,集群处于OK状态。

GlusterFS和Ceph各方面的对比

存储世界最近发生了很大变化。十年前,Fibre Channel SAN文件管理器是企业存储的标准。而在目前的环境中,受到基础架构即服务云的影响,数据存储需要更加灵活。

GlusterFS和Ceph是两个灵活的存储系统,在云环境中表现非常出色。

在尝试了解GlusterFS与Ceph之间的相似之处和不同之处之前,让我们来讨论在云环境中对灵活存储的一些要求。

  • 纵向扩展和横向扩展。在云环境中,必须可以很容易地向服务器添加更多存储空间以及扩展可用存储池。Ceph和GlusterFS都可以通过轻松将新存储设备集成到现有存储产品中来满足这一要求。

  • 高可用性。GlusterFS和Ceph的复制是同时将数据写入不同的存储节点。这样做的结果是,访问时间增加,数据可用性也提高。在Ceph中,默认情况下将数据复制到三个不同的节点,这确保备份始终可用。

  • 商品化硬件。GlusterFS和Ceph是在Linux操作系统之上开发的。因此,对硬件唯一的要求是这些产品具有能够运行Linux的硬件。任何商品化硬件都可以运行Linux操作系统,结果是使用这些技术的公司可以大大减少在硬件上的投资——如果他们这样做的话。然而,实际上,许多公司正在投资专门用于运行GlusterFS或Ceph的硬件,因为更快的硬件可以更快地访问存储。

  • 去中心化。在云环境中,永远不应该有中心点故障。对于存储,这意味着不应该用一个中央位置存储元数据。GlusterFS和Ceph实现了元数据访问去中心化的解决方案,从而降低了存储访问的可用性和冗余性。

现在来谈谈GlusterFS与Ceph的差异。顾名思义,GlusterFS是来自Linux世界的文件系统,并且遵守所有Portable Operating System Interface标准。尽管你可以将GlusterFS轻松集成到面向Linux的环境中,但在Windows环境中集成GlusterFS很难。

Ceph是一种全新的存储方法,对应于Swift对象存储。在对象存储中,应用程序不会写入文件系统,而是使用存储中的直接API访问写入存储。因此,应用程序能够绕过操作系统的功能和限制。如果已经开发了一个应用程序来写入Ceph存储,那么使用哪个操作系统无关紧要。结果是,Ceph存储在Windows环境中像在Linux环境中一样容易集成。

基于API的存储访问并不是应用程序可以访问Ceph的唯一方式。为了最佳的集成,还有一个Ceph块设备,它可以在Linux环境中用作常规块设备,使你可以像访问常规Linux硬盘一样来使用Ceph。Ceph还有CephFS,它是针对Linux环境编写的Ceph文件系统。

最近,SUSE添加了一个iSCSI接口,使得运行iSCSI客户端的客户端能像任何其他iSCSI目标一样访问Ceph存储。

所有这些功能使得Ceph成为异构环境的更好选择,而不仅仅是使用Linux操作系统。

所以Ceph是一个更灵活的产品,更容易集成到非Linux环境中。对于许多公司来说,这足以让它们在Ceph而不是GlusterFS上构建存储产品。对于仅运行Linux的环境,此功能不够有说服力,所以来谈谈另一个非常重要的事情:速度。

为了比较GlusterFS与Ceph哪个更快已经进行了几项测试,但迄今为止没有确切的结论。GlusterFS存储算法更快,并且由于GlusterFS以砖组织存储的方式实现了更多的分层,这在某些场景下(特别是使用非优化Ceph的话)可能导致更快的速度。另一方面,Ceph提供了足够的定制功能来使其与GlusterFS一样快——结果是两者的性能都不够令人信服一个比另一个更强。

然而,现实表明,Ceph访问存储的不同方法使其成为更流行的技术。事实证明,更多的公司正在考虑Ceph技术而不是GlusterFS,而且GlusterFS仍然与Red Hat密切相关。例如,SUSE还没有GlusterFS的商业实施,而Ceph已经被开源社区广泛采用,市场上有各种不同的产品。可以说,Ceph确实已经胜过GlusterFS。

从ceph对象中提取RBD中的指定文件

1. 前言

之前有个想法,是不是有办法找到rbd中的文件与对象的关系,想了很久但是一直觉得文件系统比较复杂,在fs 层的东西对ceph来说是透明的,并且对象大小是4M,而文件很小,可能在fs层进行了合并,应该很难找到对应关系,最近看到小胖有提出这个问题,那么就再次尝试了,现在就是把这个实现方法记录下来

这个提取的作用个人觉得最大的好处就是一个rbd设备,在文件系统层被破坏以后,还能够从rbd提取出文件,我们知道很多情况下设备的文件系统一旦破坏,无法挂载,数据也就无法读取,而如果能从rbd中提取出文件,这就是保证了即使文件系统损坏的情况下,数据至少不丢失

本篇是基于xfs文件系统情况下的提取,其他文件系统有时间再看看,因为目前使用的比较多的就是xfs文件系统

本篇也回答了一个可能会经常被问起的问题,能告诉我虚拟机里面的文件在后台存储在哪里么,看完本篇就知道存储在哪里了

2. XFS文件系统介绍

[root@lab8106 ~]# mkfs.xfs -f /dev/rbd0p1 
warning: device is not properly aligned /dev/rbd0p1
meta-data=/dev/rbd0p1            isize=256    agcount=9, agsize=162816 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=0        finobt=0
data     =                       bsize=4096   blocks=1310475, imaxpct=25
         =                       sunit=1024   swidth=1024 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=0
log      =internal log           bsize=4096   blocks=2560, version=2
         =                       sectsz=512   sunit=8 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0

XFS文件系统采取是AG管理的,每个AG维护自己的inode和数据,所以XFS文件系统是一种很容易扩展的文件系统,本篇里面主要用到的命令是xfs_bmap这个命令

[root@lab8106 ~]# xfs_bmap -lvp /etc/fstab
/etc/fstab:
 EXT: FILE-OFFSET      BLOCK-RANGE        AG AG-OFFSET        TOTAL FLAGS
   0: [0..7]:          26645424..26645431  1 (431024..431031)     8 00000

一个文件最小就是8个block(512b),也就是4k,这个因为上面默认的xfs的格式化就是data bsize=4K,这个值可以自行调整的,本篇尽量用默认常规的参数来讲例子

查看man xfs_bmap这个命令可以看到:

Holes are marked by replacing the startblock..endblock with hole. All the file offsets and disk blocks are in units of 512-byte blocks, no matter what the filesystem’s block size is.

意思是这个查询到的里面的计数单位都是512-byte,不管上层设置的block大小是多少,我们知道文件系统底层的sector就是512-byte,所以这个查询到的结果就可以跟当前的文件系统的sector的偏移量联系起来,这里强调一下,这个偏移量的起始位子为当前文件系统所在分区的偏移量,如果是多分区的情况,在计算整个偏移量的时候就要考虑分区的偏移量了,这个会在后面用实例进行讲解的

rbd的对象是不清楚内部分区的偏移量,所以在rbd层进行提取的时候是需要得到的是分区当中的文件相对整个磁盘的一个sector的偏移量

3. rbd的对象结构

[root@lab8106 ~]# rados -p rbd ls|grep data
rbd_data.25a636b8b4567.00000000000009ff
rbd_data.25a636b8b4567.00000000000001dd
rbd_data.25a636b8b4567.0000000000000000
rbd_data.25a636b8b4567.000000000000009f
rbd_data.25a636b8b4567.0000000000000459
rbd_data.25a636b8b4567.000000000000027e
rbd_data.25a636b8b4567.00000000000004ff
rbd_data.25a636b8b4567.000000000000027c
rbd_data.25a636b8b4567.000000000000027d
rbd_data.25a636b8b4567.0000000000000001
rbd_data.25a636b8b4567.000000000000013e
rbd_data.25a636b8b4567.00000000000003ba
rbd_data.25a636b8b4567.000000000000031b
rbd_data.25a636b8b4567.00000000000004f8

rbd被xfs格式化以后会产生一些对象,这些对象是以16进制名称的方式存储在后台的,也就是rbd大小一定的情况下对象数目是一定的,也就是名称也是一定的

[root@lab8106 ~]# parted -s /dev/rbd0 unit s print
Model: Unknown (unknown)
Disk /dev/rbd0: 20971520s
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags: 

Number  Start      End        Size       File system  Name     Flags
 1      1953s      10485759s  10483807s  xfs          primari
 2      10485760s  20963327s  10477568s               primari

上面可以看到rbd0的sector个数为20971520s
20971520s*512byte=10737418240byte=10485760KB=10240MB
sector的大小一定,总rbd大小一定的情况下sector的数目也是一定的,本篇实例的rbd大小

[root@lab8106 ~]# rbd info zp
rbd image 'zp':
    size 10000 MB in 2500 objects
    order 22 (4096 kB objects)
    block_name_prefix: rbd_data.25a776b8b4567
    format: 2
    features: layering
    flags: 
    create_timestamp: Sat Jul 22 18:04:12 2017

4. sector和ceph object的对应关系的查询

这个就像个map一样,需要把这个关系给找到,一个sector的区间对应到object的map,这里我用python写个简单的方法来做查询,也可以自己用其他语言来实现

首先查询到rbd的对象数目

[root@lab8106 ~]# rbd info zp
rbd image 'zp':
    size 10000 MB in 2500 objects
    order 22 (4096 kB objects)
    block_name_prefix: rbd_data.25a776b8b4567
    format: 2
    features: layering
    flags: 
    create_timestamp: Sat Jul 22 18:04:12 2017

处理脚本如下:

vim getsecob.py

添加下面内容

#! /bin/python
# *-* conding=UTF-8 *-*

import commands

def main():
    getmap(2500)


def getmap(object):
    sector=int(object)*4096*1024/512
    print "object:"+str(object)
    print "sector:"+str(sector)
    incre=sector/object
    for item in range(int(object)):
        a=int(item*8192)
        b=int((item+1)*8192-1)
        print str([a,b])+"  --&gt;  "+"%016x" %item

if __name__ == '__main__':
    main()

其中getmap后面为对象数目

输出是这个形式的:

[root@lab8106 ~]# python getsecob.py
object:2500
sector:20480000
[0, 8191]  --&gt;  0000000000000000
[8192, 16383]  --&gt;  0000000000000001
[16384, 24575]  --&gt;  0000000000000002
[24576, 32767]  --&gt;  0000000000000003
[32768, 40959]  --&gt;  0000000000000004
[40960, 49151]  --&gt;  0000000000000005
···

对rbd0进行分区,分区后的结果如下

[root@lab8106 ~]# parted -s /dev/rbd0 unit s print
Model: Unknown (unknown)
Disk /dev/rbd0: 20480000s
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags: 

Number  Start      End        Size       File system  Name     Flags
 1      1953s      10240000s  10238048s               primari
 2      10248192s  20471807s  10223616s               primari

这个是个测试用的image,大小为10G分成两个5G的分区,现在我们在两个分区里面分别写入两个测试文件,然后经过计算后,从后台的对象中把文件读出

mount /dev/rbd0p1 /mnt1
mount /dev/rbd0p2 /mnt2
cp /etc/fstab /mnt1
cp /etc/hostname /mnt2

首先获取文件在分区上的sector的偏移量

[root@lab8106 ~]# xfs_bmap -lvp /mnt1/fstab 
/mnt1/fstab:
 EXT: FILE-OFFSET      BLOCK-RANGE      AG AG-OFFSET        TOTAL FLAGS
   0: [0..7]:          8224..8231        0 (8224..8231)         8 01111

可以得到是(8224..8231)共8个sector
从上面的分区1的start的sector可以知道起始位置是1953,那么相对于磁盘的偏移量就变成了

(8224+1953..8231+1953) = (10177..10184)

这里说下,这个地方拿到偏移量后,直接通过对rbd设备进行dd读取也可以把这个文件读取出来,这个顺带讲下,本文主要是从对象提取:

dd if=/dev/rbd0 of=a bs=512 count=8 skip=10177

bs取512是因为sector的单位就是512b
这样就把刚刚的fstab文件读取出来了,skip就是文件的sector相对磁盘的起始位置,count就是文件所占的block数目

继续我们的对象提取方式,上面的(10177..10184)这个我们根据上面那个脚本输出的对象列表来找到对象

[8192, 16383] —&gt; 0000000000000001
获取名称,这个因为我的是测试环境,就只有一个匹配,多个image的时候要过滤出对用的rbd的对象,用prifix过滤即可
[root@lab8106 ~]# rados -p rbd ls|grep 0000000000000001
rbd_data.25a776b8b4567.0000000000000001

下载对象

[root@lab8106 ~]# rados -p rbd get rbd_data.25a776b8b4567.0000000000000001 rbd_data.25a776b8b4567.0000000000000001

根据偏移量计算对象中的偏移量

(10177..10184)
[8192, 16383]  --&gt;  0000000000000001

得到

10177-8192=1985

dd if=rbd_data.25a776b8b4567.0000000000000001 of=a bs=512 count=8 skip=1985

得到的文件a的内容即为之前文件的内容

准备取第二个分区的文件

[root@lab8106 ~]# xfs_bmap -lvp /mnt2/hostname 
/mnt2/hostname:
 EXT: FILE-OFFSET      BLOCK-RANGE      AG AG-OFFSET        TOTAL FLAGS
   0: [0..7]:          8224..8231        0 (8224..8231)         8 01111

8224+10248192..8231+10248192=10256416..10256423

从磁盘方式

[root@lab8106 ~]# dd if=/dev/rbd0 of=a bs=512 count=8 skip=10256416

从对象方式
10256416..10256423 对应
[10256384, 10264575] —> 00000000000004e4
对象偏移量

10256416-10256384=32
rados -p rbd get 
[root@lab8106 ~]# rados -p rbd get rbd_data.25a776b8b4567.00000000000004e4 rbd_data.25a776b8b4567.00000000000004e4

获取文件

[root@lab8106 ~]# dd if=rbd_data.25a776b8b4567.00000000000004e4 of=a bs=512 count=8 skip=32

如果文件比较大的情况,可能出现就是文件是跨对象的,那么还是跟上面的提取方法一样,然后进行提取后的文件进行合并即可

5. 总结

在存储系统上面存储的文件必然会对应到底层磁盘的sector,而sector也是会一一对应到后台的对象的,这个在本文当中得到了验证,所以整个逻辑就是,在文件系统层找到文件对应的sector位置,然后再在底层把sector和对象关系找好,就能从找到文件在对象当中的具体的位置,也就能定位并且能提取了,本篇是基于xfs的,其他文件系统只要能定位文件的sector,就可以在底层找到文件,这个以后会补充其他文件系统进来。