Ceph 集群在线迁移方案

一 环境准备

1.1 场景介绍

        最近收到一个需求,客户希望将运行了多年的ceph集群服务器全部更换掉,因为这些老服务器性能和容量都已经无法满足当前业务的需求,并希望在迁移到新服务器的过程中,业务不中断。在参考一些网上的方案后,选择了一个方案进行了测试,效果还不错,决定将测试过程记录下来,并且自己写了些自动化的脚本,希望以后迁移能够变得更轻松。

1.2 环境介绍

        本文测试环境为centos7,+ceph 14.2.0,主要使用RBD(块存储),暂不包含RGW,MDS。
具体节点配置如下: 

主机名 IP地址 Ceph 组件
node1 192.168.10.17 mon,osd*1
node2 192.168.10.18 mon,osd*1
node3 192.168.10.19 mon,osd*1


 

 

 

 

       集群迁移完成后,各组件分布如下:(将node1,node2,node3上的集群迁移到node4,node5,node6这3台新机器上)

主机名 IP地址 Ceph 组件
node1 192.168.10.17  
node2 192.168.10.18  
node3 192.168.10.19  
node4 192.168.10.123 mon,osd*2
node5 192.168.10.124 mon,osd*2
node6 192.168.10.125 mon,osd*2

 

 

 

 

 

 

 

 

注意:原集群一共3个osd,我在每个新节点上多增加了一块硬盘,所以迁移后集群共有6个osd

二 数据迁移

2.1 迁移思路

(注意:osd_crush_update_on_start = false 这一项必须设置为false,否则加入osd后会自动分配到默认的crush下,造成了数据迁移。)

2.2 准备数据迁移

         编辑config.ini配置文件,添加集群信息。示例配置如下:

#重要:请保证配置信息正确,不要配错,否则会影响到数据迁移后续操作

#此项name属性为需要迁移的存储池名称,size为此存储池的副本数
[pool]
name=rbd
size=3

#此项name属性所有新节点的主机名,用“,”号隔开(请用英文输入法的逗号隔开,不要有空格)
[host]
name=node4,node5,node6

#以下配置为新节点所对应的osd信息,其中osd属性为osd的id,size属性为osd的大小,单位为GB,用“,”号隔开(请用英文输入法的逗号隔开,不要有空格)
#此项配置意思为在节点node4上有两个osd,分别为osd.3 大小为20GB,osd.4,大小为20GB.
[node4]
osd=3,4
size=20,20

#此项配置意思为在节点node5上有两个osd,分别为osd.5 大小为20GB,osd.6,大小为20GB.
[node5]
osd=5,6
size=20,20

#此项配置意思为在节点node6上有两个osd,分别为osd.7 大小为20GB,osd.8,大小为20GB.
[node6]
osd=7,8
size=20,20

 

2.3 开始数据迁移

        确认config.ini信息配置无误后,开始迁移数据。
        1.执行sh crush.sh(此脚本会创建一些迁移规则,如下图所示,等待控制台不再刷新集群动态的消息时,按ctrl+c退出集群监控,继续执行下面的步骤,若想再次打开集群监控,可执行ceph -w命令)

rule.sh:(crush.sh会调用)

#!/bin/bash
poolName=$1
migrateCrush=$2
size=$3
maxId=$4
echo  "rule src_${size} {
        id $[${maxId}+1]
        type replicated
        min_size 1
        max_size 10
        step take ${poolName}
        step chooseleaf firstn ${size} type host
        step emit
}
rule src_temp_${size} {
        id $[${maxId}+2]
        type replicated
        min_size 1
        max_size 10
        step take ${poolName}
        step chooseleaf firstn ${size} type host
        step emit
        step take ${migrateCrush}
        step chooseleaf firstn ${size} type host
        step emit
}
rule target_${size} {
        id $[${maxId}+3]
        type replicated
        min_size 1
        max_size 10
        step take ${migrateCrush}
        step chooseleaf firstn ${size} type host
        step emit
}"

crush.sh:

#!/bin/bash
config="config.ini"
poolName=`awk -F '=' '/\[pool\]/{a=1}a==1&&$1~/name/{print $2;exit}' $config`
poolSize=`awk -F '=' '/\[pool\]/{a=1}a==1&&$1~/size/{print $2;exit}' $config`
migrateCrush=$poolName"_migrate_temp"
ceph osd crush add-bucket $migrateCrush root
hostnames=`awk -F '=' '/\[host\]/{a=1}a==1&&$1~/name/{print $2;exit}' $config`
for hostname in `echo "$hostnames" | sed 's/,/\n/g'`
do
        ceph osd crush add-bucket $hostname"_"$poolName host
        ceph osd crush move $hostname"_"$poolName root=$migrateCrush
        osds=`awk -F '=' '/\['$hostname'\]/{a=1}a==1&&$1~/osd/{print $2;exit}' $config`
        sizes=`awk -F '=' '/\['$hostname'\]/{a=1}a==1&&$1~/size/{print $2;exit}' $config`
        sizeArr=(${sizes//,/ })
        index=0
        for osd in `echo "$osds" | sed 's/,/\n/g'`
        do
                weight=`awk 'BEGIN{printf "%0.5f",'${sizeArr[$index]}'/1000}'`
                ceph osd crush create-or-move osd.$osd $weight host=$hostname"_"$poolName
        done
done

ceph osd getcrushmap -o crushmap
crushtool -d crushmap -o crushmap.txt
id=`grep 'id' -A 0 crushmap.txt |tail -n 1`
idArr=(${id// / })
maxId=${idArr[1]}
sh rule.sh $poolName $migrateCrush $poolSize $maxId>> crushmap.txt
crushtool -c crushmap.txt -o crushmap.bin
ceph osd setcrushmap -i crushmap.bin
ceph osd pool set $poolName crush_rule "src_"$poolSize
ceph osd pool set $poolName size $[$poolSize*2]
ceph -w

        2.执行sh migrate.sh(此脚本开始复制集群数据,数据量越大耗时越长,等待集群ok了就代表复制完毕,执行ceph -w可监控集群实时状态)

#!/bin/bash
config="config.ini"
poolName=`awk -F '=' '/\[pool\]/{a=1}a==1&&$1~/name/{print $2;exit}' $config`
poolSize=`awk -F '=' '/\[pool\]/{a=1}a==1&&$1~/size/{print $2;exit}' $config`
ceph osd pool set $poolName crush_rule "src_temp_"$poolSize
ceph -w

      3,.执行sh target.sh(此脚本将删除旧osd上的数据,看到cluster is now healthy表示完成)

#!/bin/bash
config="config.ini"
poolName=`awk -F '=' '/\[pool\]/{a=1}a==1&&$1~/name/{print $2;exit}' $config`
poolSize=`awk -F '=' '/\[pool\]/{a=1}a==1&&$1~/size/{print $2;exit}' $config`
ceph osd pool set $poolName crush_rule "target_"$poolSize
ceph osd pool set $poolName size $poolSize
ceph -w

        此时集群数据已经完成迁移,可以将旧的osd删除掉

三 MON迁移

3.1 迁移原则

        先增加一个MON,成功后再删除一个MON。

3.2 开始迁移MON

       1.将node4设置为mon和管理节点。
       2.将node1的mon和管理节点去掉。
       3.将node5设置为mon和管理节点。
      4.将node2的mon和管理节点去掉。
      5.将node6设置为mon和管理节点。
      6.将node3的mon和管理节点去掉。

mon和osd等服务都迁移完成后就可以删除旧的主机了。

 

你可能感兴趣的:(ceph)