使用ceph-deploy 2.0.0 部署ceph 12.2.5集群

时间:2022-03-16 02:21:00

1. 环境

1.1 硬件

4台 Linux虚拟机: server0, server1, server2, server3
每台有两块磁盘 : /dev/vdb, /dev/vdc
每台有两块网卡 :eth0, ens9

1.2 软件

linux版本: CentOS 7.2.1511
内核版本 : 3.10.0-327.el7.x86_64
ceph版本: 12.2.5
ceph-deploy版本: 2.0.0

2. 准备工作(所有server)

2.1 配置静态IP

每台server有两个interface, 分别配置在如下两个网段:

  • 192.168.122.0/24
  • 192.168.100.0/24

具体如下表:

Server Interface IPADDR
server0 eth0 192.168.122.160
server0 ens9 192.168.100.160
server1 eth0 192.168.122.161
server1 ens9 192.168.100.161
server2 eth0 192.168.122.162
server2 ens9 192.168.100.162
server3 eth0 192.168.122.163
server3 ens9 192.168.100.163

2.2 生成ssh key

# ssh-keygen

2.3 配置主机名解析

把如下内容追加到/etc/hosts:

192.168.100.160 server0
192.168.100.161 server1
192.168.100.162 server2
192.168.100.163 server3

2.4 配置ntp

# yum install -y ntp ntpdate ntp-doc
# vim /etc/ntp.conf (一般不需要修改)
# systemctl start ntpd.service
# systemctl enable ntpd.service

2.5 关闭防火墙

# systemctl stop firewalld
# systemctl disable firewalld

2.6 安装yum源epel

为了方便yum安装一些常用的软件包:

# yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm

3. 安装ceph软件包

3.1 添加yum源(所有server)

所有server上添加ceph.repo,内容如下:

# cat /etc/yum.repos.d/ceph.repo 
[Ceph]
name=Ceph packages for $basearch
baseurl=http://mirrors.163.com/ceph/rpm-luminous/el7/$basearch
enabled=1
priority=1
gpgcheck=1
gpgkey=https://download.ceph.com/keys/release.asc

[Ceph-noarch]
name=Ceph noarch packages
baseurl=http://mirrors.163.com/ceph/rpm-luminous/el7/noarch
enabled=1
priority=1
gpgcheck=1
gpgkey=https://download.ceph.com/keys/release.asc

[ceph-source]
name=Ceph source packages
baseurl=http://mirrors.163.com/ceph/rpm-luminous/el7/SRPMS
enabled=0
priority=1
gpgcheck=1
gpgkey=https://download.ceph.com/keys/release.asc

[Ceph]: ceph软件包的yum源,所有server都需要添加。
[Ceph-noarch]:ceph-deploy的yum源。admin server (见3.2节) 需要安装ceph-deploy,所以它需要这个yum源。admin server控制其他server的时候,也需要被控server添加这个yum源。最终,所有server都需要添加。
[ceph-source]: admin server控制其他server的时候,也需要被控server添加这个yum源。所以,所有server都需要添加。

3.2 选择admin server

选择server0作为admin server。官网上建议admin server使用一个单独的user来进行ceph-deploy操作,这里避免麻烦,还用root账户。
admin server需要免密登录所有server(包括自己),所以在admin server上配置免密登录(其他server不必配置):

# ssh-copy-id root@server0
# ssh-copy-id root@server1
# ssh-copy-id root@server2
# ssh-copy-id root@server3

测试一下:

# for i in {0..3} ; do ssh server$i hostname ; done 
server0
server1
server2
server3

3.3 安装ceph-deploy(在admin server上)

在3.1节已经添加了ceph-deploy的yum源,这里直接通过yum安装:

# yum -y install ceph-deploy

然后测试一下,发现报错:

# ceph-deploy --version
Traceback (most recent call last): File "/usr/bin/ceph-deploy", line 18, in <module> from ceph_deploy.cli import main File "/usr/lib/python2.7/site-packages/ceph_deploy/cli.py", line 1, in <module> import pkg_resources ImportError: No module named pkg_resources 

原因是缺python-setuptools,安装它即可:

# yum install python-setuptools

# ceph-deploy --version
2.0.0

3.4 安装ceph包(在admin server上执行)

这一步的目标是:admin server通过远程控制在所有server上安装ceph包。它需要在所有server上添加yum源:[Ceph], [Ceph-noarch]和[ceph-source],见3.1节。

另外注意:在所有server上安装deltarpm (yum install -y deltarpm), 否则会报如下错误:

[server0][DEBUG ] Delta RPMs disabled because /usr/bin/applydeltarpm not installed.
[server0][WARNIN] No data was received after 300 seconds, disconnecting...
[server0][INFO ] Running command: ceph --version
[server0][ERROR ] Traceback (most recent call last):
[server0][ERROR ]   File "/usr/lib/python2.7/site-packages/ceph_deploy......

下面就是安装了:

# ceph-deploy install --release=luminous server0 server1 server2 server3

成功之后,每台server都安装了ceph包,在任意sever上检查:

# ceph -v
ceph version 12.2.5 (cad919881333ac92274171586c827e01f554a70a) luminous (stable)

# ceph -v
ceph version 12.2.5 (cad919881333ac92274171586c827e01f554a70a) luminous (stable)
[root@server1 ~]# rpm -qa | grep ceph
ceph-common-12.2.5-0.el7.x86_64
ceph-mds-12.2.5-0.el7.x86_64
ceph-12.2.5-0.el7.x86_64
ceph-release-1-1.el7.noarch
libcephfs2-12.2.5-0.el7.x86_64
python-cephfs-12.2.5-0.el7.x86_64
ceph-base-12.2.5-0.el7.x86_64
ceph-mon-12.2.5-0.el7.x86_64
ceph-osd-12.2.5-0.el7.x86_64
ceph-mgr-12.2.5-0.el7.x86_64
ceph-radosgw-12.2.5-0.el7.x86_64
ceph-selinux-12.2.5-0.el7.x86_64

4. 部署ceph集群(在admin server上执行)

为了演示,我们

  1. 创建一个集群:1 mon + 1 mgr。这个是initial monitor。
  2. 添加 osd
  3. 添加 2 mon + 2 mgr
  4. 创建一个mds

实际上,我们完全可以在第1步中直接创建 3 mon + 3 mgr的集群 (3个都是initial monitor),然后添加osd就行了。这里分作1和3两步,是为了演示添加mon和mgr。

另外,ceph-deploy在部署集群的过程中,会产生一些文件(log,keyring,ceph.conf等),所以,我们在一个新目录下执行:

# mkdir test-ceph-deploy
# cd test-ceph-deploy/

若部署出现错误,需要重头开始:

ceph-deploy purge server0 server1 server2 server3
ceph-deploy purgedata server0 server1 server2 server3
ceph-deploy forgetkeys
rm ceph.*

4.1 创建集群:1 mon + 1 mgr

A. 以server2为initial monitor创建集群

# ceph-deploy new server2 

这里指定server2作为initial monitor。这一步完成之后,在当前目录下会产生如下文件:

ceph.conf               
ceph.mon.keyring        
ceph-deploy-ceph.log

ceph.conf是ceph的配置文件。它将会被分发到所有server的/etc/ceph/目录下。在后续的ceph运维中,若需要做某些配置,可以在所有server上修改/etc/ceph/ceph.conf。

# cat ceph.conf 
[global]
fsid = 744f59b7-c403-48e6-a1c6-2c74901a4d0b
mon_initial_members = server2
mon_host = 192.168.100.162
auth_cluster_required = cephx
auth_service_required = cephx
auth_client_required = cephx

ceph.mon.keyring是monitor的keyring,它定义了monitor的key,以及monitor有什么权限:

# cat ceph.mon.keyring 
[mon.]
key = AQDf7O9aAAAAABAAX4qmBiNsPhvK43wnpNCtLA==
caps mon = allow *

B. 配置ceph网络

ceph集群使用两个网络:public network和cluster network。前者用于服务client;后者用于集群内部通信,例如osd之间迁移数据。另外,两个网络上都有heartbeat。

注意:若只有一个网络,也可以部署ceph。这个网络同时担任public network和cluster network。这种情况下,跳过本小节

我们有两个网络(见第2.1节),所以在ceph.conf中,增加如下两行:

# vim ceph.conf
......
public network  = 192.168.100.0/24
cluster network = 192.168.122.0/24

注意以下两点:

  • 在2.3节,我们配置主机名解析的时候,把主机名解析为public network的地址。这是因为,ceph-deploy是作为client (见下文D小节:client.admin, client.bootstrap-mds,client.bootstrap-mgr,client.bootstrap-osd,client.bootstrap-rgw)来操作集群的,ceph集群通过public network服务于client。

  • monitor是运行于public network上的。这也很容易理解,ceph的client都需要访问monitor,若monitor运行于cluster network上,client无法访问。

C. 部署initial monitor

# ceph-deploy mon create server2 

这时候,server2上,monitor已经运行起来了。可以到server2上检查。

[root@server2 ~]# ps -ef | grep ceph
ceph       18240       1  1 14:24 ?        00:00:00 /usr/bin/ceph-mon -f --cluster ceph --id server2 --setuser ceph --setgroup ceph

如前文B小节所述,monitor运行于public network之上:

[root@server2 ~]# netstat -anpl | grep 6789 | grep LISTEN
tcp        0      0 192.168.100.162:6789    0.0.0.0:*               LISTEN      18240/ceph-mon      

D. 创建ceph keyring

经过前一步,server2上的monitor已经运行起来了。但这时候ceph -s失败,因为ceph -s是admin的命令,我们还没有admin的权限信息呢。

# ceph -c ceph.conf -s 
2018-05-07 14:25:46.127163 7f76e1834700 -1 auth: unable to find a keyring on /etc/ceph/ceph.client.admin.keyring,/etc/ceph/ceph.keyring,/etc/ceph/keyring,/etc/ceph/keyring.bin,: (2) No such file or directory
2018-05-07 14:25:46.127199 7f76e1834700 -1 monclient: ERROR: missing keyring, cannot use cephx for authentication
2018-05-07 14:25:46.127201 7f76e1834700  0 librados: client.admin initialization error (2) No such file or directory

下面使用gatherkeys来创建各个角色(包括admin)的权限信息。gatherkeys 依次对角色 admin, bootstrap-mds, bootstrap-mgr, bootstrap-osd, bootstrap-rgw作如下操作(问题:为什么没有bootstrap-rbd?):

  1. 使用 ceph auth get 来获取角色的key和权限;
  2. 若不存在,则使用auth get-or-create {角色} {权限}来创建角色的key和权限;
  3. 把角色的key保存到 {角色}.keyring文件;
# ceph-deploy gatherkeys server2
[ceph_deploy.conf][DEBUG ] found configuration file at: /root/.cephdeploy.conf
[ceph_deploy.cli][INFO ] Invoked (2.0.0): /usr/bin/ceph-deploy gatherkeys server2
......
[server2][INFO ] Running command: /usr/bin/ceph --connect-timeout=25 --cluster=ceph --name mon. --keyring=/var/lib/ceph/mon/ceph-server2/keyring auth get client.admin
[server2][INFO ] Running command: /usr/bin/ceph --connect-timeout=25 --cluster=ceph --name mon. --keyring=/var/lib/ceph/mon/ceph-server2/keyring auth get-or-create client.admin osd allow * mds allow * mon allow * mgr allow *
[server2][INFO ] Running command: /usr/bin/ceph --connect-timeout=25 --cluster=ceph --name mon. --keyring=/var/lib/ceph/mon/ceph-server2/keyring auth get client.bootstrap-mds
[server2][INFO ] Running command: /usr/bin/ceph --connect-timeout=25 --cluster=ceph --name mon. --keyring=/var/lib/ceph/mon/ceph-server2/keyring auth get-or-create client.bootstrap-mds mon allow profile bootstrap-mds
[server2][INFO ] Running command: /usr/bin/ceph --connect-timeout=25 --cluster=ceph --name mon. --keyring=/var/lib/ceph/mon/ceph-server2/keyring auth get client.bootstrap-mgr
[server2][INFO ] Running command: /usr/bin/ceph --connect-timeout=25 --cluster=ceph --name mon. --keyring=/var/lib/ceph/mon/ceph-server2/keyring auth get-or-create client.bootstrap-mgr mon allow profile bootstrap-mgr
[server2][INFO ] Running command: /usr/bin/ceph --connect-timeout=25 --cluster=ceph --name mon. --keyring=/var/lib/ceph/mon/ceph-server2/keyring auth get client.bootstrap-osd
[server2][INFO ] Running command: /usr/bin/ceph --connect-timeout=25 --cluster=ceph --name mon. --keyring=/var/lib/ceph/mon/ceph-server2/keyring auth get-or-create client.bootstrap-osd mon allow profile bootstrap-osd
[server2][INFO ] Running command: /usr/bin/ceph --connect-timeout=25 --cluster=ceph --name mon. --keyring=/var/lib/ceph/mon/ceph-server2/keyring auth get client.bootstrap-rgw
[server2][INFO ] Running command: /usr/bin/ceph --connect-timeout=25 --cluster=ceph --name mon. --keyring=/var/lib/ceph/mon/ceph-server2/keyring auth get-or-create client.bootstrap-rgw mon allow profile bootstrap-rgw
[ceph_deploy.gatherkeys][INFO ] Storing ceph.client.admin.keyring
[ceph_deploy.gatherkeys][INFO ] Storing ceph.bootstrap-mds.keyring
[ceph_deploy.gatherkeys][INFO ] Storing ceph.bootstrap-mgr.keyring
[ceph_deploy.gatherkeys][INFO ] keyring 'ceph.mon.keyring' already exists
[ceph_deploy.gatherkeys][INFO ] Storing ceph.bootstrap-osd.keyring
[ceph_deploy.gatherkeys][INFO ] Storing ceph.bootstrap-rgw.keyring
[ceph_deploy.gatherkeys][INFO ] Destroy temp directory /tmp/tmpCHsfbU

创建之后,各个角色的key和权限就存在于集群中了。某个角色(例如admin)要对集群的某个组件(例如osd)进行读写操作时,要提供自己的key;集群根据它的key找到它的权限,然后鉴定它是否能够对这个组件进行读写操作。

上面gatherkeys在生成各个角色的key+权限的同时,把角色的key保存成keyring文件,供各个角色读写集群组件时使用:

# ll
total 120
-rw-------. 1 root root    71 May  7 14:28 ceph.bootstrap-mds.keyring
-rw-------. 1 root root    71 May  7 14:28 ceph.bootstrap-mgr.keyring
-rw-------. 1 root root    71 May  7 14:28 ceph.bootstrap-osd.keyring
-rw-------. 1 root root    71 May  7 14:28 ceph.bootstrap-rgw.keyring
-rw-------. 1 root root    63 May  7 14:28 ceph.client.admin.keyring

# cat ceph.client.admin.keyring 
[client.admin]
    key = AQD88e9aAwlyBRAAVwhjmH8GGVmG+JFYs/3MAA==

# cat ceph.bootstrap-osd.keyring 
[client.bootstrap-osd]
    key = AQD+8e9aFC9+LxAApTnB/DImy5ZjoRbQhYoiVA==

现在就可以执行ceph的admin命令了(admin的key保存在ceph.client.admin.keyring文件里,通过–keyring提供):

# ceph --keyring ceph.client.admin.keyring -c ceph.conf -s
  cluster:
    id:     744f59b7-c403-48e6-a1c6-2c74901a4d0b
    health: HEALTH_OK

  services:
    mon: 1 daemons, quorum server2
    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:     


# ceph --keyring ceph.client.admin.keyring -c ceph.conf auth get client.admin
exported keyring for client.admin
[client.admin]
    key = AQD88e9aAwlyBRAAVwhjmH8GGVmG+JFYs/3MAA==
    caps mds = "allow *"
    caps mgr = "allow *"
    caps mon = "allow *"
    caps osd = "allow *"

E. 分发keyring

如前所示,我们执行admin的命令,要提供admin的key(–keyring ceph.client.admin.keyring)以及配置文件(-c ceph.conf)。在后续的运维中,我们经常需要在某个server上执行admin命令。每次都提供这些参数比较麻烦。实际上,ceph会默认地从/etc/ceph/中找keyring和ceph.conf。因此,我们可以把ceph.client.admin.keyring和ceph.conf放到每个server的/etc/ceph/。ceph-deploy可以帮我做这些:

# ceph-deploy admin server0 server1 server2 server3 

检查每个server,发现/etc/ceph/下都多了ceph.client.admin.keyring和ceph.conf这两个文件。现在就不用提供那些参数了:

# ceph -s
# ceph auth get client.admin 

F. 创建mgr

从ceph 12(luminous)开始,需要为每个monitor创建一个mgr(其功能待研究,之前的版本都没有这个组件)。

# ceph-deploy mgr create server2

# ceph -s
  cluster:
    id:     744f59b7-c403-48e6-a1c6-2c74901a4d0b
    health: HEALTH_OK

  services:
    mon: 1 daemons, quorum server2
    mgr: server2(active)    ----------------------新加的mgr
    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:     

4.2 添加OSD

ceph-deploy osd create通过调用ceph-volume来创建OSD。使用bluestore时(默认),需要指定3个device:

device 如何指定 说明
block –data 主要存储,必选。可以是磁盘,分区或者lv
block.db –block-db 可选。若不指定,则对应内容存储于block。可以是分区或者lv
block.wal –block-wal 可选。若不指定,则对应内容存储于block。可以是分区或者lv

注意:
1. 不可以使用磁盘作为block.db或者block.wal,否则会报错:blkid could not detect a PARTUUID for device;
2. 若使用磁盘或者分区作block,则ceph-volume会在其上创建lv来使用。若使用分区作block.db或block.wal,则直接使用分区而不创建lv。

在使用磁盘之前,我们先把磁盘清空。若已经创建了volume group,需要先删掉(vgremove),然后通过ceph-deploy的disk zap进行清空。ceph-deploy disk zap会发生如下错误:

# ceph-deploy disk zap server0 /dev/vdb
[ceph_deploy.conf][DEBUG ] found configuration file at: /root/.cephdeploy.conf
[ceph_deploy.cli][INFO ] Invoked (2.0.0): /usr/bin/ceph-deploy disk zap 
[ceph_deploy.osd][DEBUG ] zapping /dev/vdb on server0
......
[server0][DEBUG ] find the location of an executable
[ceph_deploy][ERROR ] Traceback (most recent call last):
[ceph_deploy][ERROR ]   File "/usr/lib/python2.7/site-packages/ceph_deploy/util/decorators.py", line 69, in newfunc
[ceph_deploy][ERROR ]     return f(*a, **kw)
[ceph_deploy][ERROR ]   File "/usr/lib/python2.7/site-packages/ceph_deploy/cli.py", line 164, in _main
[ceph_deploy][ERROR ]     return args.func(args)
[ceph_deploy][ERROR ]   File "/usr/lib/python2.7/site-packages/ceph_deploy/osd.py", line 438, in disk
[ceph_deploy][ERROR ]     disk_zap(args)
......

修改ceph-deploy的 osd.py的disk_zap函数,即可成功:

# vim /usr/lib/python2.7/site-packages/ceph_deploy/osd.py
ceph_volume_executable = system.executable_path(distro.conn, 'ceph-volume')
#if args.debug:
if False:

A. 添加osd.0(磁盘作block,无block.db,无block.wal)

# ceph-deploy osd create server0 --data /dev/vdb

# ceph -s
  cluster:
    id:     744f59b7-c403-48e6-a1c6-2c74901a4d0b
    health: HEALTH_OK

  services:
    mon: 1 daemons, quorum server2
    mgr: server2(active)
    osd: 1 osds: 1 up, 1 in

# mount | grep ceph
tmpfs on /var/lib/ceph/osd/ceph-0 type tmpfs (rw,relatime,seclabel)

# ll /var/lib/ceph/osd/ceph-0  
total 48
-rw-r--r--. 1 ceph ceph 189 May  7 15:19 activate.monmap
lrwxrwxrwx. 1 ceph ceph  93 May  7 15:19 block -> /dev/ceph-012c2043-33ef-4219-af69-34c7ed389d41/osd-block-5beb22d5-891c-4d6e-affe-87eb4bc083b2
-rw-r--r--. 1 ceph ceph   2 May  7 15:19 bluefs
-rw-r--r--. 1 ceph ceph  37 May  7 15:19 ceph_fsid
-rw-r--r--. 1 ceph ceph  37 May  7 15:19 fsid
-rw-------. 1 ceph ceph  55 May  7 15:19 keyring
-rw-r--r--. 1 ceph ceph   8 May  7 15:19 kv_backend
-rw-r--r--. 1 ceph ceph  21 May  7 15:19 magic
-rw-r--r--. 1 ceph ceph   4 May  7 15:19 mkfs_done
-rw-r--r--. 1 ceph ceph  41 May  7 15:19 osd_key
-rw-r--r--. 1 ceph ceph   6 May  7 15:19 ready
-rw-r--r--. 1 ceph ceph  10 May  7 15:19 type
-rw-r--r--. 1 ceph ceph   2 May  7 15:19 whoami

可见:
1. 使用磁盘vdb创建lv供block使用;
2. osd是mount到tmpfs的(bluefs, ceph_fsid, fsid, keyring等等都存于集群中);

B. 添加osd.1(分区作block,分区作block.db,无block.wal)

把server0的vdc分成两个分区(分区过程省略,注意,要是有gpt分区格式):vdc1作block.db,vdc2作block。

# ceph-deploy osd create server0 --data /dev/vdc2 --block-db /dev/vdc1

# ll  /var/lib/ceph/osd/ceph-1 
total 52
-rw-r--r--. 1 ceph ceph 189 May  7 15:25 activate.monmap
lrwxrwxrwx. 1 ceph ceph  93 May  7 15:25 block -> /dev/ceph-ae408599-db16-4028-914d-4006594c5cd8/osd-block-1edeced4-e5e9-45ac-a5d3-ddd238d720d4
lrwxrwxrwx. 1 root root   9 May  7 15:25 block.db -> /dev/vdc1
-rw-r--r--. 1 ceph ceph   2 May  7 15:25 bluefs
-rw-r--r--. 1 ceph ceph  37 May  7 15:25 ceph_fsid
-rw-r--r--. 1 ceph ceph  37 May  7 15:25 fsid
-rw-------. 1 ceph ceph  55 May  7 15:25 keyring
-rw-r--r--. 1 ceph ceph   8 May  7 15:25 kv_backend
-rw-r--r--. 1 ceph ceph  21 May  7 15:25 magic
-rw-r--r--. 1 ceph ceph   4 May  7 15:25 mkfs_done
-rw-r--r--. 1 ceph ceph  41 May  7 15:25 osd_key
-rw-r--r--. 1 ceph ceph  10 May  7 15:25 path_block.db
-rw-r--r--. 1 ceph ceph   6 May  7 15:25 ready
-rw-r--r--. 1 ceph ceph  10 May  7 15:25 type
-rw-r--r--. 1 ceph ceph   2 May  7 15:25 whoami

可见,使用分区vdc2创建lv供block使用; block.db直接使用vdc1;

C. 添加osd.2(分区作block,分区作block.db,分区作block.wal)

把serve1的vdb分成3个分区:vdb3作block,vdb2作block.db,vdb1作block-wal:

# ceph-deploy osd create server1 --data /dev/vdb3 --block-db /dev/vdb2 --block-wal /dev/vdb1

到server1上:

# ll /var/lib/ceph/osd/ceph-2 
total 56
-rw-r--r--. 1 ceph ceph 189 May 7 15:34 activate.monmap lrwxrwxrwx. 1 ceph ceph  93 May  7 15:34 block -> /dev/ceph-c2f66dc2-076b-46cd-a1cd-e3ef9511a38a/osd-block-7bf0f953-2feb-4064-8d19-873495cae7f5
lrwxrwxrwx. 1 root root   9 May  7 15:34 block.db -> /dev/vdb2
lrwxrwxrwx. 1 root root   9 May  7 15:34 block.wal -> /dev/vdb1
-rw-r--r--. 1 ceph ceph 2 May 7 15:34 bluefs -rw-r--r--. 1 ceph ceph 37 May 7 15:34 ceph_fsid -rw-r--r--. 1 ceph ceph 37 May 7 15:34 fsid -rw-------. 1 ceph ceph 55 May 7 15:34 keyring -rw-r--r--. 1 ceph ceph 8 May 7 15:34 kv_backend -rw-r--r--. 1 ceph ceph 21 May 7 15:34 magic -rw-r--r--. 1 ceph ceph 4 May 7 15:34 mkfs_done -rw-r--r--. 1 ceph ceph 41 May 7 15:34 osd_key -rw-r--r--. 1 ceph ceph 10 May 7 15:34 path_block.db -rw-r--r--. 1 ceph ceph 10 May 7 15:34 path_block.wal -rw-r--r--. 1 ceph ceph 6 May 7 15:34 ready -rw-r--r--. 1 ceph ceph 10 May 7 15:34 type -rw-r--r--. 1 ceph ceph 2 May 7 15:34 whoami 

D. 添加osd.3(lv作block,lv作block.db,lv作block.wal)

首先,在server1上,使用vdc创建出3个lv

# pvcreate /dev/vdc
  Physical volume "/dev/vdc" successfully created

# vgcreate myvg /dev/vdc 
  Volume group "myvg" successfully created

# lvcreate -n block-lv -L 30G myvg 
  Logical volume "block-lv" created.

# lvcreate -n db-lv -L 10G myvg
  Logical volume "db-lv" created.

# lvcreate -n wal-lv -L 10G myvg
  Logical volume "wal-lv" created.


# ls /dev/myvg/
block-lv  db-lv  wal-lv

然后,在admin server上创建osd.3:

# ceph-deploy osd create server1 --data myvg/block-lv --block-db myvg/db-lv  --block-wal myvg/wal-lv

到server1上:

# ll /var/lib/ceph/osd/ceph-3  
total 56
-rw-r--r--. 1 ceph ceph 189 May 7 15:47 activate.monmap lrwxrwxrwx. 1 ceph ceph  18 May  7 15:47 block -> /dev/myvg/block-lv
lrwxrwxrwx. 1 root root  15 May  7 15:47 block.db -> /dev/myvg/db-lv
lrwxrwxrwx. 1 root root  16 May  7 15:47 block.wal -> /dev/myvg/wal-lv
-rw-r--r--. 1 ceph ceph 2 May 7 15:47 bluefs -rw-r--r--. 1 ceph ceph 37 May 7 15:47 ceph_fsid -rw-r--r--. 1 ceph ceph 37 May 7 15:47 fsid -rw-------. 1 ceph ceph 55 May 7 15:47 keyring -rw-r--r--. 1 ceph ceph 8 May 7 15:47 kv_backend -rw-r--r--. 1 ceph ceph 21 May 7 15:47 magic -rw-r--r--. 1 ceph ceph 4 May 7 15:47 mkfs_done -rw-r--r--. 1 ceph ceph 41 May 7 15:47 osd_key -rw-r--r--. 1 ceph ceph 16 May 7 15:47 path_block.db -rw-r--r--. 1 ceph ceph 17 May 7 15:47 path_block.wal -rw-r--r--. 1 ceph ceph 6 May 7 15:47 ready -rw-r--r--. 1 ceph ceph 10 May 7 15:47 type -rw-r--r--. 1 ceph ceph 2 May 7 15:47 whoami 

注意: lv应写作 myvg/xx-lv,而不是/dev/myvg/xx-lv。否则会报错。

E. 添加其他osd

为了方便,block, block.db和block.wal都使用分区。

# ceph-deploy osd create server3 --data /dev/vdb3  --block-db /dev/vdb2  --block-wal /dev/vdb1
# ceph-deploy osd create server3 --data /dev/vdc3  --block-db /dev/vdc2  --block-wal /dev/vdc1
# ceph-deploy osd create server2 --data /dev/vdb3  --block-db /dev/vdb2  --block-wal /dev/vdb1
# ceph-deploy osd create server2 --data /dev/vdc3  --block-db /dev/vdc2  --block-wal /dev/vdc1



# ceph -s
  cluster:
    id:     744f59b7-c403-48e6-a1c6-2c74901a4d0b
    health: HEALTH_OK

  services:
    mon: 1 daemons, quorum server2
    mgr: server2(active)
    osd: 8 osds: 8 up, 8 in    <-------- 8  osd

  data:
    pools:   0 pools, 0 pgs
    objects: 0 objects, 0 bytes
    usage:   8226 MB used, 339 GB / 347 GB avail
    pgs:     

4.3 添加 2 mon + 2 mgr

# ceph-deploy mon add server0
# ceph-deploy mgr create server0
# ceph-deploy mon add server1
# ceph-deploy mgr create server1

注意:貌似新版的ceph-deploy一次只能增加一个mon.

现在集群就有3个mon和3个mgr了:

# ceph -s
  cluster:
    id:     744f59b7-c403-48e6-a1c6-2c74901a4d0b
    health: HEALTH_OK

  services:
    mon: 3 daemons, quorum server0,server1,server2
    mgr: server2(active), standbys: server0, server1
    osd: 8 osds: 8 up, 8 in

  data:
    pools:   0 pools, 0 pgs
    objects: 0 objects, 0 bytes
    usage:   8230 MB used, 339 GB / 347 GB avail
    pgs:     

4.4 创建一个mds

为了支持cephfs,我们在server2上创建一个mds:

# ceph-deploy mds create server2

成功之后,到server2上可以看见mds进程:

[root@server2 ~]# ps -ef | grep ceph-mds
ceph       19995       1  0 16:35 ?        00:00:00 /usr/bin/ceph-mds -f --cluster ceph --id server2 --setuser ceph --setgroup ceph

但这个时候,mds并没有active,如下,我们通过ceph -s看不到mds服务。直到创建ceph filesystem的时候,mds才进入active状态(见6.1节)。

# ceph -s
  cluster:
    id:     744f59b7-c403-48e6-a1c6-2c74901a4d0b
    health: HEALTH_WARN
            too few PGs per OSD (12 < min 30)

  services:    -----------------> 看不到mds
    mon: 3 daemons, quorum server0,server1,server2
    mgr: server2(active), standbys: server0, server1
    osd: 8 osds: 8 up, 8 in
    rgw: 2 daemons active

  data:
    pools:   4 pools, 32 pgs
    objects: 187 objects, 1113 bytes
    usage:   8239 MB used, 339 GB / 347 GB avail
    pgs:     32 active+clean

至此,ceph集群就完全部署起来了。下面,我们为ceph集群增加一些client。

5. 增加rgw (在admin server上操作)

我们可以使用ceph集群之外的server来部署rgw。部署之前,需要保证默认端口(7480)没有被防火墙禁止。并且需要安装ceph-radosgw包机器依赖:

ceph-deploy install --rgw <client-node> [<client-node> ...]

为了方便起见,我们复用集群内的server1和server3来部署rgw。由于ceph-radosgw已经安装(见3.4节),并且防火墙已经被停掉(见2.5节),所以,直接部署即可:

# ceph-deploy rgw create server1 server3 

成功之后,在server1和server3上rgw进程就运行起来了:

[root@server1 ~]# ps -ef | grep ceph
...... ceph 15884 1 2 16:23 ? 00:00:00 /usr/bin/radosgw -f --cluster ceph --name client.rgw.server1 --setuser ceph --setgroup ceph [root@server3 ~]# ps -ef | grep ceph ......
ceph       14107       1  2 16:23 ?        00:00:00 /usr/bin/radosgw -f --cluster ceph --name client.rgw.server3 --setuser ceph --setgroup ceph

并且我们可以通过http来访问:

# curl server1: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>

6. 增加cephfs

ceph filesystem需要mds(我们在4.4节已经部署)。并且,有两种方式来挂载:ceph fuse和ceph kernel driver。在这一节,我们:

  1. 创建一个ceph filesystem
  2. 通过ceph fuse挂载
  3. 通过ceph kernel driver挂载

6.1 创建ceph filesystem(在集群内任意server上)

A. 创建所需的pool

# ceph osd pool create cephfs_data 80
pool 'cephfs_data' created
# ceph osd pool create cephfs_metadata 40
pool 'cephfs_metadata' created

B. 创建filesystem

# ceph fs new mycephfs cephfs_metadata cephfs_data
new fs with metadata pool 6 and data pool 5

如第4.4节所示,在没有创建filesystem之前,mds没有active。现在mds就进入active状态了:

# ceph -s
  cluster:
    id:     744f59b7-c403-48e6-a1c6-2c74901a4d0b
    health: HEALTH_OK

  services:
    mon: 3 daemons, quorum server0,server1,server2
    mgr: server2(active), standbys: server0, server1
    mds: mycephfs-1/1/1 up  {0=server2=up:active}  --------->mds已经active
    osd: 8 osds: 8 up, 8 in
    rgw: 2 daemons active

  data:
    pools:   6 pools, 152 pgs
    objects: 208 objects, 3359 bytes
    usage:   8248 MB used, 339 GB / 347 GB avail
    pgs:     152 active+clean

6.2 通过ceph fuse挂载(在server2上)

和rgw一样,原则上我们在ceph集群之外的某台server上挂载ceph filesystem。但为了方便起见,我们还是在server2上挂载。

首先,要在server2上安装ceph-fuse(若使用ceph集群外的server,也只需这一个包):

# yum install -y ceph-fuse.x86_64 

然后,创建一个挂载点,就可以挂载了。注意,ceph-fuse挂载使用的是admin的权限,所以,通过-k选项传入admin的key。

# mkdir /mnt/cephfs

# ceph-fuse -k /etc/ceph/ceph.client.admin.keyring -m server0:6789 /mnt/cephfs
2018-05-07 17:27:07.205147 7f501e11f040 -1 init, newargv = 0x7f502968cb80 newargc=9
ceph-fuse[20080]: starting ceph client
ceph-fuse[20080]: starting fuse

这时候,一个全新的ceph filesystem就可以使用了。注意:这时cephfs_data是空的,但cephfs_metadata不空:

# ceph df
GLOBAL:
    SIZE     AVAIL     RAW USED     %RAW USED 
    347G      339G        8248M          2.32 
POOLS:
    NAME                    ID     USED     %USED     MAX AVAIL     OBJECTS 
    ......
    cephfs_data             5         0         0          106G           0 
    cephfs_metadata         6      2624         0          106G          21 

往里拷贝一些东西,就会发现cephfs_data也不空了:

# cp /boot/vmlinuz-3.10.0-327.el7.x86_64 /mnt/cephfs/

# ls /mnt/cephfs/
vmlinuz-3.10.0-327.el7.x86_64

# ceph df
GLOBAL:
    SIZE     AVAIL     RAW USED     %RAW USED 
    347G      339G        8263M          2.32 
POOLS:
    NAME                    ID     USED      %USED     MAX AVAIL     OBJECTS 
    ......
    cephfs_data             5      5035k         0          106G           2 
    cephfs_metadata         6       7541         0          106G          21 

6.3 通过ceph kernel driver挂载

首先,我们尝试在server3上测试ceph kernel driver挂载。

和ceph-fuse一样,通过ceph kernel driver挂载也需要admin的权限。不同的是,不需要admin的keyring文件,而是直接需要admin的key:

[root@server3 ~]# mkdir /mnt/kcephfs
[root@server3 ~]# mount -t ceph server0:6789:/ /mnt/kcephfs/ -o name=admin,secret=AQD88e9aAwlyBRAAVwhjmH8GGVmG+JFYs/3MAA==

这个命令卡了一段时间后,报出如下错误:

mount error 5 = Input/output error

在/var/log/messages中,有如下错误信息:

[root@server3 ~]# tail /var/log/messages
May  7 17:41:29 server3 kernel: libceph: mon0 192.168.100.160:6789 feature set mismatch, my 103b84a842aca < server's 40103b84a842aca, missing 400000000000000
May  7 17:41:29 server3 kernel: libceph: mon0 192.168.100.160:6789 missing required protocol features

就是说:ceph集群需要的feature set,我们的ceph kernel driver没能够全部提供,缺失的是400000000000000。

CephNotes里,我们可以看到,缺失有些feature,可以通过两种办法解决:

  1. 升级内核 (从客户端入手解决)
  2. 对集群做某些设置 (从server端入手解决)

例如:

  • missing 2040000 (CEPH_FEATURE_CRUSH_TUNABLES 和CEPH_FEATURE_CRUSH_TUNABLES2 ):
    把客户server(cephfs挂载机)的内核升到3.9(或以上) ;
    把tunables设置为legacy : ceph osd crush tunables legacy;
  • missing 40000000 (CEPH_FEATURE_OSDHASHPSPOOL):
    把客户server(rbd客户机?)的内核升到3.9(或以上) ;
    ceph osd pool set rbd hashpspool false
  • missing 800000000 (CEPH_FEATURE_OSD_CACHEPOOL):
    把客户server的内核升到3.14(或以上) ;
    删除cache pool并reload monitors;

悲剧的是,我们缺失的400000000000000 (CEPH_FEATURE_NEW_OSDOPREPLY_ENCODING),无法通过设置集群来解决,也就是说必须升级内核(到4.5以上)。

参考:http://cephnotes.ksperis.com/blog/2014/01/21/feature-set-mismatch-error-on-ceph-kernel-client

刚好,我有个开发server(devbuild:192.168.100.150),已经编译安装过内核 4.14.39。去试试。如4.1.B节所述,monitor运行于public network上(192.168.100.0/24),devbuild能够访问这个网络。这就足够了。注意:这个server不需安装任何ceph包

# ping 192.168.100.160
PING 192.168.100.160 (192.168.100.160) 56(84) bytes of data.
64 bytes from 192.168.100.160: icmp_seq=1 ttl=64 time=4.12 ms
64 bytes from 192.168.100.160: icmp_seq=2 ttl=64 time=0.557 ms
......

[root@devbuild ~]# uname -a
Linux devbuild 4.14.39.hyg.20180503  ......

[root@devbuild ~]# mkdir /mnt/kcephfs

[root@devbuild ~]# mount -t ceph 192.168.100.162:6789:/ /mnt/kcephfs/ -o name=admin,secret=AQD88e9aAwlyBRAAVwhjmH8GGVmG+JFYs/3MAA==

[root@devbuild ~]# ls /mnt/kcephfs/
vmlinuz-3.10.0-327.el7.x86_64

已经mount成功,并且能看到第6.2节拷贝过去的文件。再测试拷贝一个文件,可见读写正常:

[root@devbuild ~]# cp linux-4.14.39.tar.xz /mnt/kcephfs/

[root@devbuild ~]# ll /mnt/kcephfs/
total 103560
-rw-r--r-- 1 root root 100888428 May  7 18:27 linux-4.14.39.tar.xz
-rwxr-xr-x 1 root root   5156528 May  7 17:30 vmlinuz-3.10.0-327.el7.x86_64

另外,根据官方文档,命令:

# mount -t ceph 192.168.100.162:6789:/ /mnt/kcephfs/ -o name=admin,secret=AQD88e9aAwlyBRAAVwhjmH8GGVmG+JFYs/3MAA==

也可以换做:

# cat admin.secret 
AQD88e9aAwlyBRAAVwhjmH8GGVmG+JFYs/3MAA==

# mount -t ceph 192.168.100.162:6789:/ /mnt/kcephfs/ -o name=admin,secretfile=admin.secret

但是,我这样尝试,一直报错:

[root@devbuild ~]# cat admin.secret
AQD88e9aAwlyBRAAVwhjmH8GGVmG+JFYs/3MAA==
[root@devbuild ~]# mount -t ceph 192.168.100.162:6789:/ /mnt/kcephfs/ -o name=admin,secretfile=admin.secret
mount: wrong fs type, bad option, bad superblock on 192.168.100.162:6789:/,
       missing codepage or helper program, or other error

       In some cases useful info is found in syslog - try
       dmesg | tail or so.


[root@devbuild ~]# dmesg | tail 
[   66.850589] random: 7 urandom warning(s) missed due to ratelimiting
[  140.953833] Key type dns_resolver registered
[  141.096210] Key type ceph registered
[  141.097950] libceph: loaded (mon/osd proto 15/24)
[  141.160712] ceph: loaded (mds proto 32)
[  141.163762] libceph: bad option at 'secretfile=admin.secret'

原因是,我的这个server没有安装任何ceph包,所以没有/usr/sbin/mount.ceph这个文件。解决办法:
1. 从别的server拷贝这个文件;
2. 安装ceph-common;

# yum install -y ceph-common-12.2.5-0.el7.x86_64

前文说过,devbuild server不需安装任何ceph包,但若使用secretfile的方式,还是安装这个ceph-common为好。

7. 增加rbd

7.1 准备rbd pool

在集群内的任意server上创建一个pool,并init:

# ceph osd pool create rbd_pool 100 100
pool 'rbd_pool' created

# rbd pool init rbd_pool

7.2 创建块设备

首先我们尝试在集群内的一个server(server0)上创建块设备。

# rbd create foo --size 4096 --image-feature layering -m 192.168.100.160 -K admin.secret -p rbd_pool
# rbd map foo --name client.admin -m 192.168.100.160 -K admin.secret -p rbd_pool

rbd: sysfs write failed
rbd: error opening default pool 'rbd'
Ensure that the default pool has been created or specify an alternate pool name.
In some cases useful info is found in syslog - try "dmesg | tail".
rbd: map failed: (5) Input/output error


# dmesg | tail 
......
[527394.031762] libceph: mon0 192.168.100.160:6789 feature set mismatch, my 102b84a842a42 < server's 40102b84a842a42, missing 400000000000000
[527394.034677] libceph: mon0 192.168.100.160:6789 missing required protocol features

和6.3节遇到的问题一样,内核版本低,缺feature 400000000000000。还是到devbuild这个server上创建吧,要求:

  • devbuild server能够访问monitor (public network);
  • 安装ceph-common;
  • admin.secret;

如6.3节所述,都已满足。可以创建块设备了:

# rbd create foo --size 4096 --image-feature layering -m 192.168.100.160 -K admin.secret -p rbd_pool

# rbd map foo --name client.admin -m 192.168.100.160 -K admin.secret -p rbd_pool

选项-K admin.secret也可以换成-k ceph.client.admin.keyring。成功之后:

# ll /dev/rbd0
brw-rw----. 1 root disk 251, 0 May 10 16:31 /dev/rbd0

# ls /dev/rbd/
rbd_pool

# ls /dev/rbd/rbd_pool
foo

这时候,我们可以使用/dev/rbd0了:

# mkfs.ext4 /dev/rbd0 
# mount /dev/rbd0 /mnt/rbd/

8. 小结

本文实践了使用ceph-deploy安装部署ceph集群的过程,给集群添加了三种类型的客户端,并且解决了一些部署中常见的问题。