时间: 2020-09-03 00:08:26 人气: 2279 评论: 0
场景介绍:在我们的IDC中,存在着运行了3-6年的Ceph集群的服务器,这些服务器性能和容量等都已经无法满足当前业务的需求,在购入一批高性能机器后,希望将旧机器上的集群整体迁移到新机器上,当然,是保证业务不中断的前提下,再将旧机器下架回收。本文就介绍了一种实现业务不中断的数据迁移方案,并已经在多个生产环境执行。
本文的环境均为:Openstack+Ceph 运行虚拟机的场景,即主要使用RBD,不包含RGW,MDS。虚机的系统盘(Nova),云硬盘(Cinder),镜像盘(Glance)的块均保存在共享存储Ceph中。
环境准备
本文环境为 Openstack (Kilo) + Ceph(Jewel)
本文所用的环境包含一套完整的 Openstack 环境,一套 Ceph 环境,其中 Nova/Cinder/Glance 均已经对接到了 Ceph 集群上,具体节点配置如下:
主机名 | IP地址 | Openstack 组件 | Ceph 组件 |
|---|---|---|---|
con | 192.168.100.110 | nova,cinder,glance,neutron | mon,osd*1 |
com | 192.168.100.111 | nova,neutron | mon,osd*1 |
ceph | 192.168.100.112 | mon,osd*1 |
在集群整体迁移完后,各个组件分布如下,也就是说,将运行于 con,com,ceph三个节点的 Ceph 集群迁移到 new_mon_1,new_mon_2,new_mon_3 这三台新机器上。
主机名 | IP地址 | Openstack 组件 | Ceph 组件 |
|---|---|---|---|
con | 192.168.100.110 | nova,cinder,glance,neutron | |
com | 192.168.100.111 | nova,neutron | |
ceph | 192.168.100.112 | ||
new_mon_1 | 192.168.100.113 | mon,osd*1 | |
new_mon_2 | 192.168.100.114 | mon,osd*1 | |
new_mon_3 | 192.168.100.115 | mon,osd*1 |
在迁移之前,我们创建一个虚机,一个云盘,上传一个镜像,虚机此时正常运行,并将这这块云盘挂载到虚机上:
[root@con ~(keystone_admin)]# nova list +--------------------------------------+---------+--------+------------+-------------+-------------------------+ | ID | Name | Status | Task State | Power State | Networks | +--------------------------------------+---------+--------+------------+-------------+-------------------------+ | 4f52191f-9645-448f-977b-80ca515387f7 | vm-test | ACTIVE | - | Running | provider=192.168.88.111 | +--------------------------------------+---------+--------+------------+-------------+-------------------------+ [root@con ~(keystone_admin)]# cinder list +--------------------------------------+--------+--------------+------+-------------+----------+--------------------------------------+ | ID | Status | Display Name | Size | Volume Type | Bootable | Attached to | +--------------------------------------+--------+--------------+------+-------------+----------+--------------------------------------+ | 39c76d96-0f95-490c-b7db-b3da6d17331b | in-use | cinder-rbd | 1 | None | false | 4f52191f-9645-448f-977b-80ca515387f7 | +--------------------------------------+--------+--------------+------+-------------+----------+--------------------------------------+ [root@con ~(keystone_admin)]# ip netns exec `ip netns` ssh cirros@192.168.88.111 cirros@192.168.88.111's password: $ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT vda 253:0 0 1G 0 disk `-vda1 253:1 0 1011.9M 0 part / vdb 253:16 0 1G 0 disk $
Ceph 集群状态:
[root@ceph cluster]# ceph -s cluster 166889ab-fa7b-4a07-83da-6dfc92913a3d health HEALTH_OK monmap e47: 3 mons at {ceph=192.168.100.112:6789/0,com=192.168.100.111:6789/0,con=192.168.100.110:6789/0} election epoch 174, quorum 0,1,2 con,com,ceph osdmap e57: 3 osds: 3 up, 3 in flags sortbitwise,require_jewel_osds pgmap v6577: 768 pgs, 3 pools, 45659 kB data, 23 objects 178 MB used, 766 GB / 766 GB avail 768 active+clean [root@ceph cluster]# ceph osd tree ID WEIGHT TYPE NAME UP/DOWN REWEIGHT PRIMARY-AFFINITY -1 0.74876 root default -2 0.24959 host ceph 0 0.24959 osd.0 up 1.00000 1.00000 -3 0.24959 host con 1 0.24959 osd.1 up 1.00000 1.00000 -4 0.24959 host com 2 0.24959 osd.2 up 1.00000 1.00000 [root@ceph cluster]# ceph osd pool ls detail pool 1 'volumes' replicated size 2 min_size 1 crush_ruleset 0 object_hash rjenkins pg_num 256 pgp_num 256 last_change 58 flags hashpspool stripe_width 0 removed_snaps [1~3] pool 2 'vms' replicated size 2 min_size 1 crush_ruleset 0 object_hash rjenkins pg_num 256 pgp_num 256 last_change 59 flags hashpspool stripe_width 0 removed_snaps [1~3] pool 3 'images' replicated size 2 min_size 1 crush_ruleset 0 object_hash rjenkins pg_num 256 pgp_num 256 last_change 60 flags hashpspool stripe_width 0 removed_snaps [1~9]
OSD的数据迁移
本次迁移主要分为两个组件的迁移,即 MON 和 OSD,这里我们先介绍 OSD 的数据迁移。相比迁移MON来说,OSD的数据迁移步骤更为单纯一些,因为所有操作均在 Ceph 侧执行,对 Openstack 来说是透明的。
由于CRUSH算法的伪随机性,对于一个PG来说,如果 OSD tree 结构不变的话,它所分布在的 OSD 集合总是固定的(同一棵tree下的OSD结构不变/不增减),即对于两副本来说: PG 1.0 => [osd.66, osd.33]
• crush rule 0 (原先默认生成的): 从 old_tree 下选出size副本(这里size=2)。
• crush rule 1 (新生成的第一条): 从 old_tree 下选出两副本。对于副本数为2的集群来说,crush_rule_0 和 crush_rule_1 选出的两副本是一样的。
• crush rule 2 (新生成的第二条): 从 old_tree 下选出两副本,再从 new_tree 下选出两副本。由**原理简介第二段**可知, 由于 old_tree 下面的 OSD结构不变也没有增加,所以 crush_rule_0 和 crush_rule_1 选出的前两副本是**一样的**。
• crush rule 3 (新生成的第三条): 从 new_tree 下选出两副本。 由于crush_rule_1 的第二次选择为选出 new_tree下的前两副本,这和 crush_rule_2 选出两副本(也是前两副本)其实是**一样的**。