Ceph是一个统一的分布式存储系统,设计初衷是提供较好的性能、可靠性和可扩展性。 Ceph项目最早起源于Sage就读博士期间的工作(2004年),并随后贡献给开源社区。在经过了数年的发展之后,目前已得到众多云计算厂商的支持并被广泛应用。RedHat及OpenStack都可与Ceph整合以支持虚拟机镜像的后端存储。 --from <<Ceph 介绍及原理架构分享>>


Table of Contents

  1. 准备工作
    1. 软件版本
    2. 集群架构
    3. 系统准备
      1. 建立统一用户
      2. 安装 ceph-deploy
      3. 集群节点 hosts 设置
      4. 更改主机名(可选)
      5. ssh 免密登录
      6. 安装配置 ntp service
      7. 关闭/设置防火墙
      8. 安装ceph
  2. 部署 Ceph
    1. 部署 monitors
      1. 创建 三个 monitors:
      2. 汇集分发keys
      3. 检查集群状态
    2. 部署 managers
  3. 部署 MDS (Optional)
  4. 部署 Ceph OSD
    1. 简单块设备
      1. 整块磁盘建立OSD
      2. 磁盘分区
      3. 逻辑巻
    2. 带有 block.db 或/和 block.wal的块设备
      1. block.db 和 block.wal 大小
      2. 磁盘分区
      3. 逻辑巻
    3. 移除 OSD
  5. 自动部署

准备工作

目前主要有两种 ceph 部署方案:

我们主要使用 ceph-deploy 来部署 ceph 集群.

软件版本

ceph-deploy 目前(03/09/2018)的版本是 2.0.1:

1
2
[ceph@localhost ~]$ ceph-deploy --version
2.0.1

Ceph 配置安装源:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[ceph]
name=Ceph noarch packages
baseurl=https://download.ceph.com/rpm-mimic/el7/x86_64
enabled=1
gpgcheck=1
type=rpm-md
gpgkey=https://download.ceph.com/keys/release.asc

[ceph-noarch]
name=Ceph noarch packages
baseurl=https://download.ceph.com/rpm-mimic/el7/noarch
enabled=1
gpgcheck=1
type=rpm-md
gpgkey=https://download.ceph.com/keys/release.asc

[ceph-source]
name=Ceph noarch packages
baseurl=https://download.ceph.com/rpm-mimic/el7/SRPMS
enabled=1
gpgcheck=1
type=rpm-md
gpgkey=https://download.ceph.com/keys/release.asc

Ceph 目前的版本是 13.2.1 (mimic):

1
2
[ceph@localhost ~]$ ceph --version
ceph version 13.2.1 (5533ecdc0fda920179d7ad84e0aa65a127b20d77) mimic (stable)

系统版本采用的是最新的 CentOS 7.5:

1
2
3
4
5
6
7
8
[ceph@localhost ~]$ lsb release -a
LSB Version: :core-4.1-amd64:core-4.1-noarch:cxx-4.1-amd64:cxx-4.1-noarch:desktop-4.1-amd64:desktop-4.1-noarch:languages-4.1-amd64:languages-4.1-noarch:printing-4.1-amd64:printing-4.1-noarch
[ceph@vm084021 ~]$ lsb_release -a
LSB Version: :core-4.1-amd64:core-4.1-noarch
Distributor ID: CentOS
Description: CentOS Linux release 7.5.1804 (Core)
Release: 7.5.1804
Codename: Core

集群架构

作为一个测试集群, 为方便,我们单独用一个node作为部署节点(ceph0), 用来部署集群, 三个节点(ceph1, ceph2, ceph3) 作为监督节点(monitors), 同时这三个 mon 节点也做为osd 节点.

系统准备

建立统一用户

1
2
3
[localhost ~]$ useradd -m -d /home/ceph -r -U -u 1000 ceph
[localhost ~]$ usermod -aG wheel ceph
[localhost ~]$ sed -i "s|^# %wheel|%wheel|g" /etc/sudoers

在下面的安装中都使用 ceph 用户.

安装 ceph-deploy

在部署节点安装 ceph-deploy:

1
[ceph@ceph0 ~]$ sudo pip2 install -U ceph-deploy remoto

集群节点 hosts 设置

1
2
3
4
5
6
#### adding following lines to the end of /etc/hosts
#### change IPs according to your servers
10.0.1.10 ceph0 admin
10.0.1.11 ceph1
10.0.1.12 ceph2
10.0.1.13 ceph3

更改主机名(可选)

将主机名更改为 /etc/hosts 中对应的名字:

1
echo ceph0 > /etc/hostname

ssh 免密登录

1
2
3
4
[ceph@ceph0 ~]$ ssh-keygen -t rsa -b 2048
[ceph@ceph0 ~]$ cat .ssh/id_rsa.pub >> .ssh/authorized_keys
[ceph@ceph0 ~]$ for i in ceph1 ceph2 ceph3;do ssh-copy-id -i ~/.ssh/id_rsa.pub $i; done
[ceph@ceph0 ~]$ for i in ceph1 ceph2 ceph3;do scp ~/.ssh/id_rsa $i:~/.ssh/; done

安装配置 ntp service

1
2
3
4
5
#### on ceph0
[ceph@ceph0 ~]$ for host in ceph{0..3};do
> ssh ceph${host} "sudo yum install -y ntp ntpdate"
> ssh ceph${host} "sudo systemctl enable --now ntpd"
> done

关闭/设置防火墙

1
2
3
4
5
#### disable firewalld
[ceph@ceph0 ~]$ for host in ceph{0..3}; do
> ssh ceph${host} "sudo systemctl disable firewalld"
> ssh ceph${host} "sudo systemctl stop firewalld"
> done

如果不关闭防火墙,需要打开 Ceph 所有节点上各服务相应的端口。

1
2
3
4
5
6
7
8
9
10
#### firewalld
[ceph@ceph0 ~]$ for host in ceph{1..3}; do
firewall-cmd --permanent --add-port=3300/tcp --zone=public
firewall-cmd --permanent --add-port=6789/tcp --zone=public
firewall-cmd --permanent --add-port=6800-7300/tcp --zone=public
# or simply
firewall-cmd --permanent --add-service=ceph --zone=public
firewall-cmd --permanent --add-service=ceph-mon --zone=public

#### iptables

安装ceph

1
[ceph@ceph0 ~]$ ceph-deploy install ceph0 ceph1 ceph2 ceph3

ceph-deploy 会使用 ceph@ceph0 来连接 ceph0, 所以需要做 ssh 免密登录.

部署 Ceph

ceph 集群有一个默认的集群名 - ceph, 如果你想运行多个ceph集群, 可以在部署时通过--cluster name 指定一个名字. 如果在同一硬件上运行多个实例,还需要更改默认的端口设置,以避免冲突.

部署 monitors

创建 三个 monitors:

1
2
3
4
#### hsotname ceph1/2/3 must match the actual `hostname -s` in the remote host
[ceph@ceph0 ~]$ ceph-deploy new ceph1 ceph2 ceph3
[ceph@ceph0 ~]$ ceph-deploy mon create ceph1 ceph2 ceph3
#### a ceph.conf and ceph.mon.keyring will be created under current directory

汇集分发keys

1
2
3
4
5
6
7
8
9
10
11
#### monitors keys
#### wait for a while after "ceph-deploy mon create"
[ceph@ceph0 ~]$ ceph-deploy gatherkeys ceph1 ceph2 ceph3
#### distribute keys to admin nodes in cluster
[ceph@ceph0 ~]$ ceph-deploy admin ceph0 ceph1 ceph2 ceph3
#### change permissions
for i in ceph{1..3}; do
ssh ceph$i "sudo chown -R ceph:ceph /etc/ceph";
ssh ceph$i "sudo chown -R ceph:ceph /var/lib/ceph";
ssh ceph$i "sudo chown -R ceph:ceph /var/log/ceph";
done

检查集群状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[ceph@ceph0 ~]$ ceph -s
cluster:
id: 3cdc0d3a-6f09-4f06-977e-017e273bbb07
health: HEALTH_OK

services:
mon: 3 daemons, quorum ceph1,ceph2,ceph3
mgr: no daemons active
osd: 0 osds: 0 up, 0 in

data:
pools: 0 pools, 0 pgs
objects: 0 objects, 0
usage: 0 B used, 0 B / 0 B avail
pgs:

部署 managers

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[ceph@ceph0 ~]$ ceph-deploy mgr create ceph1 ceph2 ceph3
[ceph@ceph0 ~]$ ceph -s
cluster:
id: 3cdc0d3a-6f09-4f06-977e-017e273bbb07
health: HEALTH_OK

services:
mon: 3 daemons, quorum ceph1,ceph2, ceph3
mgr: ceph1(active), standbys: ceph2, ceph3
osd: 0 osds: 0 up, 0 in

data:
pools: 0 pools, 0 pgs
objects: 0 objects, 0
usage: 0 B used, 0 B / 0 B avail
pgs:

部署 MDS (Optional)

使用 ceph-deploy 创建 mds 非常简单:

1
2
3
4
### Usage:
[ceph@ceph0 ~]$ ceph-deploy mds create {host-name}[:{daemon-name}] [{host-name}[:{daemon-name}] ...]
### e.g.
[ceph@ceph0 ~]$ ceph-deploy mds create ceph1 ceph2 ceph3

daemon-name 是可选的, 如果要在一个节点上运行多个 mds 实例, 可能需要为每个 mds 实例设定 daemon-name.

部署 Ceph OSD

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#### ceph-deploy osd create usage
[ceph@ceph0 ~]$ ceph-deploy osd create -h
usage: ceph-deploy osd create [-h] [--data DATA] [--journal JOURNAL]
[--zap-disk] [--fs-type FS_TYPE] [--dmcrypt]
[--dmcrypt-key-dir KEYDIR] [--filestore]
[--bluestore] [--block-db BLOCK_DB]
[--block-wal BLOCK_WAL] [--debug]
[HOST]

positional arguments:
HOST Remote host to connect

optional arguments:
-h, --help show this help message and exit
--data DATA The OSD data logical volume (vg/lv) or absolute path
to device
--journal JOURNAL Logical Volume (vg/lv) or path to GPT partition
--zap-disk DEPRECATED - cannot zap when creating an OSD
--fs-type FS_TYPE filesystem to use to format DEVICE (xfs, btrfs)
--dmcrypt use dm-crypt on DEVICE
--dmcrypt-key-dir KEYDIR
directory where dm-crypt keys are stored
--filestore filestore objectstore
--bluestore bluestore objectstore
--block-db BLOCK_DB bluestore block.db path
--block-wal BLOCK_WAL
bluestore block.wal path
--debug Enable debug mode on remote ceph-volume calls

Luminous 12.2.2 之后, Ceph 中创建一个 OSD 就开始使用 ceph-volume 了.

创建一个 bluestore 的 OSD, 有如下几种选择:

  • A single block device
  • A block device and a block.db device
  • A block device and a block.val device
  • A block device ,a block.val and a block.db device

block device 也有几种选择:

  • 整块磁盘
  • 磁盘分区
  • 逻辑巻(A logical Volume of LVM)
    在使用整块磁盘和磁盘分区时, ceph-volume 默认会自动创建一个 logical volume 使用.

简单块设备

整块磁盘建立OSD

使用一整块磁盘建立一个OSD, 可用如下命令:

1
ceph-deploy osd create [host] --data [/path/to/device] [--zap-disk]

--zap-disk 是为了销毁已有的文件系统. 比如使用 ceph1 上的 /dev/sdb 来创建一个 ext4 系统的 OSD

1
[ceph@ceph0 ~]$ ceph-deploy osd create ceph1 --data /dev/sdb --fs-type ext4 --zap-disk

查看 OSD 信息:

1
2
3
4
5
6
[ceph@ceph0 ~]$ ssh ceph1 "df -h"
...
[ceph@ceph0 ~]$ ssh ceph1 "ls /var/lib/ceph/osd/ceph-1"
...
[ceph@ceph0 ~]$ ssh ceph1 "lsblk /dev/sdb"
...

磁盘分区

使用一个分区来创建一个 OSD 与使用整个磁盘类似:

1
ceph-deploy osd create [host] --data [/path/to/device_part] [--zap-disk]

注意, 磁盘格式须为GPT 分区格式(???).
例如

1
[ceph@ceph0 ~]$ ceph-deploy osd create ceph1 --data /dev/sdc1

逻辑巻

命令格式为:

1
ceph-deploy osd create [host] --data [vg/lv]

我们可以使用 loop 文件来创建 逻辑巻, 再创建 OSD.

1
2
3
4
5
6
7
8
[ceph@ceph0 ~]$ ssh ceph@ceph1
[ceph$ceph1 ~]$ dd if=/dev/zero of=ceph.0.img bs=1M count 2048
[ceph@ceph1 ~]$ sudo losetup /dev/loop0 /home/ceph/ceph.0.img
[ceph@ceph1 ~]$ sudo pvcreate /dev/loop
[ceph@ceph1 ~]$ sudo vgcreate sdavg /dev/loop0
[ceph@ceph1 ~]$ sudo lvcreate sdalv -l 100%FREE sdavg
[ceph@ceph1 ~]$ exit
[ceph@ceph0 ~]$ ceph-deploy osd create ceph1 -data sdavg/sdalv

若是指定--data /dev/sdavg/sdalv, ceph-volume 会认为是块设备而报错. 这一种只是自己手动创建了 PV, VG, LV, 其他与前面两种方式一样.

带有 block.db 或/和 block.wal的块设备

当指定 block.db 或/和 block.wal 时, 对应的设备只能为磁盘分区逻辑巻. --data 的情况与简单块设备情况类似, 我们选择整个磁盘为例.

block.db 和 block.wal 大小

默认情况下, block.dbblock.wal 都比较小, block.db=0, block.wal=100663296.

1
2
3
4
5
6
7
8
9
10
11
[ceph@ceph0 ~]$ ceph-config --show-config|grep bluestore_block
bluestore_block_create = true
bluestore_block_db_create = false
bluestore_block_db_path
bluestore_block_db_size =
bluestore_block_path
bluestore_block_preallocate_file = false
bluestore_block_size = 10737418240
bluestore_block_wal_create = false
bluestore_block_wal_path
bluestore_block_wal_size = 100663296

所以, 用来存储 block.dbblock.wal 的分区或 逻辑巻容量不用太大. 这里我们选择 10G.

磁盘分区

基本命令格式为

1
ceph-deploy osd create [host] --data [/path/to/device] --block-db [/path/to/device-partition] --block-wal [/path/to/device-partition]

例如

1
[ceph@ceph0 ~]$ ceph-deploy osd create ceph1 --data /dev/sdd --block-db /dev/sde1 --block-wal /dev/sde2

与前面相比, 只是多指定了 block-dbblock-wal的位置.

逻辑巻

1
ceph-deploy osd create [host] --data [/path/to/device] --block-db [vg/lv]  --block-wal [vg/lv]

例如

1
2
3
4
5
6
7
[ceph@ceph0 ~]$ ssh ceph1
[ceph@ceph1 ~]$ pvcreate /dev/sdh
[ceph@ceph1 ~]$ vgcreate sdhvg /dev/sdh
[ceph@ceph1 ~]$ lvcreate -n db-lv-0 -L 4G sdhvg
[ceph@ceph1 ~]$ lvcreate -n wal-lv-0 -L 8G sdhvg
[ceph@ceph1 ~]$ exit
[ceph@ceph0 ~]$ ceph-deploy osd create ceph1 --data /dev/sdg --block-db sdhvg/db-lv-0 --block-wal sdhvg/wal-lv-0

与前面一样, 也是多指定了--block-db--block-wal 的位置. 需要注意的是, --block-db--block-wal 的格式为 vg/lv, 而不能是 /dev/vg/lv, 否则会报错.

移除 OSD

如果某些 OSD 在建立的时候有问题, 要移除这些 OSD, 可按照如下命令进行.

1
2
3
4
5
6
7
8
9
10
for id in {osds_to_be_removed}; do
## mark osd out
ceph osd out $i
## remove osd from crush map
ceph osd crush remove osd.${i}
## delete osd authencation key
ceph auth del osd.${i}
## remove osd finally
ceph osd rm ${i}
done

自动部署

基于 ceph-deploy, 我们可以开发一个自动部署 Ceph 的脚本。 设定好 Ceph 集群的配置,比如下面这样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
{
"cluster": "ceph",
"install": ["ceph0", "ceph1", "ceph2", "ceph3"],
"mon": ["ceph1", "ceph2", "ceph3"],
"mgr": ["ceph1", "ceph2", "ceph3"],
"admin": ["ceph1", "ceph2", "ceph3"],
"osd":[
{
"host": "ceph1",
"data": ["sdavg/sdalv", "sdbvg/sdblv", "sdcvg/sdclv"]
},
{
"host": "ceph2",
"data": ["sdavg/sdalv", "sdbvg/sdblv", "sdcvg/sdclv"]
},
{
"host": "ceph3",
"data": ["sdavg/sdalv", "sdbvg/sdblv", "sdcvg/sdclv"]
}
],
"pool":[
{
"name": "rbd",
"pg_num": 256,
"pgp_num": 256
},
{
"name": "images",
"pg_num": 256,
"pgp_num": 256
}

}

就可以用 Python 写一个简单脚本来自动部署 Ceph。